Skip to content

Commit fbe6a22

Browse files
Heng QiNipaLocal
authored andcommitted
virtio-net: support dim profile fine-tuning
Virtio-net has different types of back-end device implementations. In order to effectively optimize the dim library's gains for different device implementations, let's use the new interface params to initialize and query dim results from a customized profile list. Signed-off-by: Heng Qi <[email protected]> Signed-off-by: NipaLocal <nipa@local>
1 parent 0bda597 commit fbe6a22

File tree

1 file changed

+47
-7
lines changed

1 file changed

+47
-7
lines changed

drivers/net/virtio_net.c

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2439,6 +2439,13 @@ static int virtnet_enable_queue_pair(struct virtnet_info *vi, int qp_index)
24392439
return err;
24402440
}
24412441

2442+
static void virtnet_cancel_dim(struct virtnet_info *vi, struct dim *dim)
2443+
{
2444+
if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_VQ_NOTF_COAL))
2445+
return;
2446+
net_dim_work_cancel(dim);
2447+
}
2448+
24422449
static int virtnet_open(struct net_device *dev)
24432450
{
24442451
struct virtnet_info *vi = netdev_priv(dev);
@@ -2465,7 +2472,7 @@ static int virtnet_open(struct net_device *dev)
24652472

24662473
for (i--; i >= 0; i--) {
24672474
virtnet_disable_queue_pair(vi, i);
2468-
cancel_work_sync(&vi->rq[i].dim.work);
2475+
virtnet_cancel_dim(vi, &vi->rq[i].dim);
24692476
}
24702477

24712478
return err;
@@ -2637,7 +2644,7 @@ static int virtnet_rx_resize(struct virtnet_info *vi,
26372644

26382645
if (running) {
26392646
napi_disable(&rq->napi);
2640-
cancel_work_sync(&rq->dim.work);
2647+
virtnet_cancel_dim(vi, &rq->dim);
26412648
}
26422649

26432650
err = virtqueue_resize(rq->vq, ring_num, virtnet_rq_unmap_free_buf);
@@ -2898,7 +2905,7 @@ static int virtnet_close(struct net_device *dev)
28982905

28992906
for (i = 0; i < vi->max_queue_pairs; i++) {
29002907
virtnet_disable_queue_pair(vi, i);
2901-
cancel_work_sync(&vi->rq[i].dim.work);
2908+
virtnet_cancel_dim(vi, &vi->rq[i].dim);
29022909
}
29032910

29042911
return 0;
@@ -4424,7 +4431,7 @@ static void virtnet_rx_dim_work(struct work_struct *work)
44244431
if (!rq->dim_enabled)
44254432
goto out;
44264433

4427-
update_moder = net_dim_get_rx_moderation(dim->mode, dim->profile_ix);
4434+
update_moder = net_dim_get_rx_irq_moder(dev, dim);
44284435
if (update_moder.usec != rq->intr_coal.max_usecs ||
44294436
update_moder.pkts != rq->intr_coal.max_packets) {
44304437
err = virtnet_send_rx_ctrl_coal_vq_cmd(vi, qnum,
@@ -5124,6 +5131,36 @@ static void virtnet_tx_timeout(struct net_device *dev, unsigned int txqueue)
51245131
jiffies_to_usecs(jiffies - READ_ONCE(txq->trans_start)));
51255132
}
51265133

5134+
static int virtnet_init_irq_moder(struct virtnet_info *vi)
5135+
{
5136+
u8 profile_flags = 0, coal_flags = 0;
5137+
int ret, i;
5138+
5139+
profile_flags |= DIM_PROFILE_RX;
5140+
coal_flags |= DIM_COALESCE_USEC | DIM_COALESCE_PKTS;
5141+
ret = net_dim_init_irq_moder(vi->dev, profile_flags, coal_flags,
5142+
DIM_CQ_PERIOD_MODE_START_FROM_EQE,
5143+
0, virtnet_rx_dim_work, NULL);
5144+
5145+
if (ret)
5146+
return ret;
5147+
5148+
for (i = 0; i < vi->max_queue_pairs; i++)
5149+
net_dim_setting(vi->dev, &vi->rq[i].dim, false);
5150+
5151+
return 0;
5152+
}
5153+
5154+
static void virtnet_free_irq_moder(struct virtnet_info *vi)
5155+
{
5156+
if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_VQ_NOTF_COAL))
5157+
return;
5158+
5159+
rtnl_lock();
5160+
net_dim_free_irq_moder(vi->dev);
5161+
rtnl_unlock();
5162+
}
5163+
51275164
static const struct net_device_ops virtnet_netdev = {
51285165
.ndo_open = virtnet_open,
51295166
.ndo_stop = virtnet_close,
@@ -5403,9 +5440,6 @@ static int virtnet_alloc_queues(struct virtnet_info *vi)
54035440
virtnet_poll_tx,
54045441
napi_tx ? napi_weight : 0);
54055442

5406-
INIT_WORK(&vi->rq[i].dim.work, virtnet_rx_dim_work);
5407-
vi->rq[i].dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
5408-
54095443
sg_init_table(vi->rq[i].sg, ARRAY_SIZE(vi->rq[i].sg));
54105444
ewma_pkt_len_init(&vi->rq[i].mrg_avg_pkt_len);
54115445
sg_init_table(vi->sq[i].sg, ARRAY_SIZE(vi->sq[i].sg));
@@ -5834,6 +5868,10 @@ static int virtnet_probe(struct virtio_device *vdev)
58345868
for (i = 0; i < vi->max_queue_pairs; i++)
58355869
if (vi->sq[i].napi.weight)
58365870
vi->sq[i].intr_coal.max_packets = 1;
5871+
5872+
err = virtnet_init_irq_moder(vi);
5873+
if (err)
5874+
goto free;
58375875
}
58385876

58395877
#ifdef CONFIG_SYSFS
@@ -5985,6 +6023,8 @@ static void virtnet_remove(struct virtio_device *vdev)
59856023
disable_rx_mode_work(vi);
59866024
flush_work(&vi->rx_mode_work);
59876025

6026+
virtnet_free_irq_moder(vi);
6027+
59886028
unregister_netdev(vi->dev);
59896029

59906030
net_failover_destroy(vi->failover);

0 commit comments

Comments
 (0)