@@ -411,6 +411,9 @@ struct virtnet_info {
411
411
/* Has control virtqueue */
412
412
bool has_cvq ;
413
413
414
+ /* Lock to protect the control VQ */
415
+ struct mutex cvq_lock ;
416
+
414
417
/* Host can handle any s/g split between our header and packet data */
415
418
bool any_header_sg ;
416
419
@@ -2675,6 +2678,7 @@ static bool virtnet_send_command_reply(struct virtnet_info *vi, u8 class, u8 cmd
2675
2678
/* Caller should know better */
2676
2679
BUG_ON (!virtio_has_feature (vi -> vdev , VIRTIO_NET_F_CTRL_VQ ));
2677
2680
2681
+ mutex_lock (& vi -> cvq_lock );
2678
2682
vi -> ctrl -> status = ~0 ;
2679
2683
vi -> ctrl -> hdr .class = class ;
2680
2684
vi -> ctrl -> hdr .cmd = cmd ;
@@ -2697,11 +2701,12 @@ static bool virtnet_send_command_reply(struct virtnet_info *vi, u8 class, u8 cmd
2697
2701
if (ret < 0 ) {
2698
2702
dev_warn (& vi -> vdev -> dev ,
2699
2703
"Failed to add sgs for command vq: %d\n." , ret );
2704
+ mutex_unlock (& vi -> cvq_lock );
2700
2705
return false;
2701
2706
}
2702
2707
2703
2708
if (unlikely (!virtqueue_kick (vi -> cvq )))
2704
- return vi -> ctrl -> status == VIRTIO_NET_OK ;
2709
+ goto unlock ;
2705
2710
2706
2711
/* Spin for a response, the kick causes an ioport write, trapping
2707
2712
* into the hypervisor, so the request should be handled immediately.
@@ -2712,6 +2717,8 @@ static bool virtnet_send_command_reply(struct virtnet_info *vi, u8 class, u8 cmd
2712
2717
cpu_relax ();
2713
2718
}
2714
2719
2720
+ unlock :
2721
+ mutex_unlock (& vi -> cvq_lock );
2715
2722
return vi -> ctrl -> status == VIRTIO_NET_OK ;
2716
2723
}
2717
2724
@@ -5736,6 +5743,8 @@ static int virtnet_probe(struct virtio_device *vdev)
5736
5743
if (virtio_has_feature (vdev , VIRTIO_NET_F_CTRL_VQ ))
5737
5744
vi -> has_cvq = true;
5738
5745
5746
+ mutex_init (& vi -> cvq_lock );
5747
+
5739
5748
if (virtio_has_feature (vdev , VIRTIO_NET_F_MTU )) {
5740
5749
mtu = virtio_cread16 (vdev ,
5741
5750
offsetof(struct virtio_net_config ,
0 commit comments