18
18
#include <linux/module.h>
19
19
#include <linux/slab.h>
20
20
#include <linux/mempool.h>
21
+ #include <linux/interrupt.h>
21
22
#include <linux/virtio.h>
22
23
#include <linux/virtio_ids.h>
23
24
#include <linux/virtio_config.h>
29
30
#include <scsi/scsi_cmnd.h>
30
31
#include <scsi/scsi_tcq.h>
31
32
#include <linux/seqlock.h>
33
+ #include <linux/blk-mq-virtio.h>
32
34
33
35
#define VIRTIO_SCSI_MEMPOOL_SZ 64
34
36
#define VIRTIO_SCSI_EVENT_LEN 8
@@ -108,7 +110,6 @@ struct virtio_scsi {
108
110
bool affinity_hint_set ;
109
111
110
112
struct hlist_node node ;
111
- struct hlist_node node_dead ;
112
113
113
114
/* Protected by event_vq lock */
114
115
bool stop_events ;
@@ -118,7 +119,6 @@ struct virtio_scsi {
118
119
struct virtio_scsi_vq req_vqs [];
119
120
};
120
121
121
- static enum cpuhp_state virtioscsi_online ;
122
122
static struct kmem_cache * virtscsi_cmd_cache ;
123
123
static mempool_t * virtscsi_cmd_pool ;
124
124
@@ -766,6 +766,13 @@ static void virtscsi_target_destroy(struct scsi_target *starget)
766
766
kfree (tgt );
767
767
}
768
768
769
+ static int virtscsi_map_queues (struct Scsi_Host * shost )
770
+ {
771
+ struct virtio_scsi * vscsi = shost_priv (shost );
772
+
773
+ return blk_mq_virtio_map_queues (& shost -> tag_set , vscsi -> vdev , 2 );
774
+ }
775
+
769
776
static struct scsi_host_template virtscsi_host_template_single = {
770
777
.module = THIS_MODULE ,
771
778
.name = "Virtio SCSI HBA" ,
@@ -801,6 +808,7 @@ static struct scsi_host_template virtscsi_host_template_multi = {
801
808
.use_clustering = ENABLE_CLUSTERING ,
802
809
.target_alloc = virtscsi_target_alloc ,
803
810
.target_destroy = virtscsi_target_destroy ,
811
+ .map_queues = virtscsi_map_queues ,
804
812
.track_queue_depth = 1 ,
805
813
};
806
814
@@ -817,80 +825,6 @@ static struct scsi_host_template virtscsi_host_template_multi = {
817
825
virtio_cwrite(vdev, struct virtio_scsi_config, fld, &__val); \
818
826
} while(0)
819
827
820
- static void __virtscsi_set_affinity (struct virtio_scsi * vscsi , bool affinity )
821
- {
822
- int i ;
823
- int cpu ;
824
-
825
- /* In multiqueue mode, when the number of cpu is equal
826
- * to the number of request queues, we let the qeueues
827
- * to be private to one cpu by setting the affinity hint
828
- * to eliminate the contention.
829
- */
830
- if ((vscsi -> num_queues == 1 ||
831
- vscsi -> num_queues != num_online_cpus ()) && affinity ) {
832
- if (vscsi -> affinity_hint_set )
833
- affinity = false;
834
- else
835
- return ;
836
- }
837
-
838
- if (affinity ) {
839
- i = 0 ;
840
- for_each_online_cpu (cpu ) {
841
- virtqueue_set_affinity (vscsi -> req_vqs [i ].vq , cpu );
842
- i ++ ;
843
- }
844
-
845
- vscsi -> affinity_hint_set = true;
846
- } else {
847
- for (i = 0 ; i < vscsi -> num_queues ; i ++ ) {
848
- if (!vscsi -> req_vqs [i ].vq )
849
- continue ;
850
-
851
- virtqueue_set_affinity (vscsi -> req_vqs [i ].vq , -1 );
852
- }
853
-
854
- vscsi -> affinity_hint_set = false;
855
- }
856
- }
857
-
858
- static void virtscsi_set_affinity (struct virtio_scsi * vscsi , bool affinity )
859
- {
860
- get_online_cpus ();
861
- __virtscsi_set_affinity (vscsi , affinity );
862
- put_online_cpus ();
863
- }
864
-
865
- static int virtscsi_cpu_online (unsigned int cpu , struct hlist_node * node )
866
- {
867
- struct virtio_scsi * vscsi = hlist_entry_safe (node , struct virtio_scsi ,
868
- node );
869
- __virtscsi_set_affinity (vscsi , true);
870
- return 0 ;
871
- }
872
-
873
- static int virtscsi_cpu_notif_add (struct virtio_scsi * vi )
874
- {
875
- int ret ;
876
-
877
- ret = cpuhp_state_add_instance (virtioscsi_online , & vi -> node );
878
- if (ret )
879
- return ret ;
880
-
881
- ret = cpuhp_state_add_instance (CPUHP_VIRT_SCSI_DEAD , & vi -> node_dead );
882
- if (ret )
883
- cpuhp_state_remove_instance (virtioscsi_online , & vi -> node );
884
- return ret ;
885
- }
886
-
887
- static void virtscsi_cpu_notif_remove (struct virtio_scsi * vi )
888
- {
889
- cpuhp_state_remove_instance_nocalls (virtioscsi_online , & vi -> node );
890
- cpuhp_state_remove_instance_nocalls (CPUHP_VIRT_SCSI_DEAD ,
891
- & vi -> node_dead );
892
- }
893
-
894
828
static void virtscsi_init_vq (struct virtio_scsi_vq * virtscsi_vq ,
895
829
struct virtqueue * vq )
896
830
{
@@ -900,14 +834,8 @@ static void virtscsi_init_vq(struct virtio_scsi_vq *virtscsi_vq,
900
834
901
835
static void virtscsi_remove_vqs (struct virtio_device * vdev )
902
836
{
903
- struct Scsi_Host * sh = virtio_scsi_host (vdev );
904
- struct virtio_scsi * vscsi = shost_priv (sh );
905
-
906
- virtscsi_set_affinity (vscsi , false);
907
-
908
837
/* Stop all the virtqueues. */
909
838
vdev -> config -> reset (vdev );
910
-
911
839
vdev -> config -> del_vqs (vdev );
912
840
}
913
841
@@ -920,6 +848,7 @@ static int virtscsi_init(struct virtio_device *vdev,
920
848
vq_callback_t * * callbacks ;
921
849
const char * * names ;
922
850
struct virtqueue * * vqs ;
851
+ struct irq_affinity desc = { .pre_vectors = 2 };
923
852
924
853
num_vqs = vscsi -> num_queues + VIRTIO_SCSI_VQ_BASE ;
925
854
vqs = kmalloc (num_vqs * sizeof (struct virtqueue * ), GFP_KERNEL );
@@ -942,7 +871,7 @@ static int virtscsi_init(struct virtio_device *vdev,
942
871
943
872
/* Discover virtqueues and write information to configuration. */
944
873
err = vdev -> config -> find_vqs (vdev , num_vqs , vqs , callbacks , names ,
945
- NULL );
874
+ & desc );
946
875
if (err )
947
876
goto out ;
948
877
@@ -1008,10 +937,6 @@ static int virtscsi_probe(struct virtio_device *vdev)
1008
937
if (err )
1009
938
goto virtscsi_init_failed ;
1010
939
1011
- err = virtscsi_cpu_notif_add (vscsi );
1012
- if (err )
1013
- goto scsi_add_host_failed ;
1014
-
1015
940
cmd_per_lun = virtscsi_config_get (vdev , cmd_per_lun ) ?: 1 ;
1016
941
shost -> cmd_per_lun = min_t (u32 , cmd_per_lun , shost -> can_queue );
1017
942
shost -> max_sectors = virtscsi_config_get (vdev , max_sectors ) ?: 0xFFFF ;
@@ -1066,20 +991,13 @@ static void virtscsi_remove(struct virtio_device *vdev)
1066
991
virtscsi_cancel_event_work (vscsi );
1067
992
1068
993
scsi_remove_host (shost );
1069
-
1070
- virtscsi_cpu_notif_remove (vscsi );
1071
-
1072
994
virtscsi_remove_vqs (vdev );
1073
995
scsi_host_put (shost );
1074
996
}
1075
997
1076
998
#ifdef CONFIG_PM_SLEEP
1077
999
static int virtscsi_freeze (struct virtio_device * vdev )
1078
1000
{
1079
- struct Scsi_Host * sh = virtio_scsi_host (vdev );
1080
- struct virtio_scsi * vscsi = shost_priv (sh );
1081
-
1082
- virtscsi_cpu_notif_remove (vscsi );
1083
1001
virtscsi_remove_vqs (vdev );
1084
1002
return 0 ;
1085
1003
}
@@ -1094,11 +1012,6 @@ static int virtscsi_restore(struct virtio_device *vdev)
1094
1012
if (err )
1095
1013
return err ;
1096
1014
1097
- err = virtscsi_cpu_notif_add (vscsi );
1098
- if (err ) {
1099
- vdev -> config -> del_vqs (vdev );
1100
- return err ;
1101
- }
1102
1015
virtio_device_ready (vdev );
1103
1016
1104
1017
if (virtio_has_feature (vdev , VIRTIO_SCSI_F_HOTPLUG ))
@@ -1153,16 +1066,6 @@ static int __init init(void)
1153
1066
pr_err ("mempool_create() for virtscsi_cmd_pool failed\n" );
1154
1067
goto error ;
1155
1068
}
1156
- ret = cpuhp_setup_state_multi (CPUHP_AP_ONLINE_DYN ,
1157
- "scsi/virtio:online" ,
1158
- virtscsi_cpu_online , NULL );
1159
- if (ret < 0 )
1160
- goto error ;
1161
- virtioscsi_online = ret ;
1162
- ret = cpuhp_setup_state_multi (CPUHP_VIRT_SCSI_DEAD , "scsi/virtio:dead" ,
1163
- NULL , virtscsi_cpu_online );
1164
- if (ret )
1165
- goto error ;
1166
1069
ret = register_virtio_driver (& virtio_scsi_driver );
1167
1070
if (ret < 0 )
1168
1071
goto error ;
@@ -1178,17 +1081,12 @@ static int __init init(void)
1178
1081
kmem_cache_destroy (virtscsi_cmd_cache );
1179
1082
virtscsi_cmd_cache = NULL ;
1180
1083
}
1181
- if (virtioscsi_online )
1182
- cpuhp_remove_multi_state (virtioscsi_online );
1183
- cpuhp_remove_multi_state (CPUHP_VIRT_SCSI_DEAD );
1184
1084
return ret ;
1185
1085
}
1186
1086
1187
1087
static void __exit fini (void )
1188
1088
{
1189
1089
unregister_virtio_driver (& virtio_scsi_driver );
1190
- cpuhp_remove_multi_state (virtioscsi_online );
1191
- cpuhp_remove_multi_state (CPUHP_VIRT_SCSI_DEAD );
1192
1090
mempool_destroy (virtscsi_cmd_pool );
1193
1091
kmem_cache_destroy (virtscsi_cmd_cache );
1194
1092
}
0 commit comments