diff options
| author | Jack Steiner <steiner@sgi.com> | 2009-12-15 19:48:17 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-16 10:20:16 -0500 |
| commit | 0cd2b0813aac660f5f7a6574083157a70c152dd5 (patch) | |
| tree | 906bf285391bf3d9ad72f9c94838fbb067453ec4 | |
| parent | 5658366ab55cccab24b4799b3ff8e94bdc1cc529 (diff) | |
gru: fix bug in allocation of kernel contexts
Fix a bug in the assignment of GRU contexts used for kernel functions. If
a sleep occurs on the wait for a semaphore, the thread could switch cpus
and allocate resources on the wrong blade.
Signed-off-by: Jack Steiner <steiner@sgi.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
| -rw-r--r-- | drivers/misc/sgi-gru/grukservices.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/drivers/misc/sgi-gru/grukservices.c b/drivers/misc/sgi-gru/grukservices.c index c13342dda5fd..bfbf8fdbcd37 100644 --- a/drivers/misc/sgi-gru/grukservices.c +++ b/drivers/misc/sgi-gru/grukservices.c | |||
| @@ -221,13 +221,21 @@ static int gru_free_kernel_contexts(void) | |||
| 221 | static struct gru_blade_state *gru_lock_kernel_context(int blade_id) | 221 | static struct gru_blade_state *gru_lock_kernel_context(int blade_id) |
| 222 | { | 222 | { |
| 223 | struct gru_blade_state *bs; | 223 | struct gru_blade_state *bs; |
| 224 | int bid; | ||
| 224 | 225 | ||
| 225 | STAT(lock_kernel_context); | 226 | STAT(lock_kernel_context); |
| 226 | bs = gru_base[blade_id]; | 227 | again: |
| 228 | bid = blade_id < 0 ? uv_numa_blade_id() : blade_id; | ||
| 229 | bs = gru_base[bid]; | ||
| 227 | 230 | ||
| 231 | /* Handle the case where migration occured while waiting for the sema */ | ||
| 228 | down_read(&bs->bs_kgts_sema); | 232 | down_read(&bs->bs_kgts_sema); |
| 233 | if (blade_id < 0 && bid != uv_numa_blade_id()) { | ||
| 234 | up_read(&bs->bs_kgts_sema); | ||
| 235 | goto again; | ||
| 236 | } | ||
| 229 | if (!bs->bs_kgts || !bs->bs_kgts->ts_gru) | 237 | if (!bs->bs_kgts || !bs->bs_kgts->ts_gru) |
| 230 | gru_load_kernel_context(bs, blade_id); | 238 | gru_load_kernel_context(bs, bid); |
| 231 | return bs; | 239 | return bs; |
| 232 | 240 | ||
| 233 | } | 241 | } |
| @@ -256,7 +264,7 @@ static int gru_get_cpu_resources(int dsr_bytes, void **cb, void **dsr) | |||
| 256 | 264 | ||
| 257 | BUG_ON(dsr_bytes > GRU_NUM_KERNEL_DSR_BYTES); | 265 | BUG_ON(dsr_bytes > GRU_NUM_KERNEL_DSR_BYTES); |
| 258 | preempt_disable(); | 266 | preempt_disable(); |
| 259 | bs = gru_lock_kernel_context(uv_numa_blade_id()); | 267 | bs = gru_lock_kernel_context(-1); |
| 260 | lcpu = uv_blade_processor_id(); | 268 | lcpu = uv_blade_processor_id(); |
| 261 | *cb = bs->kernel_cb + lcpu * GRU_HANDLE_STRIDE; | 269 | *cb = bs->kernel_cb + lcpu * GRU_HANDLE_STRIDE; |
| 262 | *dsr = bs->kernel_dsr + lcpu * GRU_NUM_KERNEL_DSR_BYTES; | 270 | *dsr = bs->kernel_dsr + lcpu * GRU_NUM_KERNEL_DSR_BYTES; |
