[POWERPC] spufs: optimize spu_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@lst.de> Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
This commit is contained in:
Родитель
079cdb6161
Коммит
26bec67386
|
@ -163,7 +163,7 @@ int spu_acquire_exclusive(struct spu_context *ctx)
|
|||
* 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;
|
||||
|
||||
|
@ -174,7 +174,7 @@ int spu_acquire_runnable(struct spu_context *ctx)
|
|||
*/
|
||||
if (!ctx->owner)
|
||||
goto out_unlock;
|
||||
ret = spu_activate(ctx, 0);
|
||||
ret = spu_activate(ctx, flags);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
}
|
||||
|
|
|
@ -164,7 +164,7 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
|
|||
/* error here usually means a signal.. we might want to test
|
||||
* the error code more precisely though
|
||||
*/
|
||||
ret = spu_acquire_runnable(ctx);
|
||||
ret = spu_acquire_runnable(ctx, 0);
|
||||
if (ret)
|
||||
return NOPFN_REFAULT;
|
||||
|
||||
|
@ -1306,7 +1306,7 @@ static ssize_t spufs_mfc_write(struct file *file, const char __user *buffer,
|
|||
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 {
|
||||
|
|
|
@ -143,7 +143,7 @@ static inline int spu_run_init(struct spu_context *ctx, u32 * npc)
|
|||
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 @@ static inline int spu_run_init(struct spu_context *ctx, u32 * npc)
|
|||
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
|
||||
|
|
|
@ -247,8 +247,8 @@ static void spu_prio_wait(struct spu_context *ctx)
|
|||
{
|
||||
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();
|
||||
|
@ -256,6 +256,7 @@ static void spu_prio_wait(struct spu_context *ctx)
|
|||
}
|
||||
__set_current_state(TASK_RUNNING);
|
||||
remove_wait_queue(&ctx->stop_wq, &wait);
|
||||
clear_bit(SPU_SCHED_WAKE, &ctx->sched_flags);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -275,7 +276,7 @@ static void spu_reschedule(struct spu *spu)
|
|||
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);
|
||||
}
|
||||
spin_unlock(&spu_prio->runq_lock);
|
||||
|
@ -315,7 +316,7 @@ static struct spu *spu_get_idle(struct spu_context *ctx)
|
|||
* 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)
|
||||
|
@ -331,7 +332,8 @@ int spu_activate(struct spu_context *ctx, u64 flags)
|
|||
}
|
||||
|
||||
spu_add_to_rq(ctx);
|
||||
spu_prio_wait(ctx);
|
||||
if (!(flags & SPU_ACTIVATE_NOWAKE))
|
||||
spu_prio_wait(ctx);
|
||||
spu_del_from_rq(ctx);
|
||||
} while (!signal_pending(current));
|
||||
|
||||
|
|
|
@ -39,6 +39,11 @@ enum {
|
|||
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. */
|
||||
|
@ -77,6 +82,7 @@ struct spu_context {
|
|||
|
||||
/* scheduler fields */
|
||||
struct list_head rq;
|
||||
unsigned long sched_flags;
|
||||
int prio;
|
||||
};
|
||||
|
||||
|
@ -179,10 +185,13 @@ int put_spu_context(struct spu_context *ctx);
|
|||
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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче