Subject: linux-next: manual merge of the net-next tree with the net tree

From: Mark Brown <[email-masked]>
Date: Fri, 29 May 2026 22:21:58 +0100

Hi all,

Today's linux-next merge of the net-next tree got a conflict in:

  drivers/net/ethernet/microsoft/mana/mana_en.c

between commit:

  17bfe0a8c014e ("net: mana: Add NULL guards in teardown path to prevent panic on attach failure")

from the net tree and commit:

  d07efe5a6e641 ("net: mana: Use per-queue allocation for tx_qp to reduce allocation size")

from the net-next tree.

I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging.  You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.

diff --combined drivers/net/ethernet/microsoft/mana/mana_en.c
index cc48cd06cb15d,c9b1df1ed1098..0000000000000
--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
@@@ -355,9 -355,9 +355,9 @@@ netdev_tx_t mana_start_xmit(struct sk_b
  	if (skb_cow_head(skb, MANA_HEADROOM))
  		goto tx_drop_count;
  
 -	txq = &apc->tx_qp[txq_idx].txq;
 +	txq = &apc->tx_qp[txq_idx]->txq;
  	gdma_sq = txq->gdma_sq;
 -	cq = &apc->tx_qp[txq_idx].tx_cq;
 +	cq = &apc->tx_qp[txq_idx]->tx_cq;
  	tx_stats = &txq->stats;
  
  	BUILD_BUG_ON(MAX_TX_WQE_SGL_ENTRIES != MANA_MAX_TX_WQE_SGL_ENTRIES);
@@@ -614,7 -614,7 +614,7 @@@ static void mana_get_stats64(struct net
  	}
  
  	for (q = 0; q < num_queues; q++) {
 -		tx_stats = &apc->tx_qp[q].txq.stats;
 +		tx_stats = &apc->tx_qp[q]->txq.stats;
  
  		do {
  			start = u64_stats_fetch_begin(&tx_stats->syncp);
@@@ -685,11 -685,11 +685,11 @@@ void mana_pre_dealloc_rxbufs(struct man
  		put_page(virt_to_head_page(mpc->rxbufs_pre[i]));
  	}
  
 -	kfree(mpc->das_pre);
 +	kvfree(mpc->das_pre);
  	mpc->das_pre = NULL;
  
  out2:
 -	kfree(mpc->rxbufs_pre);
 +	kvfree(mpc->rxbufs_pre);
  	mpc->rxbufs_pre = NULL;
  
  out1:
@@@ -806,11 -806,11 +806,11 @@@ int mana_pre_alloc_rxbufs(struct mana_p
  	num_rxb = num_queues * mpc->rx_queue_size;
  
  	WARN(mpc->rxbufs_pre, "mana rxbufs_pre exists\n");
 -	mpc->rxbufs_pre = kmalloc_array(num_rxb, sizeof(void *), GFP_KERNEL);
 +	mpc->rxbufs_pre = kvmalloc_array(num_rxb, sizeof(void *), GFP_KERNEL);
  	if (!mpc->rxbufs_pre)
  		goto error;
  
 -	mpc->das_pre = kmalloc_objs(dma_addr_t, num_rxb);
 +	mpc->das_pre = kvmalloc_objs(dma_addr_t, num_rxb);
  	if (!mpc->das_pre)
  		goto error;
  
@@@ -1262,12 -1262,6 +1262,12 @@@ static int mana_query_vport_cfg(struct 
  
  	*max_sq = resp.max_num_sq;
  	*max_rq = resp.max_num_rq;
 +
 +	if (*max_sq == 0 || *max_rq == 0) {
 +		netdev_err(apc->ndev, "Invalid max queues from vPort config\n");
 +		return -EPROTO;
 +	}
 +
  	if (resp.num_indirection_ent > 0 &&
  	    resp.num_indirection_ent <= MANA_INDIRECT_TABLE_MAX_SIZE &&
  	    is_power_of_2(resp.num_indirection_ent)) {
@@@ -1282,9 -1276,6 +1282,9 @@@
  	apc->port_handle = resp.vport;
  	ether_addr_copy(apc->mac_addr, resp.mac_addr);
  
 +	apc->vport_max_sq = *max_sq;
 +	apc->vport_max_rq = *max_rq;
 +
  	return 0;
  }
  
@@@ -1439,11 -1430,6 +1439,11 @@@ static int mana_cfg_vport_steering(stru
  
  	netdev_info(ndev, "Configured steering vPort %llu entries %u\n",
  		    apc->port_handle, apc->indir_table_sz);
 +
 +	apc->steer_rx = rx;
 +	apc->steer_rss = apc->rss_state;
 +	apc->steer_update_tab = update_tab;
 +	apc->steer_cqe_coalescing = req->cqe_coalescing_enable;
  out:
  	kfree(req);
  	return err;
@@@ -2338,26 -2324,21 +2338,26 @@@ static void mana_destroy_txq(struct man
  		return;
  
  	for (i = 0; i < apc->num_queues; i++) {
 -		debugfs_remove_recursive(apc->tx_qp[i].mana_tx_debugfs);
 -		apc->tx_qp[i].mana_tx_debugfs = NULL;
 +		if (!apc->tx_qp[i])
 +			continue;
  
 -		napi = &apc->tx_qp[i].tx_cq.napi;
 -		if (apc->tx_qp[i].txq.napi_initialized) {
 +		debugfs_remove_recursive(apc->tx_qp[i]->mana_tx_debugfs);
 +		apc->tx_qp[i]->mana_tx_debugfs = NULL;
 +
 +		napi = &apc->tx_qp[i]->tx_cq.napi;
 +		if (apc->tx_qp[i]->txq.napi_initialized) {
  			napi_synchronize(napi);
  			napi_disable_locked(napi);
  			netif_napi_del_locked(napi);
 -			apc->tx_qp[i].txq.napi_initialized = false;
 +			apc->tx_qp[i]->txq.napi_initialized = false;
  		}
 -		mana_destroy_wq_obj(apc, GDMA_SQ, apc->tx_qp[i].tx_object);
 +		mana_destroy_wq_obj(apc, GDMA_SQ, apc->tx_qp[i]->tx_object);
  
 -		mana_deinit_cq(apc, &apc->tx_qp[i].tx_cq);
 +		mana_deinit_cq(apc, &apc->tx_qp[i]->tx_cq);
  
 -		mana_deinit_txq(apc, &apc->tx_qp[i].txq);
 +		mana_deinit_txq(apc, &apc->tx_qp[i]->txq);
 +
 +		kvfree(apc->tx_qp[i]);
  	}
  
  	kfree(apc->tx_qp);
@@@ -2366,7 -2347,7 +2366,7 @@@
  
  static void mana_create_txq_debugfs(struct mana_port_context *apc, int idx)
  {
 -	struct mana_tx_qp *tx_qp = &apc->tx_qp[idx];
 +	struct mana_tx_qp *tx_qp = apc->tx_qp[idx];
  	char qnum[32];
  
  	sprintf(qnum, "TX-%d", idx);
@@@ -2405,7 -2386,7 +2405,7 @@@ static int mana_create_txq(struct mana_
  	int err;
  	int i;
  
 -	apc->tx_qp = kzalloc_objs(struct mana_tx_qp, apc->num_queues);
 +	apc->tx_qp = kzalloc_objs(struct mana_tx_qp *, apc->num_queues);
  	if (!apc->tx_qp)
  		return -ENOMEM;
  
@@@ -2425,16 -2406,10 +2425,16 @@@
  	gc = gd->gdma_context;
  
  	for (i = 0; i < apc->num_queues; i++) {
 -		apc->tx_qp[i].tx_object = INVALID_MANA_HANDLE;
 +		apc->tx_qp[i] = kvzalloc_obj(*apc->tx_qp[i]);
 +		if (!apc->tx_qp[i]) {
 +			err = -ENOMEM;
 +			goto out;
 +		}
 +
 +		apc->tx_qp[i]->tx_object = INVALID_MANA_HANDLE;
  
  		/* Create SQ */
 -		txq = &apc->tx_qp[i].txq;
 +		txq = &apc->tx_qp[i]->txq;
  
  		u64_stats_init(&txq->stats.syncp);
  		txq->ndev = net;
@@@ -2452,7 -2427,7 +2452,7 @@@
  			goto out;
  
  		/* Create SQ's CQ */
 -		cq = &apc->tx_qp[i].tx_cq;
 +		cq = &apc->tx_qp[i]->tx_cq;
  		cq->type = MANA_CQ_TYPE_TX;
  
  		cq->txq = txq;
@@@ -2481,7 -2456,7 +2481,7 @@@
  
  		err = mana_create_wq_obj(apc, apc->port_handle, GDMA_SQ,
  					 &wq_spec, &cq_spec,
 -					 &apc->tx_qp[i].tx_object);
 +					 &apc->tx_qp[i]->tx_object);
  
  		if (err)
  			goto out;
@@@ -2584,7 -2559,7 +2584,7 @@@ static void mana_destroy_rxq(struct man
  	if (rxq->gdma_rq)
  		mana_gd_destroy_queue(gc, rxq->gdma_rq);
  
 -	kfree(rxq);
 +	kvfree(rxq);
  }
  
  static int mana_fill_rx_oob(struct mana_recv_buf_oob *rx_oob, u32 mem_key,
@@@ -2724,7 -2699,7 +2724,7 @@@ static struct mana_rxq *mana_create_rxq
  
  	gc = gd->gdma_context;
  
 -	rxq = kzalloc_flex(*rxq, rx_oobs, apc->rx_queue_size);
 +	rxq = kvzalloc_flex(*rxq, rx_oobs, apc->rx_queue_size);
  	if (!rxq)
  		return NULL;
  
@@@ -3192,23 -3167,6 +3192,23 @@@ static int mana_init_port(struct net_de
  	eth_hw_addr_set(ndev, apc->mac_addr);
  	sprintf(vport, "vport%d", port_idx);
  	apc->mana_port_debugfs = debugfs_create_dir(vport, gc->mana_pci_debugfs);
 +
 +	debugfs_create_u64("port_handle", 0400, apc->mana_port_debugfs,
 +			   &apc->port_handle);
 +	debugfs_create_u32("max_sq", 0400, apc->mana_port_debugfs,
 +			   &apc->vport_max_sq);
 +	debugfs_create_u32("max_rq", 0400, apc->mana_port_debugfs,
 +			   &apc->vport_max_rq);
 +	debugfs_create_u32("indir_table_sz", 0400, apc->mana_port_debugfs,
 +			   &apc->indir_table_sz);
 +	debugfs_create_u32("steer_rx", 0400, apc->mana_port_debugfs,
 +			   &apc->steer_rx);
 +	debugfs_create_u32("steer_rss", 0400, apc->mana_port_debugfs,
 +			   &apc->steer_rss);
 +	debugfs_create_bool("steer_update_tab", 0400, apc->mana_port_debugfs,
 +			    &apc->steer_update_tab);
 +	debugfs_create_u32("steer_cqe_coalescing", 0400, apc->mana_port_debugfs,
 +			   &apc->steer_cqe_coalescing);
  	debugfs_create_u32("current_speed", 0400, apc->mana_port_debugfs,
  			   &apc->speed);
  	return 0;
@@@ -3338,21 -3296,13 +3338,21 @@@ static int mana_dealloc_queues(struct n
  
  	if (apc->tx_qp) {
  		for (i = 0; i < apc->num_queues; i++) {
 -			txq = &apc->tx_qp[i].txq;
 +			txq = &apc->tx_qp[i]->txq;
  			tsleep = 1000;
  			while (atomic_read(&txq->pending_sends) > 0 &&
  			       time_before(jiffies, timeout)) {
  				usleep_range(tsleep, tsleep + 1000);
  				tsleep <<= 1;
  			}
 +			if (atomic_read(&txq->pending_sends)) {
 +				err = pcie_flr(to_pci_dev(gd->gdma_context->dev));
 +				if (err) {
 +					netdev_err(ndev, "flr failed %d with %d pkts pending in txq %u\n",
 +						   err, atomic_read(&txq->pending_sends),
 +						   txq->gdma_txq_id);
 +				}
 +			}
  			if (atomic_read(&txq->pending_sends)) {
  				err =
  				    pcie_flr(to_pci_dev(gd->gdma_context->dev));
@@@ -3367,7 -3317,7 +3367,7 @@@
  		}
  
  		for (i = 0; i < apc->num_queues; i++) {
 -			txq = &apc->tx_qp[i].txq;
 +			txq = &apc->tx_qp[i]->txq;
  			while ((skb = skb_dequeue(&txq->pending_skbs))) {
  				mana_unmap_skb(skb, apc);
  				dev_kfree_skb_any(skb);
@@@ -3746,11 -3696,6 +3746,11 @@@ int mana_probe(struct gdma_dev *gd, boo
  	if (ac->num_ports > MAX_PORTS_IN_MANA_DEV)
  		ac->num_ports = MAX_PORTS_IN_MANA_DEV;
  
 +	debugfs_create_u16("num_vports", 0400, gc->mana_pci_debugfs,
 +			   &ac->num_ports);
 +	debugfs_create_u8("bm_hostmode", 0400, gc->mana_pci_debugfs,
 +			  &ac->bm_hostmode);
 +
  	ac->per_port_queue_reset_wq =
  		create_singlethread_workqueue("mana_per_port_queue_reset_wq");
  	if (!ac->per_port_queue_reset_wq) {
@@@ -3873,11 -3818,6 +3873,11 @@@ void mana_remove(struct gdma_dev *gd, b
  
  	mana_gd_deregister_device(gd);
  
 +	if (gc->mana_pci_debugfs) {
 +		debugfs_lookup_and_remove("bm_hostmode", gc->mana_pci_debugfs);
 +		debugfs_lookup_and_remove("num_vports", gc->mana_pci_debugfs);
 +	}
 +
  	if (suspending)
  		return;