gru: update to rev 0.9 of gru spec
authorJack Steiner <steiner@sgi.com>
Wed, 17 Jun 2009 23:28:27 +0000 (16:28 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 18 Jun 2009 20:04:02 +0000 (13:04 -0700)
Update GRU driver to the latest version of the GRU spec. This consists
of minor updates:
- changes & additions to error status bits
- new restriction on handling of TLB misses while in FMM mode
- new field (not used by software) in TFH

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>
drivers/misc/sgi-gru/gru_instructions.h
drivers/misc/sgi-gru/grufault.c
drivers/misc/sgi-gru/gruhandles.h
drivers/misc/sgi-gru/grukservices.c
drivers/misc/sgi-gru/gruprocfs.c
drivers/misc/sgi-gru/grutables.h

index 2feb885ca96fcc501b289cc84bc081e946bd7176..eb9140d32e628fcec5d5aec86fe528076ec32378 100644 (file)
@@ -253,32 +253,37 @@ struct gru_instruction {
 #define CBE_CAUSE_HA_RESPONSE_FATAL            (1 << 13)
 #define CBE_CAUSE_HA_RESPONSE_NON_FATAL                (1 << 14)
 #define CBE_CAUSE_ADDRESS_SPACE_DECODE_ERROR   (1 << 15)
-#define CBE_CAUSE_RESPONSE_DATA_ERROR          (1 << 16)
-#define CBE_CAUSE_PROTOCOL_STATE_DATA_ERROR    (1 << 17)
+#define CBE_CAUSE_PROTOCOL_STATE_DATA_ERROR    (1 << 16)
+#define CBE_CAUSE_RA_RESPONSE_DATA_ERROR       (1 << 17)
+#define CBE_CAUSE_HA_RESPONSE_DATA_ERROR       (1 << 18)
 
 /* CBE cbrexecstatus bits */
 #define CBR_EXS_ABORT_OCC_BIT                  0
 #define CBR_EXS_INT_OCC_BIT                    1
 #define CBR_EXS_PENDING_BIT                    2
 #define CBR_EXS_QUEUED_BIT                     3
-#define CBR_EXS_TLBHW_BIT                      4
+#define CBR_EXS_TLB_INVAL_BIT                  4
 #define CBR_EXS_EXCEPTION_BIT                  5
 
 #define CBR_EXS_ABORT_OCC                      (1 << CBR_EXS_ABORT_OCC_BIT)
 #define CBR_EXS_INT_OCC                                (1 << CBR_EXS_INT_OCC_BIT)
 #define CBR_EXS_PENDING                                (1 << CBR_EXS_PENDING_BIT)
 #define CBR_EXS_QUEUED                         (1 << CBR_EXS_QUEUED_BIT)
-#define CBR_EXS_TLBHW                          (1 << CBR_EXS_TLBHW_BIT)
+#define CBR_TLB_INVAL                          (1 << CBR_EXS_TLB_INVAL_BIT)
 #define CBR_EXS_EXCEPTION                      (1 << CBR_EXS_EXCEPTION_BIT)
 
 /*
  * Exceptions are retried for the following cases. If any OTHER bits are set
  * in ecause, the exception is not retryable.
  */
-#define EXCEPTION_RETRY_BITS (CBE_CAUSE_RESPONSE_DATA_ERROR |          \
-                             CBE_CAUSE_RA_REQUEST_TIMEOUT |            \
+#define EXCEPTION_RETRY_BITS (CBE_CAUSE_EXECUTION_HW_ERROR |           \
                              CBE_CAUSE_TLBHW_ERROR |                   \
-                             CBE_CAUSE_HA_REQUEST_TIMEOUT)
+                             CBE_CAUSE_RA_REQUEST_TIMEOUT |            \
+                             CBE_CAUSE_RA_RESPONSE_NON_FATAL |         \
+                             CBE_CAUSE_HA_RESPONSE_NON_FATAL |         \
+                             CBE_CAUSE_RA_RESPONSE_DATA_ERROR |        \
+                             CBE_CAUSE_HA_RESPONSE_DATA_ERROR          \
+                             )
 
 /* Message queue head structure */
 union gru_mesqhead {
index 8443e90f9f6cdca189955da730c498b6a46fd811..a489807613f8246ed9ebf0880959200421972442 100644 (file)
@@ -339,8 +339,12 @@ static int gru_try_dropin(struct gru_thread_state *gts,
         * Might be a hardware race OR a stupid user. Ignore FMM because FMM
         * is a transient state.
         */
-       if (tfh->status != TFHSTATUS_EXCEPTION)
-               goto failnoexception;
+       if (tfh->status != TFHSTATUS_EXCEPTION) {
+               gru_flush_cache(tfh);
+               if (tfh->status != TFHSTATUS_EXCEPTION)
+                       goto failnoexception;
+               STAT(tfh_stale_on_fault);
+       }
        if (tfh->state == TFHSTATE_IDLE)
                goto failidle;
        if (tfh->state == TFHSTATE_MISS_FMM && cb)
index 9f41e2cc09d5c8749c9ac7cd5188aa4b52a90df0..99ec82678f5c9df379ab3ea1b545bad7c0e22eb0 100644 (file)
@@ -255,7 +255,8 @@ struct gru_tlb_fault_handle {
        unsigned int state:3;
        unsigned int fill3:1;
 
-       unsigned int cause:7;
+       unsigned int cause:6;
+       unsigned int cb_int:1;
        unsigned int fill4:1;
 
        unsigned int indexway:12;       /* DW 0 - high 32 */
index 7d7952b27e039f20115e4823fe7c02ff345e6062..ba6fcd963f3054cc917f92ebf45f87db54b465bd 100644 (file)
@@ -406,7 +406,8 @@ static int gru_retry_exception(void *cb)
                        return CBS_IDLE;
 
                gru_get_cb_exception_detail(cb, &excdet);
-               if (excdet.ecause & ~EXCEPTION_RETRY_BITS)
+               if ((excdet.ecause & ~EXCEPTION_RETRY_BITS) ||
+                               (excdet.cbrexecstatus & CBR_EXS_ABORT_OCC))
                        break;
                if (retry-- == 0)
                        break;
index 6ef4cb4b84c8c70ca8283a0082c50bb11fe228e1..b5b9cf5c182e881de5e848fc5877a8edcc6476ab 100644 (file)
@@ -89,6 +89,7 @@ static int statistics_show(struct seq_file *s, void *p)
        printstat(s, tlb_dropin_fail_fmm);
        printstat(s, tlb_dropin_fail_no_exception);
        printstat(s, tlb_dropin_fail_no_exception_war);
+       printstat(s, tfh_stale_on_fault);
        printstat(s, mmu_invalidate_range);
        printstat(s, mmu_invalidate_page);
        printstat(s, mmu_clear_flush_young);
index 6dfb3e69411f360f9db441c4d5c347b71ff42bfd..246c63883ebf92b58147164ab2d838adac9ad0fe 100644 (file)
@@ -212,6 +212,7 @@ struct gru_stats_s {
        atomic_long_t tlb_dropin_fail_fmm;
        atomic_long_t tlb_dropin_fail_no_exception;
        atomic_long_t tlb_dropin_fail_no_exception_war;
+       atomic_long_t tfh_stale_on_fault;
        atomic_long_t mmu_invalidate_range;
        atomic_long_t mmu_invalidate_page;
        atomic_long_t mmu_clear_flush_young;