[Cbe-oss-dev] [PATCH 10/10] spu sched: avoid superflous wakeups inspu_run

장현승 hs8848.jang at samsung.com
Mon Jan 15 17:08:34 EST 2007


The series of patches seems to be a quite good work for better readability.

After applying patches, The patched spu_active() becomes :
int spu_activate(struct spu_context *ctx, unsigned long flags)
{
...
        do {
                struct spu *spu;

                spu = spu_get_idle(ctx);
                if (spu) {
                        spu_bind_context(spu, ctx);
                        return 0;
                }

                spu_add_to_rq(ctx);
                if (!(flags & SPU_ACTIVATE_NOWAKE))
                        spu_prio_wait(ctx);
        } while (!signal_pending(current));
...

If there is no available spus in spu_get_idle(), the loop will hang forever 
because spu_prio_wait() is not called because of SPU_ACTIVATE_NOWAKE propagated from spu_run_init().

Did I miss something?

The description of the patch 
"There is no need to directly wake up contexts in spu_activate" is strange 
because there was originally no wake-up code but waiting code.

> -----Original Message-----
> From: cbe-oss-dev-bounces+hs8848.jang=samsung.com at ozlabs.org [mailto:cbe-
> oss-dev-bounces+hs8848.jang=samsung.com at ozlabs.org] On Behalf Of Christoph
> Hellwig
> Sent: Monday, January 08, 2007 7:16 AM
> To: cbe-oss-dev at ozlabs.org
> Subject: [Cbe-oss-dev] [PATCH 10/10] spu sched: avoid superflous wakeups
> inspu_run
> 
> There is no need to directly wake up contexts in spu_activate when
> called from spu_run, so add a flag to surpress this wakeup.
> 
> 
> Signed-off-by: Christoph Hellwig <hch at lst.de>
> 
> Index: linux-2.6/arch/powerpc/platforms/cell/spufs/spufs.h
> ===================================================================
> --- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/spufs.h	2007-
> 01-07 21:53:39.000000000 +0100
> +++ linux-2.6/arch/powerpc/platforms/cell/spufs/spufs.h	2007-01-07
> 21:53:39.000000000 +0100
> @@ -40,6 +40,11 @@
>  struct spu_context_ops;
>  struct spu_gang;
> 
> +/* ctx->sched_flags */
> +enum {
> +	SPU_SCHED_WAKE = 0,
> +};
> +
>  struct spu_context {
>  	struct spu *spu;		  /* pointer to a physical SPU */
>  	struct spu_state csa;		  /* SPU context save area. */
> @@ -76,6 +81,7 @@
> 
>  	/* scheduler fields */
>   	struct list_head rq;
> +	unsigned long sched_flags;
>  	int prio;
>  };
> 
> @@ -188,10 +194,13 @@
>  void spu_unmap_mappings(struct spu_context *ctx);
> 
>  void spu_forget(struct spu_context *ctx);
> -int spu_acquire_runnable(struct spu_context *ctx);
> +int spu_acquire_runnable(struct spu_context *ctx, unsigned long flags);
>  void spu_acquire_saved(struct spu_context *ctx);
>  int spu_acquire_exclusive(struct spu_context *ctx);
> -int spu_activate(struct spu_context *ctx, u64 flags);
> +enum {
> +	SPU_ACTIVATE_NOWAKE = 1,
> +};
> +int spu_activate(struct spu_context *ctx, unsigned long flags);
>  void spu_deactivate(struct spu_context *ctx);
>  void spu_yield(struct spu_context *ctx);
>  int __init spu_sched_init(void);
> Index: linux-2.6/arch/powerpc/platforms/cell/spufs/sched.c
> ===================================================================
> --- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/sched.c	2007-
> 01-07 21:53:39.000000000 +0100
> +++ linux-2.6/arch/powerpc/platforms/cell/spufs/sched.c	2007-01-07
> 21:53:39.000000000 +0100
> @@ -261,8 +261,8 @@
>  {
>  	DEFINE_WAIT(wait);
> 
> +	set_bit(SPU_SCHED_WAKE, &ctx->sched_flags);
>  	prepare_to_wait_exclusive(&ctx->stop_wq, &wait,
> TASK_INTERRUPTIBLE);
> -
>  	if (!signal_pending(current)) {
>  		mutex_unlock(&ctx->state_mutex);
>  		schedule();
> @@ -270,6 +270,7 @@
>  	}
>  	__set_current_state(TASK_RUNNING);
>  	remove_wait_queue(&ctx->stop_wq, &wait);
> +	clear_bit(SPU_SCHED_WAKE, &ctx->sched_flags);
>  }
> 
>  /**
> @@ -289,7 +290,7 @@
>  	best = sched_find_first_bit(spu_prio->bitmap);
>  	if (best < MAX_PRIO) {
>  		struct spu_context *ctx = spu_grab_context(best);
> -		if (ctx)
> +		if (ctx && test_bit(SPU_SCHED_WAKE, &ctx->sched_flags))
>  			wake_up(&ctx->stop_wq);
>  	}
>  	mutex_unlock(&spu_prio->mutex);
> @@ -329,7 +330,7 @@
>   * add the context to the runqueue so it gets woken up once an spu
>   * is available.
>   */
> -int spu_activate(struct spu_context *ctx, u64 flags)
> +int spu_activate(struct spu_context *ctx, unsigned long flags)
>  {
> 
>  	if (ctx->spu)
> @@ -345,7 +346,8 @@
>  		}
> 
>  		spu_add_to_rq(ctx);
> -		spu_prio_wait(ctx);
> +		if (!(flags & SPU_ACTIVATE_NOWAKE))
> +			spu_prio_wait(ctx);
>  	} while (!signal_pending(current));
> 
> 
> Index: linux-2.6/arch/powerpc/platforms/cell/spufs/context.c
> ===================================================================
> --- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/context.c	2007-
> 01-07 21:53:38.000000000 +0100
> +++ linux-2.6/arch/powerpc/platforms/cell/spufs/context.c	2007-01-07
> 21:53:39.000000000 +0100
> @@ -159,7 +159,7 @@
>   *	Returns 0 and with the context locked on success
>   *	Returns negative error and with the context _unlocked_ on failure.
>   */
> -int spu_acquire_runnable(struct spu_context *ctx)
> +int spu_acquire_runnable(struct spu_context *ctx, unsigned long flags)
>  {
>  	int ret = -EINVAL;
> 
> @@ -170,7 +170,7 @@
>  		 */
>  		if (!ctx->owner)
>  			goto out_unlock;
> -		ret = spu_activate(ctx, 0);
> +		ret = spu_activate(ctx, flags);
>  		if (ret)
>  			goto out_unlock;
>  	}
> Index: linux-2.6/arch/powerpc/platforms/cell/spufs/file.c
> ===================================================================
> --- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/file.c	2007-01-04
> 23:14:46.000000000 +0100
> +++ linux-2.6/arch/powerpc/platforms/cell/spufs/file.c	2007-01-07
> 21:53:39.000000000 +0100
> @@ -168,7 +168,7 @@
>  	if (offset >= ps_size)
>  		goto out;
> 
> -	ret = spu_acquire_runnable(ctx);
> +	ret = spu_acquire_runnable(ctx, 0);
>  	if (ret)
>  		goto out;
> 
> @@ -1309,7 +1309,7 @@
>  	if (ret)
>  		goto out;
> 
> -	spu_acquire_runnable(ctx);
> +	spu_acquire_runnable(ctx, 0);
>  	if (file->f_flags & O_NONBLOCK) {
>  		ret = ctx->ops->send_mfc_command(ctx, &cmd);
>  	} else {
> Index: linux-2.6/arch/powerpc/platforms/cell/spufs/run.c
> ===================================================================
> --- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/run.c	2007-01-07
> 21:53:36.000000000 +0100
> +++ linux-2.6/arch/powerpc/platforms/cell/spufs/run.c	2007-01-07
> 22:46:07.000000000 +0100
> @@ -143,7 +143,7 @@
>  	int ret;
>  	unsigned long runcntl = SPU_RUNCNTL_RUNNABLE;
> 
> -	ret = spu_acquire_runnable(ctx);
> +	ret = spu_acquire_runnable(ctx, SPU_ACTIVATE_NOWAKE);
>  	if (ret)
>  		return ret;
> 
> @@ -155,7 +155,7 @@
>  			spu_release(ctx);
>  			ret = spu_setup_isolated(ctx);
>  			if (!ret)
> -				ret = spu_acquire_runnable(ctx);
> +				ret = spu_acquire_runnable(ctx,
> SPU_ACTIVATE_NOWAKE);
>  		}
> 
>  		/* if userspace has set the runcntrl register (eg, to issue
> an
> _______________________________________________
> cbe-oss-dev mailing list
> cbe-oss-dev at ozlabs.org
> https://ozlabs.org/mailman/listinfo/cbe-oss-dev



More information about the cbe-oss-dev mailing list