mirror of
https://github.com/torvalds/linux.git
synced 2024-12-11 21:52:04 +00:00
[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: Arnd Bergmann <arnd.bergmann@de.ibm.com> Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jeremy Kerr <jk@ozlabs.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
parent
197b1a8263
commit
c9101bdb1b
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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(¤t->mm->mmap_sem);
|
||||
spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE);
|
||||
down_read(¤t->mm->mmap_sem);
|
||||
goto out;
|
||||
} else {
|
||||
area = ctx->spu->problem_phys + ps_offs;
|
||||
vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
ret = spu_acquire_saved(ctx);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*pos += size;
|
||||
|
||||
spu_acquire_saved(ctx);
|
||||
|
||||
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],
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -705,7 +705,9 @@ static void __spu_schedule(struct spu *spu, struct spu_context *ctx)
|
||||
|
||||
static void spu_schedule(struct spu *spu, struct spu_context *ctx)
|
||||
{
|
||||
spu_acquire(ctx);
|
||||
/* not a candidate for interruptible because it's called either
|
||||
from the scheduler thread or from spu_deactivate */
|
||||
mutex_lock(&ctx->state_mutex);
|
||||
__spu_schedule(spu, ctx);
|
||||
spu_release(ctx);
|
||||
}
|
||||
@ -823,7 +825,9 @@ static int __spu_deactivate(struct spu_context *ctx, int force, int max_prio)
|
||||
else {
|
||||
spu_release(ctx);
|
||||
spu_schedule(spu, new);
|
||||
spu_acquire(ctx);
|
||||
/* this one can't easily be made
|
||||
interruptible */
|
||||
mutex_lock(&ctx->state_mutex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -867,7 +871,8 @@ static noinline void spusched_tick(struct spu_context *ctx)
|
||||
struct spu *spu = NULL;
|
||||
u32 status;
|
||||
|
||||
spu_acquire(ctx);
|
||||
if (spu_acquire(ctx))
|
||||
BUG(); /* a kernel thread never has signals pending */
|
||||
|
||||
if (ctx->state != SPU_STATE_RUNNABLE)
|
||||
goto out;
|
||||
|
@ -229,9 +229,9 @@ struct spu *affinity_check(struct spu_context *ctx);
|
||||
|
||||
/* context management */
|
||||
extern atomic_t nr_spu_contexts;
|
||||
static inline void spu_acquire(struct spu_context *ctx)
|
||||
static inline int __must_check spu_acquire(struct spu_context *ctx)
|
||||
{
|
||||
mutex_lock(&ctx->state_mutex);
|
||||
return mutex_lock_interruptible(&ctx->state_mutex);
|
||||
}
|
||||
|
||||
static inline void spu_release(struct spu_context *ctx)
|
||||
@ -246,7 +246,7 @@ int put_spu_context(struct spu_context *ctx);
|
||||
void spu_unmap_mappings(struct spu_context *ctx);
|
||||
|
||||
void spu_forget(struct spu_context *ctx);
|
||||
void spu_acquire_saved(struct spu_context *ctx);
|
||||
int __must_check spu_acquire_saved(struct spu_context *ctx);
|
||||
void spu_release_saved(struct spu_context *ctx);
|
||||
|
||||
int spu_stopped(struct spu_context *ctx, u32 * stat);
|
||||
@ -284,7 +284,9 @@ extern char *isolated_loader;
|
||||
} \
|
||||
spu_release(ctx); \
|
||||
schedule(); \
|
||||
spu_acquire(ctx); \
|
||||
__ret = spu_acquire(ctx); \
|
||||
if (__ret) \
|
||||
break; \
|
||||
} \
|
||||
finish_wait(&(wq), &__wait); \
|
||||
__ret; \
|
||||
|
Loading…
Reference in New Issue
Block a user