OSDN Git Service

iommu/arm-smmu: Rate-limit the context fault handler
authorMitchel Humpherys <mitchelh@codeaurora.org>
Mon, 14 Sep 2015 19:08:09 +0000 (12:08 -0700)
committerDavid Keitel <dkeitel@codeaurora.org>
Tue, 22 Mar 2016 18:14:12 +0000 (11:14 -0700)
It's not uncommon for us to take a flood of context faults when
something terrible happens.  This usually brings down the system due to
excessive logging, which makes it difficult to debug the actual root
cause of the issue.  Fix this by rate-limiting the output from the
context fault handler.

Change-Id: I1fe83bbbc7cc7aa2cf6303c6c7d2bf5733f63557
Signed-off-by: Mitchel Humpherys <mitchelh@codeaurora.org>
drivers/iommu/arm-smmu.c

index f484727..267886a 100644 (file)
@@ -1089,6 +1089,10 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
        phys_addr_t phys_soft;
        u32 frsynra;
 
+       static DEFINE_RATELIMIT_STATE(_rs,
+                                     DEFAULT_RATELIMIT_INTERVAL,
+                                     DEFAULT_RATELIMIT_BURST);
+
        mutex_lock(&smmu_domain->init_mutex);
        smmu = smmu_domain->smmu;
        if (!smmu) {
@@ -1148,25 +1152,30 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
                phys_addr_t phys_atos = arm_smmu_verify_fault(domain, iova,
                                                              fsr);
 
-               dev_err(smmu->dev,
-                       "Unhandled context fault: iova=0x%08lx, fsr=0x%x, fsynr=0x%x, cb=%d\n",
-                       iova, fsr, fsynr, cfg->cbndx);
-               dev_err(smmu->dev, "FAR    = %016lx\n", (unsigned long)far);
-               dev_err(smmu->dev, "FSR    = %08x [%s%s%s%s%s%s%s%s%s]\n", fsr,
-                       (fsr & 0x02) ? "TF " : "",
-                       (fsr & 0x04) ? "AFF " : "",
-                       (fsr & 0x08) ? "PF " : "",
-                       (fsr & 0x10) ? "EF " : "",
-                       (fsr & 0x20) ? "TLBMCF " : "",
-                       (fsr & 0x40) ? "TLBLKF " : "",
-                       (fsr & 0x80) ? "MHF " : "",
-                       (fsr & 0x40000000) ? "SS " : "",
-                       (fsr & 0x80000000) ? "MULTI " : "");
-               dev_err(smmu->dev,
-                       "soft iova-to-phys=%pa\n", &phys_soft);
-               dev_err(smmu->dev,
-                       "hard iova-to-phys (ATOS)=%pa\n", &phys_atos);
-               dev_err(smmu->dev, "SID=0x%x\n", frsynra & 0x1FF);
+               if (__ratelimit(&_rs)) {
+                       dev_err(smmu->dev,
+                               "Unhandled context fault: iova=0x%08lx, fsr=0x%x, fsynr=0x%x, cb=%d\n",
+                               iova, fsr, fsynr, cfg->cbndx);
+                       dev_err(smmu->dev, "FAR    = %016lx\n",
+                               (unsigned long)far);
+                       dev_err(smmu->dev,
+                               "FSR    = %08x [%s%s%s%s%s%s%s%s%s]\n",
+                               fsr,
+                               (fsr & 0x02) ? "TF " : "",
+                               (fsr & 0x04) ? "AFF " : "",
+                               (fsr & 0x08) ? "PF " : "",
+                               (fsr & 0x10) ? "EF " : "",
+                               (fsr & 0x20) ? "TLBMCF " : "",
+                               (fsr & 0x40) ? "TLBLKF " : "",
+                               (fsr & 0x80) ? "MHF " : "",
+                               (fsr & 0x40000000) ? "SS " : "",
+                               (fsr & 0x80000000) ? "MULTI " : "");
+                       dev_err(smmu->dev,
+                               "soft iova-to-phys=%pa\n", &phys_soft);
+                       dev_err(smmu->dev,
+                               "hard iova-to-phys (ATOS)=%pa\n", &phys_atos);
+                       dev_err(smmu->dev, "SID=0x%x\n", frsynra & 0x1FF);
+               }
                ret = IRQ_NONE;
                resume = RESUME_TERMINATE;
        }