diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2016-06-01 07:10:08 -0400 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2016-06-27 07:07:45 -0400 |
commit | 583248e6620a4726093295e2d6785fcbc2e86428 (patch) | |
tree | d2a0dc2941a1eadc46d44ecb6da4c848beb4daaf | |
parent | a4c34ff1c029e90e7d5f8dd8d29b0a93b31c3cb2 (diff) |
iommu/iova: Disable preemption around use of this_cpu_ptr()
Between acquiring the this_cpu_ptr() and using it, ideally we don't want
to be preempted and work on another CPU's private data. this_cpu_ptr()
checks whether or not preemption is disable, and get_cpu_ptr() provides
a convenient wrapper for operating on the cpu ptr inside a preemption
disabled critical section (which currently is provided by the
spinlock).
[ 167.997877] BUG: using smp_processor_id() in preemptible [00000000] code: usb-storage/216
[ 167.997940] caller is debug_smp_processor_id+0x17/0x20
[ 167.997945] CPU: 7 PID: 216 Comm: usb-storage Tainted: G U 4.7.0-rc1-gfxbench-RO_Patchwork_1057+ #1
[ 167.997948] Hardware name: Hewlett-Packard HP Pro 3500 Series/2ABF, BIOS 8.11 10/24/2012
[ 167.997951] 0000000000000000 ffff880118b7f9c8 ffffffff8140dca5 0000000000000007
[ 167.997958] ffffffff81a3a7e9 ffff880118b7f9f8 ffffffff8142a927 0000000000000000
[ 167.997965] ffff8800d499ed58 0000000000000001 00000000000fffff ffff880118b7fa08
[ 167.997971] Call Trace:
[ 167.997977] [<ffffffff8140dca5>] dump_stack+0x67/0x92
[ 167.997981] [<ffffffff8142a927>] check_preemption_disabled+0xd7/0xe0
[ 167.997985] [<ffffffff8142a947>] debug_smp_processor_id+0x17/0x20
[ 167.997990] [<ffffffff81507e17>] alloc_iova_fast+0xb7/0x210
[ 167.997994] [<ffffffff8150c55f>] intel_alloc_iova+0x7f/0xd0
[ 167.997998] [<ffffffff8151021d>] intel_map_sg+0xbd/0x240
[ 167.998002] [<ffffffff810e5efd>] ? debug_lockdep_rcu_enabled+0x1d/0x20
[ 167.998009] [<ffffffff81596059>] usb_hcd_map_urb_for_dma+0x4b9/0x5a0
[ 167.998013] [<ffffffff81596d19>] usb_hcd_submit_urb+0xe9/0xaa0
[ 167.998017] [<ffffffff810cff2f>] ? mark_held_locks+0x6f/0xa0
[ 167.998022] [<ffffffff810d525c>] ? __raw_spin_lock_init+0x1c/0x50
[ 167.998025] [<ffffffff810e5efd>] ? debug_lockdep_rcu_enabled+0x1d/0x20
[ 167.998028] [<ffffffff815988f3>] usb_submit_urb+0x3f3/0x5a0
[ 167.998032] [<ffffffff810d0082>] ? trace_hardirqs_on_caller+0x122/0x1b0
[ 167.998035] [<ffffffff81599ae7>] usb_sg_wait+0x67/0x150
[ 167.998039] [<ffffffff815dc202>] usb_stor_bulk_transfer_sglist.part.3+0x82/0xd0
[ 167.998042] [<ffffffff815dc29c>] usb_stor_bulk_srb+0x4c/0x60
[ 167.998045] [<ffffffff815dc42e>] usb_stor_Bulk_transport+0x17e/0x420
[ 167.998049] [<ffffffff815dcf32>] usb_stor_invoke_transport+0x242/0x540
[ 167.998052] [<ffffffff810e5efd>] ? debug_lockdep_rcu_enabled+0x1d/0x20
[ 167.998058] [<ffffffff815dba19>] usb_stor_transparent_scsi_command+0x9/0x10
[ 167.998061] [<ffffffff815de518>] usb_stor_control_thread+0x158/0x260
[ 167.998064] [<ffffffff815de3c0>] ? fill_inquiry_response+0x20/0x20
[ 167.998067] [<ffffffff815de3c0>] ? fill_inquiry_response+0x20/0x20
[ 167.998071] [<ffffffff8109ddfa>] kthread+0xea/0x100
[ 167.998078] [<ffffffff817ac6af>] ret_from_fork+0x1f/0x40
[ 167.998081] [<ffffffff8109dd10>] ? kthread_create_on_node+0x1f0/0x1f0
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96293
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: iommu@lists.linux-foundation.org
Cc: linux-kernel@vger.kernel.org
Fixes: 9257b4a206fc ('iommu/iova: introduce per-cpu caching to iova allocation')
Signed-off-by: Joerg Roedel <jroedel@suse.de>
-rw-r--r-- | drivers/iommu/iova.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c index ba764a0835d3..e23001bfcfee 100644 --- a/drivers/iommu/iova.c +++ b/drivers/iommu/iova.c | |||
@@ -420,8 +420,10 @@ retry: | |||
420 | 420 | ||
421 | /* Try replenishing IOVAs by flushing rcache. */ | 421 | /* Try replenishing IOVAs by flushing rcache. */ |
422 | flushed_rcache = true; | 422 | flushed_rcache = true; |
423 | preempt_disable(); | ||
423 | for_each_online_cpu(cpu) | 424 | for_each_online_cpu(cpu) |
424 | free_cpu_cached_iovas(cpu, iovad); | 425 | free_cpu_cached_iovas(cpu, iovad); |
426 | preempt_enable(); | ||
425 | goto retry; | 427 | goto retry; |
426 | } | 428 | } |
427 | 429 | ||
@@ -749,7 +751,7 @@ static bool __iova_rcache_insert(struct iova_domain *iovad, | |||
749 | bool can_insert = false; | 751 | bool can_insert = false; |
750 | unsigned long flags; | 752 | unsigned long flags; |
751 | 753 | ||
752 | cpu_rcache = this_cpu_ptr(rcache->cpu_rcaches); | 754 | cpu_rcache = get_cpu_ptr(rcache->cpu_rcaches); |
753 | spin_lock_irqsave(&cpu_rcache->lock, flags); | 755 | spin_lock_irqsave(&cpu_rcache->lock, flags); |
754 | 756 | ||
755 | if (!iova_magazine_full(cpu_rcache->loaded)) { | 757 | if (!iova_magazine_full(cpu_rcache->loaded)) { |
@@ -779,6 +781,7 @@ static bool __iova_rcache_insert(struct iova_domain *iovad, | |||
779 | iova_magazine_push(cpu_rcache->loaded, iova_pfn); | 781 | iova_magazine_push(cpu_rcache->loaded, iova_pfn); |
780 | 782 | ||
781 | spin_unlock_irqrestore(&cpu_rcache->lock, flags); | 783 | spin_unlock_irqrestore(&cpu_rcache->lock, flags); |
784 | put_cpu_ptr(rcache->cpu_rcaches); | ||
782 | 785 | ||
783 | if (mag_to_free) { | 786 | if (mag_to_free) { |
784 | iova_magazine_free_pfns(mag_to_free, iovad); | 787 | iova_magazine_free_pfns(mag_to_free, iovad); |
@@ -812,7 +815,7 @@ static unsigned long __iova_rcache_get(struct iova_rcache *rcache, | |||
812 | bool has_pfn = false; | 815 | bool has_pfn = false; |
813 | unsigned long flags; | 816 | unsigned long flags; |
814 | 817 | ||
815 | cpu_rcache = this_cpu_ptr(rcache->cpu_rcaches); | 818 | cpu_rcache = get_cpu_ptr(rcache->cpu_rcaches); |
816 | spin_lock_irqsave(&cpu_rcache->lock, flags); | 819 | spin_lock_irqsave(&cpu_rcache->lock, flags); |
817 | 820 | ||
818 | if (!iova_magazine_empty(cpu_rcache->loaded)) { | 821 | if (!iova_magazine_empty(cpu_rcache->loaded)) { |
@@ -834,6 +837,7 @@ static unsigned long __iova_rcache_get(struct iova_rcache *rcache, | |||
834 | iova_pfn = iova_magazine_pop(cpu_rcache->loaded, limit_pfn); | 837 | iova_pfn = iova_magazine_pop(cpu_rcache->loaded, limit_pfn); |
835 | 838 | ||
836 | spin_unlock_irqrestore(&cpu_rcache->lock, flags); | 839 | spin_unlock_irqrestore(&cpu_rcache->lock, flags); |
840 | put_cpu_ptr(rcache->cpu_rcaches); | ||
837 | 841 | ||
838 | return iova_pfn; | 842 | return iova_pfn; |
839 | } | 843 | } |