public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH iwl-net 0/3] idpf: virtchnl locking and async fixes
@ 2026-03-16 23:28 Emil Tantilov
  2026-03-16 23:28 ` [PATCH iwl-net 1/3] idpf: improve locking around idpf_vc_xn_push_free() Emil Tantilov
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Emil Tantilov @ 2026-03-16 23:28 UTC (permalink / raw)
  To: intel-wired-lan
  Cc: netdev, anthony.l.nguyen, aleksandr.loktionov, przemyslaw.kitszel,
	andrew+netdev, davem, edumazet, kuba, pabeni, bigeasy, clrkwllms,
	rostedt, linux-rt-devel, sgzhang, boolli

The first patch in this series improves the locking around the setting
and clearing of the free_xn_bm bitmap. Previously the lock was only
taken during init shutdown and pop, but not the push function.

Patches 2 and 3 are fixes for the async handler. Patch 2 ensures the
payload size is set before the async handler is called, and patch 3 fixes
an sleeping bug due to nesting of raw/bh spinlocks.

Emil Tantilov (3):
  idpf: improve locking around idpf_vc_xn_push_free()
  idpf: set the payload size before calling the async handler
  idpf: fix PREEMPT_RT raw/bh spinlock nesting for async VC handling

 .../net/ethernet/intel/idpf/idpf_virtchnl.c   | 40 ++++++++++++-------
 1 file changed, 25 insertions(+), 15 deletions(-)

-- 
2.37.3


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH iwl-net 1/3] idpf: improve locking around idpf_vc_xn_push_free()
  2026-03-16 23:28 [PATCH iwl-net 0/3] idpf: virtchnl locking and async fixes Emil Tantilov
@ 2026-03-16 23:28 ` Emil Tantilov
  2026-03-17 23:46   ` Li Li
  2026-03-16 23:28 ` [PATCH iwl-net 2/3] idpf: set the payload size before calling the async handler Emil Tantilov
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 14+ messages in thread
From: Emil Tantilov @ 2026-03-16 23:28 UTC (permalink / raw)
  To: intel-wired-lan
  Cc: netdev, anthony.l.nguyen, aleksandr.loktionov, przemyslaw.kitszel,
	andrew+netdev, davem, edumazet, kuba, pabeni, bigeasy, clrkwllms,
	rostedt, linux-rt-devel, sgzhang, boolli

Refactor the VC logic dealing with transaction accounting where
both push and pop_free are using the same spinlock free_xn_bm.
This resolves potential race when setting and clearing the bits
in the free_xn_bm bitmask.

Fixes: 34c21fa894a1 ("idpf: implement virtchnl transaction manager")
Reported-by: Ray Zhang <sgzhang@google.com>
Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
---
 drivers/net/ethernet/intel/idpf/idpf_virtchnl.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
index 113ecfc16dd7..21a6c9d22085 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
@@ -401,12 +401,18 @@ struct idpf_vc_xn *idpf_vc_xn_pop_free(struct idpf_vc_xn_manager *vcxn_mngr)
  * idpf_vc_xn_push_free - Push a free transaction to free list
  * @vcxn_mngr: transaction manager to push to
  * @xn: transaction to push
+ *
+ * Callers must ensure idpf_vc_xn_release_bufs() has been called (under
+ * idpf_vc_xn_lock) before invoking this function. This function must
+ * be called without holding idpf_vc_xn_lock to avoid nesting a sleepable
+ * spinlock inside a raw_spinlock on PREEMPT_RT kernels.
  */
 static void idpf_vc_xn_push_free(struct idpf_vc_xn_manager *vcxn_mngr,
 				 struct idpf_vc_xn *xn)
 {
-	idpf_vc_xn_release_bufs(xn);
+	spin_lock_bh(&vcxn_mngr->xn_bm_lock);
 	set_bit(xn->idx, vcxn_mngr->free_xn_bm);
+	spin_unlock_bh(&vcxn_mngr->xn_bm_lock);
 }
 
 /**
@@ -428,6 +434,7 @@ ssize_t idpf_vc_xn_exec(struct idpf_adapter *adapter,
 			const struct idpf_vc_xn_params *params)
 {
 	const struct kvec *send_buf = &params->send_buf;
+	bool push_free = false;
 	struct idpf_vc_xn *xn;
 	ssize_t retval;
 	u16 cookie;
@@ -514,10 +521,13 @@ ssize_t idpf_vc_xn_exec(struct idpf_adapter *adapter,
 	}
 
 release_and_unlock:
-	idpf_vc_xn_push_free(adapter->vcxn_mngr, xn);
+	idpf_vc_xn_release_bufs(xn);
+	push_free = true;
 	/* If we receive a VC reply after here, it will be dropped. */
 only_unlock:
 	idpf_vc_xn_unlock(xn);
+	if (push_free)
+		idpf_vc_xn_push_free(adapter->vcxn_mngr, xn);
 
 	return retval;
 }
@@ -559,7 +569,7 @@ idpf_vc_xn_forward_async(struct idpf_adapter *adapter, struct idpf_vc_xn *xn,
 	}
 
 release_bufs:
-	idpf_vc_xn_push_free(adapter->vcxn_mngr, xn);
+	idpf_vc_xn_release_bufs(xn);
 
 	return err;
 }
@@ -619,6 +629,7 @@ idpf_vc_xn_forward_reply(struct idpf_adapter *adapter,
 	case IDPF_VC_XN_ASYNC:
 		err = idpf_vc_xn_forward_async(adapter, xn, ctlq_msg);
 		idpf_vc_xn_unlock(xn);
+		idpf_vc_xn_push_free(adapter->vcxn_mngr, xn);
 		return err;
 	default:
 		dev_err_ratelimited(&adapter->pdev->dev, "Overwriting VC reply (op %d)\n",
-- 
2.37.3


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH iwl-net 2/3] idpf: set the payload size before calling the async handler
  2026-03-16 23:28 [PATCH iwl-net 0/3] idpf: virtchnl locking and async fixes Emil Tantilov
  2026-03-16 23:28 ` [PATCH iwl-net 1/3] idpf: improve locking around idpf_vc_xn_push_free() Emil Tantilov
@ 2026-03-16 23:28 ` Emil Tantilov
  2026-03-18  0:11   ` Li Li
  2026-03-16 23:28 ` [PATCH iwl-net 3/3] idpf: fix PREEMPT_RT raw/bh spinlock nesting for async VC handling Emil Tantilov
  2026-03-17  9:00 ` [PATCH iwl-net 0/3] idpf: virtchnl locking and async fixes Sebastian Andrzej Siewior
  3 siblings, 1 reply; 14+ messages in thread
From: Emil Tantilov @ 2026-03-16 23:28 UTC (permalink / raw)
  To: intel-wired-lan
  Cc: netdev, anthony.l.nguyen, aleksandr.loktionov, przemyslaw.kitszel,
	andrew+netdev, davem, edumazet, kuba, pabeni, bigeasy, clrkwllms,
	rostedt, linux-rt-devel, sgzhang, boolli

Set the payload size before forwarding the reply to the async handler.
Without this, xn->reply_sz will be 0 and idpf_mac_filter_async_handler()
will never get past the size check.

Fixes: 34c21fa894a1 ("idpf: implement virtchnl transaction manager")
Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
---
 drivers/net/ethernet/intel/idpf/idpf_virtchnl.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
index 21a6c9d22085..6b9692b30040 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
@@ -627,6 +627,10 @@ idpf_vc_xn_forward_reply(struct idpf_adapter *adapter,
 		err = -ENXIO;
 		goto out_unlock;
 	case IDPF_VC_XN_ASYNC:
+		/* Set reply_sz from the actual payload so that async_handler
+		 * can evaluate the response.
+		 */
+		xn->reply_sz = ctlq_msg->data_len;
 		err = idpf_vc_xn_forward_async(adapter, xn, ctlq_msg);
 		idpf_vc_xn_unlock(xn);
 		idpf_vc_xn_push_free(adapter->vcxn_mngr, xn);
-- 
2.37.3


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH iwl-net 3/3] idpf: fix PREEMPT_RT raw/bh spinlock nesting for async VC handling
  2026-03-16 23:28 [PATCH iwl-net 0/3] idpf: virtchnl locking and async fixes Emil Tantilov
  2026-03-16 23:28 ` [PATCH iwl-net 1/3] idpf: improve locking around idpf_vc_xn_push_free() Emil Tantilov
  2026-03-16 23:28 ` [PATCH iwl-net 2/3] idpf: set the payload size before calling the async handler Emil Tantilov
@ 2026-03-16 23:28 ` Emil Tantilov
  2026-03-18  0:13   ` Li Li
  2026-03-17  9:00 ` [PATCH iwl-net 0/3] idpf: virtchnl locking and async fixes Sebastian Andrzej Siewior
  3 siblings, 1 reply; 14+ messages in thread
From: Emil Tantilov @ 2026-03-16 23:28 UTC (permalink / raw)
  To: intel-wired-lan
  Cc: netdev, anthony.l.nguyen, aleksandr.loktionov, przemyslaw.kitszel,
	andrew+netdev, davem, edumazet, kuba, pabeni, bigeasy, clrkwllms,
	rostedt, linux-rt-devel, sgzhang, boolli

Restructure the ASYNC case to allow calling idpf_vc_xn_forward_reply()
outside of idpf_vc_xn_lock(). This avoids invalid wait context reported by
the kernel due to the async handler taking BH spinlock:

[  805.726977] =============================
[  805.726991] [ BUG: Invalid wait context ]
[  805.727006] 7.0.0-rc2-net-devq-031026+ #28 Tainted: G S         OE
[  805.727026] -----------------------------
[  805.727038] kworker/u261:0/572 is trying to lock:
[  805.727051] ff190da6a8dbb6a0 (&vport_config->mac_filter_list_lock){+...}-{3:3}, at: idpf_mac_filter_async_handler+0xe9/0x260 [idpf]
[  805.727099] other info that might help us debug this:
[  805.727111] context-{5:5}
[  805.727119] 3 locks held by kworker/u261:0/572:
[  805.727132]  #0: ff190da6db3e6148 ((wq_completion)idpf-0000:83:00.0-mbx){+.+.}-{0:0}, at: process_one_work+0x4b5/0x730
[  805.727163]  #1: ff3c6f0a6131fe50 ((work_completion)(&(&adapter->mbx_task)->work)){+.+.}-{0:0}, at: process_one_work+0x1e5/0x730
[  805.727191]  #2: ff190da765190020 (&x->wait#34){+.+.}-{2:2}, at: idpf_recv_mb_msg+0xc8/0x710 [idpf]
[  805.727218] stack backtrace:
...
[  805.727238] Workqueue: idpf-0000:83:00.0-mbx idpf_mbx_task [idpf]
[  805.727247] Call Trace:
[  805.727249]  <TASK>
[  805.727251]  dump_stack_lvl+0x77/0xb0
[  805.727259]  __lock_acquire+0xb3b/0x2290
[  805.727268]  ? __irq_work_queue_local+0x59/0x130
[  805.727275]  lock_acquire+0xc6/0x2f0
[  805.727277]  ? idpf_mac_filter_async_handler+0xe9/0x260 [idpf]
[  805.727284]  ? _printk+0x5b/0x80
[  805.727290]  _raw_spin_lock_bh+0x38/0x50
[  805.727298]  ? idpf_mac_filter_async_handler+0xe9/0x260 [idpf]
[  805.727303]  idpf_mac_filter_async_handler+0xe9/0x260 [idpf]
[  805.727310]  idpf_recv_mb_msg+0x1c8/0x710 [idpf]
[  805.727317]  process_one_work+0x226/0x730
[  805.727322]  worker_thread+0x19e/0x340
[  805.727325]  ? __pfx_worker_thread+0x10/0x10
[  805.727328]  kthread+0xf4/0x130
[  805.727333]  ? __pfx_kthread+0x10/0x10
[  805.727336]  ret_from_fork+0x32c/0x410
[  805.727345]  ? __pfx_kthread+0x10/0x10
[  805.727347]  ret_from_fork_asm+0x1a/0x30
[  805.727354]  </TASK>

Fixes: 34c21fa894a1 ("idpf: implement virtchnl transaction manager")
Reported-by: Ray Zhang <sgzhang@google.com>
Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
---
 .../net/ethernet/intel/idpf/idpf_virtchnl.c   | 21 +++++++------------
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
index 6b9692b30040..8ceabd86e172 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
@@ -546,32 +546,24 @@ static int
 idpf_vc_xn_forward_async(struct idpf_adapter *adapter, struct idpf_vc_xn *xn,
 			 const struct idpf_ctlq_msg *ctlq_msg)
 {
-	int err = 0;
-
 	if (ctlq_msg->cookie.mbx.chnl_opcode != xn->vc_op) {
 		dev_err_ratelimited(&adapter->pdev->dev, "Async message opcode does not match transaction opcode (msg: %d) (xn: %d)\n",
 				    ctlq_msg->cookie.mbx.chnl_opcode, xn->vc_op);
 		xn->reply_sz = 0;
-		err = -EINVAL;
-		goto release_bufs;
+		return -EINVAL;
 	}
 
-	if (xn->async_handler) {
-		err = xn->async_handler(adapter, xn, ctlq_msg);
-		goto release_bufs;
-	}
+	if (xn->async_handler)
+		return xn->async_handler(adapter, xn, ctlq_msg);
 
 	if (ctlq_msg->cookie.mbx.chnl_retval) {
 		xn->reply_sz = 0;
 		dev_err_ratelimited(&adapter->pdev->dev, "Async message failure (op %d)\n",
 				    ctlq_msg->cookie.mbx.chnl_opcode);
-		err = -EINVAL;
+		return -EINVAL;
 	}
 
-release_bufs:
-	idpf_vc_xn_release_bufs(xn);
-
-	return err;
+	return 0;
 }
 
 /**
@@ -631,7 +623,10 @@ idpf_vc_xn_forward_reply(struct idpf_adapter *adapter,
 		 * can evaluate the response.
 		 */
 		xn->reply_sz = ctlq_msg->data_len;
+		idpf_vc_xn_unlock(xn);
 		err = idpf_vc_xn_forward_async(adapter, xn, ctlq_msg);
+		idpf_vc_xn_lock(xn);
+		idpf_vc_xn_release_bufs(xn);
 		idpf_vc_xn_unlock(xn);
 		idpf_vc_xn_push_free(adapter->vcxn_mngr, xn);
 		return err;
-- 
2.37.3


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH iwl-net 0/3] idpf: virtchnl locking and async fixes
  2026-03-16 23:28 [PATCH iwl-net 0/3] idpf: virtchnl locking and async fixes Emil Tantilov
                   ` (2 preceding siblings ...)
  2026-03-16 23:28 ` [PATCH iwl-net 3/3] idpf: fix PREEMPT_RT raw/bh spinlock nesting for async VC handling Emil Tantilov
@ 2026-03-17  9:00 ` Sebastian Andrzej Siewior
  2026-03-17 14:20   ` Tantilov, Emil S
  3 siblings, 1 reply; 14+ messages in thread
From: Sebastian Andrzej Siewior @ 2026-03-17  9:00 UTC (permalink / raw)
  To: Emil Tantilov
  Cc: intel-wired-lan, netdev, anthony.l.nguyen, aleksandr.loktionov,
	przemyslaw.kitszel, andrew+netdev, davem, edumazet, kuba, pabeni,
	clrkwllms, rostedt, linux-rt-devel, sgzhang, boolli

On 2026-03-16 16:28:16 [-0700], Emil Tantilov wrote:
> The first patch in this series improves the locking around the setting
> and clearing of the free_xn_bm bitmap. Previously the lock was only
> taken during init shutdown and pop, but not the push function.
> 
> Patches 2 and 3 are fixes for the async handler. Patch 2 ensures the
> payload size is set before the async handler is called, and patch 3 fixes
> an sleeping bug due to nesting of raw/bh spinlocks.

Why is there a raw_spinlock_t? From a quick look a spinlock_t would do
just fine with not runtime change for !PREEMPT_RT.

Sebastian

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH iwl-net 0/3] idpf: virtchnl locking and async fixes
  2026-03-17  9:00 ` [PATCH iwl-net 0/3] idpf: virtchnl locking and async fixes Sebastian Andrzej Siewior
@ 2026-03-17 14:20   ` Tantilov, Emil S
  2026-03-17 14:38     ` Sebastian Andrzej Siewior
  0 siblings, 1 reply; 14+ messages in thread
From: Tantilov, Emil S @ 2026-03-17 14:20 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: intel-wired-lan, netdev, anthony.l.nguyen, aleksandr.loktionov,
	przemyslaw.kitszel, andrew+netdev, davem, edumazet, kuba, pabeni,
	clrkwllms, rostedt, linux-rt-devel, sgzhang, boolli



On 3/17/2026 2:00 AM, Sebastian Andrzej Siewior wrote:
> On 2026-03-16 16:28:16 [-0700], Emil Tantilov wrote:
>> The first patch in this series improves the locking around the setting
>> and clearing of the free_xn_bm bitmap. Previously the lock was only
>> taken during init shutdown and pop, but not the push function.
>>
>> Patches 2 and 3 are fixes for the async handler. Patch 2 ensures the
>> payload size is set before the async handler is called, and patch 3 fixes
>> an sleeping bug due to nesting of raw/bh spinlocks.
> 
> Why is there a raw_spinlock_t? From a quick look a spinlock_t would do
> just fine with not runtime change for !PREEMPT_RT.

The handling of the virtchannel messages is done via the completion API
and the transactions are using the raw spinlock from struct
swait_queue_head:

https://elixir.bootlin.com/linux/v6.19.8/source/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c#L298

https://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue.git/tree/include/linux/swait.h?h=dev-queue#n44

Thanks,
Emil

> 
> Sebastian


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH iwl-net 0/3] idpf: virtchnl locking and async fixes
  2026-03-17 14:20   ` Tantilov, Emil S
@ 2026-03-17 14:38     ` Sebastian Andrzej Siewior
  2026-03-17 19:30       ` Tantilov, Emil S
  0 siblings, 1 reply; 14+ messages in thread
From: Sebastian Andrzej Siewior @ 2026-03-17 14:38 UTC (permalink / raw)
  To: Tantilov, Emil S
  Cc: intel-wired-lan, netdev, anthony.l.nguyen, aleksandr.loktionov,
	przemyslaw.kitszel, andrew+netdev, davem, edumazet, kuba, pabeni,
	clrkwllms, rostedt, linux-rt-devel, sgzhang, boolli

On 2026-03-17 07:20:18 [-0700], Tantilov, Emil S wrote:
> > Why is there a raw_spinlock_t? From a quick look a spinlock_t would do
> > just fine with not runtime change for !PREEMPT_RT.
> 
> The handling of the virtchannel messages is done via the completion API
> and the transactions are using the raw spinlock from struct
> swait_queue_head:
> 
> https://elixir.bootlin.com/linux/v6.19.8/source/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c#L298
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue.git/tree/include/linux/swait.h?h=dev-queue#n44

I am aware that completions use a raw_spinlock_t. I don't see the link.
What would break if you make that lock a spinlock_t?

> Thanks,
> Emil

Sebastian

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH iwl-net 0/3] idpf: virtchnl locking and async fixes
  2026-03-17 14:38     ` Sebastian Andrzej Siewior
@ 2026-03-17 19:30       ` Tantilov, Emil S
  2026-03-18  7:24         ` Sebastian Andrzej Siewior
  0 siblings, 1 reply; 14+ messages in thread
From: Tantilov, Emil S @ 2026-03-17 19:30 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: intel-wired-lan, netdev, anthony.l.nguyen, aleksandr.loktionov,
	przemyslaw.kitszel, andrew+netdev, davem, edumazet, kuba, pabeni,
	clrkwllms, rostedt, linux-rt-devel, sgzhang, boolli



On 3/17/2026 7:38 AM, Sebastian Andrzej Siewior wrote:
> On 2026-03-17 07:20:18 [-0700], Tantilov, Emil S wrote:
>>> Why is there a raw_spinlock_t? From a quick look a spinlock_t would do
>>> just fine with not runtime change for !PREEMPT_RT.
>>
>> The handling of the virtchannel messages is done via the completion API
>> and the transactions are using the raw spinlock from struct
>> swait_queue_head:
>>
>> https://elixir.bootlin.com/linux/v6.19.8/source/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c#L298
>>
>> https://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue.git/tree/include/linux/swait.h?h=dev-queue#n44
> 
> I am aware that completions use a raw_spinlock_t. I don't see the link.
> What would break if you make that lock a spinlock_t?

Right. Scope and risk - these fixes are specifically for the async
handler and I did not want to touch the global locking that will
impact the entire VC handling. We do have series in flight for -next
that refactor that code, while moving it to libie:
https://lore.kernel.org/netdev/20251117134912.18566-10-larysa.zaremba@intel.com/

... that also remove the raw spinlock. With that being said, I can look
into converting the lock to spinlock_t if that is the preferred approach.

Thanks,
Emil

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH iwl-net 1/3] idpf: improve locking around idpf_vc_xn_push_free()
  2026-03-16 23:28 ` [PATCH iwl-net 1/3] idpf: improve locking around idpf_vc_xn_push_free() Emil Tantilov
@ 2026-03-17 23:46   ` Li Li
  0 siblings, 0 replies; 14+ messages in thread
From: Li Li @ 2026-03-17 23:46 UTC (permalink / raw)
  To: Emil Tantilov
  Cc: intel-wired-lan, netdev, anthony.l.nguyen, aleksandr.loktionov,
	przemyslaw.kitszel, andrew+netdev, davem, edumazet, kuba, pabeni,
	bigeasy, clrkwllms, rostedt, linux-rt-devel, sgzhang

As discussed in the previous email, I had an minor & optional comment:

Personally, I think the code would read better if we just get rid of
the push_free state and use 2 separate code paths:

release_and_unlock:
idpf_vc_xn_release_bufs(xn);
idpf_vc_xn_unlock(xn);
idpf_vc_xn_push_free(&adapter->vcxn_mngr, xn);
return retval;

only_unlock:
idpf_vc_xn_unlock(xn);
return retval;

But I don't have strong opinions whether or not the suggestion above
is taken, and the patch LGTM.

Thank you Emil!

Reviewed-by: Li Li <boolli@google.com>



On Mon, Mar 16, 2026 at 4:28 PM Emil Tantilov <emil.s.tantilov@intel.com> wrote:
>
> Refactor the VC logic dealing with transaction accounting where
> both push and pop_free are using the same spinlock free_xn_bm.
> This resolves potential race when setting and clearing the bits
> in the free_xn_bm bitmask.
>
> Fixes: 34c21fa894a1 ("idpf: implement virtchnl transaction manager")
> Reported-by: Ray Zhang <sgzhang@google.com>
> Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
> ---
>  drivers/net/ethernet/intel/idpf/idpf_virtchnl.c | 17 ++++++++++++++---
>  1 file changed, 14 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
> index 113ecfc16dd7..21a6c9d22085 100644
> --- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
> +++ b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
> @@ -401,12 +401,18 @@ struct idpf_vc_xn *idpf_vc_xn_pop_free(struct idpf_vc_xn_manager *vcxn_mngr)
>   * idpf_vc_xn_push_free - Push a free transaction to free list
>   * @vcxn_mngr: transaction manager to push to
>   * @xn: transaction to push
> + *
> + * Callers must ensure idpf_vc_xn_release_bufs() has been called (under
> + * idpf_vc_xn_lock) before invoking this function. This function must
> + * be called without holding idpf_vc_xn_lock to avoid nesting a sleepable
> + * spinlock inside a raw_spinlock on PREEMPT_RT kernels.
>   */
>  static void idpf_vc_xn_push_free(struct idpf_vc_xn_manager *vcxn_mngr,
>                                  struct idpf_vc_xn *xn)
>  {
> -       idpf_vc_xn_release_bufs(xn);
> +       spin_lock_bh(&vcxn_mngr->xn_bm_lock);
>         set_bit(xn->idx, vcxn_mngr->free_xn_bm);
> +       spin_unlock_bh(&vcxn_mngr->xn_bm_lock);
>  }
>
>  /**
> @@ -428,6 +434,7 @@ ssize_t idpf_vc_xn_exec(struct idpf_adapter *adapter,
>                         const struct idpf_vc_xn_params *params)
>  {
>         const struct kvec *send_buf = &params->send_buf;
> +       bool push_free = false;
>         struct idpf_vc_xn *xn;
>         ssize_t retval;
>         u16 cookie;
> @@ -514,10 +521,13 @@ ssize_t idpf_vc_xn_exec(struct idpf_adapter *adapter,
>         }
>
>  release_and_unlock:
> -       idpf_vc_xn_push_free(adapter->vcxn_mngr, xn);
> +       idpf_vc_xn_release_bufs(xn);
> +       push_free = true;
>         /* If we receive a VC reply after here, it will be dropped. */
>  only_unlock:
>         idpf_vc_xn_unlock(xn);
> +       if (push_free)
> +               idpf_vc_xn_push_free(adapter->vcxn_mngr, xn);
>
>         return retval;
>  }
> @@ -559,7 +569,7 @@ idpf_vc_xn_forward_async(struct idpf_adapter *adapter, struct idpf_vc_xn *xn,
>         }
>
>  release_bufs:
> -       idpf_vc_xn_push_free(adapter->vcxn_mngr, xn);
> +       idpf_vc_xn_release_bufs(xn);
>
>         return err;
>  }
> @@ -619,6 +629,7 @@ idpf_vc_xn_forward_reply(struct idpf_adapter *adapter,
>         case IDPF_VC_XN_ASYNC:
>                 err = idpf_vc_xn_forward_async(adapter, xn, ctlq_msg);
>                 idpf_vc_xn_unlock(xn);
> +               idpf_vc_xn_push_free(adapter->vcxn_mngr, xn);
>                 return err;
>         default:
>                 dev_err_ratelimited(&adapter->pdev->dev, "Overwriting VC reply (op %d)\n",
> --
> 2.37.3
>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH iwl-net 2/3] idpf: set the payload size before calling the async handler
  2026-03-16 23:28 ` [PATCH iwl-net 2/3] idpf: set the payload size before calling the async handler Emil Tantilov
@ 2026-03-18  0:11   ` Li Li
  2026-03-19 16:21     ` Tantilov, Emil S
  0 siblings, 1 reply; 14+ messages in thread
From: Li Li @ 2026-03-18  0:11 UTC (permalink / raw)
  To: Emil Tantilov
  Cc: intel-wired-lan, netdev, anthony.l.nguyen, aleksandr.loktionov,
	przemyslaw.kitszel, andrew+netdev, davem, edumazet, kuba, pabeni,
	bigeasy, clrkwllms, rostedt, linux-rt-devel, sgzhang

On Mon, Mar 16, 2026 at 4:28 PM Emil Tantilov <emil.s.tantilov@intel.com> wrote:
>
> Set the payload size before forwarding the reply to the async handler.
> Without this, xn->reply_sz will be 0 and idpf_mac_filter_async_handler()
> will never get past the size check.
>
> Fixes: 34c21fa894a1 ("idpf: implement virtchnl transaction manager")
> Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
> ---
>  drivers/net/ethernet/intel/idpf/idpf_virtchnl.c | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
> index 21a6c9d22085..6b9692b30040 100644
> --- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
> +++ b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
> @@ -627,6 +627,10 @@ idpf_vc_xn_forward_reply(struct idpf_adapter *adapter,
>                 err = -ENXIO;
>                 goto out_unlock;
>         case IDPF_VC_XN_ASYNC:

Optional comment: could we only set the size if ctlq_msg->data_len >
0, in case the hw returns some invalid values?

> +               /* Set reply_sz from the actual payload so that async_handler
> +                * can evaluate the response.
> +                */
> +               xn->reply_sz = ctlq_msg->data_len;
>                 err = idpf_vc_xn_forward_async(adapter, xn, ctlq_msg);
>                 idpf_vc_xn_unlock(xn);
>                 idpf_vc_xn_push_free(adapter->vcxn_mngr, xn);
> --
> 2.37.3
>

Reviewed-by: Li Li <boolli@google.com>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH iwl-net 3/3] idpf: fix PREEMPT_RT raw/bh spinlock nesting for async VC handling
  2026-03-16 23:28 ` [PATCH iwl-net 3/3] idpf: fix PREEMPT_RT raw/bh spinlock nesting for async VC handling Emil Tantilov
@ 2026-03-18  0:13   ` Li Li
  0 siblings, 0 replies; 14+ messages in thread
From: Li Li @ 2026-03-18  0:13 UTC (permalink / raw)
  To: Emil Tantilov
  Cc: intel-wired-lan, netdev, anthony.l.nguyen, aleksandr.loktionov,
	przemyslaw.kitszel, andrew+netdev, davem, edumazet, kuba, pabeni,
	bigeasy, clrkwllms, rostedt, linux-rt-devel, sgzhang

Thank you!

Reviewed-by: Li Li <boolli@google.com>

On Mon, Mar 16, 2026 at 4:28 PM Emil Tantilov <emil.s.tantilov@intel.com> wrote:
>
> Restructure the ASYNC case to allow calling idpf_vc_xn_forward_reply()
> outside of idpf_vc_xn_lock(). This avoids invalid wait context reported by
> the kernel due to the async handler taking BH spinlock:
>
> [  805.726977] =============================
> [  805.726991] [ BUG: Invalid wait context ]
> [  805.727006] 7.0.0-rc2-net-devq-031026+ #28 Tainted: G S         OE
> [  805.727026] -----------------------------
> [  805.727038] kworker/u261:0/572 is trying to lock:
> [  805.727051] ff190da6a8dbb6a0 (&vport_config->mac_filter_list_lock){+...}-{3:3}, at: idpf_mac_filter_async_handler+0xe9/0x260 [idpf]
> [  805.727099] other info that might help us debug this:
> [  805.727111] context-{5:5}
> [  805.727119] 3 locks held by kworker/u261:0/572:
> [  805.727132]  #0: ff190da6db3e6148 ((wq_completion)idpf-0000:83:00.0-mbx){+.+.}-{0:0}, at: process_one_work+0x4b5/0x730
> [  805.727163]  #1: ff3c6f0a6131fe50 ((work_completion)(&(&adapter->mbx_task)->work)){+.+.}-{0:0}, at: process_one_work+0x1e5/0x730
> [  805.727191]  #2: ff190da765190020 (&x->wait#34){+.+.}-{2:2}, at: idpf_recv_mb_msg+0xc8/0x710 [idpf]
> [  805.727218] stack backtrace:
> ...
> [  805.727238] Workqueue: idpf-0000:83:00.0-mbx idpf_mbx_task [idpf]
> [  805.727247] Call Trace:
> [  805.727249]  <TASK>
> [  805.727251]  dump_stack_lvl+0x77/0xb0
> [  805.727259]  __lock_acquire+0xb3b/0x2290
> [  805.727268]  ? __irq_work_queue_local+0x59/0x130
> [  805.727275]  lock_acquire+0xc6/0x2f0
> [  805.727277]  ? idpf_mac_filter_async_handler+0xe9/0x260 [idpf]
> [  805.727284]  ? _printk+0x5b/0x80
> [  805.727290]  _raw_spin_lock_bh+0x38/0x50
> [  805.727298]  ? idpf_mac_filter_async_handler+0xe9/0x260 [idpf]
> [  805.727303]  idpf_mac_filter_async_handler+0xe9/0x260 [idpf]
> [  805.727310]  idpf_recv_mb_msg+0x1c8/0x710 [idpf]
> [  805.727317]  process_one_work+0x226/0x730
> [  805.727322]  worker_thread+0x19e/0x340
> [  805.727325]  ? __pfx_worker_thread+0x10/0x10
> [  805.727328]  kthread+0xf4/0x130
> [  805.727333]  ? __pfx_kthread+0x10/0x10
> [  805.727336]  ret_from_fork+0x32c/0x410
> [  805.727345]  ? __pfx_kthread+0x10/0x10
> [  805.727347]  ret_from_fork_asm+0x1a/0x30
> [  805.727354]  </TASK>
>
> Fixes: 34c21fa894a1 ("idpf: implement virtchnl transaction manager")
> Reported-by: Ray Zhang <sgzhang@google.com>
> Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
> ---
>  .../net/ethernet/intel/idpf/idpf_virtchnl.c   | 21 +++++++------------
>  1 file changed, 8 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
> index 6b9692b30040..8ceabd86e172 100644
> --- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
> +++ b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
> @@ -546,32 +546,24 @@ static int
>  idpf_vc_xn_forward_async(struct idpf_adapter *adapter, struct idpf_vc_xn *xn,
>                          const struct idpf_ctlq_msg *ctlq_msg)
>  {
> -       int err = 0;
> -
>         if (ctlq_msg->cookie.mbx.chnl_opcode != xn->vc_op) {
>                 dev_err_ratelimited(&adapter->pdev->dev, "Async message opcode does not match transaction opcode (msg: %d) (xn: %d)\n",
>                                     ctlq_msg->cookie.mbx.chnl_opcode, xn->vc_op);
>                 xn->reply_sz = 0;
> -               err = -EINVAL;
> -               goto release_bufs;
> +               return -EINVAL;
>         }
>
> -       if (xn->async_handler) {
> -               err = xn->async_handler(adapter, xn, ctlq_msg);
> -               goto release_bufs;
> -       }
> +       if (xn->async_handler)
> +               return xn->async_handler(adapter, xn, ctlq_msg);
>
>         if (ctlq_msg->cookie.mbx.chnl_retval) {
>                 xn->reply_sz = 0;
>                 dev_err_ratelimited(&adapter->pdev->dev, "Async message failure (op %d)\n",
>                                     ctlq_msg->cookie.mbx.chnl_opcode);
> -               err = -EINVAL;
> +               return -EINVAL;
>         }
>
> -release_bufs:
> -       idpf_vc_xn_release_bufs(xn);
> -
> -       return err;
> +       return 0;
>  }
>
>  /**
> @@ -631,7 +623,10 @@ idpf_vc_xn_forward_reply(struct idpf_adapter *adapter,
>                  * can evaluate the response.
>                  */
>                 xn->reply_sz = ctlq_msg->data_len;
> +               idpf_vc_xn_unlock(xn);
>                 err = idpf_vc_xn_forward_async(adapter, xn, ctlq_msg);
> +               idpf_vc_xn_lock(xn);
> +               idpf_vc_xn_release_bufs(xn);
>                 idpf_vc_xn_unlock(xn);
>                 idpf_vc_xn_push_free(adapter->vcxn_mngr, xn);
>                 return err;
> --
> 2.37.3
>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH iwl-net 0/3] idpf: virtchnl locking and async fixes
  2026-03-17 19:30       ` Tantilov, Emil S
@ 2026-03-18  7:24         ` Sebastian Andrzej Siewior
  2026-03-18 13:06           ` Tantilov, Emil S
  0 siblings, 1 reply; 14+ messages in thread
From: Sebastian Andrzej Siewior @ 2026-03-18  7:24 UTC (permalink / raw)
  To: Tantilov, Emil S
  Cc: intel-wired-lan, netdev, anthony.l.nguyen, aleksandr.loktionov,
	przemyslaw.kitszel, andrew+netdev, davem, edumazet, kuba, pabeni,
	clrkwllms, rostedt, linux-rt-devel, sgzhang, boolli

On 2026-03-17 12:30:39 [-0700], Tantilov, Emil S wrote:
> > What would break if you make that lock a spinlock_t?
> 
> Right. Scope and risk - these fixes are specifically for the async
> handler and I did not want to touch the global locking that will
> impact the entire VC handling. We do have series in flight for -next
> that refactor that code, while moving it to libie:
> https://lore.kernel.org/netdev/20251117134912.18566-10-larysa.zaremba@intel.com/

Now I understood. You fiddle with the completion's lock. That is
something that should not have been done.

> ... that also remove the raw spinlock. With that being said, I can look
> into converting the lock to spinlock_t if that is the preferred approach.

The preferred approach is that, if you pick raw_spinlock_t for locking,
you are aware of all the consequences and you have a solid reason for
it. The comment in the file says
| For now, this API is only used from within a workqueue context;
| - * raw_spin_lock() is enough.

that is not it.

> Thanks,
> Emil

Sebastian

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH iwl-net 0/3] idpf: virtchnl locking and async fixes
  2026-03-18  7:24         ` Sebastian Andrzej Siewior
@ 2026-03-18 13:06           ` Tantilov, Emil S
  0 siblings, 0 replies; 14+ messages in thread
From: Tantilov, Emil S @ 2026-03-18 13:06 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: intel-wired-lan, netdev, anthony.l.nguyen, aleksandr.loktionov,
	przemyslaw.kitszel, andrew+netdev, davem, edumazet, kuba, pabeni,
	clrkwllms, rostedt, linux-rt-devel, sgzhang, boolli



On 3/18/2026 12:24 AM, Sebastian Andrzej Siewior wrote:
> On 2026-03-17 12:30:39 [-0700], Tantilov, Emil S wrote:
>>> What would break if you make that lock a spinlock_t?
>>
>> Right. Scope and risk - these fixes are specifically for the async
>> handler and I did not want to touch the global locking that will
>> impact the entire VC handling. We do have series in flight for -next
>> that refactor that code, while moving it to libie:
>> https://lore.kernel.org/netdev/20251117134912.18566-10-larysa.zaremba@intel.com/
> 
> Now I understood. You fiddle with the completion's lock. That is
> something that should not have been done.
> 
>> ... that also remove the raw spinlock. With that being said, I can look
>> into converting the lock to spinlock_t if that is the preferred approach.
> 
> The preferred approach is that, if you pick raw_spinlock_t for locking,
> you are aware of all the consequences and you have a solid reason for
> it. The comment in the file says
> | For now, this API is only used from within a workqueue context;
> | - * raw_spin_lock() is enough.
> 
> that is not it.

Understood. I will convert it in v2.

Thanks for the feedback!
Emil

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH iwl-net 2/3] idpf: set the payload size before calling the async handler
  2026-03-18  0:11   ` Li Li
@ 2026-03-19 16:21     ` Tantilov, Emil S
  0 siblings, 0 replies; 14+ messages in thread
From: Tantilov, Emil S @ 2026-03-19 16:21 UTC (permalink / raw)
  To: Li Li
  Cc: intel-wired-lan, netdev, anthony.l.nguyen, aleksandr.loktionov,
	przemyslaw.kitszel, andrew+netdev, davem, edumazet, kuba, pabeni,
	bigeasy, clrkwllms, rostedt, linux-rt-devel, sgzhang



On 3/17/2026 5:11 PM, Li Li wrote:
> On Mon, Mar 16, 2026 at 4:28 PM Emil Tantilov <emil.s.tantilov@intel.com> wrote:
>>
>> Set the payload size before forwarding the reply to the async handler.
>> Without this, xn->reply_sz will be 0 and idpf_mac_filter_async_handler()
>> will never get past the size check.
>>
>> Fixes: 34c21fa894a1 ("idpf: implement virtchnl transaction manager")
>> Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
>> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
>> ---
>>   drivers/net/ethernet/intel/idpf/idpf_virtchnl.c | 4 ++++
>>   1 file changed, 4 insertions(+)
>>
>> diff --git a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
>> index 21a6c9d22085..6b9692b30040 100644
>> --- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
>> +++ b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
>> @@ -627,6 +627,10 @@ idpf_vc_xn_forward_reply(struct idpf_adapter *adapter,
>>                  err = -ENXIO;
>>                  goto out_unlock;
>>          case IDPF_VC_XN_ASYNC:
> 
> Optional comment: could we only set the size if ctlq_msg->data_len >
> 0, in case the hw returns some invalid values?

0 is a valid size, but event if it wasn't the async handler already has
a check for it, which is how this issue was caught (see description).

Thanks,
Emil

> 
>> +               /* Set reply_sz from the actual payload so that async_handler
>> +                * can evaluate the response.
>> +                */
>> +               xn->reply_sz = ctlq_msg->data_len;
>>                  err = idpf_vc_xn_forward_async(adapter, xn, ctlq_msg);
>>                  idpf_vc_xn_unlock(xn);
>>                  idpf_vc_xn_push_free(adapter->vcxn_mngr, xn);
>> --
>> 2.37.3
>>
> 
> Reviewed-by: Li Li <boolli@google.com>


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2026-03-19 16:21 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-16 23:28 [PATCH iwl-net 0/3] idpf: virtchnl locking and async fixes Emil Tantilov
2026-03-16 23:28 ` [PATCH iwl-net 1/3] idpf: improve locking around idpf_vc_xn_push_free() Emil Tantilov
2026-03-17 23:46   ` Li Li
2026-03-16 23:28 ` [PATCH iwl-net 2/3] idpf: set the payload size before calling the async handler Emil Tantilov
2026-03-18  0:11   ` Li Li
2026-03-19 16:21     ` Tantilov, Emil S
2026-03-16 23:28 ` [PATCH iwl-net 3/3] idpf: fix PREEMPT_RT raw/bh spinlock nesting for async VC handling Emil Tantilov
2026-03-18  0:13   ` Li Li
2026-03-17  9:00 ` [PATCH iwl-net 0/3] idpf: virtchnl locking and async fixes Sebastian Andrzej Siewior
2026-03-17 14:20   ` Tantilov, Emil S
2026-03-17 14:38     ` Sebastian Andrzej Siewior
2026-03-17 19:30       ` Tantilov, Emil S
2026-03-18  7:24         ` Sebastian Andrzej Siewior
2026-03-18 13:06           ` Tantilov, Emil S

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox