@@ -110,6 +110,9 @@ struct virtio_scsi {
110110 /* If the affinity hint is set for virtqueues */
111111 bool affinity_hint_set ;
112112
113+ /* CPU hotplug notifier */
114+ struct notifier_block nb ;
115+
113116 struct virtio_scsi_vq ctrl_vq ;
114117 struct virtio_scsi_vq event_vq ;
115118 struct virtio_scsi_vq req_vqs [];
@@ -762,6 +765,23 @@ static void virtscsi_set_affinity(struct virtio_scsi *vscsi, bool affinity)
762765 put_online_cpus ();
763766}
764767
768+ static int virtscsi_cpu_callback (struct notifier_block * nfb ,
769+ unsigned long action , void * hcpu )
770+ {
771+ struct virtio_scsi * vscsi = container_of (nfb , struct virtio_scsi , nb );
772+ switch (action ) {
773+ case CPU_ONLINE :
774+ case CPU_ONLINE_FROZEN :
775+ case CPU_DEAD :
776+ case CPU_DEAD_FROZEN :
777+ __virtscsi_set_affinity (vscsi , true);
778+ break ;
779+ default :
780+ break ;
781+ }
782+ return NOTIFY_OK ;
783+ }
784+
765785static void virtscsi_init_vq (struct virtio_scsi_vq * virtscsi_vq ,
766786 struct virtqueue * vq )
767787{
@@ -884,6 +904,13 @@ static int virtscsi_probe(struct virtio_device *vdev)
884904 if (err )
885905 goto virtscsi_init_failed ;
886906
907+ vscsi -> nb .notifier_call = & virtscsi_cpu_callback ;
908+ err = register_hotcpu_notifier (& vscsi -> nb );
909+ if (err ) {
910+ pr_err ("registering cpu notifier failed\n" );
911+ goto scsi_add_host_failed ;
912+ }
913+
887914 cmd_per_lun = virtscsi_config_get (vdev , cmd_per_lun ) ?: 1 ;
888915 shost -> cmd_per_lun = min_t (u32 , cmd_per_lun , shost -> can_queue );
889916 shost -> max_sectors = virtscsi_config_get (vdev , max_sectors ) ?: 0xFFFF ;
@@ -921,6 +948,8 @@ static void virtscsi_remove(struct virtio_device *vdev)
921948
922949 scsi_remove_host (shost );
923950
951+ unregister_hotcpu_notifier (& vscsi -> nb );
952+
924953 virtscsi_remove_vqs (vdev );
925954 scsi_host_put (shost );
926955}
0 commit comments