Re: [PATCH net-next v14 06/13] rtase: Implement .ndo_start_xmit function

Jakub Kicinski
2023-12-12T19:32:18Z

On Fri, 8 Dec 2023 17:47:26 +0800 Justin Lai wrote:
> +static int tx_handler(struct rtase_ring *ring, int budget)

I don't see how this is called, the way you split the submission makes
it a bit hard to review, oh well. Anyway - if you pass the NAPI budget
here - that's not right, it may be 0, and you'd loop forever.
For Tx - you should try to reap some fixed number of packets, say 128,
the budget is for Rx, not for Tx.

> + const struct rtase_private *tp = ring->ivec->tp;
> + struct net_device *dev = tp->dev;
> + int workdone = 0;
> + u32 dirty_tx;
> + u32 tx_left;
> +
> + dirty_tx = ring->dirty_idx;
> + tx_left = READ_ONCE(ring->cur_idx) - dirty_tx;
> +
> + while (tx_left > 0) {
> + u32 entry = dirty_tx % NUM_DESC;
> + struct tx_desc *desc = ring->desc +
> + sizeof(struct tx_desc) * entry;
> + u32 len = ring->mis.len[entry];
> + u32 status;
> +
> + status = le32_to_cpu(desc->opts1);
> +
> + if (status & DESC_OWN)
> + break;
> +
> + rtase_unmap_tx_skb(tp->pdev, len, desc);
> + ring->mis.len[entry] = 0;
> + if (ring->skbuff[entry]) {
> + dev_consume_skb_any(ring->skbuff[entry]);

napi_consume_skb, assuming you call this from NAPI

> + ring->skbuff[entry] = NULL;
> + }
> +
> + dev->stats.tx_bytes += len;
> + dev->stats.tx_packets++;
> + dirty_tx++;
> + tx_left--;
> + workdone++;
> +
> + if (workdone == budget)
> + break;
> + }
> +
> + if (ring->dirty_idx != dirty_tx) {
> + WRITE_ONCE(ring->dirty_idx, dirty_tx);
> +
> + if (__netif_subqueue_stopped(dev, ring->index) &&
> + rtase_tx_avail(ring))
> + netif_start_subqueue(dev, ring->index);

Please use the start / stop macros from include/net/netdev_queues.h
I'm pretty sure the current code is racy.

> + if (ring->cur_idx != dirty_tx)
> + rtase_w8(tp, RTASE_TPPOLL, BIT(ring->index));
> + }
> +
> + return workdone;
> +}

> + /* multiqueues */
> + q_idx = skb_get_queue_mapping(skb);
> + ring = &tp->tx_ring[q_idx];

As Paolo pointed out elsewhere you seem to only support one queue.
Remove this indirection, please, and always use queue 0, otherwise
it's a bit confusing.