diff options
author | Christoph Hellwig <hch@lst.de> | 2007-07-20 15:39:34 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@klappe.arndb.de> | 2007-07-20 15:41:52 -0400 |
commit | 27b1ea091f0c088ecad0d492f37fbe7b8d54d7dc (patch) | |
tree | 5d54369e0b21877ee9ea57dddfab9733bcd82490 | |
parent | 27ec41d3a1d4df2b7cd190e93aad22ab86a72aa1 (diff) |
[CELL] spufs: make sure context are scheduled again after spu_acquire_saved
Currently a process is removed from the physical spu when spu_acquire_saved
is saved but never put back. This patch adds a new spu_release_saved
that is to be paired with spu_acquire_saved and put the process back if
it has been in RUNNABLE state before.
Niether Jeremy not be are entirely happy about this exact patch because
it adds another spu_activate call outside of the owner thread, but I
feel this is the best short-term fix we can come up with.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/context.c | 18 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/coredump.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/file.c | 42 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/spufs.h | 5 |
4 files changed, 44 insertions, 23 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c index 0e5e55f53c8b..6b091ea1d192 100644 --- a/arch/powerpc/platforms/cell/spufs/context.c +++ b/arch/powerpc/platforms/cell/spufs/context.c | |||
@@ -165,6 +165,22 @@ int spu_acquire_runnable(struct spu_context *ctx, unsigned long flags) | |||
165 | void spu_acquire_saved(struct spu_context *ctx) | 165 | void spu_acquire_saved(struct spu_context *ctx) |
166 | { | 166 | { |
167 | spu_acquire(ctx); | 167 | spu_acquire(ctx); |
168 | if (ctx->state != SPU_STATE_SAVED) | 168 | if (ctx->state != SPU_STATE_SAVED) { |
169 | set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags); | ||
169 | spu_deactivate(ctx); | 170 | spu_deactivate(ctx); |
171 | } | ||
172 | } | ||
173 | |||
174 | /** | ||
175 | * spu_release_saved - unlock spu context and return it to the runqueue | ||
176 | * @ctx: context to unlock | ||
177 | */ | ||
178 | void spu_release_saved(struct spu_context *ctx) | ||
179 | { | ||
180 | BUG_ON(ctx->state != SPU_STATE_SAVED); | ||
181 | |||
182 | if (test_and_clear_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags)) | ||
183 | spu_activate(ctx, 0); | ||
184 | |||
185 | spu_release(ctx); | ||
170 | } | 186 | } |
diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c index 5d9ad5a0307b..5e31799b1e3f 100644 --- a/arch/powerpc/platforms/cell/spufs/coredump.c +++ b/arch/powerpc/platforms/cell/spufs/coredump.c | |||
@@ -226,7 +226,7 @@ static void spufs_arch_write_notes(struct file *file) | |||
226 | spu_acquire_saved(ctx_info->ctx); | 226 | spu_acquire_saved(ctx_info->ctx); |
227 | for (j = 0; j < spufs_coredump_num_notes; j++) | 227 | for (j = 0; j < spufs_coredump_num_notes; j++) |
228 | spufs_arch_write_note(ctx_info, j, file); | 228 | spufs_arch_write_note(ctx_info, j, file); |
229 | spu_release(ctx_info->ctx); | 229 | spu_release_saved(ctx_info->ctx); |
230 | list_del(&ctx_info->list); | 230 | list_del(&ctx_info->list); |
231 | kfree(ctx_info); | 231 | kfree(ctx_info); |
232 | } | 232 | } |
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 9351db9472d9..88da996f6d2f 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c | |||
@@ -370,7 +370,7 @@ spufs_regs_read(struct file *file, char __user *buffer, | |||
370 | 370 | ||
371 | spu_acquire_saved(ctx); | 371 | spu_acquire_saved(ctx); |
372 | ret = __spufs_regs_read(ctx, buffer, size, pos); | 372 | ret = __spufs_regs_read(ctx, buffer, size, pos); |
373 | spu_release(ctx); | 373 | spu_release_saved(ctx); |
374 | return ret; | 374 | return ret; |
375 | } | 375 | } |
376 | 376 | ||
@@ -392,7 +392,7 @@ spufs_regs_write(struct file *file, const char __user *buffer, | |||
392 | ret = copy_from_user(lscsa->gprs + *pos - size, | 392 | ret = copy_from_user(lscsa->gprs + *pos - size, |
393 | buffer, size) ? -EFAULT : size; | 393 | buffer, size) ? -EFAULT : size; |
394 | 394 | ||
395 | spu_release(ctx); | 395 | spu_release_saved(ctx); |
396 | return ret; | 396 | return ret; |
397 | } | 397 | } |
398 | 398 | ||
@@ -421,7 +421,7 @@ spufs_fpcr_read(struct file *file, char __user * buffer, | |||
421 | 421 | ||
422 | spu_acquire_saved(ctx); | 422 | spu_acquire_saved(ctx); |
423 | ret = __spufs_fpcr_read(ctx, buffer, size, pos); | 423 | ret = __spufs_fpcr_read(ctx, buffer, size, pos); |
424 | spu_release(ctx); | 424 | spu_release_saved(ctx); |
425 | return ret; | 425 | return ret; |
426 | } | 426 | } |
427 | 427 | ||
@@ -443,7 +443,7 @@ spufs_fpcr_write(struct file *file, const char __user * buffer, | |||
443 | ret = copy_from_user((char *)&lscsa->fpcr + *pos - size, | 443 | ret = copy_from_user((char *)&lscsa->fpcr + *pos - size, |
444 | buffer, size) ? -EFAULT : size; | 444 | buffer, size) ? -EFAULT : size; |
445 | 445 | ||
446 | spu_release(ctx); | 446 | spu_release_saved(ctx); |
447 | return ret; | 447 | return ret; |
448 | } | 448 | } |
449 | 449 | ||
@@ -868,7 +868,7 @@ static ssize_t spufs_signal1_read(struct file *file, char __user *buf, | |||
868 | 868 | ||
869 | spu_acquire_saved(ctx); | 869 | spu_acquire_saved(ctx); |
870 | ret = __spufs_signal1_read(ctx, buf, len, pos); | 870 | ret = __spufs_signal1_read(ctx, buf, len, pos); |
871 | spu_release(ctx); | 871 | spu_release_saved(ctx); |
872 | 872 | ||
873 | return ret; | 873 | return ret; |
874 | } | 874 | } |
@@ -999,7 +999,7 @@ static ssize_t spufs_signal2_read(struct file *file, char __user *buf, | |||
999 | 999 | ||
1000 | spu_acquire_saved(ctx); | 1000 | spu_acquire_saved(ctx); |
1001 | ret = __spufs_signal2_read(ctx, buf, len, pos); | 1001 | ret = __spufs_signal2_read(ctx, buf, len, pos); |
1002 | spu_release(ctx); | 1002 | spu_release_saved(ctx); |
1003 | 1003 | ||
1004 | return ret; | 1004 | return ret; |
1005 | } | 1005 | } |
@@ -1626,7 +1626,7 @@ static void spufs_decr_set(void *data, u64 val) | |||
1626 | struct spu_lscsa *lscsa = ctx->csa.lscsa; | 1626 | struct spu_lscsa *lscsa = ctx->csa.lscsa; |
1627 | spu_acquire_saved(ctx); | 1627 | spu_acquire_saved(ctx); |
1628 | lscsa->decr.slot[0] = (u32) val; | 1628 | lscsa->decr.slot[0] = (u32) val; |
1629 | spu_release(ctx); | 1629 | spu_release_saved(ctx); |
1630 | } | 1630 | } |
1631 | 1631 | ||
1632 | static u64 __spufs_decr_get(void *data) | 1632 | static u64 __spufs_decr_get(void *data) |
@@ -1642,7 +1642,7 @@ static u64 spufs_decr_get(void *data) | |||
1642 | u64 ret; | 1642 | u64 ret; |
1643 | spu_acquire_saved(ctx); | 1643 | spu_acquire_saved(ctx); |
1644 | ret = __spufs_decr_get(data); | 1644 | ret = __spufs_decr_get(data); |
1645 | spu_release(ctx); | 1645 | spu_release_saved(ctx); |
1646 | return ret; | 1646 | return ret; |
1647 | } | 1647 | } |
1648 | DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_ops, spufs_decr_get, spufs_decr_set, | 1648 | DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_ops, spufs_decr_get, spufs_decr_set, |
@@ -1654,7 +1654,7 @@ static void spufs_decr_status_set(void *data, u64 val) | |||
1654 | struct spu_lscsa *lscsa = ctx->csa.lscsa; | 1654 | struct spu_lscsa *lscsa = ctx->csa.lscsa; |
1655 | spu_acquire_saved(ctx); | 1655 | spu_acquire_saved(ctx); |
1656 | lscsa->decr_status.slot[0] = (u32) val; | 1656 | lscsa->decr_status.slot[0] = (u32) val; |
1657 | spu_release(ctx); | 1657 | spu_release_saved(ctx); |
1658 | } | 1658 | } |
1659 | 1659 | ||
1660 | static u64 __spufs_decr_status_get(void *data) | 1660 | static u64 __spufs_decr_status_get(void *data) |
@@ -1670,7 +1670,7 @@ static u64 spufs_decr_status_get(void *data) | |||
1670 | u64 ret; | 1670 | u64 ret; |
1671 | spu_acquire_saved(ctx); | 1671 | spu_acquire_saved(ctx); |
1672 | ret = __spufs_decr_status_get(data); | 1672 | ret = __spufs_decr_status_get(data); |
1673 | spu_release(ctx); | 1673 | spu_release_saved(ctx); |
1674 | return ret; | 1674 | return ret; |
1675 | } | 1675 | } |
1676 | DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_status_ops, spufs_decr_status_get, | 1676 | DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_status_ops, spufs_decr_status_get, |
@@ -1682,7 +1682,7 @@ static void spufs_event_mask_set(void *data, u64 val) | |||
1682 | struct spu_lscsa *lscsa = ctx->csa.lscsa; | 1682 | struct spu_lscsa *lscsa = ctx->csa.lscsa; |
1683 | spu_acquire_saved(ctx); | 1683 | spu_acquire_saved(ctx); |
1684 | lscsa->event_mask.slot[0] = (u32) val; | 1684 | lscsa->event_mask.slot[0] = (u32) val; |
1685 | spu_release(ctx); | 1685 | spu_release_saved(ctx); |
1686 | } | 1686 | } |
1687 | 1687 | ||
1688 | static u64 __spufs_event_mask_get(void *data) | 1688 | static u64 __spufs_event_mask_get(void *data) |
@@ -1698,7 +1698,7 @@ static u64 spufs_event_mask_get(void *data) | |||
1698 | u64 ret; | 1698 | u64 ret; |
1699 | spu_acquire_saved(ctx); | 1699 | spu_acquire_saved(ctx); |
1700 | ret = __spufs_event_mask_get(data); | 1700 | ret = __spufs_event_mask_get(data); |
1701 | spu_release(ctx); | 1701 | spu_release_saved(ctx); |
1702 | return ret; | 1702 | return ret; |
1703 | } | 1703 | } |
1704 | DEFINE_SIMPLE_ATTRIBUTE(spufs_event_mask_ops, spufs_event_mask_get, | 1704 | DEFINE_SIMPLE_ATTRIBUTE(spufs_event_mask_ops, spufs_event_mask_get, |
@@ -1722,7 +1722,7 @@ static u64 spufs_event_status_get(void *data) | |||
1722 | 1722 | ||
1723 | spu_acquire_saved(ctx); | 1723 | spu_acquire_saved(ctx); |
1724 | ret = __spufs_event_status_get(data); | 1724 | ret = __spufs_event_status_get(data); |
1725 | spu_release(ctx); | 1725 | spu_release_saved(ctx); |
1726 | return ret; | 1726 | return ret; |
1727 | } | 1727 | } |
1728 | DEFINE_SIMPLE_ATTRIBUTE(spufs_event_status_ops, spufs_event_status_get, | 1728 | DEFINE_SIMPLE_ATTRIBUTE(spufs_event_status_ops, spufs_event_status_get, |
@@ -1734,7 +1734,7 @@ static void spufs_srr0_set(void *data, u64 val) | |||
1734 | struct spu_lscsa *lscsa = ctx->csa.lscsa; | 1734 | struct spu_lscsa *lscsa = ctx->csa.lscsa; |
1735 | spu_acquire_saved(ctx); | 1735 | spu_acquire_saved(ctx); |
1736 | lscsa->srr0.slot[0] = (u32) val; | 1736 | lscsa->srr0.slot[0] = (u32) val; |
1737 | spu_release(ctx); | 1737 | spu_release_saved(ctx); |
1738 | } | 1738 | } |
1739 | 1739 | ||
1740 | static u64 spufs_srr0_get(void *data) | 1740 | static u64 spufs_srr0_get(void *data) |
@@ -1744,7 +1744,7 @@ static u64 spufs_srr0_get(void *data) | |||
1744 | u64 ret; | 1744 | u64 ret; |
1745 | spu_acquire_saved(ctx); | 1745 | spu_acquire_saved(ctx); |
1746 | ret = lscsa->srr0.slot[0]; | 1746 | ret = lscsa->srr0.slot[0]; |
1747 | spu_release(ctx); | 1747 | spu_release_saved(ctx); |
1748 | return ret; | 1748 | return ret; |
1749 | } | 1749 | } |
1750 | DEFINE_SIMPLE_ATTRIBUTE(spufs_srr0_ops, spufs_srr0_get, spufs_srr0_set, | 1750 | DEFINE_SIMPLE_ATTRIBUTE(spufs_srr0_ops, spufs_srr0_get, spufs_srr0_set, |
@@ -1800,7 +1800,7 @@ static u64 spufs_lslr_get(void *data) | |||
1800 | 1800 | ||
1801 | spu_acquire_saved(ctx); | 1801 | spu_acquire_saved(ctx); |
1802 | ret = __spufs_lslr_get(data); | 1802 | ret = __spufs_lslr_get(data); |
1803 | spu_release(ctx); | 1803 | spu_release_saved(ctx); |
1804 | 1804 | ||
1805 | return ret; | 1805 | return ret; |
1806 | } | 1806 | } |
@@ -1864,7 +1864,7 @@ static ssize_t spufs_mbox_info_read(struct file *file, char __user *buf, | |||
1864 | spin_lock(&ctx->csa.register_lock); | 1864 | spin_lock(&ctx->csa.register_lock); |
1865 | ret = __spufs_mbox_info_read(ctx, buf, len, pos); | 1865 | ret = __spufs_mbox_info_read(ctx, buf, len, pos); |
1866 | spin_unlock(&ctx->csa.register_lock); | 1866 | spin_unlock(&ctx->csa.register_lock); |
1867 | spu_release(ctx); | 1867 | spu_release_saved(ctx); |
1868 | 1868 | ||
1869 | return ret; | 1869 | return ret; |
1870 | } | 1870 | } |
@@ -1902,7 +1902,7 @@ static ssize_t spufs_ibox_info_read(struct file *file, char __user *buf, | |||
1902 | spin_lock(&ctx->csa.register_lock); | 1902 | spin_lock(&ctx->csa.register_lock); |
1903 | ret = __spufs_ibox_info_read(ctx, buf, len, pos); | 1903 | ret = __spufs_ibox_info_read(ctx, buf, len, pos); |
1904 | spin_unlock(&ctx->csa.register_lock); | 1904 | spin_unlock(&ctx->csa.register_lock); |
1905 | spu_release(ctx); | 1905 | spu_release_saved(ctx); |
1906 | 1906 | ||
1907 | return ret; | 1907 | return ret; |
1908 | } | 1908 | } |
@@ -1943,7 +1943,7 @@ static ssize_t spufs_wbox_info_read(struct file *file, char __user *buf, | |||
1943 | spin_lock(&ctx->csa.register_lock); | 1943 | spin_lock(&ctx->csa.register_lock); |
1944 | ret = __spufs_wbox_info_read(ctx, buf, len, pos); | 1944 | ret = __spufs_wbox_info_read(ctx, buf, len, pos); |
1945 | spin_unlock(&ctx->csa.register_lock); | 1945 | spin_unlock(&ctx->csa.register_lock); |
1946 | spu_release(ctx); | 1946 | spu_release_saved(ctx); |
1947 | 1947 | ||
1948 | return ret; | 1948 | return ret; |
1949 | } | 1949 | } |
@@ -1993,7 +1993,7 @@ static ssize_t spufs_dma_info_read(struct file *file, char __user *buf, | |||
1993 | spin_lock(&ctx->csa.register_lock); | 1993 | spin_lock(&ctx->csa.register_lock); |
1994 | ret = __spufs_dma_info_read(ctx, buf, len, pos); | 1994 | ret = __spufs_dma_info_read(ctx, buf, len, pos); |
1995 | spin_unlock(&ctx->csa.register_lock); | 1995 | spin_unlock(&ctx->csa.register_lock); |
1996 | spu_release(ctx); | 1996 | spu_release_saved(ctx); |
1997 | 1997 | ||
1998 | return ret; | 1998 | return ret; |
1999 | } | 1999 | } |
@@ -2044,7 +2044,7 @@ static ssize_t spufs_proxydma_info_read(struct file *file, char __user *buf, | |||
2044 | spin_lock(&ctx->csa.register_lock); | 2044 | spin_lock(&ctx->csa.register_lock); |
2045 | ret = __spufs_proxydma_info_read(ctx, buf, len, pos); | 2045 | ret = __spufs_proxydma_info_read(ctx, buf, len, pos); |
2046 | spin_unlock(&ctx->csa.register_lock); | 2046 | spin_unlock(&ctx->csa.register_lock); |
2047 | spu_release(ctx); | 2047 | spu_release_saved(ctx); |
2048 | 2048 | ||
2049 | return ret; | 2049 | return ret; |
2050 | } | 2050 | } |
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index fdace9284378..1438aa2c346e 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h | |||
@@ -40,6 +40,10 @@ enum { | |||
40 | struct spu_context_ops; | 40 | struct spu_context_ops; |
41 | struct spu_gang; | 41 | struct spu_gang; |
42 | 42 | ||
43 | enum { | ||
44 | SPU_SCHED_WAS_ACTIVE, /* was active upon spu_acquire_saved() */ | ||
45 | }; | ||
46 | |||
43 | struct spu_context { | 47 | struct spu_context { |
44 | struct spu *spu; /* pointer to a physical SPU */ | 48 | struct spu *spu; /* pointer to a physical SPU */ |
45 | struct spu_state csa; /* SPU context save area. */ | 49 | struct spu_state csa; /* SPU context save area. */ |
@@ -214,6 +218,7 @@ void spu_unmap_mappings(struct spu_context *ctx); | |||
214 | void spu_forget(struct spu_context *ctx); | 218 | void spu_forget(struct spu_context *ctx); |
215 | int spu_acquire_runnable(struct spu_context *ctx, unsigned long flags); | 219 | int spu_acquire_runnable(struct spu_context *ctx, unsigned long flags); |
216 | void spu_acquire_saved(struct spu_context *ctx); | 220 | void spu_acquire_saved(struct spu_context *ctx); |
221 | void spu_release_saved(struct spu_context *ctx); | ||
217 | 222 | ||
218 | int spu_activate(struct spu_context *ctx, unsigned long flags); | 223 | int spu_activate(struct spu_context *ctx, unsigned long flags); |
219 | void spu_deactivate(struct spu_context *ctx); | 224 | void spu_deactivate(struct spu_context *ctx); |