public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	patches@lists.linux.dev, David Howells <dhowells@redhat.com>,
	Marc Dionne <marc.dionne@auristor.com>,
	linux-afs@lists.infradead.org, linux-fsdevel@vger.kernel.org,
	Christian Brauner <brauner@kernel.org>,
	Sasha Levin <sashal@kernel.org>
Subject: [PATCH 6.11 45/63] afs: Fix lock recursion
Date: Fri, 15 Nov 2024 07:38:08 +0100	[thread overview]
Message-ID: <20241115063727.539320914@linuxfoundation.org> (raw)
In-Reply-To: <20241115063725.892410236@linuxfoundation.org>

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

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

From: David Howells <dhowells@redhat.com>

[ Upstream commit 610a79ffea02102899a1373fe226d949944a7ed6 ]

afs_wake_up_async_call() can incur lock recursion.  The problem is that it
is called from AF_RXRPC whilst holding the ->notify_lock, but it tries to
take a ref on the afs_call struct in order to pass it to a work queue - but
if the afs_call is already queued, we then have an extraneous ref that must
be put... calling afs_put_call() may call back down into AF_RXRPC through
rxrpc_kernel_shutdown_call(), however, which might try taking the
->notify_lock again.

This case isn't very common, however, so defer it to a workqueue.  The oops
looks something like:

  BUG: spinlock recursion on CPU#0, krxrpcio/7001/1646
   lock: 0xffff888141399b30, .magic: dead4ead, .owner: krxrpcio/7001/1646, .owner_cpu: 0
  CPU: 0 UID: 0 PID: 1646 Comm: krxrpcio/7001 Not tainted 6.12.0-rc2-build3+ #4351
  Hardware name: ASUS All Series/H97-PLUS, BIOS 2306 10/09/2014
  Call Trace:
   <TASK>
   dump_stack_lvl+0x47/0x70
   do_raw_spin_lock+0x3c/0x90
   rxrpc_kernel_shutdown_call+0x83/0xb0
   afs_put_call+0xd7/0x180
   rxrpc_notify_socket+0xa0/0x190
   rxrpc_input_split_jumbo+0x198/0x1d0
   rxrpc_input_data+0x14b/0x1e0
   ? rxrpc_input_call_packet+0xc2/0x1f0
   rxrpc_input_call_event+0xad/0x6b0
   rxrpc_input_packet_on_conn+0x1e1/0x210
   rxrpc_input_packet+0x3f2/0x4d0
   rxrpc_io_thread+0x243/0x410
   ? __pfx_rxrpc_io_thread+0x10/0x10
   kthread+0xcf/0xe0
   ? __pfx_kthread+0x10/0x10
   ret_from_fork+0x24/0x40
   ? __pfx_kthread+0x10/0x10
   ret_from_fork_asm+0x1a/0x30
   </TASK>

Signed-off-by: David Howells <dhowells@redhat.com>
Link: https://lore.kernel.org/r/1394602.1729162732@warthog.procyon.org.uk
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 fs/afs/internal.h |  2 ++
 fs/afs/rxrpc.c    | 83 +++++++++++++++++++++++++++++++++--------------
 2 files changed, 61 insertions(+), 24 deletions(-)

diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index b306c09808706..c9d620175e80c 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -130,6 +130,7 @@ struct afs_call {
 	wait_queue_head_t	waitq;		/* processes awaiting completion */
 	struct work_struct	async_work;	/* async I/O processor */
 	struct work_struct	work;		/* actual work processor */
+	struct work_struct	free_work;	/* Deferred free processor */
 	struct rxrpc_call	*rxcall;	/* RxRPC call handle */
 	struct rxrpc_peer	*peer;		/* Remote endpoint */
 	struct key		*key;		/* security for this call */
@@ -1333,6 +1334,7 @@ extern int __net_init afs_open_socket(struct afs_net *);
 extern void __net_exit afs_close_socket(struct afs_net *);
 extern void afs_charge_preallocation(struct work_struct *);
 extern void afs_put_call(struct afs_call *);
+void afs_deferred_put_call(struct afs_call *call);
 void afs_make_call(struct afs_call *call, gfp_t gfp);
 void afs_wait_for_call_to_complete(struct afs_call *call);
 extern struct afs_call *afs_alloc_flat_call(struct afs_net *,
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c
index c453428f3c8ba..9f2a3bb56ec69 100644
--- a/fs/afs/rxrpc.c
+++ b/fs/afs/rxrpc.c
@@ -18,6 +18,7 @@
 
 struct workqueue_struct *afs_async_calls;
 
+static void afs_deferred_free_worker(struct work_struct *work);
 static void afs_wake_up_call_waiter(struct sock *, struct rxrpc_call *, unsigned long);
 static void afs_wake_up_async_call(struct sock *, struct rxrpc_call *, unsigned long);
 static void afs_process_async_call(struct work_struct *);
@@ -149,6 +150,7 @@ static struct afs_call *afs_alloc_call(struct afs_net *net,
 	call->debug_id = atomic_inc_return(&rxrpc_debug_id);
 	refcount_set(&call->ref, 1);
 	INIT_WORK(&call->async_work, afs_process_async_call);
+	INIT_WORK(&call->free_work, afs_deferred_free_worker);
 	init_waitqueue_head(&call->waitq);
 	spin_lock_init(&call->state_lock);
 	call->iter = &call->def_iter;
@@ -159,6 +161,36 @@ static struct afs_call *afs_alloc_call(struct afs_net *net,
 	return call;
 }
 
+static void afs_free_call(struct afs_call *call)
+{
+	struct afs_net *net = call->net;
+	int o;
+
+	ASSERT(!work_pending(&call->async_work));
+
+	rxrpc_kernel_put_peer(call->peer);
+
+	if (call->rxcall) {
+		rxrpc_kernel_shutdown_call(net->socket, call->rxcall);
+		rxrpc_kernel_put_call(net->socket, call->rxcall);
+		call->rxcall = NULL;
+	}
+	if (call->type->destructor)
+		call->type->destructor(call);
+
+	afs_unuse_server_notime(call->net, call->server, afs_server_trace_put_call);
+	kfree(call->request);
+
+	o = atomic_read(&net->nr_outstanding_calls);
+	trace_afs_call(call->debug_id, afs_call_trace_free, 0, o,
+		       __builtin_return_address(0));
+	kfree(call);
+
+	o = atomic_dec_return(&net->nr_outstanding_calls);
+	if (o == 0)
+		wake_up_var(&net->nr_outstanding_calls);
+}
+
 /*
  * Dispose of a reference on a call.
  */
@@ -173,32 +205,34 @@ void afs_put_call(struct afs_call *call)
 	o = atomic_read(&net->nr_outstanding_calls);
 	trace_afs_call(debug_id, afs_call_trace_put, r - 1, o,
 		       __builtin_return_address(0));
+	if (zero)
+		afs_free_call(call);
+}
 
-	if (zero) {
-		ASSERT(!work_pending(&call->async_work));
-		ASSERT(call->type->name != NULL);
-
-		rxrpc_kernel_put_peer(call->peer);
-
-		if (call->rxcall) {
-			rxrpc_kernel_shutdown_call(net->socket, call->rxcall);
-			rxrpc_kernel_put_call(net->socket, call->rxcall);
-			call->rxcall = NULL;
-		}
-		if (call->type->destructor)
-			call->type->destructor(call);
+static void afs_deferred_free_worker(struct work_struct *work)
+{
+	struct afs_call *call = container_of(work, struct afs_call, free_work);
 
-		afs_unuse_server_notime(call->net, call->server, afs_server_trace_put_call);
-		kfree(call->request);
+	afs_free_call(call);
+}
 
-		trace_afs_call(call->debug_id, afs_call_trace_free, 0, o,
-			       __builtin_return_address(0));
-		kfree(call);
+/*
+ * Dispose of a reference on a call, deferring the cleanup to a workqueue
+ * to avoid lock recursion.
+ */
+void afs_deferred_put_call(struct afs_call *call)
+{
+	struct afs_net *net = call->net;
+	unsigned int debug_id = call->debug_id;
+	bool zero;
+	int r, o;
 
-		o = atomic_dec_return(&net->nr_outstanding_calls);
-		if (o == 0)
-			wake_up_var(&net->nr_outstanding_calls);
-	}
+	zero = __refcount_dec_and_test(&call->ref, &r);
+	o = atomic_read(&net->nr_outstanding_calls);
+	trace_afs_call(debug_id, afs_call_trace_put, r - 1, o,
+		       __builtin_return_address(0));
+	if (zero)
+		schedule_work(&call->free_work);
 }
 
 static struct afs_call *afs_get_call(struct afs_call *call,
@@ -640,7 +674,8 @@ static void afs_wake_up_call_waiter(struct sock *sk, struct rxrpc_call *rxcall,
 }
 
 /*
- * wake up an asynchronous call
+ * Wake up an asynchronous call.  The caller is holding the call notify
+ * spinlock around this, so we can't call afs_put_call().
  */
 static void afs_wake_up_async_call(struct sock *sk, struct rxrpc_call *rxcall,
 				   unsigned long call_user_ID)
@@ -657,7 +692,7 @@ static void afs_wake_up_async_call(struct sock *sk, struct rxrpc_call *rxcall,
 			       __builtin_return_address(0));
 
 		if (!queue_work(afs_async_calls, &call->async_work))
-			afs_put_call(call);
+			afs_deferred_put_call(call);
 	}
 }
 
-- 
2.43.0




  parent reply	other threads:[~2024-11-15  6:48 UTC|newest]

Thread overview: 78+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-11-15  6:37 [PATCH 6.11 00/63] 6.11.9-rc1 review Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 01/63] smb: client: Fix use-after-free of network namespace Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 02/63] nvme/host: Fix RCU list traversal to use SRCU primitive Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 03/63] 9p: v9fs_fid_find: also lookup by inode if not found dentry Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 04/63] 9p: Avoid creating multiple slab caches with the same name Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 05/63] selftests/bpf: Verify that sync_linked_regs preserves subreg_def Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 06/63] nvmet-passthru: clear EUID/NGUID/UUID while using loop target Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 07/63] irqchip/ocelot: Fix trigger register address Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 08/63] pinctrl: aw9523: add missing mutex_destroy Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 09/63] pinctrl: intel: platform: Add Panther Lake to the list of supported Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 10/63] nvme: tcp: avoid race between queue_lock lock and destroy Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 11/63] block: Fix elevator_get_default() checking for NULL q->tag_set Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 12/63] HID: multitouch: Add support for B2402FVA track point Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 13/63] HID: multitouch: Add quirk for HONOR MagicBook Art 14 touchpad Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 14/63] iommu/arm-smmu: Clarify MMU-500 CPRE workaround Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 15/63] nvme: disable CC.CRIME (NVME_CC_CRIME) Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 16/63] bpf: use kvzmalloc to allocate BPF verifier environment Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 17/63] crypto: api - Fix liveliness check in crypto_alg_tested Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 18/63] crypto: marvell/cesa - Disable hash algorithms Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 19/63] s390/ap: Fix CCA crypto card behavior within protected execution environment Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 20/63] sound: Make CONFIG_SND depend on INDIRECT_IOMEM instead of UML Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 21/63] drm/vmwgfx: Limit display layout ioctl array size to VMWGFX_NUM_DISPLAY_UNITS Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 22/63] selftests/bpf: Assert link info uprobe_multi count & path_size if unset Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 23/63] RDMA/siw: Add sendpage_ok() check to disable MSG_SPLICE_PAGES Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 24/63] ALSA: hda/tas2781: Add new quirk for Lenovo, ASUS, Dell projects Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 25/63] kasan: Disable Software Tag-Based KASAN with GCC Greg Kroah-Hartman
2024-11-15  6:55   ` Jiri Slaby
2024-11-15  9:27     ` Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 26/63] nvme-multipath: defer partition scanning Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 27/63] drm/amdkfd: Accounting pdd vram_usage for svm Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 28/63] powerpc/powernv: Free name on error in opal_event_init() Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 29/63] net: phy: mdio-bcm-unimac: Add BCM6846 support Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 30/63] drm/xe/query: Increase timestamp width Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 31/63] nvme-loop: flush off pending I/O while shutting down loop controller Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 32/63] nvme: make keep-alive synchronous operation Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 33/63] samples/landlock: Fix port parsing in sandboxer Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 34/63] vDPA/ifcvf: Fix pci_read_config_byte() return code handling Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 35/63] virtio_pci: Fix admin vq cleanup by using correct info pointer Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 6.11 36/63] bpf: Add sk_is_inet and IS_ICSK check in tls_sw_has_ctx_tx/rx Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 6.11 37/63] bpf: Fix mismatched RCU unlock flavour in bpf_out_neigh_v6 Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 6.11 38/63] ASoC: Intel: avs: Update stream status in a separate thread Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 6.11 39/63] ASoC: codecs: Fix error handling in aw_dev_get_dsp_status function Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 6.11 40/63] ASoC: amd: yc: Add quirk for ASUS Vivobook S15 M3502RA Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 6.11 41/63] ASoC: amd: yc: Fix non-functional mic on ASUS E1404FA Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 6.11 42/63] ASoC: Intel: soc-acpi: lnl: Add match entry for TM2 laptops Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 6.11 43/63] netfs: Downgrade i_rwsem for a buffered write Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 6.11 44/63] fs: Fix uninitialized value issue in from_kuid and from_kgid Greg Kroah-Hartman
2024-11-15  6:38 ` Greg Kroah-Hartman [this message]
2024-11-15  6:38 ` [PATCH 6.11 46/63] HID: i2c-hid: Delayed i2c resume wakeup for 0x0d42 Goodix touchpad Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 6.11 47/63] HID: multitouch: Add quirk for Logitech Bolt receiver w/ Casa touchpad Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 6.11 48/63] HID: lenovo: Add support for Thinkpad X1 Tablet Gen 3 keyboard Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 6.11 49/63] ASoC: codecs: lpass-rx-macro: fix RXn(rx,n) macro for DSM_CTL and SEC7 regs Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 6.11 50/63] RISCV: KVM: use raw_spinlock for critical section in imsic Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 6.11 51/63] ASoC: rt722-sdca: increase clk_stop_timeout to fix clock stop issue Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 6.11 52/63] LoongArch: Use "Exception return address" to comment ERA Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 6.11 53/63] ASoC: fsl_micfil: Add sample rate constraint Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 6.11 54/63] LoongArch: KVM: Mark hrtimer to expire in hard interrupt context Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 6.11 55/63] net: usb: qmi_wwan: add Fibocom FG132 0x0112 composition Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 6.11 56/63] bpf: Check validity of link->type in bpf_link_show_fdinfo() Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 6.11 57/63] drm/xe: Enlarge the invalidation timeout from 150 to 500 Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 6.11 58/63] drm/xe/guc/ct: Flush g2h worker in case of g2h response timeout Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 6.11 59/63] drm/xe: Handle unreliable MMIO reads during forcewake Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 6.11 60/63] drm/xe/ufence: Prefetch ufence addr to catch bogus address Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 6.11 61/63] drm/xe: Dont restart parallel queues multiple times on GT reset Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 6.11 62/63] mm: krealloc: Fix MTE false alarm in __do_krealloc Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 6.11 63/63] 9p: fix slab cache name creation for real Greg Kroah-Hartman
2024-11-15  8:16 ` [PATCH 6.11 00/63] 6.11.9-rc1 review Luna Jernberg
2024-11-15 17:40 ` Peter Schneider
2024-11-15 18:11 ` Jon Hunter
2024-11-15 19:48 ` Florian Fainelli
2024-11-15 21:18 ` Mark Brown
2024-11-15 23:50 ` Ron Economos
2024-11-16  8:07 ` Naresh Kamboju
2024-11-16 17:17 ` [PATCH 6.11] " Hardik Garg
2024-11-16 20:52 ` [PATCH 6.11 00/63] " Markus Reichelt
2024-11-16 21:04 ` Shuah Khan
2024-11-17 13:24 ` Muhammad Usama Anjum
2024-11-17 13:30 ` Pavel Machek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20241115063727.539320914@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=brauner@kernel.org \
    --cc=dhowells@redhat.com \
    --cc=linux-afs@lists.infradead.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=marc.dionne@auristor.com \
    --cc=patches@lists.linux.dev \
    --cc=sashal@kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox