lkml.org 
[lkml]   [2016]   [Jun]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.2.y-ckt 153/206] iommu/vt-d: Ratelimit fault handler
    Date
    4.2.8-ckt12 -stable review patch.  If anyone has any objections, please let me know.

    ---8<------------------------------------------------------------

    From: Alex Williamson <alex.williamson@redhat.com>

    commit c43fce4eebae257ca413733690e2076757282093 upstream.

    Fault rates can easily overwhelm the console and make the system
    unresponsive. Ratelimit to allow an opportunity for maintenance.

    Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
    Fixes: 0ac2491f57af ('x86, dmar: move page fault handling code to dmar.c')
    Signed-off-by: Joerg Roedel <jroedel@suse.de>
    Signed-off-by: Kamal Mostafa <kamal@canonical.com>
    ---
    drivers/iommu/dmar.c | 33 ++++++++++++++++++++++-----------
    1 file changed, 22 insertions(+), 11 deletions(-)

    diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
    index b526875..3e93632 100644
    --- a/drivers/iommu/dmar.c
    +++ b/drivers/iommu/dmar.c
    @@ -1575,10 +1575,17 @@ irqreturn_t dmar_fault(int irq, void *dev_id)
    int reg, fault_index;
    u32 fault_status;
    unsigned long flag;
    + bool ratelimited;
    + static DEFINE_RATELIMIT_STATE(rs,
    + DEFAULT_RATELIMIT_INTERVAL,
    + DEFAULT_RATELIMIT_BURST);
    +
    + /* Disable printing, simply clear the fault when ratelimited */
    + ratelimited = !__ratelimit(&rs);

    raw_spin_lock_irqsave(&iommu->register_lock, flag);
    fault_status = readl(iommu->reg + DMAR_FSTS_REG);
    - if (fault_status)
    + if (fault_status && !ratelimited)
    pr_err("DRHD: handling fault status reg %x\n", fault_status);

    /* TBD: ignore advanced fault log currently */
    @@ -1600,24 +1607,28 @@ irqreturn_t dmar_fault(int irq, void *dev_id)
    if (!(data & DMA_FRCD_F))
    break;

    - fault_reason = dma_frcd_fault_reason(data);
    - type = dma_frcd_type(data);
    + if (!ratelimited) {
    + fault_reason = dma_frcd_fault_reason(data);
    + type = dma_frcd_type(data);

    - data = readl(iommu->reg + reg +
    - fault_index * PRIMARY_FAULT_REG_LEN + 8);
    - source_id = dma_frcd_source_id(data);
    + data = readl(iommu->reg + reg +
    + fault_index * PRIMARY_FAULT_REG_LEN + 8);
    + source_id = dma_frcd_source_id(data);
    +
    + guest_addr = dmar_readq(iommu->reg + reg +
    + fault_index * PRIMARY_FAULT_REG_LEN);
    + guest_addr = dma_frcd_page_addr(guest_addr);
    + }

    - guest_addr = dmar_readq(iommu->reg + reg +
    - fault_index * PRIMARY_FAULT_REG_LEN);
    - guest_addr = dma_frcd_page_addr(guest_addr);
    /* clear the fault */
    writel(DMA_FRCD_F, iommu->reg + reg +
    fault_index * PRIMARY_FAULT_REG_LEN + 12);

    raw_spin_unlock_irqrestore(&iommu->register_lock, flag);

    - dmar_fault_do_one(iommu, type, fault_reason,
    - source_id, guest_addr);
    + if (!ratelimited)
    + dmar_fault_do_one(iommu, type, fault_reason,
    + source_id, guest_addr);

    fault_index++;
    if (fault_index >= cap_num_fault_regs(iommu->cap))
    --
    2.7.4
    \
     
     \ /
      Last update: 2016-06-10 00:01    [W:4.123 / U:0.556 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site