]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/powerpc/platforms/cell/spufs/file.c
Merge git://git.infradead.org/mtd-2.6
[linux-2.6-omap-h63xx.git] / arch / powerpc / platforms / cell / spufs / file.c
index adb5abb9af5d71f0cb7cc6eeb319f400ec9a0eb4..b73c369cc6f167a4fa52c9162cfed557c9c1bba0 100644 (file)
@@ -548,6 +548,11 @@ spufs_regs_read(struct file *file, char __user *buffer,
        int ret;
        struct spu_context *ctx = file->private_data;
 
+       /* pre-check for file position: if we'd return EOF, there's no point
+        * causing a deschedule */
+       if (*pos >= sizeof(ctx->csa.lscsa->gprs))
+               return 0;
+
        ret = spu_acquire_saved(ctx);
        if (ret)
                return ret;
@@ -2437,7 +2442,7 @@ static int spufs_switch_log_open(struct inode *inode, struct file *file)
                goto out;
        }
 
-       ctx->switch_log = kzalloc(sizeof(struct switch_log) +
+       ctx->switch_log = kmalloc(sizeof(struct switch_log) +
                SWITCH_LOG_BUFSIZE * sizeof(struct switch_log_entry),
                GFP_KERNEL);
 
@@ -2446,6 +2451,7 @@ static int spufs_switch_log_open(struct inode *inode, struct file *file)
                goto out;
        }
 
+       ctx->switch_log->head = ctx->switch_log->tail = 0;
        init_waitqueue_head(&ctx->switch_log->wait);
        rc = 0;
 
@@ -2503,30 +2509,38 @@ static ssize_t spufs_switch_log_read(struct file *file, char __user *buf,
                char tbuf[128];
                int width;
 
-               if (file->f_flags & O_NONBLOCK) {
-                       if (spufs_switch_log_used(ctx) == 0) {
+               if (spufs_switch_log_used(ctx) == 0) {
+                       if (cnt > 0) {
+                               /* If there's data ready to go, we can
+                                * just return straight away */
+                               break;
+
+                       } else if (file->f_flags & O_NONBLOCK) {
                                error = -EAGAIN;
                                break;
+
+                       } else {
+                               /* spufs_wait will drop the mutex and
+                                * re-acquire, but since we're in read(), the
+                                * file cannot be _released (and so
+                                * ctx->switch_log is stable).
+                                */
+                               error = spufs_wait(ctx->switch_log->wait,
+                                               spufs_switch_log_used(ctx) > 0);
+
+                               /* On error, spufs_wait returns without the
+                                * state mutex held */
+                               if (error)
+                                       return error;
+
+                               /* We may have had entries read from underneath
+                                * us while we dropped the mutex in spufs_wait,
+                                * so re-check */
+                               if (spufs_switch_log_used(ctx) == 0)
+                                       continue;
                        }
-               } else {
-                       /* spufs_wait will drop the mutex and re-acquire,
-                        * but since we're in read(), the file cannot be
-                        * _released (and so ctx->switch_log is stable).
-                        */
-                       error = spufs_wait(ctx->switch_log->wait,
-                                       spufs_switch_log_used(ctx) > 0);
-
-                       /* On error, spufs_wait returns without the
-                        * state mutex held */
-                       if (error)
-                               return error;
                }
 
-               /* We may have had entries read from underneath us while we
-                * dropped the mutex in spufs_wait, so re-check */
-               if (ctx->switch_log->head == ctx->switch_log->tail)
-                       continue;
-
                width = switch_log_sprint(ctx, tbuf, sizeof(tbuf));
                if (width < len)
                        ctx->switch_log->tail =