Skip to content

Commit

Permalink
virtio_net: unify the code for recycling the xmit ptr
Browse files Browse the repository at this point in the history
There are two completely similar and independent implementations. This
is inconvenient for the subsequent addition of new types. So extract a
function from this piece of code and call this function uniformly to
recover old xmit ptr.

Signed-off-by: Xuan Zhuo <[email protected]>
Acked-by: Jason Wang <[email protected]>
Message-Id: <[email protected]>
Signed-off-by: Michael S. Tsirkin <[email protected]>
  • Loading branch information
fengidri authored and mstsirkin committed Mar 19, 2024
1 parent 0d197a1 commit b1dc24a
Showing 1 changed file with 39 additions and 43 deletions.
82 changes: 39 additions & 43 deletions drivers/net/virtio_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ struct virtnet_stat_desc {
size_t offset;
};

struct virtnet_sq_free_stats {
u64 packets;
u64 bytes;
};

struct virtnet_sq_stats {
struct u64_stats_sync syncp;
u64_stats_t packets;
Expand Down Expand Up @@ -372,6 +377,31 @@ static struct xdp_frame *ptr_to_xdp(void *ptr)
return (struct xdp_frame *)((unsigned long)ptr & ~VIRTIO_XDP_FLAG);
}

static void __free_old_xmit(struct send_queue *sq, bool in_napi,
struct virtnet_sq_free_stats *stats)
{
unsigned int len;
void *ptr;

while ((ptr = virtqueue_get_buf(sq->vq, &len)) != NULL) {
++stats->packets;

if (!is_xdp_frame(ptr)) {
struct sk_buff *skb = ptr;

pr_debug("Sent skb %p\n", skb);

stats->bytes += skb->len;
napi_consume_skb(skb, in_napi);
} else {
struct xdp_frame *frame = ptr_to_xdp(ptr);

stats->bytes += xdp_get_frame_len(frame);
xdp_return_frame(frame);
}
}
}

/* Converting between virtqueue no. and kernel tx/rx queue no.
* 0:rx0 1:tx0 2:rx1 3:tx1 ... 2N:rxN 2N+1:txN 2N+2:cvq
*/
Expand Down Expand Up @@ -798,37 +828,19 @@ static void virtnet_rq_unmap_free_buf(struct virtqueue *vq, void *buf)

static void free_old_xmit_skbs(struct send_queue *sq, bool in_napi)
{
unsigned int len;
unsigned int packets = 0;
unsigned int bytes = 0;
void *ptr;
struct virtnet_sq_free_stats stats = {0};

while ((ptr = virtqueue_get_buf(sq->vq, &len)) != NULL) {
if (likely(!is_xdp_frame(ptr))) {
struct sk_buff *skb = ptr;

pr_debug("Sent skb %p\n", skb);

bytes += skb->len;
napi_consume_skb(skb, in_napi);
} else {
struct xdp_frame *frame = ptr_to_xdp(ptr);

bytes += xdp_get_frame_len(frame);
xdp_return_frame(frame);
}
packets++;
}
__free_old_xmit(sq, in_napi, &stats);

/* Avoid overhead when no packets have been processed
* happens when called speculatively from start_xmit.
*/
if (!packets)
if (!stats.packets)
return;

u64_stats_update_begin(&sq->stats.syncp);
u64_stats_add(&sq->stats.bytes, bytes);
u64_stats_add(&sq->stats.packets, packets);
u64_stats_add(&sq->stats.bytes, stats.bytes);
u64_stats_add(&sq->stats.packets, stats.packets);
u64_stats_update_end(&sq->stats.syncp);
}

Expand Down Expand Up @@ -967,15 +979,12 @@ static int virtnet_xdp_xmit(struct net_device *dev,
int n, struct xdp_frame **frames, u32 flags)
{
struct virtnet_info *vi = netdev_priv(dev);
struct virtnet_sq_free_stats stats = {0};
struct receive_queue *rq = vi->rq;
struct bpf_prog *xdp_prog;
struct send_queue *sq;
unsigned int len;
int packets = 0;
int bytes = 0;
int nxmit = 0;
int kicks = 0;
void *ptr;
int ret;
int i;

Expand All @@ -994,20 +1003,7 @@ static int virtnet_xdp_xmit(struct net_device *dev,
}

/* Free up any pending old buffers before queueing new ones. */
while ((ptr = virtqueue_get_buf(sq->vq, &len)) != NULL) {
if (likely(is_xdp_frame(ptr))) {
struct xdp_frame *frame = ptr_to_xdp(ptr);

bytes += xdp_get_frame_len(frame);
xdp_return_frame(frame);
} else {
struct sk_buff *skb = ptr;

bytes += skb->len;
napi_consume_skb(skb, false);
}
packets++;
}
__free_old_xmit(sq, false, &stats);

for (i = 0; i < n; i++) {
struct xdp_frame *xdpf = frames[i];
Expand All @@ -1027,8 +1023,8 @@ static int virtnet_xdp_xmit(struct net_device *dev,
}
out:
u64_stats_update_begin(&sq->stats.syncp);
u64_stats_add(&sq->stats.bytes, bytes);
u64_stats_add(&sq->stats.packets, packets);
u64_stats_add(&sq->stats.bytes, stats.bytes);
u64_stats_add(&sq->stats.packets, stats.packets);
u64_stats_add(&sq->stats.xdp_tx, n);
u64_stats_add(&sq->stats.xdp_tx_drops, n - nxmit);
u64_stats_add(&sq->stats.kicks, kicks);
Expand Down

0 comments on commit b1dc24a

Please sign in to comment.