Skip to content

Commit 4aef80b

Browse files
author
Fox Snowpatch
committed
1 parent 56e2adc commit 4aef80b

File tree

2 files changed

+24
-6
lines changed

2 files changed

+24
-6
lines changed

arch/powerpc/kernel/iommu.c

+20-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/types.h>
1515
#include <linux/slab.h>
1616
#include <linux/mm.h>
17+
#include <linux/delay.h>
1718
#include <linux/spinlock.h>
1819
#include <linux/string.h>
1920
#include <linux/dma-mapping.h>
@@ -803,6 +804,7 @@ bool iommu_table_in_use(struct iommu_table *tbl)
803804
static void iommu_table_free(struct kref *kref)
804805
{
805806
struct iommu_table *tbl;
807+
unsigned long start_time;
806808

807809
tbl = container_of(kref, struct iommu_table, it_kref);
808810

@@ -817,8 +819,24 @@ static void iommu_table_free(struct kref *kref)
817819
iommu_debugfs_del(tbl);
818820

819821
/* verify that table contains no entries */
820-
if (iommu_table_in_use(tbl))
821-
pr_warn("%s: Unexpected TCEs\n", __func__);
822+
start_time = jiffies;
823+
while (iommu_table_in_use(tbl)) {
824+
int sec;
825+
826+
pr_info("%s: Unexpected TCEs, wait for 50ms\n", __func__);
827+
msleep(50);
828+
829+
/* Come out of the loop if we have already waited for 120 seconds
830+
* for the TCEs to be free'ed. TCE are being free'ed
831+
* asynchronously by some DMA buffer management API - like
832+
* page_pool.
833+
*/
834+
sec = (s32)((u32)jiffies - (u32)start_time) / HZ;
835+
if (sec >= 120) {
836+
pr_warn("%s: TCEs still mapped even after 120 seconds\n", __func__);
837+
break;
838+
}
839+
}
822840

823841
/* free bitmap */
824842
vfree(tbl->it_map);

arch/powerpc/platforms/pseries/iommu.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -2390,6 +2390,10 @@ static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long acti
23902390

23912391
switch (action) {
23922392
case OF_RECONFIG_DETACH_NODE:
2393+
if (pci && pci->table_group)
2394+
iommu_pseries_free_group(pci->table_group,
2395+
np->full_name);
2396+
23932397
/*
23942398
* Removing the property will invoke the reconfig
23952399
* notifier again, which causes dead-lock on the
@@ -2400,10 +2404,6 @@ static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long acti
24002404
if (remove_dma_window_named(np, false, DIRECT64_PROPNAME, true))
24012405
remove_dma_window_named(np, false, DMA64_PROPNAME, true);
24022406

2403-
if (pci && pci->table_group)
2404-
iommu_pseries_free_group(pci->table_group,
2405-
np->full_name);
2406-
24072407
spin_lock(&dma_win_list_lock);
24082408
list_for_each_entry(window, &dma_win_list, list) {
24092409
if (window->device == np) {

0 commit comments

Comments
 (0)