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


Groups > linux.kernel > #1230592

[PATCH 3.13.y-ckt 56/57] netlink: don't hold mutex in rcu callback when releasing mmapd ring

From Kamal Mostafa <kamal@canonical.com>
Newsgroups linux.kernel
Subject [PATCH 3.13.y-ckt 56/57] netlink: don't hold mutex in rcu callback when releasing mmapd ring
Date 2015-09-22 20:00 +0200
Message-ID <qbA1f-46k-81@gated-at.bofh.it> (permalink)
References <qbzRv-3UF-5@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


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

------------------

From: Florian Westphal <fw@strlen.de>

[ Upstream commit 0470eb99b4721586ccac954faac3fa4472da0845 ]

Kirill A. Shutemov says:

This simple test-case trigers few locking asserts in kernel:

int main(int argc, char **argv)
{
        unsigned int block_size = 16 * 4096;
        struct nl_mmap_req req = {
                .nm_block_size          = block_size,
                .nm_block_nr            = 64,
                .nm_frame_size          = 16384,
                .nm_frame_nr            = 64 * block_size / 16384,
        };
        unsigned int ring_size;
	int fd;

	fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
        if (setsockopt(fd, SOL_NETLINK, NETLINK_RX_RING, &req, sizeof(req)) < 0)
                exit(1);
        if (setsockopt(fd, SOL_NETLINK, NETLINK_TX_RING, &req, sizeof(req)) < 0)
                exit(1);

	ring_size = req.nm_block_nr * req.nm_block_size;
	mmap(NULL, 2 * ring_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
	return 0;
}

+++ exited with 0 +++
BUG: sleeping function called from invalid context at /home/kas/git/public/linux-mm/kernel/locking/mutex.c:616
in_atomic(): 1, irqs_disabled(): 0, pid: 1, name: init
3 locks held by init/1:
 #0:  (reboot_mutex){+.+...}, at: [<ffffffff81080959>] SyS_reboot+0xa9/0x220
 #1:  ((reboot_notifier_list).rwsem){.+.+..}, at: [<ffffffff8107f379>] __blocking_notifier_call_chain+0x39/0x70
 #2:  (rcu_callback){......}, at: [<ffffffff810d32e0>] rcu_do_batch.isra.49+0x160/0x10c0
Preemption disabled at:[<ffffffff8145365f>] __delay+0xf/0x20

CPU: 1 PID: 1 Comm: init Not tainted 4.1.0-00009-gbddf4c4818e0 #253
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS Debian-1.8.2-1 04/01/2014
 ffff88017b3d8000 ffff88027bc03c38 ffffffff81929ceb 0000000000000102
 0000000000000000 ffff88027bc03c68 ffffffff81085a9d 0000000000000002
 ffffffff81ca2a20 0000000000000268 0000000000000000 ffff88027bc03c98
Call Trace:
 <IRQ>  [<ffffffff81929ceb>] dump_stack+0x4f/0x7b
 [<ffffffff81085a9d>] ___might_sleep+0x16d/0x270
 [<ffffffff81085bed>] __might_sleep+0x4d/0x90
 [<ffffffff8192e96f>] mutex_lock_nested+0x2f/0x430
 [<ffffffff81932fed>] ? _raw_spin_unlock_irqrestore+0x5d/0x80
 [<ffffffff81464143>] ? __this_cpu_preempt_check+0x13/0x20
 [<ffffffff8182fc3d>] netlink_set_ring+0x1ed/0x350
 [<ffffffff8182e000>] ? netlink_undo_bind+0x70/0x70
 [<ffffffff8182fe20>] netlink_sock_destruct+0x80/0x150
 [<ffffffff817e484d>] __sk_free+0x1d/0x160
 [<ffffffff817e49a9>] sk_free+0x19/0x20
[..]

Cong Wang says:

We can't hold mutex lock in a rcu callback, [..]

Thomas Graf says:

The socket should be dead at this point. It might be simpler to
add a netlink_release_ring() function which doesn't require
locking at all.

Reported-by: "Kirill A. Shutemov" <kirill@shutemov.name>
Diagnosed-by: Cong Wang <cwang@twopensource.com>
Suggested-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
---
 net/netlink/af_netlink.c | 79 ++++++++++++++++++++++++++++--------------------
 1 file changed, 47 insertions(+), 32 deletions(-)

diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 8a2b386..de0f385 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -342,25 +342,52 @@ err1:
 	return NULL;
 }
 
+
+static void
+__netlink_set_ring(struct sock *sk, struct nl_mmap_req *req, bool tx_ring, void **pg_vec,
+		   unsigned int order)
+{
+	struct netlink_sock *nlk = nlk_sk(sk);
+	struct sk_buff_head *queue;
+	struct netlink_ring *ring;
+
+	queue = tx_ring ? &sk->sk_write_queue : &sk->sk_receive_queue;
+	ring  = tx_ring ? &nlk->tx_ring : &nlk->rx_ring;
+
+	spin_lock_bh(&queue->lock);
+
+	ring->frame_max		= req->nm_frame_nr - 1;
+	ring->head		= 0;
+	ring->frame_size	= req->nm_frame_size;
+	ring->pg_vec_pages	= req->nm_block_size / PAGE_SIZE;
+
+	swap(ring->pg_vec_len, req->nm_block_nr);
+	swap(ring->pg_vec_order, order);
+	swap(ring->pg_vec, pg_vec);
+
+	__skb_queue_purge(queue);
+	spin_unlock_bh(&queue->lock);
+
+	WARN_ON(atomic_read(&nlk->mapped));
+
+	if (pg_vec)
+		free_pg_vec(pg_vec, order, req->nm_block_nr);
+}
+
 static int netlink_set_ring(struct sock *sk, struct nl_mmap_req *req,
-			    bool closing, bool tx_ring)
+			    bool tx_ring)
 {
 	struct netlink_sock *nlk = nlk_sk(sk);
 	struct netlink_ring *ring;
-	struct sk_buff_head *queue;
 	void **pg_vec = NULL;
 	unsigned int order = 0;
-	int err;
 
 	ring  = tx_ring ? &nlk->tx_ring : &nlk->rx_ring;
-	queue = tx_ring ? &sk->sk_write_queue : &sk->sk_receive_queue;
 
-	if (!closing) {
-		if (atomic_read(&nlk->mapped))
-			return -EBUSY;
-		if (atomic_read(&ring->pending))
-			return -EBUSY;
-	}
+	if (atomic_read(&nlk->mapped))
+		return -EBUSY;
+	if (atomic_read(&ring->pending))
+		return -EBUSY;
 
 	if (req->nm_block_nr) {
 		if (ring->pg_vec != NULL)
@@ -392,31 +419,19 @@ static int netlink_set_ring(struct sock *sk, struct nl_mmap_req *req,
 			return -EINVAL;
 	}
 
-	err = -EBUSY;
 	mutex_lock(&nlk->pg_vec_lock);
-	if (closing || atomic_read(&nlk->mapped) == 0) {
-		err = 0;
-		spin_lock_bh(&queue->lock);
-
-		ring->frame_max		= req->nm_frame_nr - 1;
-		ring->head		= 0;
-		ring->frame_size	= req->nm_frame_size;
-		ring->pg_vec_pages	= req->nm_block_size / PAGE_SIZE;
-
-		swap(ring->pg_vec_len, req->nm_block_nr);
-		swap(ring->pg_vec_order, order);
-		swap(ring->pg_vec, pg_vec);
-
-		__skb_queue_purge(queue);
-		spin_unlock_bh(&queue->lock);
-
-		WARN_ON(atomic_read(&nlk->mapped));
+	if (atomic_read(&nlk->mapped) == 0) {
+		__netlink_set_ring(sk, req, tx_ring, pg_vec, order);
+		mutex_unlock(&nlk->pg_vec_lock);
+		return 0;
 	}
+
 	mutex_unlock(&nlk->pg_vec_lock);
 
 	if (pg_vec)
 		free_pg_vec(pg_vec, order, req->nm_block_nr);
-	return err;
+
+	return -EBUSY;
 }
 
 static void netlink_mm_open(struct vm_area_struct *vma)
@@ -885,10 +900,10 @@ static void netlink_sock_destruct(struct sock *sk)
 
 		memset(&req, 0, sizeof(req));
 		if (nlk->rx_ring.pg_vec)
-			netlink_set_ring(sk, &req, true, false);
+			__netlink_set_ring(sk, &req, false, NULL, 0);
 		memset(&req, 0, sizeof(req));
 		if (nlk->tx_ring.pg_vec)
-			netlink_set_ring(sk, &req, true, true);
+			__netlink_set_ring(sk, &req, true, NULL, 0);
 	}
 #endif /* CONFIG_NETLINK_MMAP */
 
@@ -2182,7 +2197,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
 			return -EINVAL;
 		if (copy_from_user(&req, optval, sizeof(req)))
 			return -EFAULT;
-		err = netlink_set_ring(sk, &req, false,
+		err = netlink_set_ring(sk, &req,
 				       optname == NETLINK_TX_RING);
 		break;
 	}
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

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


Thread

[3.13.y-ckt stable] Linux 3.13.11-ckt27 stable review Kamal Mostafa <kamal@canonical.com> - 2015-09-22 19:50 +0200
  [PATCH 3.13.y-ckt 15/57] target/iscsi: Fix double free of a TUR followed by a solicited NOPOUT Kamal Mostafa <kamal@canonical.com> - 2015-09-22 19:50 +0200
  [PATCH 3.13.y-ckt 12/57] xen-blkback: replace work_pending with work_busy in purge_persistent_gnt() Kamal Mostafa <kamal@canonical.com> - 2015-09-22 19:50 +0200
  [PATCH 3.13.y-ckt 16/57] rbd: fix copyup completion race Kamal Mostafa <kamal@canonical.com> - 2015-09-22 19:50 +0200
  [PATCH 3.13.y-ckt 57/57] net: gso: use feature flag argument in all protocol gso handlers Kamal Mostafa <kamal@canonical.com> - 2015-09-22 20:00 +0200
  [PATCH 3.13.y-ckt 50/57] ipv6: lock socket in ip6_datagram_connect() Kamal Mostafa <kamal@canonical.com> - 2015-09-22 20:00 +0200
  [PATCH 3.13.y-ckt 47/57] rds: fix an integer overflow test in rds_info_getsockopt() Kamal Mostafa <kamal@canonical.com> - 2015-09-22 20:00 +0200
  [PATCH 3.13.y-ckt 53/57] net: pktgen: fix race between pktgen_thread_worker() and kthread_stop() Kamal Mostafa <kamal@canonical.com> - 2015-09-22 20:00 +0200
  [PATCH 3.13.y-ckt 54/57] net: call rcu_read_lock early in process_backlog Kamal Mostafa <kamal@canonical.com> - 2015-09-22 20:00 +0200
  [PATCH 3.13.y-ckt 52/57] net/tipc: initialize security state for new connection socket Kamal Mostafa <kamal@canonical.com> - 2015-09-22 20:00 +0200
  [PATCH 3.13.y-ckt 40/57] ipc/sem.c: update/correct memory barriers Kamal Mostafa <kamal@canonical.com> - 2015-09-22 20:00 +0200
  [PATCH 3.13.y-ckt 21/57] perf: Fix fasync handling on inherited events Kamal Mostafa <kamal@canonical.com> - 2015-09-22 20:00 +0200
  [PATCH 3.13.y-ckt 51/57] rtnetlink: verify IFLA_VF_INFO attributes before passing them to driver Kamal Mostafa <kamal@canonical.com> - 2015-09-22 20:00 +0200
  [PATCH 3.13.y-ckt 56/57] netlink: don't hold mutex in rcu callback when releasing mmapd ring Kamal Mostafa <kamal@canonical.com> - 2015-09-22 20:00 +0200
  [PATCH 3.13.y-ckt 48/57] udp: fix dst races with multicast early demux Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:00 +0200
  [PATCH 3.13.y-ckt 49/57] sparc64: Fix userspace FPU register corruptions. Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:00 +0200
  [PATCH 3.13.y-ckt 44/57] ip6_gre: release cached dst on tunnel removal Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:00 +0200
  [PATCH 3.13.y-ckt 46/57] net: Fix skb_set_peeked use-after-free bug Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:00 +0200
  [PATCH 3.13.y-ckt 39/57] ipc/sem.c: change memory barrier in sem_lock() to smp_rmb() Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:10 +0200
  [PATCH 3.13.y-ckt 43/57] batman-adv: protect tt_local_entry from concurrent delete events Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:10 +0200
  [PATCH 3.13.y-ckt 36/57] crypto: caam - fix memory corruption in ahash_final_ctx Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:10 +0200
  [PATCH 3.13.y-ckt 32/57] libiscsi: Fix host busy blocking during connection teardown Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:10 +0200
  [PATCH 3.13.y-ckt 24/57] ipc: modify message queue accounting to not take kernel data structures into account Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:10 +0200
  [PATCH 3.13.y-ckt 42/57] arm64: KVM: Fix host crash when injecting a fault into a 32bit guest Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:10 +0200
  [PATCH 3.13.y-ckt 35/57] EDAC, ppc4xx: Access mci->csrows array elements properly Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:10 +0200
  [PATCH 3.13.y-ckt 33/57] libfc: Fix fc_exch_recv_req() error path Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:10 +0200
  [PATCH 3.13.y-ckt 38/57] ipc,sem: fix use after free on IPC_RMID after a task using same semaphore set exits Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:10 +0200
  [PATCH 3.13.y-ckt 37/57] mm/hwpoison: fix page refcount of unknown non LRU page Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:10 +0200
  [PATCH 3.13.y-ckt 25/57] ocfs2: fix BUG in ocfs2_downconvert_thread_do_work() Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:10 +0200
  [PATCH 3.13.y-ckt 17/57] md/raid1: extend spinlock to protect raid1_end_read_request against inconsistencies Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:10 +0200
  [PATCH 3.13.y-ckt 45/57] net: Fix RCU splat in af_key Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:10 +0200
  [PATCH 3.13.y-ckt 34/57] libfc: Fix fc_fcp_cleanup_each_cmd() Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:10 +0200
  [PATCH 3.13.y-ckt 41/57] Add factory recertified Crucial M500s to blacklist Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:10 +0200
  [PATCH 3.13.y-ckt 04/57] virtio-net: drop NETIF_F_FRAGLIST Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:20 +0200
  [PATCH 3.13.y-ckt 14/57] regmap: regcache-rbtree: Clean new present bits on present bitmap resize Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:20 +0200
  [PATCH 3.13.y-ckt 27/57] KVM: x86: Use adjustment in guest cycles when handling MSR_IA32_TSC_ADJUST Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:20 +0200
  [PATCH 3.13.y-ckt 05/57] RDS: verify the underlying transport exists before creating a connection Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:20 +0200
  [PATCH 3.13.y-ckt 07/57] xen/gntdevt: Fix race condition in gntdev_release() Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:20 +0200
  [PATCH 3.13.y-ckt 13/57] USB: sierra: add 1199:68AB device ID Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:20 +0200
  [PATCH 3.13.y-ckt 31/57] drm/radeon: add new OLAND pci id Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:20 +0200
  [PATCH 3.13.y-ckt 10/57] crypto: ixp4xx - Remove bogus BUG_ON on scattered dst buffer Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:20 +0200
  [PATCH 3.13.y-ckt 29/57] dm thin metadata: delete btrees when releasing metadata snapshot Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:20 +0200
  [PATCH 3.13.y-ckt 20/57] xhci: fix off by one error in TRB DMA address boundary check Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:20 +0200
  [PATCH 3.13.y-ckt 30/57] dm btree: add ref counting ops for the leaves of top level btrees Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:20 +0200
  [PATCH 3.13.y-ckt 18/57] target: REPORT LUNS should return LUN 0 even for dynamic ACLs Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:20 +0200
  [PATCH 3.13.y-ckt 02/57] md: flush ->event_work before stopping array. Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:20 +0200
  [PATCH 3.13.y-ckt 03/57] ipv6: addrconf: validate new MTU before applying it Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:20 +0200
  [PATCH 3.13.y-ckt 22/57] mm, vmscan: Do not wait for page writeback for GFP_NOFS allocations Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:20 +0200
  [PATCH 3.13.y-ckt 19/57] MIPS: Fix sched_getaffinity with MT FPAFF enabled Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:20 +0200
  [PATCH 3.13.y-ckt 28/57] localmodconfig: Use Kbuild files too Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:20 +0200
  [PATCH 3.13.y-ckt 09/57] nfsd: Drop BUG_ON and ignore SECLABEL on absent filesystem Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:20 +0200
  [PATCH 3.13.y-ckt 11/57] xen-blkfront: don't add indirect pages to list when !feature_persistent Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:20 +0200
  [PATCH 3.13.y-ckt 08/57] PCI: Restore PCI_MSIX_FLAGS_BIRMASK definition Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:20 +0200
  [PATCH 3.13.y-ckt 23/57] MIPS: Make set_pte() SMP safe. Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:20 +0200
  [PATCH 3.13.y-ckt 26/57] fsnotify: fix oops in fsnotify_clear_marks_by_group_flags() Kamal Mostafa <kamal@canonical.com> - 2015-09-22 21:20 +0200

csiph-web