diff options
| author | Jack Steiner <steiner@sgi.com> | 2009-06-17 19:28:28 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-18 16:04:02 -0400 |
| commit | 1a2c09e3b41e334b6651d53b39cfe8ceefbc45f8 (patch) | |
| tree | f005fcb5c5251256767b15f4a23ee220e6de5c88 /drivers/misc | |
| parent | 270952a907220c0331fdaecbb55df892921c5e2d (diff) | |
gru: fix cache coherency issues with instruction retry
Fix two problems related to GRU instruction failures. Cache coherency is
not maintained for CBEs except when loading or unloading contexts. When
reading a CBE to extract error information, the CBE must first be flushed
from the cache.
The function that reads kerrnel CBEs was reading the wrong CBE.
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>
Diffstat (limited to 'drivers/misc')
| -rw-r--r-- | drivers/misc/sgi-gru/grufault.c | 3 | ||||
| -rw-r--r-- | drivers/misc/sgi-gru/grufile.c | 2 | ||||
| -rw-r--r-- | drivers/misc/sgi-gru/grukservices.c | 12 | ||||
| -rw-r--r-- | drivers/misc/sgi-gru/grutables.h | 1 |
4 files changed, 14 insertions, 4 deletions
diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c index a489807613f8..6d0681236db5 100644 --- a/drivers/misc/sgi-gru/grufault.c +++ b/drivers/misc/sgi-gru/grufault.c | |||
| @@ -614,7 +614,7 @@ int gru_get_exception_detail(unsigned long arg) | |||
| 614 | } else if (gts->ts_gru) { | 614 | } else if (gts->ts_gru) { |
| 615 | cbrnum = thread_cbr_number(gts, ucbnum); | 615 | cbrnum = thread_cbr_number(gts, ucbnum); |
| 616 | cbe = get_cbe_by_index(gts->ts_gru, cbrnum); | 616 | cbe = get_cbe_by_index(gts->ts_gru, cbrnum); |
| 617 | prefetchw(cbe);/* Harmless on hardware, required for emulator */ | 617 | gru_flush_cache(cbe); /* CBE not coherent */ |
| 618 | excdet.opc = cbe->opccpy; | 618 | excdet.opc = cbe->opccpy; |
| 619 | excdet.exopc = cbe->exopccpy; | 619 | excdet.exopc = cbe->exopccpy; |
| 620 | excdet.ecause = cbe->ecause; | 620 | excdet.ecause = cbe->ecause; |
| @@ -622,6 +622,7 @@ int gru_get_exception_detail(unsigned long arg) | |||
| 622 | excdet.exceptdet1 = cbe->idef3upd; | 622 | excdet.exceptdet1 = cbe->idef3upd; |
| 623 | excdet.cbrstate = cbe->cbrstate; | 623 | excdet.cbrstate = cbe->cbrstate; |
| 624 | excdet.cbrexecstatus = cbe->cbrexecstatus; | 624 | excdet.cbrexecstatus = cbe->cbrexecstatus; |
| 625 | gru_flush_cache(cbe); | ||
| 625 | ret = 0; | 626 | ret = 0; |
| 626 | } else { | 627 | } else { |
| 627 | ret = -EAGAIN; | 628 | ret = -EAGAIN; |
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c index 796ac704795e..bfc88d1b2a5b 100644 --- a/drivers/misc/sgi-gru/grufile.c +++ b/drivers/misc/sgi-gru/grufile.c | |||
| @@ -46,6 +46,7 @@ | |||
| 46 | 46 | ||
| 47 | struct gru_blade_state *gru_base[GRU_MAX_BLADES] __read_mostly; | 47 | struct gru_blade_state *gru_base[GRU_MAX_BLADES] __read_mostly; |
| 48 | unsigned long gru_start_paddr __read_mostly; | 48 | unsigned long gru_start_paddr __read_mostly; |
| 49 | void *gru_start_vaddr __read_mostly; | ||
| 49 | unsigned long gru_end_paddr __read_mostly; | 50 | unsigned long gru_end_paddr __read_mostly; |
| 50 | unsigned int gru_max_gids __read_mostly; | 51 | unsigned int gru_max_gids __read_mostly; |
| 51 | struct gru_stats_s gru_stats; | 52 | struct gru_stats_s gru_stats; |
| @@ -376,7 +377,6 @@ static int __init gru_init(void) | |||
| 376 | { | 377 | { |
| 377 | int ret, irq, chip; | 378 | int ret, irq, chip; |
| 378 | char id[10]; | 379 | char id[10]; |
| 379 | void *gru_start_vaddr; | ||
| 380 | 380 | ||
| 381 | if (!is_uv_system()) | 381 | if (!is_uv_system()) |
| 382 | return 0; | 382 | return 0; |
diff --git a/drivers/misc/sgi-gru/grukservices.c b/drivers/misc/sgi-gru/grukservices.c index ba6fcd963f30..7586b89fd0d3 100644 --- a/drivers/misc/sgi-gru/grukservices.c +++ b/drivers/misc/sgi-gru/grukservices.c | |||
| @@ -98,6 +98,9 @@ | |||
| 98 | #define ASYNC_HAN_TO_BID(h) ((h) - 1) | 98 | #define ASYNC_HAN_TO_BID(h) ((h) - 1) |
| 99 | #define ASYNC_BID_TO_HAN(b) ((b) + 1) | 99 | #define ASYNC_BID_TO_HAN(b) ((b) + 1) |
| 100 | #define ASYNC_HAN_TO_BS(h) gru_base[ASYNC_HAN_TO_BID(h)] | 100 | #define ASYNC_HAN_TO_BS(h) gru_base[ASYNC_HAN_TO_BID(h)] |
| 101 | #define KCB_TO_GID(cb) ((cb - gru_start_vaddr) / \ | ||
| 102 | (GRU_SIZE * GRU_CHIPLETS_PER_BLADE)) | ||
| 103 | #define KCB_TO_BS(cb) gru_base[KCB_TO_GID(cb)] | ||
| 101 | 104 | ||
| 102 | #define GRU_NUM_KERNEL_CBR 1 | 105 | #define GRU_NUM_KERNEL_CBR 1 |
| 103 | #define GRU_NUM_KERNEL_DSR_BYTES 256 | 106 | #define GRU_NUM_KERNEL_DSR_BYTES 256 |
| @@ -354,14 +357,19 @@ int gru_get_cb_exception_detail(void *cb, | |||
| 354 | struct control_block_extended_exc_detail *excdet) | 357 | struct control_block_extended_exc_detail *excdet) |
| 355 | { | 358 | { |
| 356 | struct gru_control_block_extended *cbe; | 359 | struct gru_control_block_extended *cbe; |
| 360 | struct gru_blade_state *bs; | ||
| 361 | int cbrnum; | ||
| 357 | 362 | ||
| 358 | cbe = get_cbe(GRUBASE(cb), get_cb_number(cb)); | 363 | bs = KCB_TO_BS(cb); |
| 359 | prefetchw(cbe); /* Harmless on hardware, required for emulator */ | 364 | cbrnum = thread_cbr_number(bs->bs_kgts, get_cb_number(cb)); |
| 365 | cbe = get_cbe(GRUBASE(cb), cbrnum); | ||
| 366 | gru_flush_cache(cbe); /* CBE not coherent */ | ||
| 360 | excdet->opc = cbe->opccpy; | 367 | excdet->opc = cbe->opccpy; |
| 361 | excdet->exopc = cbe->exopccpy; | 368 | excdet->exopc = cbe->exopccpy; |
| 362 | excdet->ecause = cbe->ecause; | 369 | excdet->ecause = cbe->ecause; |
| 363 | excdet->exceptdet0 = cbe->idef1upd; | 370 | excdet->exceptdet0 = cbe->idef1upd; |
| 364 | excdet->exceptdet1 = cbe->idef3upd; | 371 | excdet->exceptdet1 = cbe->idef3upd; |
| 372 | gru_flush_cache(cbe); | ||
| 365 | return 0; | 373 | return 0; |
| 366 | } | 374 | } |
| 367 | 375 | ||
diff --git a/drivers/misc/sgi-gru/grutables.h b/drivers/misc/sgi-gru/grutables.h index 246c63883ebf..665704683ab8 100644 --- a/drivers/misc/sgi-gru/grutables.h +++ b/drivers/misc/sgi-gru/grutables.h | |||
| @@ -153,6 +153,7 @@ | |||
| 153 | extern struct gru_stats_s gru_stats; | 153 | extern struct gru_stats_s gru_stats; |
| 154 | extern struct gru_blade_state *gru_base[]; | 154 | extern struct gru_blade_state *gru_base[]; |
| 155 | extern unsigned long gru_start_paddr, gru_end_paddr; | 155 | extern unsigned long gru_start_paddr, gru_end_paddr; |
| 156 | extern void *gru_start_vaddr; | ||
| 156 | extern unsigned int gru_max_gids; | 157 | extern unsigned int gru_max_gids; |
| 157 | 158 | ||
| 158 | #define GRU_MAX_BLADES MAX_NUMNODES | 159 | #define GRU_MAX_BLADES MAX_NUMNODES |
