Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1635573

[PATCH 3.12 23/86] net/mlx4_core: Fix racy CQ (Completion Queue) free

From Jiri Slaby <jslaby@suse.cz>
Newsgroups linux.kernel
Subject [PATCH 3.12 23/86] net/mlx4_core: Fix racy CQ (Completion Queue) free
Date 2017-05-04 11:30 +0200
Message-ID <tDlfc-1wD-25@gated-at.bofh.it> (permalink)
References <tDkVQ-1oS-3@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


From: Jack Morgenstein <jackm@dev.mellanox.co.il>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 291c566a28910614ce42d0ffe82196eddd6346f4 upstream.

In function mlx4_cq_completion() and mlx4_cq_event(), the
radix_tree_lookup requires a rcu_read_lock.
This is mandatory: if another core frees the CQ, it could
run the radix_tree_node_rcu_free() call_rcu() callback while
its being used by the radix tree lookup function.

Additionally, in function mlx4_cq_event(), since we are adding
the rcu lock around the radix-tree lookup, we no longer need to take
the spinlock. Also, the synchronize_irq() call for the async event
eliminates the need for incrementing the cq reference count in
mlx4_cq_event().

Other changes:
1. In function mlx4_cq_free(), replace spin_lock_irq with spin_lock:
   we no longer take this spinlock in the interrupt context.
   The spinlock here, therefore, simply protects against different
   threads simultaneously invoking mlx4_cq_free() for different cq's.

2. In function mlx4_cq_free(), we move the radix tree delete to before
   the synchronize_irq() calls. This guarantees that we will not
   access this cq during any subsequent interrupts, and therefore can
   safely free the CQ after the synchronize_irq calls. The rcu_read_lock
   in the interrupt handlers only needs to protect against corrupting the
   radix tree; the interrupt handlers may access the cq outside the
   rcu_read_lock due to the synchronize_irq calls which protect against
   premature freeing of the cq.

3. In function mlx4_cq_event(), we change the mlx_warn message to mlx4_dbg.

4. We leave the cq reference count mechanism in place, because it is
   still needed for the cq completion tasklet mechanism.

Fixes: 6d90aa5cf17b ("net/mlx4_core: Make sure there are no pending async events when freeing CQ")
Fixes: 225c7b1feef1 ("IB/mlx4: Add a driver Mellanox ConnectX InfiniBand adapters")
Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
Signed-off-by: Matan Barak <matanb@mellanox.com>
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/net/ethernet/mellanox/mlx4/cq.c | 38 +++++++++++++++++----------------
 1 file changed, 20 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/cq.c b/drivers/net/ethernet/mellanox/mlx4/cq.c
index 004e4231af67..528597f65937 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cq.c
@@ -57,13 +57,19 @@ void mlx4_cq_completion(struct mlx4_dev *dev, u32 cqn)
 {
 	struct mlx4_cq *cq;
 
+	rcu_read_lock();
 	cq = radix_tree_lookup(&mlx4_priv(dev)->cq_table.tree,
 			       cqn & (dev->caps.num_cqs - 1));
+	rcu_read_unlock();
+
 	if (!cq) {
 		mlx4_dbg(dev, "Completion event for bogus CQ %08x\n", cqn);
 		return;
 	}
 
+	/* Acessing the CQ outside of rcu_read_lock is safe, because
+	 * the CQ is freed only after interrupt handling is completed.
+	 */
 	++cq->arm_sn;
 
 	cq->comp(cq);
@@ -74,23 +80,19 @@ void mlx4_cq_event(struct mlx4_dev *dev, u32 cqn, int event_type)
 	struct mlx4_cq_table *cq_table = &mlx4_priv(dev)->cq_table;
 	struct mlx4_cq *cq;
 
-	spin_lock(&cq_table->lock);
-
+	rcu_read_lock();
 	cq = radix_tree_lookup(&cq_table->tree, cqn & (dev->caps.num_cqs - 1));
-	if (cq)
-		atomic_inc(&cq->refcount);
-
-	spin_unlock(&cq_table->lock);
+	rcu_read_unlock();
 
 	if (!cq) {
-		mlx4_warn(dev, "Async event for bogus CQ %08x\n", cqn);
+		mlx4_dbg(dev, "Async event for bogus CQ %08x\n", cqn);
 		return;
 	}
 
+	/* Acessing the CQ outside of rcu_read_lock is safe, because
+	 * the CQ is freed only after interrupt handling is completed.
+	 */
 	cq->event(cq, event_type);
-
-	if (atomic_dec_and_test(&cq->refcount))
-		complete(&cq->free);
 }
 
 static int mlx4_SW2HW_CQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
@@ -261,9 +263,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent,
 	if (err)
 		return err;
 
-	spin_lock_irq(&cq_table->lock);
+	spin_lock(&cq_table->lock);
 	err = radix_tree_insert(&cq_table->tree, cq->cqn, cq);
-	spin_unlock_irq(&cq_table->lock);
+	spin_unlock(&cq_table->lock);
 	if (err)
 		goto err_icm;
 
@@ -303,9 +305,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent,
 	return 0;
 
 err_radix:
-	spin_lock_irq(&cq_table->lock);
+	spin_lock(&cq_table->lock);
 	radix_tree_delete(&cq_table->tree, cq->cqn);
-	spin_unlock_irq(&cq_table->lock);
+	spin_unlock(&cq_table->lock);
 
 err_icm:
 	mlx4_cq_free_icm(dev, cq->cqn);
@@ -324,11 +326,11 @@ void mlx4_cq_free(struct mlx4_dev *dev, struct mlx4_cq *cq)
 	if (err)
 		mlx4_warn(dev, "HW2SW_CQ failed (%d) for CQN %06x\n", err, cq->cqn);
 
-	synchronize_irq(priv->eq_table.eq[cq->vector].irq);
-
-	spin_lock_irq(&cq_table->lock);
+	spin_lock(&cq_table->lock);
 	radix_tree_delete(&cq_table->tree, cq->cqn);
-	spin_unlock_irq(&cq_table->lock);
+	spin_unlock(&cq_table->lock);
+
+	synchronize_irq(priv->eq_table.eq[cq->vector].irq);
 
 	if (atomic_dec_and_test(&cq->refcount))
 		complete(&cq->free);
-- 
2.12.2

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

[PATCH 3.12 00/86] 3.12.74-stable review Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:10 +0200
  [PATCH 3.12 01/86] drm/vmwgfx: NULL pointer dereference in vmw_surface_define_ioctl() Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:10 +0200
    [PATCH 3.12 04/86] drm/vmwgfx: fix integer overflow in vmw_surface_define_ioctl() Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:10 +0200
    [PATCH 3.12 81/86] ALSA: seq: Don't break snd_use_lock_sync() loop by timeout Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:10 +0200
    [PATCH 3.12 25/86] perf/x86: Avoid exposing wrong/stale data in intel_pmu_lbr_read_32() Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:10 +0200
    [PATCH 3.12 03/86] drm/vmwgfx: Remove getparam error message Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:10 +0200
    [PATCH 3.12 05/86] Reset TreeId to zero on SMB2 TREE_CONNECT Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:10 +0200
    [PATCH 3.12 85/86] nfsd: check for oversized NFSv2/v3 arguments Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:10 +0200
    [PATCH 3.12 59/86] kvm: arm/arm64: Fix locking for kvm_free_stage2_pgd Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:10 +0200
    [PATCH 3.12 26/86] x86/vdso: Plug race between mapping and ELF header setup Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:10 +0200
    [PATCH 3.12 82/86] MIPS: KGDB: Use kernel context for sleeping threads Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:10 +0200
    [PATCH 3.12 31/86] xen, fbfront: fix connecting to backend Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:10 +0200
    [PATCH 3.12 56/86] ACPI / power: Avoid maybe-uninitialized warning Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:10 +0200
    [PATCH 3.12 78/86] MIPS: Fix crash registers on non-crashing CPUs Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:10 +0200
    [PATCH 3.12 28/86] iscsi-target: Drop work-around for legacy GlobalSAN initiator Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:10 +0200
    [PATCH 3.12 29/86] scsi: sr: Sanity check returned mode data Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:10 +0200
    [PATCH 3.12 83/86] p9_client_readdir() fix Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:10 +0200
    [PATCH 3.12 06/86] ptrace: fix PTRACE_LISTEN race corrupting task->state Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:10 +0200
    [PATCH 3.12 80/86] xen/x86: don't lose event interrupts Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:10 +0200
    [PATCH 3.12 55/86] Input: elantech - add Fujitsu Lifebook E547 to force crc_enabled Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:10 +0200
    [PATCH 3.12 77/86] md:raid1: fix a dead loop when read from a WriteMostly disk Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 63/86] net/packet: fix overflow in check for tp_frame_nr Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 72/86] net: ipv4: fix multipath RTM_GETROUTE behavior when iif is given Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 61/86] powerpc: Reject binutils 2.24 when building little endian Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 75/86] ipv6: check raw payload size correctly in ioctl Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 60/86] block: fix del_gendisk() vs blkdev_ioctl crash Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 33/86] char: lack of bool string made CONFIG_DEVPORT always on Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 74/86] ip6mr: fix notification device destruction Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 66/86] tty: nozomi: avoid a harmless gcc warning Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 67/86] hostap: avoid uninitialized variable use in hfa384x_get_rid Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 64/86] net/packet: fix overflow in check for tp_reserve Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 76/86] ext4: check if in-inode xattr is corrupted in ext4_expand_extra_isize_ea() Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 45/86] net: ipv6: check route protocol when deleting routes Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 46/86] KEYS: Disallow keyrings beginning with '.' to be joined as session keyrings Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 65/86] netfilter: arp_tables: fix invoking 32bit "iptable -P INPUT ACCEPT" failed in 64bit kernel Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 42/86] rtl8150: Use heap buffers for all register access Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 30/86] scsi: sd: Fix capacity calculation with 32-bit sector_t Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 39/86] mm: Tighten x86 /dev/mem with zeroing reads Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 43/86] catc: Combine failure cleanup code in catc_probe() Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 51/86] cifs: Do not send echoes before Negotiate is complete Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 40/86] virtio-console: avoid DMA from stack Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 69/86] net: neigh: guard against NULL solicit() method Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 49/86] tracing: Allocate the snapshot buffer before enabling probe Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 50/86] ring-buffer: Have ring_buffer_iter_empty() return true when empty Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 53/86] Drivers: hv: don't leak memory in vmbus_establish_gpadl() Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 62/86] ping: implement proper locking Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 79/86] RDS: Fix the atomicity for congestion map update Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 84/86] Input: i8042 - add Clevo P650RS to the i8042 reset list Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 52/86] CIFS: remove bad_network_name flag Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 54/86] Drivers: hv: get rid of timeout in vmbus_open() Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 47/86] KEYS: Change the name of the dead type to ".dead" to prevent user access Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 41/86] pegasus: Use heap buffers for all register access Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 37/86] ext4: fix inode checksum calculation problem if i_extra_size is small Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 38/86] platform/x86: acer-wmi: setup accelerometer when machine has appropriate notify event Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 71/86] l2tp: take reference on sessions being dumped Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 68/86] gfs2: avoid uninitialized variable warning Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 70/86] net: phy: handle state correctly in phy_stop_machine Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 58/86] x86/mce/AMD: Give a name to MCA bank 3 when accessed with legacy MSRs Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 73/86] sctp: listen on the sock only when it's state is listening or closed Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:20 +0200
    [PATCH 3.12 18/86] usb: dwc3: gadget: delay unmap of bounced requests Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:30 +0200
    [PATCH 3.12 32/86] char: Drop bogus dependency of DEVPORT on !M68K Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:30 +0200
    [PATCH 3.12 36/86] dvb-usb-v2: avoid use-after-free Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:30 +0200
    [PATCH 3.12 14/86] metag/usercopy: Add missing fixups Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:30 +0200
    [PATCH 3.12 10/86] metag/usercopy: Add early abort to copy_to_user Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:30 +0200
    [PATCH 3.12 21/86] usb: hub: Wait for connection to be reestablished after port reset Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:30 +0200
    [PATCH 3.12 13/86] metag/usercopy: Fix src fixup in from user rapf loops Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:30 +0200
    [PATCH 3.12 23/86] net/mlx4_core: Fix racy CQ (Completion Queue) free Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:30 +0200
    [PATCH 3.12 34/86] zram: do not use copy_page with non-page aligned address Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:30 +0200
    [PATCH 3.12 19/86] mtd: bcm47xxpart: fix parsing first block after aligned TRX Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:30 +0200
    [PATCH 3.12 16/86] s390/decompressor: fix initrd corruption caused by bss clear Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:30 +0200
    [PATCH 3.12 08/86] metag/usercopy: Drop unused macros Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:30 +0200
    [PATCH 3.12 24/86] Input: xpad - add support for Razer Wildcat gamepad Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:30 +0200
    [PATCH 3.12 44/86] catc: Use heap buffer for memory size test Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:30 +0200
    [PATCH 3.12 35/86] powerpc: Disable HFSCR[TM] if TM is not supported Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:30 +0200
    [PATCH 3.12 15/86] powerpc: Don't try to fix up misaligned load-with-reservation instructions Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:30 +0200
    [PATCH 3.12 07/86] ring-buffer: Fix return value check in test_ringbuffer() Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:30 +0200
    [PATCH 3.12 17/86] mm/mempolicy.c: fix error handling in set_mempolicy and mbind. Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:30 +0200
    [PATCH 3.12 09/86] metag/usercopy: Fix alignment error checking Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:30 +0200
    [PATCH 3.12 22/86] net/mlx4_en: Fix bad WQE issue Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:30 +0200
    [PATCH 3.12 20/86] net/packet: fix overflow in check for priv area size Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:30 +0200
    [PATCH 3.12 12/86] metag/usercopy: Set flags before ADDZ Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:30 +0200
    [PATCH 3.12 11/86] metag/usercopy: Zero rest of buffer from copy_from_user Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:30 +0200
  Re: [PATCH 3.12 00/86] 3.12.74-stable review Jiri Slaby <jslaby@suse.cz> - 2017-05-04 11:30 +0200
  Re: [PATCH 3.12 00/86] 3.12.74-stable review Guenter Roeck <linux@roeck-us.net> - 2017-05-04 18:00 +0200
    Re: [PATCH 3.12 00/86] 3.12.74-stable review Jiri Slaby <jslaby@suse.cz> - 2017-05-09 21:00 +0200
  Re: [PATCH 3.12 00/86] 3.12.74-stable review Shuah Khan <shuahkh@osg.samsung.com> - 2017-05-04 21:00 +0200

csiph-web