Netdev List
 help / color / mirror / Atom feed
* [PATCH v1 17/18] ibmveth: Wire ethtool set_channels to MQ RX queue resize
From: Mingming Cao @ 2026-06-30 14:53 UTC (permalink / raw)
  To: netdev
  Cc: horms, bjking1, haren, ricklind, mmc, kuba, edumazet, pabeni,
	linuxppc-dev, maddy, mpe, Dave Marquardt
In-Reply-To: <cover.1782758799.git.mmc@linux.ibm.com>

Expose incremental RX resize through ethtool channel control.

get_channels() reports rx_count from adapter->num_rx_queues and max_rx
as IBMVETH_MAX_RX_QUEUES when MQ firmware is enabled, else 1.

set_channels() validates rx_count is within 1..IBMVETH_MAX_RX_QUEUES.
When rx_count changes and the interface is up, call
ibmveth_resize_rx_queues_incremental(). When the interface is down,
store the requested rx_count in adapter->num_rx_queues so the next open
registers that many queues. Non-MQ firmware returns -EOPNOTSUPP for
rx > 1.

TX queue changes keep existing stop/wake behavior when tx_count changes.

Signed-off-by: Mingming Cao <mmc@linux.ibm.com>
Reviewed-by: Dave Marquardt <davemarq@linux.ibm.com>
---
 drivers/net/ethernet/ibm/ibmveth.c | 58 +++++++++++++++++++++++++++---
 1 file changed, 54 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
index ac4d89a66a8d..50a332ab83fd 100644
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c
@@ -2534,19 +2534,69 @@ static int ibmveth_set_channels(struct net_device *netdev,
 				struct ethtool_channels *channels)
 {
 	struct ibmveth_adapter *adapter = netdev_priv(netdev);
-	unsigned int old = netdev->real_num_tx_queues,
-		     goal = channels->tx_count;
+	unsigned int old_rx = adapter->num_rx_queues;
+	unsigned int goal_rx = channels->rx_count;
+	unsigned int old = netdev->real_num_tx_queues;
+	unsigned int goal = channels->tx_count;
+	int rxq_entries = adapter->rx_queue[0].num_slots;
 	int rc, i;
 
 	/* If ndo_open has not been called yet then don't allocate, just set
 	 * desired netdev_queue's and return
 	 */
-	if (!(netdev->flags & IFF_UP))
+	if (!(netdev->flags & IFF_UP)) {
+		if (goal_rx > 1 && !adapter->multi_queue) {
+			netdev_err(netdev,
+				   "Cannot resize to %u RX queues: multi-queue mode not supported by firmware\n",
+				   goal_rx);
+			return -EOPNOTSUPP;
+		}
+
+		if (goal_rx < 1 || goal_rx > IBMVETH_MAX_RX_QUEUES) {
+			netdev_err(netdev,
+				   "Invalid RX queue count %u (must be 1-%d)\n",
+				   goal_rx, IBMVETH_MAX_RX_QUEUES);
+			return -EINVAL;
+		}
+
+		/* Stash desired RX count; open() publishes it via
+		 * netif_set_real_num_rx_queues() after queue registration.
+		 */
+		if (goal_rx != adapter->num_rx_queues)
+			adapter->num_rx_queues = goal_rx;
+
 		return netif_set_real_num_tx_queues(netdev, goal);
+	}
+
+	if (goal_rx > 1 && !adapter->multi_queue) {
+		netdev_err(netdev,
+			   "Cannot resize to %u RX queues: multi-queue mode not supported by firmware\n",
+			   goal_rx);
+		return -EOPNOTSUPP;
+	}
+
+	if (goal_rx < 1 || goal_rx > IBMVETH_MAX_RX_QUEUES) {
+		netdev_err(netdev,
+			   "Invalid RX queue count %u (must be 1-%d)\n",
+			   goal_rx, IBMVETH_MAX_RX_QUEUES);
+		return -EINVAL;
+	}
+
+	if (goal_rx != old_rx) {
+		rc = ibmveth_resize_rx_queues_incremental(adapter, goal_rx,
+							  rxq_entries);
+		if (rc) {
+			netdev_err(netdev, "Failed to resize RX queues: %d\n", rc);
+			return rc;
+		}
+	}
 
 	/* We have IBMVETH_MAX_QUEUES netdev_queue's allocated
 	 * but we may need to alloc/free the ltb's.
 	 */
+	if (goal == old)
+		return 0;
+
 	netif_tx_stop_all_queues(netdev);
 
 	/* Allocate any queue that we need */
@@ -2580,7 +2630,7 @@ static int ibmveth_set_channels(struct net_device *netdev,
 
 	netif_tx_wake_all_queues(netdev);
 
-	return rc;
+	return 0;
 }
 
 static const struct ethtool_ops netdev_ethtool_ops = {
-- 
2.39.3 (Apple Git-146)


^ permalink raw reply related

* [PATCH v1 16/18] ibmveth: Implement incremental MQ RX queue resize
From: Mingming Cao @ 2026-06-30 14:53 UTC (permalink / raw)
  To: netdev
  Cc: horms, bjking1, haren, ricklind, mmc, kuba, edumazet, pabeni,
	linuxppc-dev, maddy, mpe, Dave Marquardt
In-Reply-To: <cover.1782758799.git.mmc@linux.ibm.com>

Add ibmveth_resize_rx_queues_incremental() to grow or shrink
adapter->num_rx_queues while the netdev stays up.

Scale-up, per new queue index:
  alloc RX resources and per-queue pools
  register subordinate queue with PHYP
  request_irq(), then ibmveth_enable_irq(), then napi_enable
  update num_rx_queues, replenish new queues
  netif_set_real_num_rx_queues()

Scale-down disables NAPI on excess queues, drains pending buffers,
disables PHYP IRQ delivery and waits for in-flight handlers with
synchronize_irq() before lowering num_rx_queues, then tears down
IRQ/PHYP/memory.

Reject out-of-range new_count. On scale-down netif failure, re-enable
NAPI on queues not yet torn down. Refresh VIO CMO entitlement after a
successful resize when FW_FEATURE_CMO is enabled.

Scale-up rollback mirrors scale-down: drain posted buffers and wait for
in-flight handlers before deregistering with PHYP.

In replenish_task(), skip queues with queue_index >= num_rx_queues and
require pool->free_map before replenishing so in-flight handlers avoid
queues being torn down without clearing probe-time pool->active on free.

Queue 0 is never removed here. Scale-up failure unwinds only queues
added in this call. ethtool -L wiring is next.

Signed-off-by: Mingming Cao <mmc@linux.ibm.com>
Reviewed-by: Dave Marquardt <davemarq@linux.ibm.com>
---
 drivers/net/ethernet/ibm/ibmveth.c | 183 ++++++++++++++++++++++++++++-
 1 file changed, 178 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
index cd0acd1715da..ac4d89a66a8d 100644
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c
@@ -945,18 +945,22 @@ static void ibmveth_replenish_task(struct ibmveth_adapter *adapter,
 	unsigned long flags;
 	int i;
 
-	if (queue_index >= adapter->num_rx_queues)
-		return;
-
 	adapter->replenish_task_cycles++;
 
+	if (queue_index >= adapter->num_rx_queues) {
+		netdev_dbg(adapter->netdev,
+			   "Skipping replenish for freed queue %d (num_queues=%d)\n",
+			   queue_index, adapter->num_rx_queues);
+		return;
+	}
+
 	spin_lock_irqsave(&rxq->replenish_lock, flags);
 
 	for (i = (IBMVETH_NUM_BUFF_POOLS - 1); i >= 0; i--) {
 		struct ibmveth_buff_pool *pool =
 			&adapter->rx_buff_pool[queue_index][i];
 
-		if (pool->active &&
+		if (pool->active && pool->free_map &&
 		    (atomic_read(&pool->available) < pool->threshold))
 			ibmveth_replenish_buffer_pool(adapter, pool,
 						      queue_index);
@@ -1682,7 +1686,7 @@ ibmveth_register_single_rx_queue(struct ibmveth_adapter *adapter,
  * the IRQ mapping for subordinate queues. Queue 0 is freed only through
  * ibmveth_free_all_queues() (H_FREE_LOGICAL_LAN).
  */
-static void __maybe_unused
+static void
 ibmveth_deregister_single_rx_queue(struct ibmveth_adapter *adapter,
 				   int queue_idx)
 {
@@ -1714,6 +1718,175 @@ ibmveth_deregister_single_rx_queue(struct ibmveth_adapter *adapter,
 	netdev_dbg(adapter->netdev, "Deregistered queue %d\n", queue_idx);
 }
 
+/**
+ * ibmveth_resize_rx_queues_incremental - Resize RX queue count incrementally
+ * @adapter: ibmveth adapter structure
+ * @new_count: Target number of RX queues
+ * @rxq_entries: Number of entries per RX queue
+ *
+ * Adds or removes RX queues without tearing down the entire adapter.
+ * Active queues continue receiving during scale-up; scale-down drains
+ * excess queues before deregistering them with the hypervisor.
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+static int
+ibmveth_resize_rx_queues_incremental(struct ibmveth_adapter *adapter,
+				     int new_count, int rxq_entries)
+{
+	struct net_device *netdev = adapter->netdev;
+	u64 mac_address = ether_addr_to_u64(netdev->dev_addr);
+	int old_count = adapter->num_rx_queues;
+	int failed_queue;
+	int rc, i;
+
+	if (old_count == new_count) {
+		netdev_dbg(netdev, "RX queue count unchanged (%d), nothing to do\n",
+			   old_count);
+		return 0;
+	}
+
+	if (new_count < 1 || new_count > IBMVETH_MAX_RX_QUEUES) {
+		netdev_err(netdev, "Invalid RX queue count %d (must be 1-%d)\n",
+			   new_count, IBMVETH_MAX_RX_QUEUES);
+		return -EINVAL;
+	}
+
+	netdev_info(netdev, "Incrementally resizing RX queues: %d to %d\n",
+		    old_count, new_count);
+
+	if (new_count > old_count) {
+		netdev_dbg(netdev, "Scale-up: adding queues %d-%d\n",
+			   old_count, new_count - 1);
+
+		for (i = old_count; i < new_count; i++) {
+			rc = ibmveth_alloc_single_rx_queue(adapter, i, rxq_entries);
+			if (rc) {
+				netdev_err(netdev, "Failed to allocate queue %d: %d\n",
+					   i, rc);
+				goto cleanup_new_queues;
+			}
+
+			rc = ibmveth_register_single_rx_queue(adapter, i,
+							      mac_address);
+			if (rc) {
+				netdev_err(netdev, "Failed to register queue %d: %d\n",
+					   i, rc);
+				ibmveth_free_single_rx_queue(adapter, i);
+				goto cleanup_new_queues;
+			}
+
+			rc = ibmveth_setup_single_rx_interrupt(adapter, i);
+			if (rc) {
+				netdev_err(netdev,
+					   "Failed to setup IRQ for queue %d: %d\n",
+					   i, rc);
+				ibmveth_deregister_single_rx_queue(adapter, i);
+				ibmveth_free_single_rx_queue(adapter, i);
+				goto cleanup_new_queues;
+			}
+
+			rc = ibmveth_enable_irq(adapter, i);
+			if (rc) {
+				netdev_err(netdev,
+					   "Failed to enable IRQ for queue %d: %d\n",
+					   i, rc);
+				ibmveth_cleanup_single_rx_interrupt(adapter, i);
+				ibmveth_deregister_single_rx_queue(adapter, i);
+				ibmveth_free_single_rx_queue(adapter, i);
+				goto cleanup_new_queues;
+			}
+
+			napi_enable(&adapter->napi[i]);
+		}
+
+		adapter->num_rx_queues = new_count;
+
+		for (i = old_count; i < new_count; i++)
+			ibmveth_replenish_task(adapter, i);
+
+		rc = netif_set_real_num_rx_queues(netdev, new_count);
+		if (rc) {
+			netdev_err(netdev, "Failed to set real RX queues to %d: %d\n",
+				   new_count, rc);
+			goto cleanup_new_queues;
+		}
+	} else {
+		netdev_dbg(netdev, "Scale-down: removing queues %d-%d\n",
+			   new_count, old_count - 1);
+
+		for (i = new_count; i < old_count; i++)
+			napi_disable(&adapter->napi[i]);
+
+		for (i = new_count; i < old_count; i++)
+			ibmveth_drain_rx_queue(adapter, i);
+
+		synchronize_net();
+
+		rc = netif_set_real_num_rx_queues(netdev, new_count);
+		if (rc) {
+			netdev_err(netdev, "Failed to set real RX queues to %d: %d\n",
+				   new_count, rc);
+			for (i = new_count; i < old_count; i++)
+				napi_enable(&adapter->napi[i]);
+			return rc;
+		}
+
+		/* Disable hypervisor interrupts and wait for handlers to complete
+		 * before updating num_rx_queues.
+		 */
+		for (i = new_count; i < old_count; i++) {
+			ibmveth_disable_irq(adapter, i);
+			synchronize_irq(adapter->queue_irq[i]);
+		}
+
+		adapter->num_rx_queues = new_count;
+
+		for (i = new_count; i < old_count; i++) {
+			ibmveth_cleanup_single_rx_interrupt(adapter, i);
+			ibmveth_deregister_single_rx_queue(adapter, i);
+			ibmveth_free_single_rx_queue(adapter, i);
+		}
+	}
+
+	netdev_info(netdev, "Successfully resized to %d RX queues (incremental)\n",
+		    adapter->num_rx_queues);
+
+	if (firmware_has_feature(FW_FEATURE_CMO))
+		vio_cmo_set_dev_desired(adapter->vdev,
+					ibmveth_get_desired_dma(adapter->vdev));
+
+	return 0;
+
+cleanup_new_queues:
+	failed_queue = i;
+	netdev_err(netdev,
+		   "Scale-up failed at queue %d, cleaning up queues %d-%d\n",
+		   failed_queue, old_count, failed_queue - 1);
+	for (i = old_count; i < failed_queue; i++)
+		napi_disable(&adapter->napi[i]);
+
+	for (i = old_count; i < failed_queue; i++)
+		ibmveth_drain_rx_queue(adapter, i);
+
+	synchronize_net();
+
+	for (i = old_count; i < failed_queue; i++) {
+		ibmveth_disable_irq(adapter, i);
+		synchronize_irq(adapter->queue_irq[i]);
+	}
+
+	for (i = old_count; i < failed_queue; i++) {
+		ibmveth_cleanup_single_rx_interrupt(adapter, i);
+		ibmveth_deregister_single_rx_queue(adapter, i);
+		ibmveth_free_single_rx_queue(adapter, i);
+	}
+	adapter->num_rx_queues = old_count;
+	netdev_warn(netdev, "Keeping %d queues after scale-up failure\n",
+		    old_count);
+	return rc;
+}
+
 /**
  * ibmveth_free_all_queues - Free all RX queues at once
  * @adapter: ibmveth adapter structure
-- 
2.39.3 (Apple Git-146)


^ permalink raw reply related

* [PATCH bpf-next v4 1/2] bpf, sockmap: disallow update and delete from tc, xdp, socket_filter and flow_dissector
From: Sechang Lim @ 2026-06-30 14:54 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Eduard Zingerman, Kumar Kartikeya Dwivedi, John Fastabend,
	David S. Miller, Jakub Kicinski, Jesper Dangaard Brouer,
	Shuah Khan
  Cc: Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa,
	Emil Tsalapatis, Stanislav Fomichev, Jiayuan Chen, Varun R Mallya,
	Ihor Solodrai, bpf, netdev, linux-kernel, linux-kselftest
In-Reply-To: <20260630145410.3648099-1-rhkrqnwk98@gmail.com>

sock_map_update_common() and __sock_map_delete() hold stab->lock and call
sock_map_unref() -> sock_map_del_link(), which takes sk_callback_lock for
write. That gives the order stab->lock -> sk_callback_lock.

The reverse order comes from the SK_SKB stream parser.
sk_psock_strp_data_ready() holds sk_callback_lock for read, and after the
verdict tcp_bpf_strp_read_sock() acks the consumed data inline via
__tcp_cleanup_rbuf(). The ACK goes out egress, where a sched_cls program
deletes from the sockmap and takes stab->lock:

  WARNING: possible circular locking dependency detected
  ------------------------------------------------------
  syz.9.8824 is trying to acquire lock:
  (&stab->lock){+.-.}-{3:3}, at: __sock_map_delete net/core/sock_map.c:421
  but task is already holding lock:
  (clock-AF_INET){++.-}-{3:3}, at: sk_psock_strp_data_ready net/core/skmsg.c:1173

  -> #1 (clock-AF_INET){++.-}-{3:3}:
         _raw_write_lock_bh
         sock_map_del_link net/core/sock_map.c:167
         sock_map_unref net/core/sock_map.c:184
         sock_map_update_common net/core/sock_map.c:509
         sock_map_update_elem_sys net/core/sock_map.c:588
         map_update_elem kernel/bpf/syscall.c:1805

  -> #0 (&stab->lock){+.-.}-{3:3}:
         _raw_spin_lock_bh
         __sock_map_delete net/core/sock_map.c:421
         sock_map_delete_elem net/core/sock_map.c:452
         bpf_prog_06044d24140080b6
         tcx_run net/core/dev.c:4451
         sch_handle_egress net/core/dev.c:4541
         __dev_queue_xmit net/core/dev.c:4808
         ...
         tcp_bpf_strp_read_sock net/ipv4/tcp_bpf.c:701
         strp_data_ready net/strparser/strparser.c:402
         sk_psock_strp_data_ready net/core/skmsg.c:1174
         tcp_data_queue net/ipv4/tcp_input.c:5661

  Possible unsafe locking scenario:

         CPU0                    CPU1
         ----                    ----
    rlock(clock-AF_INET);
                                 lock(&stab->lock);
                                 lock(clock-AF_INET);
    lock(&stab->lock);

   *** DEADLOCK ***

A tc, xdp, socket_filter or flow_dissector program has no reason to
update or delete a sockmap, and redirect does not go through here. Drop
them from may_update_sockmap() so the verifier rejects it. It also
closes the matching sockhash inversion.

Suggested-by: John Fastabend <john.fastabend@gmail.com>
Signed-off-by: Sechang Lim <rhkrqnwk98@gmail.com>
---
 kernel/bpf/verifier.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 25aea4271cd0..83ea3b33ff67 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -8488,12 +8488,7 @@ static bool may_update_sockmap(struct bpf_verifier_env *env, int func_id)
 		if (func_id == BPF_FUNC_map_delete_elem)
 			return true;
 		break;
-	case BPF_PROG_TYPE_SOCKET_FILTER:
-	case BPF_PROG_TYPE_SCHED_CLS:
-	case BPF_PROG_TYPE_SCHED_ACT:
-	case BPF_PROG_TYPE_XDP:
 	case BPF_PROG_TYPE_SK_REUSEPORT:
-	case BPF_PROG_TYPE_FLOW_DISSECTOR:
 	case BPF_PROG_TYPE_SK_LOOKUP:
 		return true;
 	default:
-- 
2.43.0


^ permalink raw reply related

* [PATCH v1 18/18] ibmveth: Fix MQ RX poll and shutdown hangs after queue resize
From: Mingming Cao @ 2026-06-30 14:53 UTC (permalink / raw)
  To: netdev
  Cc: horms, bjking1, haren, ricklind, mmc, kuba, edumazet, pabeni,
	linuxppc-dev, maddy, mpe, Dave Marquardt
In-Reply-To: <cover.1782758799.git.mmc@linux.ibm.com>

After aggressive ethtool -L cycling, PHYP can leave a VALID RX descriptor
with a correlator that no longer matches the per-queue buffer pools. Poll
treated this as fatal: ibmveth_rxq_get_buffer() WARNed and returned NULL
without advancing the ring, then restart_poll retried the same slot forever.

Advance past bad correlators instead of spinning: validate correlators
without WARN_ON, skip invalid slots in poll (count as invalid_buffers),
and advance the RX ring when remove_buffer_from_pool cannot map the
correlator. Rate-limit the bad correlator message.

Complete NAPI when the interface is down or napi_disable is pending so
ibmveth_cleanup_rx_interrupts() can finish. Do not restart_poll in that
window. Close keeps hypervisor IRQ disable before napi_disable (via
cleanup_rx_interrupts()).

Signed-off-by: Mingming Cao <mmc@linux.ibm.com>
Reviewed-by: Dave Marquardt <davemarq@linux.ibm.com>
---
 drivers/net/ethernet/ibm/ibmveth.c | 76 ++++++++++++++++++++++--------
 1 file changed, 57 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
index 50a332ab83fd..d7bf01271161 100644
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c
@@ -158,6 +158,25 @@ static inline int ibmveth_rxq_frame_length(struct ibmveth_adapter *adapter,
 	return be32_to_cpu(rxq->queue_addr[rxq->index].length);
 }
 
+static inline bool
+ibmveth_rxq_correlator_valid(struct ibmveth_adapter *adapter, int queue_index,
+			     u64 correlator)
+{
+	unsigned int pool = correlator >> 32;
+	unsigned int index = correlator & 0xffffffffUL;
+
+	return pool < IBMVETH_NUM_BUFF_POOLS &&
+	       index < adapter->rx_buff_pool[queue_index][pool].size;
+}
+
+static inline void ibmveth_rxq_advance(struct ibmveth_rx_q *rxq)
+{
+	if (++rxq->index == rxq->num_slots) {
+		rxq->index = 0;
+		rxq->toggle = !rxq->toggle;
+	}
+}
+
 static inline int ibmveth_rxq_csum_good(struct ibmveth_adapter *adapter,
 					int queue_index)
 {
@@ -1284,17 +1303,12 @@ static int ibmveth_remove_buffer_from_pool(struct ibmveth_adapter *adapter,
 	unsigned int free_index;
 	struct sk_buff *skb;
 
-	if (WARN_ON(pool >= IBMVETH_NUM_BUFF_POOLS) ||
-	    WARN_ON(index >= adapter->rx_buff_pool[queue_index][pool].size)) {
-		schedule_work(&adapter->work);
+	if (!ibmveth_rxq_correlator_valid(adapter, queue_index, correlator))
 		return -EINVAL;
-	}
 
 	skb = adapter->rx_buff_pool[queue_index][pool].skbuff[index];
-	if (WARN_ON(!skb)) {
-		schedule_work(&adapter->work);
+	if (!skb)
 		return -EFAULT;
-	}
 
 	/* if we are going to reuse the buffer then keep the pointers around
 	 * but mark index as available. replenish will see the skb pointer and
@@ -1335,11 +1349,8 @@ static inline struct sk_buff *ibmveth_rxq_get_buffer(struct ibmveth_adapter *ada
 	unsigned int pool = correlator >> 32;
 	unsigned int index = correlator & 0xffffffffUL;
 
-	if (WARN_ON(pool >= IBMVETH_NUM_BUFF_POOLS) ||
-	    WARN_ON(index >= adapter->rx_buff_pool[queue_index][pool].size)) {
-		schedule_work(&adapter->work);
+	if (!ibmveth_rxq_correlator_valid(adapter, queue_index, correlator))
 		return NULL;
-	}
 
 	return adapter->rx_buff_pool[queue_index][pool].skbuff[index];
 }
@@ -1365,14 +1376,15 @@ static int ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter,
 
 	cor = rxq->queue_addr[rxq->index].correlator;
 	rc = ibmveth_remove_buffer_from_pool(adapter, cor, queue_index, reuse);
-	if (unlikely(rc))
+	if (unlikely(rc)) {
+		if (rc == -EINVAL || rc == -EFAULT)
+			goto advance;
 		return rc;
-
-	if (++rxq->index == rxq->num_slots) {
-		rxq->index = 0;
-		rxq->toggle = !rxq->toggle;
 	}
 
+advance:
+	ibmveth_rxq_advance(rxq);
+
 	return 0;
 }
 
@@ -2931,11 +2943,19 @@ static int ibmveth_poll(struct napi_struct *napi, int budget)
 	if (WARN_ON(queue_index < 0 || queue_index >= adapter->num_rx_queues))
 		return 0;
 
+	if (!netif_running(netdev) || napi_disable_pending(napi)) {
+		napi_complete_done(napi, 0);
+		return 0;
+	}
+
 	if (adapter->rx_qstats)
 		adapter->rx_qstats[queue_index].polls++;
 
 restart_poll:
 	while (frames_processed < budget) {
+		if (!netif_running(netdev) || napi_disable_pending(napi))
+			break;
+
 		if (!ibmveth_rxq_pending_buffer(adapter, queue_index))
 			break;
 
@@ -2959,8 +2979,21 @@ static int ibmveth_poll(struct napi_struct *napi, int budget)
 			__sum16 iph_check = 0;
 
 			skb = ibmveth_rxq_get_buffer(adapter, queue_index);
-			if (unlikely(!skb))
-				break;
+			if (unlikely(!skb)) {
+				if (net_ratelimit())
+					netdev_err(netdev,
+						   "bad correlator on queue %d, skipping slot\n",
+						   queue_index);
+				if (adapter->rx_qstats)
+					adapter->rx_qstats[queue_index].invalid_buffers++;
+				else
+					adapter->rx_invalid_buffer++;
+				rc = ibmveth_rxq_harvest_buffer(adapter, queue_index,
+								true);
+				if (unlikely(rc))
+					break;
+				continue;
+			}
 
 			/* if the large packet bit is set in the rx queue
 			 * descriptor, the mss will be written by PHYP eight
@@ -3034,8 +3067,11 @@ static int ibmveth_poll(struct napi_struct *napi, int budget)
 
 	ibmveth_replenish_task(adapter, queue_index);
 
-	if (frames_processed == budget)
+	if (frames_processed == budget) {
+		if (!netif_running(netdev) || napi_disable_pending(napi))
+			napi_complete_done(napi, frames_processed);
 		goto out;
+	}
 
 	if (!napi_complete_done(napi, frames_processed))
 		goto out;
@@ -3053,6 +3089,8 @@ static int ibmveth_poll(struct napi_struct *napi, int budget)
 	}
 
 	if (ibmveth_rxq_pending_buffer(adapter, queue_index) &&
+	    netif_running(netdev) &&
+	    !napi_disable_pending(napi) &&
 	    napi_schedule(napi)) {
 		lpar_rc = ibmveth_disable_irq(adapter, queue_index);
 		WARN_ON(lpar_rc != H_SUCCESS);
-- 
2.39.3 (Apple Git-146)


^ permalink raw reply related

* [PATCH bpf-next v4 2/2] selftests/bpf: drop tc/xdp/flow_dissector/socket_filter sockmap mutation tests
From: Sechang Lim @ 2026-06-30 14:54 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Eduard Zingerman, Kumar Kartikeya Dwivedi, John Fastabend,
	David S. Miller, Jakub Kicinski, Jesper Dangaard Brouer,
	Shuah Khan
  Cc: Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa,
	Emil Tsalapatis, Stanislav Fomichev, Jiayuan Chen, Varun R Mallya,
	Ihor Solodrai, bpf, netdev, linux-kernel, linux-kselftest
In-Reply-To: <20260630145410.3648099-1-rhkrqnwk98@gmail.com>

tc, xdp, socket_filter and flow_dissector programs can no longer update
or delete a sockmap. Adjust the tests:

 - verifier_sockmap_mutate: the tc, xdp, socket_filter and
   flow_dissector cases now expect __failure with "cannot update sockmap
   in this context".
 - sockmap_basic: drop "sockmap update" / "sockhash update", which load
   a SEC("tc") program that copies a sock between maps.
 - fexit_bpf2bpf: drop "func_sockmap_update", whose freplace program
   updates a sockmap in the tc cls_redirect context.

Remove the now-unused test_sockmap_update.c and freplace_cls_redirect.c.

Signed-off-by: Sechang Lim <rhkrqnwk98@gmail.com>
---
 .../selftests/bpf/prog_tests/fexit_bpf2bpf.c  | 13 -----
 .../selftests/bpf/prog_tests/sockmap_basic.c  | 52 -------------------
 .../bpf/progs/freplace_cls_redirect.c         | 34 ------------
 .../selftests/bpf/progs/test_sockmap_update.c | 48 -----------------
 .../bpf/progs/verifier_sockmap_mutate.c       | 12 ++---
 5 files changed, 6 insertions(+), 153 deletions(-)
 delete mode 100644 tools/testing/selftests/bpf/progs/freplace_cls_redirect.c
 delete mode 100644 tools/testing/selftests/bpf/progs/test_sockmap_update.c

diff --git a/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c b/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c
index 92c20803ea76..d3a954158c33 100644
--- a/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c
+++ b/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c
@@ -336,17 +336,6 @@ static void test_fmod_ret_freplace(void)
 }
 
 
-static void test_func_sockmap_update(void)
-{
-	const char *prog_name[] = {
-		"freplace/cls_redirect",
-	};
-	test_fexit_bpf2bpf_common("./freplace_cls_redirect.bpf.o",
-				  "./test_cls_redirect.bpf.o",
-				  ARRAY_SIZE(prog_name),
-				  prog_name, false, NULL);
-}
-
 static void test_func_replace_void(void)
 {
 	const char *prog_name[] = {
@@ -599,8 +588,6 @@ void serial_test_fexit_bpf2bpf(void)
 		test_func_replace();
 	if (test__start_subtest("func_replace_verify"))
 		test_func_replace_verify();
-	if (test__start_subtest("func_sockmap_update"))
-		test_func_sockmap_update();
 	if (test__start_subtest("func_replace_return_code"))
 		test_func_replace_return_code();
 	if (test__start_subtest("func_map_prog_compatibility"))
diff --git a/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c b/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c
index cb3229711f93..33f788e2786d 100644
--- a/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c
+++ b/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c
@@ -7,7 +7,6 @@
 
 #include "test_progs.h"
 #include "test_skmsg_load_helpers.skel.h"
-#include "test_sockmap_update.skel.h"
 #include "test_sockmap_invalid_update.skel.h"
 #include "test_sockmap_skb_verdict_attach.skel.h"
 #include "test_sockmap_progs_query.skel.h"
@@ -235,53 +234,6 @@ static void test_skmsg_helpers_with_link(enum bpf_map_type map_type)
 	test_skmsg_load_helpers__destroy(skel);
 }
 
-static void test_sockmap_update(enum bpf_map_type map_type)
-{
-	int err, prog, src;
-	struct test_sockmap_update *skel;
-	struct bpf_map *dst_map;
-	const __u32 zero = 0;
-	char dummy[14] = {0};
-	LIBBPF_OPTS(bpf_test_run_opts, topts,
-		.data_in = dummy,
-		.data_size_in = sizeof(dummy),
-		.repeat = 1,
-	);
-	__s64 sk;
-
-	sk = connected_socket_v4();
-	if (!ASSERT_NEQ(sk, -1, "connected_socket_v4"))
-		return;
-
-	skel = test_sockmap_update__open_and_load();
-	if (!ASSERT_OK_PTR(skel, "open_and_load"))
-		goto close_sk;
-
-	prog = bpf_program__fd(skel->progs.copy_sock_map);
-	src = bpf_map__fd(skel->maps.src);
-	if (map_type == BPF_MAP_TYPE_SOCKMAP)
-		dst_map = skel->maps.dst_sock_map;
-	else
-		dst_map = skel->maps.dst_sock_hash;
-
-	err = bpf_map_update_elem(src, &zero, &sk, BPF_NOEXIST);
-	if (!ASSERT_OK(err, "update_elem(src)"))
-		goto out;
-
-	err = bpf_prog_test_run_opts(prog, &topts);
-	if (!ASSERT_OK(err, "test_run"))
-		goto out;
-	if (!ASSERT_NEQ(topts.retval, 0, "test_run retval"))
-		goto out;
-
-	compare_cookies(skel->maps.src, dst_map);
-
-out:
-	test_sockmap_update__destroy(skel);
-close_sk:
-	close(sk);
-}
-
 static void test_sockmap_invalid_update(void)
 {
 	struct test_sockmap_invalid_update *skel;
@@ -1385,10 +1337,6 @@ void test_sockmap_basic(void)
 		test_skmsg_helpers(BPF_MAP_TYPE_SOCKMAP);
 	if (test__start_subtest("sockhash sk_msg load helpers"))
 		test_skmsg_helpers(BPF_MAP_TYPE_SOCKHASH);
-	if (test__start_subtest("sockmap update"))
-		test_sockmap_update(BPF_MAP_TYPE_SOCKMAP);
-	if (test__start_subtest("sockhash update"))
-		test_sockmap_update(BPF_MAP_TYPE_SOCKHASH);
 	if (test__start_subtest("sockmap update in unsafe context"))
 		test_sockmap_invalid_update();
 	if (test__start_subtest("sockmap copy"))
diff --git a/tools/testing/selftests/bpf/progs/freplace_cls_redirect.c b/tools/testing/selftests/bpf/progs/freplace_cls_redirect.c
deleted file mode 100644
index 7e94412d47a5..000000000000
--- a/tools/testing/selftests/bpf/progs/freplace_cls_redirect.c
+++ /dev/null
@@ -1,34 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (c) 2020 Facebook
-
-#include <linux/stddef.h>
-#include <linux/bpf.h>
-#include <linux/pkt_cls.h>
-#include <bpf/bpf_endian.h>
-#include <bpf/bpf_helpers.h>
-
-struct {
-	__uint(type, BPF_MAP_TYPE_SOCKMAP);
-	__type(key, int);
-	__type(value, int);
-	__uint(max_entries, 2);
-} sock_map SEC(".maps");
-
-SEC("freplace/cls_redirect")
-int freplace_cls_redirect_test(struct __sk_buff *skb)
-{
-	int ret = 0;
-	const int zero = 0;
-	struct bpf_sock *sk;
-
-	sk = bpf_map_lookup_elem(&sock_map, &zero);
-	if (!sk)
-		return TC_ACT_SHOT;
-
-	ret = bpf_map_update_elem(&sock_map, &zero, sk, 0);
-	bpf_sk_release(sk);
-
-	return ret == 0 ? TC_ACT_OK : TC_ACT_SHOT;
-}
-
-char _license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/progs/test_sockmap_update.c b/tools/testing/selftests/bpf/progs/test_sockmap_update.c
deleted file mode 100644
index 6d64ea536e3d..000000000000
--- a/tools/testing/selftests/bpf/progs/test_sockmap_update.c
+++ /dev/null
@@ -1,48 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (c) 2020 Cloudflare
-#include "vmlinux.h"
-#include <bpf/bpf_helpers.h>
-
-struct {
-	__uint(type, BPF_MAP_TYPE_SOCKMAP);
-	__uint(max_entries, 1);
-	__type(key, __u32);
-	__type(value, __u64);
-} src SEC(".maps");
-
-struct {
-	__uint(type, BPF_MAP_TYPE_SOCKMAP);
-	__uint(max_entries, 1);
-	__type(key, __u32);
-	__type(value, __u64);
-} dst_sock_map SEC(".maps");
-
-struct {
-	__uint(type, BPF_MAP_TYPE_SOCKHASH);
-	__uint(max_entries, 1);
-	__type(key, __u32);
-	__type(value, __u64);
-} dst_sock_hash SEC(".maps");
-
-SEC("tc")
-int copy_sock_map(void *ctx)
-{
-	struct bpf_sock *sk;
-	bool failed = false;
-	__u32 key = 0;
-
-	sk = bpf_map_lookup_elem(&src, &key);
-	if (!sk)
-		return SK_DROP;
-
-	if (bpf_map_update_elem(&dst_sock_map, &key, sk, 0))
-		failed = true;
-
-	if (bpf_map_update_elem(&dst_sock_hash, &key, sk, 0))
-		failed = true;
-
-	bpf_sk_release(sk);
-	return failed ? SK_DROP : SK_PASS;
-}
-
-char _license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/progs/verifier_sockmap_mutate.c b/tools/testing/selftests/bpf/progs/verifier_sockmap_mutate.c
index fe4b123187b8..20332a731d4e 100644
--- a/tools/testing/selftests/bpf/progs/verifier_sockmap_mutate.c
+++ b/tools/testing/selftests/bpf/progs/verifier_sockmap_mutate.c
@@ -74,7 +74,7 @@ static __always_inline void test_sockmap_lookup_and_mutate(void)
 }
 
 SEC("action")
-__success
+__failure __msg("cannot update sockmap in this context")
 int test_sched_act(struct __sk_buff *skb)
 {
 	test_sockmap_mutate(skb->sk);
@@ -82,7 +82,7 @@ int test_sched_act(struct __sk_buff *skb)
 }
 
 SEC("classifier")
-__success
+__failure __msg("cannot update sockmap in this context")
 int test_sched_cls(struct __sk_buff *skb)
 {
 	test_sockmap_mutate(skb->sk);
@@ -90,7 +90,7 @@ int test_sched_cls(struct __sk_buff *skb)
 }
 
 SEC("flow_dissector")
-__success
+__failure __msg("cannot update sockmap in this context")
 int test_flow_dissector_delete(struct __sk_buff *skb __always_unused)
 {
 	test_sockmap_delete();
@@ -98,7 +98,7 @@ int test_flow_dissector_delete(struct __sk_buff *skb __always_unused)
 }
 
 SEC("flow_dissector")
-__failure __msg("program of this type cannot use helper bpf_sk_release")
+__failure __msg("cannot update sockmap in this context")
 int test_flow_dissector_update(struct __sk_buff *skb __always_unused)
 {
 	test_sockmap_lookup_and_update(); /* no access to skb->sk */
@@ -146,7 +146,7 @@ int test_sk_reuseport(struct sk_reuseport_md *ctx)
 }
 
 SEC("socket")
-__success
+__failure __msg("cannot update sockmap in this context")
 int test_socket_filter(struct __sk_buff *skb)
 {
 	test_sockmap_mutate(skb->sk);
@@ -179,7 +179,7 @@ int test_sockops_update_dedicated(struct bpf_sock_ops *ctx)
 }
 
 SEC("xdp")
-__success
+__failure __msg("cannot update sockmap in this context")
 int test_xdp(struct xdp_md *ctx __always_unused)
 {
 	test_sockmap_lookup_and_mutate();
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH net 0/3] Fix broken TC_ACT_REDIRECT from qdiscs
From: Daniel Borkmann @ 2026-06-30 15:09 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior; +Cc: kuba, pabeni, jhs, andrii, memxor, bpf, netdev
In-Reply-To: <20260630143730.ZhXWjEIh@linutronix.de>

On 6/30/26 4:37 PM, Sebastian Andrzej Siewior wrote:
> On 2026-06-30 14:33:28 [+0200], Daniel Borkmann wrote:
>> This is an alternative fix to [0] in order to not uglify
>> __dev_queue_xmit() with sprinkled ifdefs given this can be
>> simplified and isolated through a simple test into the BPF
>> redirect helper itself.
>>
>> I've also added a proper BPF selftest, so there is no need
>> to check-in a binary BPF object into selftests given we do
>> have BPF infra for all of this.
> 
> 1/3 makes sense. Assuming we wouldn't have this per-task memory
> assignment, wouldn't then the state from one redirect leak into another?

For the normal/functional case out of tcx / cls_bpf via clsact
not given skb_do_redirect() is called right after return. (For
the full qdisc case it was never working in the first place.)

> For what it's worth:
> Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> 
> Sebastian


^ permalink raw reply

* RE: [PATCH net-next v6 14/15] dt-bindings: net: add onsemi's S2500
From: Selvamani Rajagopal @ 2026-06-30 15:09 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Andrew Lunn, Piergiorgio Beruto, Heiner Kallweit, Russell King,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Andrew Lunn, Parthiban Veerasooran, Richard Cochran, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Simon Horman, Jonathan Corbet,
	Shuah Khan, netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	devicetree@vger.kernel.org, linux-doc@vger.kernel.org, Jerry Ray
In-Reply-To: <20260630-beryl-mongrel-of-exercise-abf63a@quoll>

> -----Original Message-----
> From: Krzysztof Kozlowski <krzk@kernel.org>
> Subject: Re: [PATCH net-next v6 14/15] dt-bindings: net: add onsemi's S2500
> 
> No improvements.
> 
> So not only you ignored review comment but you also ignored actual
> review tag.
> 
> Don't worry, we can ignore your patches as well.

Fair comment. Sorry about that. I looked through my emails. Both were missed. Will take care of it.

> 
> Best regards,
> Krzysztof


^ permalink raw reply

* [PATCH net] net/sched: sch_teql: move rcu_read_lock()/spin_lock() from _bh variants
From: Jamal Hadi Salim @ 2026-06-30 15:09 UTC (permalink / raw)
  To: netdev; +Cc: davem, edumazet, kuba, pabeni, horms, jiri, victor,
	Jamal Hadi Salim

This is a followup based on sashiko comments [1] on commit e5b811fe7931
("net/sched: sch_teql: Introduce slaves_lock to avoid race condition and UAF")

Use plain rcu_read_lock()/spin_lock() in teql_master_xmit() instead of the
_bh variants, since ndo_start_xmit is already invoked with BH disabled
by the core stack and the _bh primitives can warn in_hardirq() when xmit
is reached through netpoll or a softirq xmit path with hard IRQs disabled.

Moves rcu_read_lock() after restart: label + adds rcu_read_unlock() before
goto restart (fixes the unbounded RCU hold across retries)

[1] https://sashiko.dev/#/patchset/20260628111229.669751-1-jhs%40mojatatu.com

Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
---
 net/sched/sch_teql.c | 27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index 24ba31f8c828..5c42a29a981c 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -311,14 +311,14 @@ static netdev_tx_t teql_master_xmit(struct sk_buff *skb, struct net_device *dev)
 	int subq = skb_get_queue_mapping(skb);
 	struct sk_buff *skb_res = NULL;
 
-	rcu_read_lock_bh();
-
-	start = rcu_dereference_bh(master->slaves);
-
 restart:
 	nores = 0;
 	busy = 0;
 
+	rcu_read_lock();
+
+	start = rcu_dereference(master->slaves);
+
 	q = start;
 	if (!q)
 		goto drop;
@@ -345,17 +345,17 @@ static netdev_tx_t teql_master_xmit(struct sk_buff *skb, struct net_device *dev)
 				    netdev_start_xmit(skb, slave, slave_txq, false) ==
 				    NETDEV_TX_OK) {
 					__netif_tx_unlock(slave_txq);
-					spin_lock_bh(&master->slaves_lock);
+					spin_lock(&master->slaves_lock);
 					if (rcu_dereference_protected(master->slaves,
 								      lockdep_is_held(&master->slaves_lock)) == q)
 						rcu_assign_pointer(master->slaves,
 								   rcu_dereference_protected(NEXT_SLAVE(q),
 											     lockdep_is_held(&master->slaves_lock)));
-					spin_unlock_bh(&master->slaves_lock);
+					spin_unlock(&master->slaves_lock);
 					netif_wake_queue(dev);
 					master->tx_packets++;
 					master->tx_bytes += length;
-					rcu_read_unlock_bh();
+					rcu_read_unlock();
 					return NETDEV_TX_OK;
 				}
 				__netif_tx_unlock(slave_txq);
@@ -364,37 +364,38 @@ static netdev_tx_t teql_master_xmit(struct sk_buff *skb, struct net_device *dev)
 				busy = 1;
 			break;
 		case 1:
-			spin_lock_bh(&master->slaves_lock);
+			spin_lock(&master->slaves_lock);
 			if (rcu_dereference_protected(master->slaves,
 						      lockdep_is_held(&master->slaves_lock)) == q)
 				rcu_assign_pointer(master->slaves,
 						   rcu_dereference_protected(NEXT_SLAVE(q),
 									     lockdep_is_held(&master->slaves_lock)));
-			spin_unlock_bh(&master->slaves_lock);
-			rcu_read_unlock_bh();
+			spin_unlock(&master->slaves_lock);
+			rcu_read_unlock();
 			return NETDEV_TX_OK;
 		default:
 			nores = 1;
 			break;
 		}
 		__skb_pull(skb, skb_network_offset(skb));
-	} while ((q = rcu_dereference_bh(NEXT_SLAVE(q))) != start);
+	} while ((q = rcu_dereference(NEXT_SLAVE(q))) != start);
 
 	if (nores && skb_res == NULL) {
 		skb_res = skb;
+		rcu_read_unlock();
 		goto restart;
 	}
 
 	if (busy) {
 		netif_stop_queue(dev);
-		rcu_read_unlock_bh();
+		rcu_read_unlock();
 		return NETDEV_TX_BUSY;
 	}
 	master->tx_errors++;
 
 drop:
 	master->tx_dropped++;
-	rcu_read_unlock_bh();
+	rcu_read_unlock();
 	dev_kfree_skb(skb);
 	return NETDEV_TX_OK;
 }
-- 
2.34.1


^ permalink raw reply related

* [RFC net-next] bonding: Retry updating slave MAC after a failure
From: Paritosh Potukuchi @ 2026-06-30 15:09 UTC (permalink / raw)
  To: netdev; +Cc: linux-kernel, paritosh.potukuchi


Hi all,

I came across this TODO in bond_set_mac_address() :

        /* TODO: consider downing the slave
         * and retry ?
         * User should expect communications
         * breakage anyway until ARP finish
         * updating, so...
         */

Currently, if the dev_set_mac_address() fails on a slave, we go
ahead and unwind the bond and its slaves.

As the TODO suggests, one possible solution is to try setting
the MAC again, after putting down the interface. This is because some 
drivers may reject changing the MAC when the device is UP.

The solution I am proposing is as follows:

dev_set_mac_address on the slave
        - If this fails, temporarily stop the slave - ndo_stop
                - If stop fails, unwind
        - call dev_set_mac_address() on the slave
                - If this fails, unwind
        - Bring up the slave by calling ndo_open
                - If this fails, unwind
If dev_set_mac_address on slave passes, we go to the next slave


Before working on a patch, I wanted to get feedback on whether
this interpretation of the TODO makes sense and whether there
are concerns with temporarily stopping and restarting a slave
during bond_set_mac_address().

Thanks,
Paritosh

^ permalink raw reply

* Re: [PATCH net v3 1/1] net/sched: sch_teql: Introduce slaves_lock to avoid race condition and UAF
From: Jamal Hadi Salim @ 2026-06-30 15:12 UTC (permalink / raw)
  To: Paolo Abeni
  Cc: netdev, davem, edumazet, kuba, horms, victor, jiri, security,
	zdi-disclosures, stable
In-Reply-To: <3dab7c8e-aed3-41f2-97e0-558c7a82f925@redhat.com>

On Tue, Jun 30, 2026 at 10:12 AM Paolo Abeni <pabeni@redhat.com> wrote:
>
> On 6/30/26 1:49 PM, Jamal Hadi Salim wrote:
> > On Tue, Jun 30, 2026 at 7:15 AM Paolo Abeni <pabeni@redhat.com> wrote:
> >> On 6/28/26 1:12 PM, Jamal Hadi Salim wrote:
> >>> The teql master->slaves singly linked list is not protected against
> >>> multiple writes. It can be mod'ed concurently from teql_master_xmit(),
> >>> teql_dequeue(), teql_init() and teql_destroy() without holding any list
> >>> lock or RCU protection.
> >>>
> >>> zdi-disclosures@trendmicro.com has demonstrated that the qdisc is freed
> >>> after an RCU grace period, but teql_master_xmit() running on another
> >>> CPU can still hold a stale pointer into the list, resulting in a
> >>> slab-use-after-free:
> >>>
> >>> BUG: KASAN: slab-use-after-free in teql_master_xmit+0xf0f/0x16b0
> >>> Read of size 8 at addr ffff888013fb0440 by task poc/332
> >>> Freed 512-byte region [ffff888013fb0400, ffff888013fb0600) (kmalloc-512)
> >>>
> >>> The fix?
> >>> Add a per-master slaves_lock spinlock that serializes all mutations of
> >>> master->slaves and the NEXT_SLAVE() links in teql_destroy() and
> >>> teql_qdisc_init(). teql_master_xmit() also takes the same slaves_lock
> >>> around those updates.
> >>> Annotate master->slaves and the per-slave ->next pointer with __rcu and
> >>> use the appropriate RCU accessors everywhere they are touched:
> >>> rcu_assign_pointer() on the writer side (under slaves_lock),
> >>> rcu_dereference_protected() for the writer-side loads (also under
> >>> slaves_lock), rcu_dereference_bh() for the loads in teql_master_xmit() and
> >>> rtnl_dereference() for the loads in teql_master_open()/teql_master_mtu(),
> >>> which run under RTNL.
> >>> Pair this with rcu_read_lock_bh()/rcu_read_unlock_bh() around the list
> >>> traversal in teql_master_xmit(), so that readers either observe a fully
> >>> linked list or are deferred until the in-flight mutation completes. The two
> >>> early-return paths in teql_master_xmit() are updated to release the RCU-bh
> >>> read-side critical section before returning, since leaving it held would
> >>> disable BH on that CPU for good.
> >>>
> >>> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> >>> Reported-by: zdi-disclosures@trendmicro.com
> >>> Tested-by: Victor Nogueira <victor@mojatatu.com>
> >>> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
> >>
> >> Looks good, thanks!
> >>
> >> Please note that sashiko/gemini found a pre-existing issues which may
> >> require a follow-up/separate fix:
> >>
> >> https://sashiko.dev/#/patchset/20260628111229.669751-1-jhs%40mojatatu.com
> >>
> >> (the 2nd one in the above link, IDK how to generate a direct link to a
> >> specific comment)
> >
> > I just sent v4 which covered that but i will send a followup instead
> > if you already applied.
>
> The PW bot is went on vacation and no 'patch applied' notification is
> reaching the ML; v3 is already applied.
>
> > BTW: What is the ruling on when Sashiko finds a pre-existing issue?
> > Should we address that as a separate follow-up patch? It is unclear
> > what the policy is.
>
> The general guidance is that pre-existing issues should be addressed
> separately.
>

Ok - i think it would help if this was documented somewhere..

> > This teql patch was one of the hardest to deal with in terms of
> > reproduciability and the fact sashiko kept coming up with pre-existing
> > issues - including the one Simon and I were discussing. Note: None of
> > the pre-existing issues affected reproducibility at all although i am
> > sure one of the AI-kiddies reading the sashiko reports will find a way
> > to create a poc (this is why i entertain fixing them when they look
> > simple enough)
> Not an ideal situation both ways (which is increasingly the case).
>
> Addressing incrementally pre-existing issues can lead to an huge/endless
> number of iterations when touching some unfortunate area (4 is _not_ a
> big number ;) delaying the actual fix indefinitely.
>

Agreed. I guess i get anxious the AI-kiddies seem to be following
sashiko and as soon as it complains about something they immediately
followup looking for new vectors and i feel like i will be going back
to fixing the next issue ;->

I just sent a followup.

cheers,
jamal
> /P
>
>

^ permalink raw reply

* Re: [PATCH 3/3] net: stmmac: dwmac-socfpga: Add mac-mode DT property support
From: Nazle Asmade, Muhammad Nazim Amirul @ 2026-06-30 15:13 UTC (permalink / raw)
  To: Maxime Chevallier, Andrew Lunn
  Cc: dinguyen@kernel.org, rmk+kernel@armlinux.org.uk,
	krzk+dt@kernel.org, conor+dt@kernel.org, robh@kernel.org,
	davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
	pabeni@redhat.com, andrew+netdev@lunn.ch,
	devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <7c57bb08-b72d-44bf-be44-f1bcb2aa9a84@bootlin.com>

On 30/6/2026 10:04 pm, Maxime Chevallier wrote:
> On 6/30/26 16:02, Andrew Lunn wrote:
>> On Tue, Jun 30, 2026 at 06:31:08AM -0700, muhammad.nazim.amirul.nazle.asmade@altera.com wrote:
>>> From: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
>>>
>>> Russell King's commit de696c63c1dc ("net: stmmac: socfpga: convert to
>>> use phy_interface") replaced mac_interface with phy_interface in
>>> socfpga_get_plat_phymode(), noting that no upstream DTS files set the
>>> "mac-mode" property, making the two values identical.
>>>
>>> The Agilex5 SoCDK TSN Config2 board is an exception: its gmac1 TSN
>>> port uses GMII internally in the MAC while the PHY-side interface is
>>> RGMII, so mac-mode and phy-mode differ.
>>
>> Maybe you need to represent the hardware block which magically
>> converts GMII to RGMII in DT?
> 
> Yeah that's what we have on CycloneV, and we force the INTF_SEL to GMII if that
> HW block is present. I wonder if there's the same on agileX5 ?

Hi Maxime, Andrew

Yes, Agilex5 has the same concept. The GMII-to-RGMII converter is a 
Quartus soft IP instantiated in the FPGA fabric — equivalent to the 
CycloneV EMAC splitter. The XGMAC outputs GMII signals to the FPGA 
fabric, the soft IP converts them to RGMII, and the RGMII signals then 
go through the FPGA HVIO pins to the external Marvell 88E1512 PHY.

BR,
Nazim>
>>
>> 	 Andrew
> 


^ permalink raw reply

* Re: [PATCH net 2/3] net/sched: Handle TC_ACT_REDIRECT from qdisc filter chains
From: Jamal Hadi Salim @ 2026-06-30 15:16 UTC (permalink / raw)
  To: Daniel Borkmann
  Cc: kuba, pabeni, bigeasy, andrii, memxor, bpf, netdev,
	Victor Nogueira
In-Reply-To: <20260630123331.186840-3-daniel@iogearbox.net>

On Tue, Jun 30, 2026 at 8:33 AM Daniel Borkmann <daniel@iogearbox.net> wrote:
>
> From: Jamal Hadi Salim <jhs@mojatatu.com>
>
> When a TC filter attached to a qdisc filter chain returns
> TC_ACT_REDIRECT (ex: via an eBPF program calling bpf_redirect() or an
> act_bpf action), the redirect was silently lost i.e no qdisc classify
> function handled TC_ACT_REDIRECT, so the packet fell through the
> switch and was enqueued normally instead of being redirected.
>
> This has been broken since bpf_redirect() was introduced for TC in
> commit 27b29f63058d ("bpf: add bpf_redirect() helper"). We got lucky
> for a long time because bpf_net_context was a per-CPU variable that
> was always available.
>
> commit 401cb7dae813 ("net: Reference bpf_redirect_info via task_struct
> on PREEMPT_RT.") turned bpf_net_context into a task_struct member that
> is only set up by explicit callers. Without a caller setting it up,
> bpf_redirect() itself crashes with a NULL pointer dereference in
> bpf_net_ctx_get_ri(). However, even with bpf_net_context available,
> TC_ACT_REDIRECT from qdisc filter chains cannot be honored without
> adding skb_do_redirect() calls to every qdisc classify function, which
> would require changes across net/sched/. Isolate it to ebpf core where
> it belongs.
>
> Instead, add a tcf_classify_qdisc() inline helper in pkt_cls.h, as a
> wrapper around tcf_classify() for use by qdisc classify functions and
> tcf_qevent_handle(). When the classify verdict is TC_ACT_REDIRECT,
> the wrapper converts it to TC_ACT_SHOT, dropping the packet rather
> than letting it continue silently. Dropping is preferred over
> letting the packet through because the user immediately sees packet
> loss. Silently passing the packet through would hide the problem and
> leave the user wondering why their redirect is not working.
>
> The clsact fast path, tc_run() continues to call tcf_classify() directly
> and is unaffected: TC_ACT_REDIRECT is returned as-is and handled by
> sch_handle_egress/ingress() calling skb_do_redirect() as before.
>
> Fixes: 27b29f63058d ("bpf: add bpf_redirect() helper")
> Fixes: 401cb7dae813 ("net: Reference bpf_redirect_info via task_struct on PREEMPT_RT.")
> Tested-by: Victor Nogueira <victor@mojatatu.com>
> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
> ---
>  include/net/pkt_cls.h    | 14 +++++++++++++-
>  net/sched/cls_api.c      |  4 +---
>  net/sched/sch_cake.c     |  2 +-
>  net/sched/sch_drr.c      |  2 +-
>  net/sched/sch_dualpi2.c  |  2 +-
>  net/sched/sch_ets.c      |  2 +-
>  net/sched/sch_fq_codel.c |  2 +-
>  net/sched/sch_fq_pie.c   |  2 +-
>  net/sched/sch_hfsc.c     |  2 +-
>  net/sched/sch_htb.c      |  2 +-
>  net/sched/sch_multiq.c   |  2 +-
>  net/sched/sch_prio.c     |  2 +-
>  net/sched/sch_qfq.c      |  2 +-
>  net/sched/sch_sfb.c      |  2 +-
>  net/sched/sch_sfq.c      |  2 +-
>  15 files changed, 27 insertions(+), 17 deletions(-)
>
> diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
> index 3bd08d7f39c1..5f5cb36439fe 100644
> --- a/include/net/pkt_cls.h
> +++ b/include/net/pkt_cls.h
> @@ -156,8 +156,20 @@ static inline int tcf_classify(struct sk_buff *skb,
>  {
>         return TC_ACT_UNSPEC;
>  }
> -
>  #endif
> +static inline int tcf_classify_qdisc(struct sk_buff *skb,
> +                                    const struct tcf_proto *tp,
> +                                    struct tcf_result *res, bool compat_mode)
> +{
> +       int ret = tcf_classify(skb, NULL, tp, res, compat_mode);
> +
> +       /* TC_ACT_REDIRECT from qdisc filter chains is not supported.
> +        * Use BPF via tcx or mirred redirect instead.
> +        */
> +       if (unlikely(ret == TC_ACT_REDIRECT))
> +               ret = TC_ACT_SHOT;
> +       return ret;
> +}
>


Why did you remove the warning?
A lesser issue is that you introduced a space above #endif

cheers,
jamal
>  static inline unsigned long
>  __cls_set_class(unsigned long *clp, unsigned long cl)
> diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
> index ac49ca6d9a0c..3ca56d060e28 100644
> --- a/net/sched/cls_api.c
> +++ b/net/sched/cls_api.c
> @@ -4033,9 +4033,7 @@ struct sk_buff *tcf_qevent_handle(struct tcf_qevent *qe, struct Qdisc *sch, stru
>
>         fl = rcu_dereference_bh(qe->filter_chain);
>
> -       switch (tcf_classify(skb, NULL, fl, &cl_res, false)) {
> -       case TC_ACT_REDIRECT:
> -               fallthrough;
> +       switch (tcf_classify_qdisc(skb, fl, &cl_res, false)) {
>         case TC_ACT_SHOT:
>                 qdisc_qstats_drop(sch);
>                 __qdisc_drop(skb, to_free);
> diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c
> index a3c185505afc..94eb47ac54ee 100644
> --- a/net/sched/sch_cake.c
> +++ b/net/sched/sch_cake.c
> @@ -1730,7 +1730,7 @@ static u32 cake_classify(struct Qdisc *sch, struct cake_tin_data **t,
>                 goto hash;
>
>         *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
> -       result = tcf_classify(skb, NULL, filter, &res, false);
> +       result = tcf_classify_qdisc(skb, filter, &res, false);
>
>         if (result >= 0) {
>  #ifdef CONFIG_NET_CLS_ACT
> diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c
> index 020657f959b5..91b1ef824afa 100644
> --- a/net/sched/sch_drr.c
> +++ b/net/sched/sch_drr.c
> @@ -312,7 +312,7 @@ static struct drr_class *drr_classify(struct sk_buff *skb, struct Qdisc *sch,
>
>         *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
>         fl = rcu_dereference_bh(q->filter_list);
> -       result = tcf_classify(skb, NULL, fl, &res, false);
> +       result = tcf_classify_qdisc(skb, fl, &res, false);
>         if (result >= 0) {
>  #ifdef CONFIG_NET_CLS_ACT
>                 switch (result) {
> diff --git a/net/sched/sch_dualpi2.c b/net/sched/sch_dualpi2.c
> index 5434df6ca8ef..98364f74211e 100644
> --- a/net/sched/sch_dualpi2.c
> +++ b/net/sched/sch_dualpi2.c
> @@ -364,7 +364,7 @@ static int dualpi2_skb_classify(struct dualpi2_sched_data *q,
>                 return NET_XMIT_SUCCESS;
>         }
>
> -       result = tcf_classify(skb, NULL, fl, &res, false);
> +       result = tcf_classify_qdisc(skb, fl, &res, false);
>         if (result >= 0) {
>  #ifdef CONFIG_NET_CLS_ACT
>                 switch (result) {
> diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c
> index cb8cf437ce87..25fcf4079fec 100644
> --- a/net/sched/sch_ets.c
> +++ b/net/sched/sch_ets.c
> @@ -391,7 +391,7 @@ static struct ets_class *ets_classify(struct sk_buff *skb, struct Qdisc *sch,
>         *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
>         if (TC_H_MAJ(skb->priority) != sch->handle) {
>                 fl = rcu_dereference_bh(q->filter_list);
> -               err = tcf_classify(skb, NULL, fl, &res, false);
> +               err = tcf_classify_qdisc(skb, fl, &res, false);
>  #ifdef CONFIG_NET_CLS_ACT
>                 switch (err) {
>                 case TC_ACT_STOLEN:
> diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c
> index cafd1f943d99..6cce86ba383c 100644
> --- a/net/sched/sch_fq_codel.c
> +++ b/net/sched/sch_fq_codel.c
> @@ -91,7 +91,7 @@ static unsigned int fq_codel_classify(struct sk_buff *skb, struct Qdisc *sch,
>                 return fq_codel_hash(q, skb) + 1;
>
>         *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
> -       result = tcf_classify(skb, NULL, filter, &res, false);
> +       result = tcf_classify_qdisc(skb, filter, &res, false);
>         if (result >= 0) {
>  #ifdef CONFIG_NET_CLS_ACT
>                 switch (result) {
> diff --git a/net/sched/sch_fq_pie.c b/net/sched/sch_fq_pie.c
> index 72f48fa4010b..069e1facd413 100644
> --- a/net/sched/sch_fq_pie.c
> +++ b/net/sched/sch_fq_pie.c
> @@ -96,7 +96,7 @@ static unsigned int fq_pie_classify(struct sk_buff *skb, struct Qdisc *sch,
>                 return fq_pie_hash(q, skb) + 1;
>
>         *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
> -       result = tcf_classify(skb, NULL, filter, &res, false);
> +       result = tcf_classify_qdisc(skb, filter, &res, false);
>         if (result >= 0) {
>  #ifdef CONFIG_NET_CLS_ACT
>                 switch (result) {
> diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
> index 7e537295b8b6..e87f5021a199 100644
> --- a/net/sched/sch_hfsc.c
> +++ b/net/sched/sch_hfsc.c
> @@ -1143,7 +1143,7 @@ hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
>         *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
>         head = &q->root;
>         tcf = rcu_dereference_bh(q->root.filter_list);
> -       while (tcf && (result = tcf_classify(skb, NULL, tcf, &res, false)) >= 0) {
> +       while (tcf && (result = tcf_classify_qdisc(skb, tcf, &res, false)) >= 0) {
>  #ifdef CONFIG_NET_CLS_ACT
>                 switch (result) {
>                 case TC_ACT_QUEUED:
> diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
> index 908b9ba9ba2e..fdac0dc8f35a 100644
> --- a/net/sched/sch_htb.c
> +++ b/net/sched/sch_htb.c
> @@ -243,7 +243,7 @@ static struct htb_class *htb_classify(struct sk_buff *skb, struct Qdisc *sch,
>         }
>
>         *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
> -       while (tcf && (result = tcf_classify(skb, NULL, tcf, &res, false)) >= 0) {
> +       while (tcf && (result = tcf_classify_qdisc(skb, tcf, &res, false)) >= 0) {
>  #ifdef CONFIG_NET_CLS_ACT
>                 switch (result) {
>                 case TC_ACT_QUEUED:
> diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
> index 4e465d11e3d7..004f0d275caf 100644
> --- a/net/sched/sch_multiq.c
> +++ b/net/sched/sch_multiq.c
> @@ -36,7 +36,7 @@ multiq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
>         int err;
>
>         *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
> -       err = tcf_classify(skb, NULL, fl, &res, false);
> +       err = tcf_classify_qdisc(skb, fl, &res, false);
>  #ifdef CONFIG_NET_CLS_ACT
>         switch (err) {
>         case TC_ACT_STOLEN:
> diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
> index e4dd56a89072..79437c587e7e 100644
> --- a/net/sched/sch_prio.c
> +++ b/net/sched/sch_prio.c
> @@ -39,7 +39,7 @@ prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
>         *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
>         if (TC_H_MAJ(skb->priority) != sch->handle) {
>                 fl = rcu_dereference_bh(q->filter_list);
> -               err = tcf_classify(skb, NULL, fl, &res, false);
> +               err = tcf_classify_qdisc(skb, fl, &res, false);
>  #ifdef CONFIG_NET_CLS_ACT
>                 switch (err) {
>                 case TC_ACT_STOLEN:
> diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
> index cb56787e1d25..6f3b7273cb16 100644
> --- a/net/sched/sch_qfq.c
> +++ b/net/sched/sch_qfq.c
> @@ -709,7 +709,7 @@ static struct qfq_class *qfq_classify(struct sk_buff *skb, struct Qdisc *sch,
>
>         *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
>         fl = rcu_dereference_bh(q->filter_list);
> -       result = tcf_classify(skb, NULL, fl, &res, false);
> +       result = tcf_classify_qdisc(skb, fl, &res, false);
>         if (result >= 0) {
>  #ifdef CONFIG_NET_CLS_ACT
>                 switch (result) {
> diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c
> index b1d465094276..ed39869199c0 100644
> --- a/net/sched/sch_sfb.c
> +++ b/net/sched/sch_sfb.c
> @@ -260,7 +260,7 @@ static bool sfb_classify(struct sk_buff *skb, struct tcf_proto *fl,
>         struct tcf_result res;
>         int result;
>
> -       result = tcf_classify(skb, NULL, fl, &res, false);
> +       result = tcf_classify_qdisc(skb, fl, &res, false);
>         if (result >= 0) {
>  #ifdef CONFIG_NET_CLS_ACT
>                 switch (result) {
> diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
> index 758b88f21865..77675f9a4c46 100644
> --- a/net/sched/sch_sfq.c
> +++ b/net/sched/sch_sfq.c
> @@ -171,7 +171,7 @@ static unsigned int sfq_classify(struct sk_buff *skb, struct Qdisc *sch,
>                 return sfq_hash(q, skb) + 1;
>
>         *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
> -       result = tcf_classify(skb, NULL, fl, &res, false);
> +       result = tcf_classify_qdisc(skb, fl, &res, false);
>         if (result >= 0) {
>  #ifdef CONFIG_NET_CLS_ACT
>                 switch (result) {
> --
> 2.43.0
>

^ permalink raw reply

* Re: [PATCH net 2/3] net/sched: Handle TC_ACT_REDIRECT from qdisc filter chains
From: Daniel Borkmann @ 2026-06-30 15:23 UTC (permalink / raw)
  To: Jamal Hadi Salim
  Cc: kuba, pabeni, bigeasy, andrii, memxor, bpf, netdev,
	Victor Nogueira
In-Reply-To: <CAM0EoMn6H6cKCweHmt=8ve2i0JuK=E8W1Q89oqDD7vra_Uuk-w@mail.gmail.com>

On 6/30/26 5:16 PM, Jamal Hadi Salim wrote:
> On Tue, Jun 30, 2026 at 8:33 AM Daniel Borkmann <daniel@iogearbox.net> wrote:
>> From: Jamal Hadi Salim <jhs@mojatatu.com>
>>
>> When a TC filter attached to a qdisc filter chain returns
>> TC_ACT_REDIRECT (ex: via an eBPF program calling bpf_redirect() or an
>> act_bpf action), the redirect was silently lost i.e no qdisc classify
>> function handled TC_ACT_REDIRECT, so the packet fell through the
>> switch and was enqueued normally instead of being redirected.
>>
>> This has been broken since bpf_redirect() was introduced for TC in
>> commit 27b29f63058d ("bpf: add bpf_redirect() helper"). We got lucky
>> for a long time because bpf_net_context was a per-CPU variable that
>> was always available.
>>
>> commit 401cb7dae813 ("net: Reference bpf_redirect_info via task_struct
>> on PREEMPT_RT.") turned bpf_net_context into a task_struct member that
>> is only set up by explicit callers. Without a caller setting it up,
>> bpf_redirect() itself crashes with a NULL pointer dereference in
>> bpf_net_ctx_get_ri(). However, even with bpf_net_context available,
>> TC_ACT_REDIRECT from qdisc filter chains cannot be honored without
>> adding skb_do_redirect() calls to every qdisc classify function, which
>> would require changes across net/sched/. Isolate it to ebpf core where
>> it belongs.
>>
>> Instead, add a tcf_classify_qdisc() inline helper in pkt_cls.h, as a
>> wrapper around tcf_classify() for use by qdisc classify functions and
>> tcf_qevent_handle(). When the classify verdict is TC_ACT_REDIRECT,
>> the wrapper converts it to TC_ACT_SHOT, dropping the packet rather
>> than letting it continue silently. Dropping is preferred over
>> letting the packet through because the user immediately sees packet
>> loss. Silently passing the packet through would hide the problem and
>> leave the user wondering why their redirect is not working.
>>
>> The clsact fast path, tc_run() continues to call tcf_classify() directly
>> and is unaffected: TC_ACT_REDIRECT is returned as-is and handled by
>> sch_handle_egress/ingress() calling skb_do_redirect() as before.
>>
>> Fixes: 27b29f63058d ("bpf: add bpf_redirect() helper")
>> Fixes: 401cb7dae813 ("net: Reference bpf_redirect_info via task_struct on PREEMPT_RT.")
>> Tested-by: Victor Nogueira <victor@mojatatu.com>
>> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
>> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
>> ---
>>   include/net/pkt_cls.h    | 14 +++++++++++++-
>>   net/sched/cls_api.c      |  4 +---
>>   net/sched/sch_cake.c     |  2 +-
>>   net/sched/sch_drr.c      |  2 +-
>>   net/sched/sch_dualpi2.c  |  2 +-
>>   net/sched/sch_ets.c      |  2 +-
>>   net/sched/sch_fq_codel.c |  2 +-
>>   net/sched/sch_fq_pie.c   |  2 +-
>>   net/sched/sch_hfsc.c     |  2 +-
>>   net/sched/sch_htb.c      |  2 +-
>>   net/sched/sch_multiq.c   |  2 +-
>>   net/sched/sch_prio.c     |  2 +-
>>   net/sched/sch_qfq.c      |  2 +-
>>   net/sched/sch_sfb.c      |  2 +-
>>   net/sched/sch_sfq.c      |  2 +-
>>   15 files changed, 27 insertions(+), 17 deletions(-)
>>
>> diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
>> index 3bd08d7f39c1..5f5cb36439fe 100644
>> --- a/include/net/pkt_cls.h
>> +++ b/include/net/pkt_cls.h
>> @@ -156,8 +156,20 @@ static inline int tcf_classify(struct sk_buff *skb,
>>   {
>>          return TC_ACT_UNSPEC;
>>   }
>> -
>>   #endif
>> +static inline int tcf_classify_qdisc(struct sk_buff *skb,
>> +                                    const struct tcf_proto *tp,
>> +                                    struct tcf_result *res, bool compat_mode)
>> +{
>> +       int ret = tcf_classify(skb, NULL, tp, res, compat_mode);
>> +
>> +       /* TC_ACT_REDIRECT from qdisc filter chains is not supported.
>> +        * Use BPF via tcx or mirred redirect instead.
>> +        */
>> +       if (unlikely(ret == TC_ACT_REDIRECT))
>> +               ret = TC_ACT_SHOT;
>> +       return ret;
>> +}
> 
> Why did you remove the warning?
> A lesser issue is that you introduced a space above #endif

I don't think we need to put out an extra warn to spam the log, this
can be easily traced either via bpftrace or qdisc stats etc; plus the
guidance to eBPF with clsact is also obsolete. Given noone has run
into this the last 10y, I don't think it really matters tbh.

Thanks,
Daniel

^ permalink raw reply

* [ANN] netdev foundation TSC meeting notes - Jun 30th
From: Jakub Kicinski @ 2026-06-30 15:25 UTC (permalink / raw)
  To: netdev

Present: Eric, Jakub, Johannes, Kuniyuki, Simon, Willem, Paolo

Academic Research program
  - Revised with:
    - Limit of USD 50k/grant
    - Simon as email contact (happy for an alias to be created instead)
  - Contacted board for funding approval, expect them to meet in
    coming weeks to discuss 

Netconf: 
 - on the first day of Netdev 0x1A. 13th July
 - Have room for ~20 people
 - Finalizing invites today / tomorrow
 - Driver upstreaming challenges, some drivers reaching v50
   - May be more suitable for a broader discussion / driver BoF?
 - Foundation sponsorship for a meal
   - Double check what netdev.conf has planned

Logo
 - Some delay in paperwork due to the complexity of it
 - Now aiming for LPC rather than Netdev
 - Comments on the draft sheet
   - Mesh in the background would be good to represent networking
   - Yes on tux, otherwise the logs are generic, but need a distinct one
   - A voting sheeting to grade the suggestions to be circulated

Wireless CI running on netdev foundation infra

^ permalink raw reply

* Re: [PATCH 2/3] arm64: dts: socfpga: agilex5: Add SoCDK TSN Config2 board
From: Andrew Lunn @ 2026-06-30 15:25 UTC (permalink / raw)
  To: Nazle Asmade, Muhammad Nazim Amirul
  Cc: dinguyen@kernel.org, maxime.chevallier@bootlin.com,
	rmk+kernel@armlinux.org.uk, krzk+dt@kernel.org,
	conor+dt@kernel.org, robh@kernel.org, davem@davemloft.net,
	edumazet@google.com, kuba@kernel.org, pabeni@redhat.com,
	andrew+netdev@lunn.ch, devicetree@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <347c50ed-234a-4f29-b63a-1e0010c6b09d@altera.com>

On Tue, Jun 30, 2026 at 02:39:50PM +0000, Nazle Asmade, Muhammad Nazim Amirul wrote:
> On 30/6/2026 9:58 pm, Andrew Lunn wrote:
> >> + * gmac1 is the TSN port. The MAC operates in GMII mode internally
> >> + * while the PHY-side interface is RGMII, so mac-mode and phy-mode differ.
> >> + */
> >> +&gmac1 {
> >> +	status = "okay";
> >> +	phy-mode = "rgmii"; /* TX/RX clock delays provided by Agilex5 I/O hardware */
> > Could you provide more details about this. I want to understand the
> > big picture.
> > 
> > Normally we talk about the PCB providing the delays. This sounds like
> > it is the FPGA? So i need convincing this is correct.
> Hi Andrew,
> 
> Thanks for your quick review and yes, it is the FPGA — specifically a 
> soft IP block in the FPGA fabric that implements the RGMII clock delays 
> and is configured before Linux boots via the FPGA bitstream. The driver 
> must not add additional delays on top.

So it depends on how the converter block is described, but ....

From a big picture, MAC and PHY pair, it is the MAC which
implements the delays.

https://elixir.bootlin.com/linux/v6.15/source/Documentation/devicetree/bindings/net/ethernet-controller.yaml#L346

# There are a small number of cases where the MAC has hard coded
# delays which cannot be disabled. The 'phy-mode' only describes the
# PCB.  The inability to disable the delays in the MAC does not change
# the meaning of 'phy-mode'. It does however mean that a 'phy-mode' of
# 'rgmii' is now invalid, it cannot be supported, since both the PCB
# and the MAC and PHY adding delays cannot result in a functional
# link. Thus the MAC should report a fatal error for any modes which
# cannot be supported. When the MAC implements the delay, it must
# ensure that the PHY does not also implement the same delay. So it
# must modify the phy-mode it passes to the PHY, removing the delay it
# has added. Failure to remove the delay will result in a
# non-functioning link.

    Andrew

---
pw-bot: cr

^ permalink raw reply

* Re: [PATCH v2 10/19] pmdomain: imx: use platform_device_set_of_node()
From: Frank Li @ 2026-06-30 15:27 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Lee Jones, Mark Brown, Thierry Reding, Sebastian Hesselbarth,
	Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Srinivas Kandagatla, Greg Kroah-Hartman, Vinod Koul,
	Rafael J. Wysocki, Danilo Krummrich, Rob Herring, Saravana Kannan,
	Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
	Christophe Leroy (CS GROUP), Andi Shyti, Andy Shevchenko,
	Joerg Roedel, Will Deacon, Robin Murphy, Doug Berger,
	Florian Fainelli, Broadcom internal kernel review list,
	Ulf Hansson, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Matthew Brost, Thomas Hellström, Rodrigo Vivi,
	David Airlie, Simona Vetter, Peter Chen, Paul Cercueil, Bin Liu,
	Philipp Zabel, Maximilian Luz, Hans de Goede, Ilpo Järvinen,
	Krzysztof Kozlowski, Benjamin Herrenschmidt, brgl, linux-kernel,
	netdev, linux-arm-msm, linux-sound, driver-core, devicetree,
	linuxppc-dev, linux-i2c, iommu, linux-pm, imx, linux-arm-kernel,
	intel-xe, dri-devel, linux-usb, linux-mips, platform-driver-x86
In-Reply-To: <20260629-pdev-fwnode-ref-v2-10-8abe2513f96e@oss.qualcomm.com>

On Mon, Jun 29, 2026 at 11:12:33AM +0200, Bartosz Golaszewski wrote:
>
> Ahead of reworking the reference counting logic for platform devices,
> encapsulate the assignment of the OF node for dynamically allocated
> platform devices with the provided helper.
>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/pmdomain/imx/gpc.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/pmdomain/imx/gpc.c b/drivers/pmdomain/imx/gpc.c
> index 42e50c9b4fb9ffb96a20a462d4eb5168942a893c..abca5f449a226fbae4213926e1395c413160c950 100644
> --- a/drivers/pmdomain/imx/gpc.c
> +++ b/drivers/pmdomain/imx/gpc.c
> @@ -487,8 +487,7 @@ static int imx_gpc_probe(struct platform_device *pdev)
>                         domain->ipg_rate_mhz = ipg_rate_mhz;
>
>                         pd_pdev->dev.parent = &pdev->dev;
> -                       pd_pdev->dev.of_node = of_node_get(np);
> -                       pd_pdev->dev.fwnode = of_fwnode_handle(np);
> +                       platform_device_set_of_node(pd_pdev, np);
>
>                         ret = platform_device_add(pd_pdev);
>                         if (ret) {
>
> --
> 2.47.3
>
>

^ permalink raw reply

* Re: [PATCH net-next v5 14/15] dt-bindings: net: add onsemi's S2500
From: Rob Herring @ 2026-06-30 15:29 UTC (permalink / raw)
  To: Selvamani Rajagopal
  Cc: Andrew Lunn, Piergiorgio Beruto, Heiner Kallweit, Russell King,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Andrew Lunn, Parthiban Veerasooran, Richard Cochran,
	Krzysztof Kozlowski, Conor Dooley, Simon Horman, Jonathan Corbet,
	Shuah Khan, netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	devicetree@vger.kernel.org, linux-doc@vger.kernel.org, Jerry Ray
In-Reply-To: <CYYPR02MB9828308552BBC60427E8EF2283E82@CYYPR02MB9828.namprd02.prod.outlook.com>

On Mon, Jun 29, 2026 at 12:07 PM Selvamani Rajagopal
<Selvamani.Rajagopal@onsemi.com> wrote:
>
> > -----Original Message-----
> > From: Rob Herring <robh@kernel.org>
> > Sent: Sunday, June 14, 2026 9:11 PM
> > To: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
> > Subject: Re: [PATCH net-next v5 14/15] dt-bindings: net: add onsemi's S2500
> >
> >
> >
> > And you are missing tags from prior versions. It is your responsibility
> > to add them.
>
> I added the prior version's link under each version. Somehow "b4 prep --show-revision" command doesn't pickup the older
> versions. It shows v4 and v5 correctly as the emails containing patches were sent in a threaded manner.
>
> But with v1,v2,v3, as each patch was sent through individual email (with proper subject line, of course) using outlook.
> I don't know if there is a way to fix this.

While links to prior versions is nice, tags means Reviewed-by,
Acked-by, etc. lines. If you get those on version N, then you have to
add them on version N+1 and later unless there are significant changes
that nullify them. However, you don't need to send another version
only to add tags. The tools will pickup tags from the current version.

The only advice for outlook is don't use it. It is incapable of
following maillist etiquette.

Rob

^ permalink raw reply

* [PATCH net] selftests/tc-testing: Add tests that force multiq and taprio to enqueue to child's gso_skb
From: Victor Nogueira @ 2026-06-30 15:36 UTC (permalink / raw)
  To: davem, edumazet, kuba, pabeni, jhs, jiri
  Cc: netdev, hexlabsecurity, pctammela

Add test cases to reproduce scenarios fixed recently [1] where
multiqueue and taprio forced their children into enqueueing an skb to
gso_skb (during peek), but failed to dequeue from gso_skb because they
called the child's dequeue callback directly. This causes a desync in the
child's qlen/backlog and results in an eventual null-ptr-deref (with a
qfq or dualpi2 child).

Test cases are the following:

- Force multiq to dequeue from its child's gso_skb with qfq leaf (fb6c)
- Force multiq to dequeue from its child's gso_skb with dualpi2 leaf (1922)
- Force taprio to dequeue from its child's gso_skb with qfq leaf (476f)
- Force taprio to dequeue from its child's gso_skb with dualpi2 leaf (0235)

[1] https://lore.kernel.org/netdev/20260625-b4-disp-31bcb279-v1-0-85c40b83c529@proton.me/

Signed-off-by: Victor Nogueira <victor@mojatatu.com>
---
 .../tc-testing/tc-tests/infra/qdiscs.json     | 164 ++++++++++++++++++
 1 file changed, 164 insertions(+)

diff --git a/tools/testing/selftests/tc-testing/tc-tests/infra/qdiscs.json b/tools/testing/selftests/tc-testing/tc-tests/infra/qdiscs.json
index a1f97a4b606e..0cf12c50fb74 100644
--- a/tools/testing/selftests/tc-testing/tc-tests/infra/qdiscs.json
+++ b/tools/testing/selftests/tc-testing/tc-tests/infra/qdiscs.json
@@ -1540,5 +1540,169 @@
             "$TC qdisc del dev $DUMMY root",
             "$IP addr del 10.10.10.10/24 dev $DUMMY || true"
         ]
+    },
+    {
+        "id": "fb6c",
+        "name": "Force multiq to dequeue from its child's gso_skb with qfq leaf",
+        "category": [
+            "qdisc",
+            "tbf",
+            "multiq",
+            "qfq"
+        ],
+        "plugins": {
+            "requires": "nsPlugin"
+        },
+        "setup": [
+            "echo \"1 1 4\" > /sys/bus/netdevsim/new_device",
+            "$IP link set dev $ETH up || true",
+            "$IP l set addr 01:02:03:04:05:06 dev $ETH || true",
+            "$IP n add dev $ETH 10.10.11.1 lladdr 01:02:03:04:05:06 dev $ETH || true",
+            "$IP addr add 10.10.11.10/24 dev $ETH || true",
+            "$TC qdisc add dev $ETH root handle 1: tbf rate 88bit burst 1661b peakrate 2257333 minburst 1024 limit 7b",
+            "$TC qdisc add dev $ETH parent 1: handle 2: multiq",
+            "$TC qdisc add dev $ETH parent 2:1 handle 3: qfq",
+            "$TC class add dev $ETH classid 3:1 parent 3: qfq maxpkt 512 weight 1",
+            "$TC filter add dev $ETH parent 2: protocol all prio 1 matchall action skbedit queue_mapping 0",
+            "$TC filter add dev $ETH parent 3: protocol all prio 1 matchall classid 3:1 action ok"
+        ],
+        "cmdUnderTest": "ping -c 1 10.10.11.1 -W0.01 -I$ETH || true",
+        "expExitCode": "0",
+        "verifyCmd": "$TC -s -j qdisc ls dev $ETH parent 1:",
+        "matchJSON": [
+            {
+                "kind": "multiq",
+                "handle": "2:",
+                "bytes": 98,
+                "packets": 1,
+                "backlog": 0,
+                "qlen": 0
+            }
+        ],
+        "teardown": [
+            "$TC qdisc del dev $ETH handle 1: root",
+            "echo \"1\" > /sys/bus/netdevsim/del_device"
+        ]
+    },
+    {
+        "id": "1922",
+        "name": "Force multiq to dequeue from its child's gso_skb with dualpi2 leaf",
+        "category": [
+            "qdisc",
+            "tbf",
+            "multiq",
+            "dualpi2"
+        ],
+        "plugins": {
+            "requires": "nsPlugin"
+        },
+        "setup": [
+            "echo \"1 1 4\" > /sys/bus/netdevsim/new_device",
+            "$IP link set dev $ETH up || true",
+            "$IP l set addr 01:02:03:04:05:06 dev $ETH || true",
+            "$IP n add dev $ETH 10.10.11.1 lladdr 01:02:03:04:05:06 dev $ETH || true",
+            "$IP addr add 10.10.11.10/24 dev $ETH || true",
+            "$TC qdisc add dev $ETH root handle 1: tbf rate 88bit burst 1661b peakrate 2257333 minburst 1024 limit 7b",
+            "$TC qdisc add dev $ETH parent 1: handle 2: multiq",
+            "$TC qdisc add dev $ETH parent 2:1 handle 3: dualpi2",
+            "$TC filter add dev $ETH parent 2: protocol ip prio 1 u32 match ip dst 10.10.11.1 action skbedit queue_mapping 0",
+            "$TC filter add dev $ETH parent 3: protocol ip prio 1 u32 match ip dst 10.10.11.1 classid 3:1 action ok"
+        ],
+        "cmdUnderTest": "ping -c 1 10.10.11.1 -W0.01 -I$ETH || true",
+        "expExitCode": "0",
+        "verifyCmd": "$TC -j -s qdisc ls dev $ETH handle 3:",
+        "matchJSON": [
+            {
+                "kind": "dualpi2",
+                "handle": "3:",
+                "bytes": 98,
+                "packets": 1,
+                "backlog": 0,
+                "qlen": 0
+            }
+        ],
+        "teardown": [
+            "$TC qdisc del dev $ETH handle 1: root",
+            "echo \"1\" > /sys/bus/netdevsim/del_device"
+        ]
+    },
+    {
+        "id": "476f",
+        "name": "Force taprio to dequeue from its child's gso_skb with qfq leaf",
+        "category": [
+            "qdisc",
+            "tbf",
+            "multiq",
+            "qfq"
+        ],
+        "plugins": {
+            "requires": "nsPlugin"
+        },
+        "setup": [
+            "echo \"1 1 4\" > /sys/bus/netdevsim/new_device",
+            "$IP link set dev $ETH up || true",
+            "$IP l set addr 01:02:03:04:05:06 dev $ETH || true",
+            "$IP n add dev $ETH 10.10.11.1 lladdr 01:02:03:04:05:06 dev $ETH || true",
+            "$TC qdisc add dev $ETH root handle 1: taprio num_tc 2 map 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 queues 1@0 1@1 base-time 9000000000000000000 sched-entry S 03 200000 flags 0x0 clockid CLOCK_TAI",
+            "$TC qdisc add dev $ETH parent 1:1 handle 3: qfq",
+            "$TC class add dev $ETH classid 3:1 parent 3: qfq maxpkt 512 weight 1",
+            "$TC filter add dev $ETH parent 3: protocol all prio 1 matchall classid 3:1 action ok"
+        ],
+        "cmdUnderTest": "ping -c 1 10.10.11.1 -W0.01 -I$ETH || true",
+        "expExitCode": "0",
+        "verifyCmd": "$TC -s -j qdisc ls dev $ETH",
+        "matchJSON": [
+            {
+                "kind": "taprio",
+                "handle": "1:",
+                "bytes": 98,
+                "packets": 1,
+                "backlog": 0,
+                "qlen": 0
+            }
+        ],
+        "teardown": [
+            "$TC qdisc del dev $ETH handle 1: root",
+            "echo \"1\" > /sys/bus/netdevsim/del_device"
+        ]
+    },
+    {
+        "id": "0235",
+        "name": "Force taprio to dequeue from its child's gso_skb with dualpi2 leaf",
+        "category": [
+            "qdisc",
+            "tbf",
+            "taprio",
+            "dualpi2"
+        ],
+        "plugins": {
+            "requires": "nsPlugin"
+        },
+        "setup": [
+            "echo \"1 1 4\" > /sys/bus/netdevsim/new_device",
+            "$IP link set dev $ETH up || true",
+            "$IP l set addr 01:02:03:04:05:06 dev $ETH || true",
+            "$IP n add dev $ETH 10.10.11.1 lladdr 01:02:03:04:05:06 dev $ETH || true",
+            "$TC qdisc add dev $ETH root handle 1: taprio num_tc 2 map 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 queues 1@0 1@1 base-time 9000000000000000000 sched-entry S 03 200000 flags 0x0 clockid CLOCK_TAI",
+            "$TC qdisc replace dev $ETH parent 1:1 handle 3: dualpi2",
+            "$TC filter add dev $ETH parent 3: protocol ip prio 1 u32 match ip dst 10.10.11.1 classid 3:1 action ok"
+        ],
+        "cmdUnderTest": "ping -c 1 10.10.11.1 -W0.01 -I$ETH || true",
+        "expExitCode": "0",
+        "verifyCmd": "$TC -j -s qdisc ls dev $ETH handle 3:",
+        "matchJSON": [
+            {
+                "kind": "dualpi2",
+                "handle": "3:",
+                "bytes": 98,
+                "packets": 1,
+                "backlog": 0,
+                "qlen": 0
+            }
+        ],
+        "teardown": [
+            "$TC qdisc del dev $ETH handle 1: root",
+            "echo \"1\" > /sys/bus/netdevsim/del_device"
+        ]
     }
 ]
-- 
2.54.0


^ permalink raw reply related

* Re: [PATCH 3/3] net: stmmac: dwmac-socfpga: Add mac-mode DT property support
From: Maxime Chevallier @ 2026-06-30 15:42 UTC (permalink / raw)
  To: Nazle Asmade, Muhammad Nazim Amirul, Andrew Lunn
  Cc: dinguyen@kernel.org, rmk+kernel@armlinux.org.uk,
	krzk+dt@kernel.org, conor+dt@kernel.org, robh@kernel.org,
	davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
	pabeni@redhat.com, andrew+netdev@lunn.ch,
	devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <b6c52ac8-32dc-4a58-83ec-ef600b306448@altera.com>



On 6/30/26 17:13, Nazle Asmade, Muhammad Nazim Amirul wrote:

> Yes, Agilex5 has the same concept. The GMII-to-RGMII converter is a 
> Quartus soft IP instantiated in the FPGA fabric — equivalent to the 
> CycloneV EMAC splitter. The XGMAC outputs GMII signals to the FPGA 
> fabric, the soft IP converts them to RGMII, and the RGMII signals then 
> go through the FPGA HVIO pins to the external Marvell 88E1512 PHY.

Does this converter need any special config, and does it expose any
control registers ? or is it fully autonomous ?

If it's fully autonomous, can you detect its presence through some
capability registers or something like that ?


Maxime


^ permalink raw reply

* Re: [PATCH net] selftests/tc-testing: Add tests that force multiq and taprio to enqueue to child's gso_skb
From: Pedro Tammela @ 2026-06-30 15:43 UTC (permalink / raw)
  To: Victor Nogueira, davem, edumazet, kuba, pabeni, jhs, jiri
  Cc: netdev, hexlabsecurity
In-Reply-To: <20260630153651.249752-1-victor@mojatatu.com>

On 30/06/2026 12:36, Victor Nogueira wrote:
> Add test cases to reproduce scenarios fixed recently [1] where
> multiqueue and taprio forced their children into enqueueing an skb to
> gso_skb (during peek), but failed to dequeue from gso_skb because they
> called the child's dequeue callback directly. This causes a desync in the
> child's qlen/backlog and results in an eventual null-ptr-deref (with a
> qfq or dualpi2 child).
> 
> Test cases are the following:
> 
> - Force multiq to dequeue from its child's gso_skb with qfq leaf (fb6c)
> - Force multiq to dequeue from its child's gso_skb with dualpi2 leaf (1922)
> - Force taprio to dequeue from its child's gso_skb with qfq leaf (476f)
> - Force taprio to dequeue from its child's gso_skb with dualpi2 leaf (0235)
> 
> [1] https://lore.kernel.org/netdev/20260625-b4-disp-31bcb279-v1-0-85c40b83c529@proton.me/
> 
> Signed-off-by: Victor Nogueira <victor@mojatatu.com>

Reviewed-by: Pedro Tammela <pctammela@mojatatu.com>

> ---
>   .../tc-testing/tc-tests/infra/qdiscs.json     | 164 ++++++++++++++++++
>   1 file changed, 164 insertions(+)
> 
> diff --git a/tools/testing/selftests/tc-testing/tc-tests/infra/qdiscs.json b/tools/testing/selftests/tc-testing/tc-tests/infra/qdiscs.json
> index a1f97a4b606e..0cf12c50fb74 100644
> --- a/tools/testing/selftests/tc-testing/tc-tests/infra/qdiscs.json
> +++ b/tools/testing/selftests/tc-testing/tc-tests/infra/qdiscs.json
> @@ -1540,5 +1540,169 @@
>               "$TC qdisc del dev $DUMMY root",
>               "$IP addr del 10.10.10.10/24 dev $DUMMY || true"
>           ]
> +    },
> +    {
> +        "id": "fb6c",
> +        "name": "Force multiq to dequeue from its child's gso_skb with qfq leaf",
> +        "category": [
> +            "qdisc",
> +            "tbf",
> +            "multiq",
> +            "qfq"
> +        ],
> +        "plugins": {
> +            "requires": "nsPlugin"
> +        },
> +        "setup": [
> +            "echo \"1 1 4\" > /sys/bus/netdevsim/new_device",
> +            "$IP link set dev $ETH up || true",
> +            "$IP l set addr 01:02:03:04:05:06 dev $ETH || true",
> +            "$IP n add dev $ETH 10.10.11.1 lladdr 01:02:03:04:05:06 dev $ETH || true",
> +            "$IP addr add 10.10.11.10/24 dev $ETH || true",
> +            "$TC qdisc add dev $ETH root handle 1: tbf rate 88bit burst 1661b peakrate 2257333 minburst 1024 limit 7b",
> +            "$TC qdisc add dev $ETH parent 1: handle 2: multiq",
> +            "$TC qdisc add dev $ETH parent 2:1 handle 3: qfq",
> +            "$TC class add dev $ETH classid 3:1 parent 3: qfq maxpkt 512 weight 1",
> +            "$TC filter add dev $ETH parent 2: protocol all prio 1 matchall action skbedit queue_mapping 0",
> +            "$TC filter add dev $ETH parent 3: protocol all prio 1 matchall classid 3:1 action ok"
> +        ],
> +        "cmdUnderTest": "ping -c 1 10.10.11.1 -W0.01 -I$ETH || true",
> +        "expExitCode": "0",
> +        "verifyCmd": "$TC -s -j qdisc ls dev $ETH parent 1:",
> +        "matchJSON": [
> +            {
> +                "kind": "multiq",
> +                "handle": "2:",
> +                "bytes": 98,
> +                "packets": 1,
> +                "backlog": 0,
> +                "qlen": 0
> +            }
> +        ],
> +        "teardown": [
> +            "$TC qdisc del dev $ETH handle 1: root",
> +            "echo \"1\" > /sys/bus/netdevsim/del_device"
> +        ]
> +    },
> +    {
> +        "id": "1922",
> +        "name": "Force multiq to dequeue from its child's gso_skb with dualpi2 leaf",
> +        "category": [
> +            "qdisc",
> +            "tbf",
> +            "multiq",
> +            "dualpi2"
> +        ],
> +        "plugins": {
> +            "requires": "nsPlugin"
> +        },
> +        "setup": [
> +            "echo \"1 1 4\" > /sys/bus/netdevsim/new_device",
> +            "$IP link set dev $ETH up || true",
> +            "$IP l set addr 01:02:03:04:05:06 dev $ETH || true",
> +            "$IP n add dev $ETH 10.10.11.1 lladdr 01:02:03:04:05:06 dev $ETH || true",
> +            "$IP addr add 10.10.11.10/24 dev $ETH || true",
> +            "$TC qdisc add dev $ETH root handle 1: tbf rate 88bit burst 1661b peakrate 2257333 minburst 1024 limit 7b",
> +            "$TC qdisc add dev $ETH parent 1: handle 2: multiq",
> +            "$TC qdisc add dev $ETH parent 2:1 handle 3: dualpi2",
> +            "$TC filter add dev $ETH parent 2: protocol ip prio 1 u32 match ip dst 10.10.11.1 action skbedit queue_mapping 0",
> +            "$TC filter add dev $ETH parent 3: protocol ip prio 1 u32 match ip dst 10.10.11.1 classid 3:1 action ok"
> +        ],
> +        "cmdUnderTest": "ping -c 1 10.10.11.1 -W0.01 -I$ETH || true",
> +        "expExitCode": "0",
> +        "verifyCmd": "$TC -j -s qdisc ls dev $ETH handle 3:",
> +        "matchJSON": [
> +            {
> +                "kind": "dualpi2",
> +                "handle": "3:",
> +                "bytes": 98,
> +                "packets": 1,
> +                "backlog": 0,
> +                "qlen": 0
> +            }
> +        ],
> +        "teardown": [
> +            "$TC qdisc del dev $ETH handle 1: root",
> +            "echo \"1\" > /sys/bus/netdevsim/del_device"
> +        ]
> +    },
> +    {
> +        "id": "476f",
> +        "name": "Force taprio to dequeue from its child's gso_skb with qfq leaf",
> +        "category": [
> +            "qdisc",
> +            "tbf",
> +            "multiq",
> +            "qfq"
> +        ],
> +        "plugins": {
> +            "requires": "nsPlugin"
> +        },
> +        "setup": [
> +            "echo \"1 1 4\" > /sys/bus/netdevsim/new_device",
> +            "$IP link set dev $ETH up || true",
> +            "$IP l set addr 01:02:03:04:05:06 dev $ETH || true",
> +            "$IP n add dev $ETH 10.10.11.1 lladdr 01:02:03:04:05:06 dev $ETH || true",
> +            "$TC qdisc add dev $ETH root handle 1: taprio num_tc 2 map 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 queues 1@0 1@1 base-time 9000000000000000000 sched-entry S 03 200000 flags 0x0 clockid CLOCK_TAI",
> +            "$TC qdisc add dev $ETH parent 1:1 handle 3: qfq",
> +            "$TC class add dev $ETH classid 3:1 parent 3: qfq maxpkt 512 weight 1",
> +            "$TC filter add dev $ETH parent 3: protocol all prio 1 matchall classid 3:1 action ok"
> +        ],
> +        "cmdUnderTest": "ping -c 1 10.10.11.1 -W0.01 -I$ETH || true",
> +        "expExitCode": "0",
> +        "verifyCmd": "$TC -s -j qdisc ls dev $ETH",
> +        "matchJSON": [
> +            {
> +                "kind": "taprio",
> +                "handle": "1:",
> +                "bytes": 98,
> +                "packets": 1,
> +                "backlog": 0,
> +                "qlen": 0
> +            }
> +        ],
> +        "teardown": [
> +            "$TC qdisc del dev $ETH handle 1: root",
> +            "echo \"1\" > /sys/bus/netdevsim/del_device"
> +        ]
> +    },
> +    {
> +        "id": "0235",
> +        "name": "Force taprio to dequeue from its child's gso_skb with dualpi2 leaf",
> +        "category": [
> +            "qdisc",
> +            "tbf",
> +            "taprio",
> +            "dualpi2"
> +        ],
> +        "plugins": {
> +            "requires": "nsPlugin"
> +        },
> +        "setup": [
> +            "echo \"1 1 4\" > /sys/bus/netdevsim/new_device",
> +            "$IP link set dev $ETH up || true",
> +            "$IP l set addr 01:02:03:04:05:06 dev $ETH || true",
> +            "$IP n add dev $ETH 10.10.11.1 lladdr 01:02:03:04:05:06 dev $ETH || true",
> +            "$TC qdisc add dev $ETH root handle 1: taprio num_tc 2 map 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 queues 1@0 1@1 base-time 9000000000000000000 sched-entry S 03 200000 flags 0x0 clockid CLOCK_TAI",
> +            "$TC qdisc replace dev $ETH parent 1:1 handle 3: dualpi2",
> +            "$TC filter add dev $ETH parent 3: protocol ip prio 1 u32 match ip dst 10.10.11.1 classid 3:1 action ok"
> +        ],
> +        "cmdUnderTest": "ping -c 1 10.10.11.1 -W0.01 -I$ETH || true",
> +        "expExitCode": "0",
> +        "verifyCmd": "$TC -j -s qdisc ls dev $ETH handle 3:",
> +        "matchJSON": [
> +            {
> +                "kind": "dualpi2",
> +                "handle": "3:",
> +                "bytes": 98,
> +                "packets": 1,
> +                "backlog": 0,
> +                "qlen": 0
> +            }
> +        ],
> +        "teardown": [
> +            "$TC qdisc del dev $ETH handle 1: root",
> +            "echo \"1\" > /sys/bus/netdevsim/del_device"
> +        ]
>       }
>   ]


^ permalink raw reply

* Re: [PATCH net] net: airoha: fix max receive size configuration
From: Paolo Abeni @ 2026-06-30 15:44 UTC (permalink / raw)
  To: Lorenzo Bianconi, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Simon Horman
  Cc: linux-arm-kernel, linux-mediatek, netdev, Madhur Agrawal
In-Reply-To: <20260625-airoha-fix-rx-max-len-v1-1-45b9b827358d@kernel.org>

On 6/25/26 8:49 AM, Lorenzo Bianconi wrote:
> Set the GDM maximum receive size to AIROHA_MAX_RX_SIZE unconditionally
> during hardware initialization instead of updating it according to the
> configured MTU. This avoids dropping incoming frames that exceed the
> current MTU but could still be processed by the networking stack, which
> is able to fragment the reply on the TX side (e.g. ICMP echo requests).
> Move the per-port MTU configuration to the PPE egress path where it
> belongs, and set the tx frame size running airoha_ppe_set_xmit_frame_size()
> to dynamically track the maximum MTU across running interfaces sharing
> the same PPE instance.
> Fix the PPE MTU register addressing to pack two port entries per
> register word and add WAN_MTU0 configuration for non-LAN GDM devices.
> 
> Fixes: 54d989d58d2a ("net: airoha: Move min/max packet len configuration in airoha_dev_open()")
> Tested-by: Madhur Agrawal <madhur.agrawal@airoha.com>
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>

PW bot is on holiday, no automated notifications for a while.

Applied, thanks!

/P


^ permalink raw reply

* Re: [PATCH net v2] net: libwx: fix VMDQ mask for 1-queue mode
From: Paolo Abeni @ 2026-06-30 15:46 UTC (permalink / raw)
  To: Jiawen Wu, netdev
  Cc: Mengyuan Lou, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Simon Horman, Jacob Keller, Kees Cook,
	Larysa Zaremba
In-Reply-To: <161F704D2C983E2C+20260626092530.551028-1-jiawenwu@trustnetic.com>

On 6/26/26 11:25 AM, Jiawen Wu wrote:
> In wx_set_vmdq_queues(), the VMDQ mask was not set for the devices not
> supporting WX_FLAG_MULTI_64_FUNC, i.e., NGBE devices. A mask of 0 causes
> __ALIGN_MASK(1, ~vmdq->mask) to return 0, which incorrectly sets
> q_per_pool to 0 in wx_write_qde().
> 
> Fix the VMDQ 1-queue mask to 0x7F then ensures that __ALIGN_MASK(1,
> ~0x7F) correctly evaluates to 1.
> 
> Fixes: c52d4b898901 ("net: libwx: Redesign flow when sriov is enabled")
> Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
> Reviewed-by: Larysa Zaremba <larysa.zaremba@intel.com>

The PW bot is on holiday, no automated notifications for a while.

Applied, thanks!

/P


^ permalink raw reply

* Re: [PATCH] net: lan743x: Initialize eth_syslock spinlock before use
From: Paolo Abeni @ 2026-06-30 15:47 UTC (permalink / raw)
  To: Andrea Righi, Bryan Whitehead, UNGLinuxDriver
  Cc: Andrew Lunn, David S . Miller, Eric Dumazet, Jakub Kicinski,
	Raju Lakkaraju, David Thompson, netdev, linux-kernel
In-Reply-To: <20260626163218.3591486-1-arighi@nvidia.com>

On 6/26/26 6:32 PM, Andrea Righi wrote:
> lan743x_hardware_init() calls pci11x1x_strap_get_status() during the
> PCI11x1x probe sequence. That helper acquires the Ethernet subsystem
> hardware lock via lan743x_hs_syslock_acquire(), which relies on
> adapter->eth_syslock_spinlock to serialize access.
> 
> The spinlock is currently initialized only after the strap status is
> read. With CONFIG_DEBUG_SPINLOCK enabled, taking the zeroed initialized
> spinlock can trip the spinlock debug check.
> 
> Fix by initializing adapter->eth_syslock_spinlock before reading the
> strap status so the probe path never attempts to lock an uninitialized
> spinlock.
> 
> Fixes: 46b777ad9a8c ("net: lan743x: Add support to SGMII 1G and 2.5G")
> Cc: stable@vger.kernel.org # v6.0+
> Signed-off-by: Andrea Righi <arighi@nvidia.com>

The PW bot is on holiday, no automated notifications for a while.

Applied, thanks!

/P


^ permalink raw reply

* Re: [PATCH net] net: gianfar: dispose irq mappings on probe failure and device removal
From: Paolo Abeni @ 2026-06-30 15:49 UTC (permalink / raw)
  To: Rosen Penev, netdev
  Cc: Claudiu Manoil, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Andy Fleming, open list
In-Reply-To: <20260626225228.427392-1-rosenp@gmail.com>

On 6/27/26 12:52 AM, Rosen Penev wrote:
> irq_of_parse_and_map() creates irqdomain mappings that should be
> balanced with irq_dispose_mapping(). The driver never called
> irq_dispose_mapping(), leaking mappings on probe failure and
> device removal.
> 
> Fix by adding irq_dispose_mapping() in free_gfar_dev() and
> expanding its loop from priv->num_grps to MAXGROUPS so the
> error path also catches partially-initialized groups. All
> irqinfo pointers are pre-initialized to NULL in gfar_of_init(),
> making the NULL-guarded walk in free_gfar_dev() safe for every
> scenario.
> 
> gfar_parse_group() itself is left as a simple parse function
> with no resource management; cleanup is centralized in the
> caller's error path.
> 
> Assisted-by: opencode:big-pickle
> Fixes: b31a1d8b4151 ("gianfar: Convert gianfar to an of_platform_driver")
> Signed-off-by: Rosen Penev <rosenp@gmail.com>

The PW bot is on holiday, no automated notifications for a while.

Applied, thanks!

/P


^ permalink raw reply

* Re: [PATCH net] bridge: stp: Fix a potential use-after-free when deleting a bridge
From: Paolo Abeni @ 2026-06-30 15:50 UTC (permalink / raw)
  To: Ido Schimmel, netdev, bridge; +Cc: davem, kuba, edumazet, razor, horms
In-Reply-To: <20260629072117.497959-1-idosch@nvidia.com>

On 6/29/26 9:21 AM, Ido Schimmel wrote:
> The three STP timers are not supposed to be armed while the bridge is
> administratively down. They are synchronously deactivated when the
> bridge is put administratively down and the various call sites check for
> 'IFF_UP' before arming them.
> 
> This check is missing from br_topology_change_detection() and it is
> possible to engineer a situation in which the topology change timer is
> armed while the bridge is administratively down, resulting in a
> use-after-free [1] when the bridge is deleted.
> 
> Fix by adding the missing check and for good measures synchronously
> shutdown the three timers when the bridge is deleted.
> 
> [1]
> ODEBUG: free active (active state 0) object: ffff88811662b9b0 object type: timer_list hint: br_topology_change_timer_expired (net/bridge/br_stp_timer.c:120)
> WARNING: lib/debugobjects.c:629 at debug_print_object+0x1bc/0x450, CPU#9: ip/359
> 
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Reported-by: Noam Rathaus <noamr@ssd-disclosure.com>
> Reported-by: Neil Young <contact@ssd-disclosure.com>
> Acked-by: Nikolay Aleksandrov <nikolay@nvidia.com>
> Signed-off-by: Ido Schimmel <idosch@nvidia.com>

The PW bot is on holiday, no automated notifications for a while.

Applied, thanks!

/P


^ permalink raw reply


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