swiotlb: save io_tlb_used to local variable before leaving critical section
authorDongli Zhang <dongli.zhang@oracle.com>
Fri, 12 Apr 2019 11:38:26 +0000 (19:38 +0800)
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Fri, 12 Apr 2019 23:44:46 +0000 (19:44 -0400)
When swiotlb is full, the kernel would print io_tlb_used. However, the
result might be inaccurate at that time because we have left the critical
section protected by spinlock.

Therefore, we backup the io_tlb_used into local variable before leaving
critical section.

Fixes: 83ca25948940 ("swiotlb: dump used and total slots when swiotlb buffer is full")
Suggested-by: HÃ¥kon Bugge <haakon.bugge@oracle.com>
Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
kernel/dma/swiotlb.c

index 82c767374c7047abe0aa25ed08ec4f6a7ff8b6d5..38d57218809c17531f2c963652c401c1baadd021 100644 (file)
@@ -445,6 +445,7 @@ phys_addr_t swiotlb_tbl_map_single(struct device *hwdev,
        unsigned long mask;
        unsigned long offset_slots;
        unsigned long max_slots;
+       unsigned long tmp_io_tlb_used;
 
        if (no_iotlb_memory)
                panic("Can not allocate SWIOTLB buffer earlier and can't now provide you with the DMA bounce buffer");
@@ -531,10 +532,12 @@ phys_addr_t swiotlb_tbl_map_single(struct device *hwdev,
        } while (index != wrap);
 
 not_found:
+       tmp_io_tlb_used = io_tlb_used;
+
        spin_unlock_irqrestore(&io_tlb_lock, flags);
        if (!(attrs & DMA_ATTR_NO_WARN) && printk_ratelimit())
-               dev_warn(hwdev, "swiotlb buffer is full (sz: %zd bytes), total %lu, used %lu\n",
-                        size, io_tlb_nslabs, io_tlb_used);
+               dev_warn(hwdev, "swiotlb buffer is full (sz: %zd bytes), total %lu (slots), used %lu (slots)\n",
+                        size, io_tlb_nslabs, tmp_io_tlb_used);
        return DMA_MAPPING_ERROR;
 found:
        io_tlb_used += nslots;