Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c9101bdb authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Paul Mackerras
Browse files

[POWERPC] spufs: make state_mutex interruptible



Make most places that use spu_acquire/spu_acquire_saved interruptible,
this allows getting out of the spufs code when e.g. pressing ctrl+c.
There are a few places where we get called e.g. from spufs teardown
routines were we can't simply err out so these are left with a comment.
For now I've also not touched the poll routines because it's open what
libspe would expect in terms of interrupted system calls.

Acked-by: default avatarArnd Bergmann <arnd.bergmann@de.ibm.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJeremy Kerr <jk@ozlabs.org>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent 197b1a82
Loading
Loading
Loading
Loading
+20 −3
Original line number Diff line number Diff line
@@ -106,7 +106,17 @@ int put_spu_context(struct spu_context *ctx)
void spu_forget(struct spu_context *ctx)
{
	struct mm_struct *mm;
	spu_acquire_saved(ctx);

	/*
	 * This is basically an open-coded spu_acquire_saved, except that
	 * we don't acquire the state mutex interruptible.
	 */
	mutex_lock(&ctx->state_mutex);
	if (ctx->state != SPU_STATE_SAVED) {
		set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags);
		spu_deactivate(ctx);
	}

	mm = ctx->owner;
	ctx->owner = NULL;
	mmput(mm);
@@ -137,13 +147,20 @@ void spu_unmap_mappings(struct spu_context *ctx)
 * spu_acquire_saved - lock spu contex and make sure it is in saved state
 * @ctx:	spu contex to lock
 */
void spu_acquire_saved(struct spu_context *ctx)
int spu_acquire_saved(struct spu_context *ctx)
{
	spu_acquire(ctx);
	int ret;

	ret = spu_acquire(ctx);
	if (ret)
		return ret;

	if (ctx->state != SPU_STATE_SAVED) {
		set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags);
		spu_deactivate(ctx);
	}

	return 0;
}

/**
+6 −2
Original line number Diff line number Diff line
@@ -148,7 +148,9 @@ int spufs_coredump_extra_notes_size(void)

	fd = 0;
	while ((ctx = coredump_next_context(&fd)) != NULL) {
		spu_acquire_saved(ctx);
		rc = spu_acquire_saved(ctx);
		if (rc)
			break;
		rc = spufs_ctx_note_size(ctx, fd);
		spu_release_saved(ctx);
		if (rc < 0)
@@ -224,7 +226,9 @@ int spufs_coredump_extra_notes_write(struct file *file, loff_t *foffset)

	fd = 0;
	while ((ctx = coredump_next_context(&fd)) != NULL) {
		spu_acquire_saved(ctx);
		rc = spu_acquire_saved(ctx);
		if (rc)
			return rc;

		for (j = 0; spufs_coredump_read[j].name != NULL; j++) {
			rc = spufs_arch_write_note(ctx, j, file, fd, foffset);
+10 −2
Original line number Diff line number Diff line
@@ -107,7 +107,7 @@ int spufs_handle_class1(struct spu_context *ctx)
	u64 ea, dsisr, access;
	unsigned long flags;
	unsigned flt = 0;
	int ret;
	int ret, ret2;

	/*
	 * dar and dsisr get passed from the registers
@@ -146,7 +146,14 @@ int spufs_handle_class1(struct spu_context *ctx)
	if (ret)
		ret = spu_handle_mm_fault(current->mm, ea, dsisr, &flt);

	spu_acquire(ctx);
	/*
	 * If spu_acquire fails due to a pending signal we just want to return
	 * EINTR to userspace even if that means missing the dma restart or
	 * updating the page fault statistics.
	 */
	ret2 = spu_acquire(ctx);
	if (ret2)
		goto out;

	/*
	 * Clear dsisr under ctxt lock after handling the fault, so that
@@ -177,6 +184,7 @@ int spufs_handle_class1(struct spu_context *ctx)
	} else
		spufs_handle_event(ctx, ea, SPE_EVENT_SPE_DATA_STORAGE);

 out:
	spuctx_switch_state(ctx, SPU_UTIL_SYSTEM);
	return ret;
}
+161 −48
Original line number Diff line number Diff line
@@ -198,9 +198,12 @@ spufs_mem_read(struct file *file, char __user *buffer,
	struct spu_context *ctx = file->private_data;
	ssize_t ret;

	spu_acquire(ctx);
	ret = spu_acquire(ctx);
	if (ret)
		return ret;
	ret = __spufs_mem_read(ctx, buffer, size, pos);
	spu_release(ctx);

	return ret;
}

@@ -220,7 +223,10 @@ spufs_mem_write(struct file *file, const char __user *buffer,
	if (size > LS_SIZE - pos)
		size = LS_SIZE - pos;

	spu_acquire(ctx);
	ret = spu_acquire(ctx);
	if (ret)
		return ret;

	local_store = ctx->ops->get_ls(ctx);
	ret = copy_from_user(local_store + pos, buffer, size);
	spu_release(ctx);
@@ -260,7 +266,8 @@ static unsigned long spufs_mem_mmap_nopfn(struct vm_area_struct *vma,
	pr_debug("spufs_mem_mmap_nopfn address=0x%lx -> 0x%lx, offset=0x%lx\n",
		 addr0, address, offset);

	spu_acquire(ctx);
	if (spu_acquire(ctx))
		return NOPFN_REFAULT;

	if (ctx->state == SPU_STATE_SAVED) {
		vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
@@ -363,20 +370,19 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
	 * to return NOPFN_REFAULT because the mappings may have
	 * hanged.
	 */
	spu_acquire(ctx);
	if (spu_acquire(ctx))
		return NOPFN_REFAULT;

	if (ctx->state == SPU_STATE_SAVED) {
		up_read(&current->mm->mmap_sem);
		spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE);
		down_read(&current->mm->mmap_sem);
		goto out;
	}

	} else {
		area = ctx->spu->problem_phys + ps_offs;
		vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT);
	}

out:
	spu_release(ctx);

	return NOPFN_REFAULT;
}

@@ -413,8 +419,11 @@ static int spufs_cntl_mmap(struct file *file, struct vm_area_struct *vma)
static int spufs_cntl_get(void *data, u64 *val)
{
	struct spu_context *ctx = data;
	int ret;

	spu_acquire(ctx);
	ret = spu_acquire(ctx);
	if (ret)
		return ret;
	*val = ctx->ops->status_read(ctx);
	spu_release(ctx);

@@ -424,8 +433,11 @@ static int spufs_cntl_get(void *data, u64 *val)
static int spufs_cntl_set(void *data, u64 val)
{
	struct spu_context *ctx = data;
	int ret;

	spu_acquire(ctx);
	ret = spu_acquire(ctx);
	if (ret)
		return ret;
	ctx->ops->runcntl_write(ctx, val);
	spu_release(ctx);

@@ -493,7 +505,9 @@ spufs_regs_read(struct file *file, char __user *buffer,
	int ret;
	struct spu_context *ctx = file->private_data;

	spu_acquire_saved(ctx);
	ret = spu_acquire_saved(ctx);
	if (ret)
		return ret;
	ret = __spufs_regs_read(ctx, buffer, size, pos);
	spu_release_saved(ctx);
	return ret;
@@ -512,7 +526,9 @@ spufs_regs_write(struct file *file, const char __user *buffer,
		return -EFBIG;
	*pos += size;

	spu_acquire_saved(ctx);
	ret = spu_acquire_saved(ctx);
	if (ret)
		return ret;

	ret = copy_from_user(lscsa->gprs + *pos - size,
			     buffer, size) ? -EFAULT : size;
@@ -544,7 +560,9 @@ spufs_fpcr_read(struct file *file, char __user * buffer,
	int ret;
	struct spu_context *ctx = file->private_data;

	spu_acquire_saved(ctx);
	ret = spu_acquire_saved(ctx);
	if (ret)
		return ret;
	ret = __spufs_fpcr_read(ctx, buffer, size, pos);
	spu_release_saved(ctx);
	return ret;
@@ -561,10 +579,12 @@ spufs_fpcr_write(struct file *file, const char __user * buffer,
	size = min_t(ssize_t, sizeof(lscsa->fpcr) - *pos, size);
	if (size <= 0)
		return -EFBIG;
	*pos += size;

	spu_acquire_saved(ctx);
	ret = spu_acquire_saved(ctx);
	if (ret)
		return ret;

	*pos += size;
	ret = copy_from_user((char *)&lscsa->fpcr + *pos - size,
			     buffer, size) ? -EFAULT : size;

@@ -611,7 +631,10 @@ static ssize_t spufs_mbox_read(struct file *file, char __user *buf,

	udata = (void __user *)buf;

	spu_acquire(ctx);
	count = spu_acquire(ctx);
	if (count)
		return count;

	for (count = 0; (count + 4) <= len; count += 4, udata++) {
		int ret;
		ret = ctx->ops->mbox_read(ctx, &mbox_data);
@@ -647,12 +670,15 @@ static ssize_t spufs_mbox_stat_read(struct file *file, char __user *buf,
			size_t len, loff_t *pos)
{
	struct spu_context *ctx = file->private_data;
	ssize_t ret;
	u32 mbox_stat;

	if (len < 4)
		return -EINVAL;

	spu_acquire(ctx);
	ret = spu_acquire(ctx);
	if (ret)
		return ret;

	mbox_stat = ctx->ops->mbox_stat_read(ctx) & 0xff;

@@ -721,7 +747,9 @@ static ssize_t spufs_ibox_read(struct file *file, char __user *buf,

	udata = (void __user *)buf;

	spu_acquire(ctx);
	count = spu_acquire(ctx);
	if (count)
		return count;

	/* wait only for the first element */
	count = 0;
@@ -767,7 +795,11 @@ static unsigned int spufs_ibox_poll(struct file *file, poll_table *wait)

	poll_wait(file, &ctx->ibox_wq, wait);

	spu_acquire(ctx);
	/*
	 * For now keep this uninterruptible and also ignore the rule
	 * that poll should not sleep.  Will be fixed later.
	 */
	mutex_lock(&ctx->state_mutex);
	mask = ctx->ops->mbox_stat_poll(ctx, POLLIN | POLLRDNORM);
	spu_release(ctx);

@@ -785,12 +817,15 @@ static ssize_t spufs_ibox_stat_read(struct file *file, char __user *buf,
			size_t len, loff_t *pos)
{
	struct spu_context *ctx = file->private_data;
	ssize_t ret;
	u32 ibox_stat;

	if (len < 4)
		return -EINVAL;

	spu_acquire(ctx);
	ret = spu_acquire(ctx);
	if (ret)
		return ret;
	ibox_stat = (ctx->ops->mbox_stat_read(ctx) >> 16) & 0xff;
	spu_release(ctx);

@@ -862,7 +897,9 @@ static ssize_t spufs_wbox_write(struct file *file, const char __user *buf,
	if (__get_user(wbox_data, udata))
		return -EFAULT;

	spu_acquire(ctx);
	count = spu_acquire(ctx);
	if (count)
		return count;

	/*
	 * make sure we can at least write one element, by waiting
@@ -903,7 +940,11 @@ static unsigned int spufs_wbox_poll(struct file *file, poll_table *wait)

	poll_wait(file, &ctx->wbox_wq, wait);

	spu_acquire(ctx);
	/*
	 * For now keep this uninterruptible and also ignore the rule
	 * that poll should not sleep.  Will be fixed later.
	 */
	mutex_lock(&ctx->state_mutex);
	mask = ctx->ops->mbox_stat_poll(ctx, POLLOUT | POLLWRNORM);
	spu_release(ctx);

@@ -921,12 +962,15 @@ static ssize_t spufs_wbox_stat_read(struct file *file, char __user *buf,
			size_t len, loff_t *pos)
{
	struct spu_context *ctx = file->private_data;
	ssize_t ret;
	u32 wbox_stat;

	if (len < 4)
		return -EINVAL;

	spu_acquire(ctx);
	ret = spu_acquire(ctx);
	if (ret)
		return ret;
	wbox_stat = (ctx->ops->mbox_stat_read(ctx) >> 8) & 0xff;
	spu_release(ctx);

@@ -997,7 +1041,9 @@ static ssize_t spufs_signal1_read(struct file *file, char __user *buf,
	int ret;
	struct spu_context *ctx = file->private_data;

	spu_acquire_saved(ctx);
	ret = spu_acquire_saved(ctx);
	if (ret)
		return ret;
	ret = __spufs_signal1_read(ctx, buf, len, pos);
	spu_release_saved(ctx);

@@ -1008,6 +1054,7 @@ static ssize_t spufs_signal1_write(struct file *file, const char __user *buf,
			size_t len, loff_t *pos)
{
	struct spu_context *ctx;
	ssize_t ret;
	u32 data;

	ctx = file->private_data;
@@ -1018,7 +1065,9 @@ static ssize_t spufs_signal1_write(struct file *file, const char __user *buf,
	if (copy_from_user(&data, buf, 4))
		return -EFAULT;

	spu_acquire(ctx);
	ret = spu_acquire(ctx);
	if (ret)
		return ret;
	ctx->ops->signal1_write(ctx, data);
	spu_release(ctx);

@@ -1128,7 +1177,9 @@ static ssize_t spufs_signal2_read(struct file *file, char __user *buf,
	struct spu_context *ctx = file->private_data;
	int ret;

	spu_acquire_saved(ctx);
	ret = spu_acquire_saved(ctx);
	if (ret)
		return ret;
	ret = __spufs_signal2_read(ctx, buf, len, pos);
	spu_release_saved(ctx);

@@ -1139,6 +1190,7 @@ static ssize_t spufs_signal2_write(struct file *file, const char __user *buf,
			size_t len, loff_t *pos)
{
	struct spu_context *ctx;
	ssize_t ret;
	u32 data;

	ctx = file->private_data;
@@ -1149,7 +1201,9 @@ static ssize_t spufs_signal2_write(struct file *file, const char __user *buf,
	if (copy_from_user(&data, buf, 4))
		return -EFAULT;

	spu_acquire(ctx);
	ret = spu_acquire(ctx);
	if (ret)
		return ret;
	ctx->ops->signal2_write(ctx, data);
	spu_release(ctx);

@@ -1220,13 +1274,18 @@ static const struct file_operations spufs_signal2_nosched_fops = {
static int __##__get(void *data, u64 *val)				\
{									\
	struct spu_context *ctx = data;					\
	int ret = 0;							\
									\
	if (__acquire == SPU_ATTR_ACQUIRE) {				\
		spu_acquire(ctx);					\
		ret = spu_acquire(ctx);					\
		if (ret)						\
			return ret;					\
		*val = __get(ctx);					\
		spu_release(ctx);					\
	} else if (__acquire == SPU_ATTR_ACQUIRE_SAVED)	{		\
		spu_acquire_saved(ctx);					\
		ret = spu_acquire_saved(ctx);				\
		if (ret)						\
			return ret;					\
		*val = __get(ctx);					\
		spu_release_saved(ctx);					\
	} else								\
@@ -1239,8 +1298,11 @@ DEFINE_SPUFS_SIMPLE_ATTRIBUTE(__name, __##__get, __set, __fmt);
static int spufs_signal1_type_set(void *data, u64 val)
{
	struct spu_context *ctx = data;
	int ret;

	spu_acquire(ctx);
	ret = spu_acquire(ctx);
	if (ret)
		return ret;
	ctx->ops->signal1_type_set(ctx, val);
	spu_release(ctx);

@@ -1258,8 +1320,11 @@ DEFINE_SPUFS_ATTRIBUTE(spufs_signal1_type, spufs_signal1_type_get,
static int spufs_signal2_type_set(void *data, u64 val)
{
	struct spu_context *ctx = data;
	int ret;

	spu_acquire(ctx);
	ret = spu_acquire(ctx);
	if (ret)
		return ret;
	ctx->ops->signal2_type_set(ctx, val);
	spu_release(ctx);

@@ -1512,12 +1577,17 @@ static ssize_t spufs_mfc_read(struct file *file, char __user *buffer,
	if (size != 4)
		goto out;

	spu_acquire(ctx);
	ret = spu_acquire(ctx);
	if (ret)
		return ret;

	ret = -EINVAL;
	if (file->f_flags & O_NONBLOCK) {
		status = ctx->ops->read_mfc_tagstatus(ctx);
		if (!(status & ctx->tagwait))
			ret = -EAGAIN;
		else
			/* XXX(hch): shouldn't we clear ret here? */
			ctx->tagwait &= ~status;
	} else {
		ret = spufs_wait(ctx->mfc_wq,
@@ -1642,7 +1712,10 @@ static ssize_t spufs_mfc_write(struct file *file, const char __user *buffer,
	if (ret)
		goto out;

	spu_acquire(ctx);
	ret = spu_acquire(ctx);
	if (ret)
		goto out;

	ret = spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE);
	if (ret)
		goto out;
@@ -1677,7 +1750,11 @@ static unsigned int spufs_mfc_poll(struct file *file,poll_table *wait)

	poll_wait(file, &ctx->mfc_wq, wait);

	spu_acquire(ctx);
	/*
	 * For now keep this uninterruptible and also ignore the rule
	 * that poll should not sleep.  Will be fixed later.
	 */
	mutex_lock(&ctx->state_mutex);
	ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2);
	free_elements = ctx->ops->get_mfc_free_elements(ctx);
	tagstatus = ctx->ops->read_mfc_tagstatus(ctx);
@@ -1700,7 +1777,9 @@ static int spufs_mfc_flush(struct file *file, fl_owner_t id)
	struct spu_context *ctx = file->private_data;
	int ret;

	spu_acquire(ctx);
	ret = spu_acquire(ctx);
	if (ret)
		return ret;
#if 0
/* this currently hangs */
	ret = spufs_wait(ctx->mfc_wq,
@@ -1746,7 +1825,11 @@ static const struct file_operations spufs_mfc_fops = {
static int spufs_npc_set(void *data, u64 val)
{
	struct spu_context *ctx = data;
	spu_acquire(ctx);
	int ret;

	ret = spu_acquire(ctx);
	if (ret)
		return ret;
	ctx->ops->npc_write(ctx, val);
	spu_release(ctx);

@@ -1764,7 +1847,11 @@ static int spufs_decr_set(void *data, u64 val)
{
	struct spu_context *ctx = data;
	struct spu_lscsa *lscsa = ctx->csa.lscsa;
	spu_acquire_saved(ctx);
	int ret;

	ret = spu_acquire_saved(ctx);
	if (ret)
		return ret;
	lscsa->decr.slot[0] = (u32) val;
	spu_release_saved(ctx);

@@ -1782,7 +1869,11 @@ DEFINE_SPUFS_ATTRIBUTE(spufs_decr_ops, spufs_decr_get, spufs_decr_set,
static int spufs_decr_status_set(void *data, u64 val)
{
	struct spu_context *ctx = data;
	spu_acquire_saved(ctx);
	int ret;

	ret = spu_acquire_saved(ctx);
	if (ret)
		return ret;
	if (val)
		ctx->csa.priv2.mfc_control_RW |= MFC_CNTL_DECREMENTER_RUNNING;
	else
@@ -1807,7 +1898,11 @@ static int spufs_event_mask_set(void *data, u64 val)
{
	struct spu_context *ctx = data;
	struct spu_lscsa *lscsa = ctx->csa.lscsa;
	spu_acquire_saved(ctx);
	int ret;

	ret = spu_acquire_saved(ctx);
	if (ret)
		return ret;
	lscsa->event_mask.slot[0] = (u32) val;
	spu_release_saved(ctx);

@@ -1840,7 +1935,11 @@ static int spufs_srr0_set(void *data, u64 val)
{
	struct spu_context *ctx = data;
	struct spu_lscsa *lscsa = ctx->csa.lscsa;
	spu_acquire_saved(ctx);
	int ret;

	ret = spu_acquire_saved(ctx);
	if (ret)
		return ret;
	lscsa->srr0.slot[0] = (u32) val;
	spu_release_saved(ctx);

@@ -1947,7 +2046,9 @@ static ssize_t spufs_mbox_info_read(struct file *file, char __user *buf,
	if (!access_ok(VERIFY_WRITE, buf, len))
		return -EFAULT;

	spu_acquire_saved(ctx);
	ret = spu_acquire_saved(ctx);
	if (ret)
		return ret;
	spin_lock(&ctx->csa.register_lock);
	ret = __spufs_mbox_info_read(ctx, buf, len, pos);
	spin_unlock(&ctx->csa.register_lock);
@@ -1985,7 +2086,9 @@ static ssize_t spufs_ibox_info_read(struct file *file, char __user *buf,
	if (!access_ok(VERIFY_WRITE, buf, len))
		return -EFAULT;

	spu_acquire_saved(ctx);
	ret = spu_acquire_saved(ctx);
	if (ret)
		return ret;
	spin_lock(&ctx->csa.register_lock);
	ret = __spufs_ibox_info_read(ctx, buf, len, pos);
	spin_unlock(&ctx->csa.register_lock);
@@ -2026,7 +2129,9 @@ static ssize_t spufs_wbox_info_read(struct file *file, char __user *buf,
	if (!access_ok(VERIFY_WRITE, buf, len))
		return -EFAULT;

	spu_acquire_saved(ctx);
	ret = spu_acquire_saved(ctx);
	if (ret)
		return ret;
	spin_lock(&ctx->csa.register_lock);
	ret = __spufs_wbox_info_read(ctx, buf, len, pos);
	spin_unlock(&ctx->csa.register_lock);
@@ -2076,7 +2181,9 @@ static ssize_t spufs_dma_info_read(struct file *file, char __user *buf,
	if (!access_ok(VERIFY_WRITE, buf, len))
		return -EFAULT;

	spu_acquire_saved(ctx);
	ret = spu_acquire_saved(ctx);
	if (ret)
		return ret;
	spin_lock(&ctx->csa.register_lock);
	ret = __spufs_dma_info_read(ctx, buf, len, pos);
	spin_unlock(&ctx->csa.register_lock);
@@ -2127,7 +2234,9 @@ static ssize_t spufs_proxydma_info_read(struct file *file, char __user *buf,
	struct spu_context *ctx = file->private_data;
	int ret;

	spu_acquire_saved(ctx);
	ret = spu_acquire_saved(ctx);
	if (ret)
		return ret;
	spin_lock(&ctx->csa.register_lock);
	ret = __spufs_proxydma_info_read(ctx, buf, len, pos);
	spin_unlock(&ctx->csa.register_lock);
@@ -2216,8 +2325,12 @@ static unsigned long long spufs_class2_intrs(struct spu_context *ctx)
static int spufs_show_stat(struct seq_file *s, void *private)
{
	struct spu_context *ctx = s->private;
	int ret;

	ret = spu_acquire(ctx);
	if (ret)
		return ret;

	spu_acquire(ctx);
	seq_printf(s, "%s %llu %llu %llu %llu "
		      "%llu %llu %llu %llu %llu %llu %llu %llu\n",
		ctx_state_names[ctx->stats.util_state],
+8 −3
Original line number Diff line number Diff line
@@ -292,7 +292,7 @@ static int spu_process_callback(struct spu_context *ctx)
	u32 ls_pointer, npc;
	void __iomem *ls;
	long spu_ret;
	int ret;
	int ret, ret2;

	/* get syscall block from local store */
	npc = ctx->ops->npc_read(ctx) & ~3;
@@ -314,9 +314,11 @@ static int spu_process_callback(struct spu_context *ctx)
		if (spu_ret <= -ERESTARTSYS) {
			ret = spu_handle_restartsys(ctx, &spu_ret, &npc);
		}
		spu_acquire(ctx);
		ret2 = spu_acquire(ctx);
		if (ret == -ERESTARTSYS)
			return ret;
		if (ret2)
			return -EINTR;
	}

	/* write result, jump over indirect pointer */
@@ -338,7 +340,9 @@ long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event)
	spu_enable_spu(ctx);
	ctx->event_return = 0;

	spu_acquire(ctx);
	ret = spu_acquire(ctx);
	if (ret)
		goto out_unlock;

	spu_update_sched_info(ctx);

@@ -414,6 +418,7 @@ long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event)

out:
	*event = ctx->event_return;
out_unlock:
	mutex_unlock(&ctx->run_mutex);
	return ret;
}
Loading