Loading drivers/scsi/virtio_scsi.c +12 −114 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <linux/module.h> #include <linux/slab.h> #include <linux/mempool.h> #include <linux/interrupt.h> #include <linux/virtio.h> #include <linux/virtio_ids.h> #include <linux/virtio_config.h> Loading @@ -29,6 +30,7 @@ #include <scsi/scsi_cmnd.h> #include <scsi/scsi_tcq.h> #include <linux/seqlock.h> #include <linux/blk-mq-virtio.h> #define VIRTIO_SCSI_MEMPOOL_SZ 64 #define VIRTIO_SCSI_EVENT_LEN 8 Loading Loading @@ -108,7 +110,6 @@ struct virtio_scsi { bool affinity_hint_set; struct hlist_node node; struct hlist_node node_dead; /* Protected by event_vq lock */ bool stop_events; Loading @@ -118,7 +119,6 @@ struct virtio_scsi { struct virtio_scsi_vq req_vqs[]; }; static enum cpuhp_state virtioscsi_online; static struct kmem_cache *virtscsi_cmd_cache; static mempool_t *virtscsi_cmd_pool; Loading Loading @@ -766,6 +766,13 @@ static void virtscsi_target_destroy(struct scsi_target *starget) kfree(tgt); } static int virtscsi_map_queues(struct Scsi_Host *shost) { struct virtio_scsi *vscsi = shost_priv(shost); return blk_mq_virtio_map_queues(&shost->tag_set, vscsi->vdev, 2); } static struct scsi_host_template virtscsi_host_template_single = { .module = THIS_MODULE, .name = "Virtio SCSI HBA", Loading Loading @@ -801,6 +808,7 @@ static struct scsi_host_template virtscsi_host_template_multi = { .use_clustering = ENABLE_CLUSTERING, .target_alloc = virtscsi_target_alloc, .target_destroy = virtscsi_target_destroy, .map_queues = virtscsi_map_queues, .track_queue_depth = 1, }; Loading @@ -817,80 +825,6 @@ static struct scsi_host_template virtscsi_host_template_multi = { virtio_cwrite(vdev, struct virtio_scsi_config, fld, &__val); \ } while(0) static void __virtscsi_set_affinity(struct virtio_scsi *vscsi, bool affinity) { int i; int cpu; /* In multiqueue mode, when the number of cpu is equal * to the number of request queues, we let the qeueues * to be private to one cpu by setting the affinity hint * to eliminate the contention. */ if ((vscsi->num_queues == 1 || vscsi->num_queues != num_online_cpus()) && affinity) { if (vscsi->affinity_hint_set) affinity = false; else return; } if (affinity) { i = 0; for_each_online_cpu(cpu) { virtqueue_set_affinity(vscsi->req_vqs[i].vq, cpu); i++; } vscsi->affinity_hint_set = true; } else { for (i = 0; i < vscsi->num_queues; i++) { if (!vscsi->req_vqs[i].vq) continue; virtqueue_set_affinity(vscsi->req_vqs[i].vq, -1); } vscsi->affinity_hint_set = false; } } static void virtscsi_set_affinity(struct virtio_scsi *vscsi, bool affinity) { get_online_cpus(); __virtscsi_set_affinity(vscsi, affinity); put_online_cpus(); } static int virtscsi_cpu_online(unsigned int cpu, struct hlist_node *node) { struct virtio_scsi *vscsi = hlist_entry_safe(node, struct virtio_scsi, node); __virtscsi_set_affinity(vscsi, true); return 0; } static int virtscsi_cpu_notif_add(struct virtio_scsi *vi) { int ret; ret = cpuhp_state_add_instance(virtioscsi_online, &vi->node); if (ret) return ret; ret = cpuhp_state_add_instance(CPUHP_VIRT_SCSI_DEAD, &vi->node_dead); if (ret) cpuhp_state_remove_instance(virtioscsi_online, &vi->node); return ret; } static void virtscsi_cpu_notif_remove(struct virtio_scsi *vi) { cpuhp_state_remove_instance_nocalls(virtioscsi_online, &vi->node); cpuhp_state_remove_instance_nocalls(CPUHP_VIRT_SCSI_DEAD, &vi->node_dead); } static void virtscsi_init_vq(struct virtio_scsi_vq *virtscsi_vq, struct virtqueue *vq) { Loading @@ -900,14 +834,8 @@ static void virtscsi_init_vq(struct virtio_scsi_vq *virtscsi_vq, static void virtscsi_remove_vqs(struct virtio_device *vdev) { struct Scsi_Host *sh = virtio_scsi_host(vdev); struct virtio_scsi *vscsi = shost_priv(sh); virtscsi_set_affinity(vscsi, false); /* Stop all the virtqueues. */ vdev->config->reset(vdev); vdev->config->del_vqs(vdev); } Loading @@ -920,6 +848,7 @@ static int virtscsi_init(struct virtio_device *vdev, vq_callback_t **callbacks; const char **names; struct virtqueue **vqs; struct irq_affinity desc = { .pre_vectors = 2 }; num_vqs = vscsi->num_queues + VIRTIO_SCSI_VQ_BASE; vqs = kmalloc(num_vqs * sizeof(struct virtqueue *), GFP_KERNEL); Loading @@ -942,7 +871,7 @@ static int virtscsi_init(struct virtio_device *vdev, /* Discover virtqueues and write information to configuration. */ err = vdev->config->find_vqs(vdev, num_vqs, vqs, callbacks, names, NULL); &desc); if (err) goto out; Loading Loading @@ -1008,10 +937,6 @@ static int virtscsi_probe(struct virtio_device *vdev) if (err) goto virtscsi_init_failed; err = virtscsi_cpu_notif_add(vscsi); if (err) goto scsi_add_host_failed; cmd_per_lun = virtscsi_config_get(vdev, cmd_per_lun) ?: 1; shost->cmd_per_lun = min_t(u32, cmd_per_lun, shost->can_queue); shost->max_sectors = virtscsi_config_get(vdev, max_sectors) ?: 0xFFFF; Loading Loading @@ -1066,9 +991,6 @@ static void virtscsi_remove(struct virtio_device *vdev) virtscsi_cancel_event_work(vscsi); scsi_remove_host(shost); virtscsi_cpu_notif_remove(vscsi); virtscsi_remove_vqs(vdev); scsi_host_put(shost); } Loading @@ -1076,10 +998,6 @@ static void virtscsi_remove(struct virtio_device *vdev) #ifdef CONFIG_PM_SLEEP static int virtscsi_freeze(struct virtio_device *vdev) { struct Scsi_Host *sh = virtio_scsi_host(vdev); struct virtio_scsi *vscsi = shost_priv(sh); virtscsi_cpu_notif_remove(vscsi); virtscsi_remove_vqs(vdev); return 0; } Loading @@ -1094,11 +1012,6 @@ static int virtscsi_restore(struct virtio_device *vdev) if (err) return err; err = virtscsi_cpu_notif_add(vscsi); if (err) { vdev->config->del_vqs(vdev); return err; } virtio_device_ready(vdev); if (virtio_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) Loading Loading @@ -1153,16 +1066,6 @@ static int __init init(void) pr_err("mempool_create() for virtscsi_cmd_pool failed\n"); goto error; } ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, "scsi/virtio:online", virtscsi_cpu_online, NULL); if (ret < 0) goto error; virtioscsi_online = ret; ret = cpuhp_setup_state_multi(CPUHP_VIRT_SCSI_DEAD, "scsi/virtio:dead", NULL, virtscsi_cpu_online); if (ret) goto error; ret = register_virtio_driver(&virtio_scsi_driver); if (ret < 0) goto error; Loading @@ -1178,17 +1081,12 @@ static int __init init(void) kmem_cache_destroy(virtscsi_cmd_cache); virtscsi_cmd_cache = NULL; } if (virtioscsi_online) cpuhp_remove_multi_state(virtioscsi_online); cpuhp_remove_multi_state(CPUHP_VIRT_SCSI_DEAD); return ret; } static void __exit fini(void) { unregister_virtio_driver(&virtio_scsi_driver); cpuhp_remove_multi_state(virtioscsi_online); cpuhp_remove_multi_state(CPUHP_VIRT_SCSI_DEAD); mempool_destroy(virtscsi_cmd_pool); kmem_cache_destroy(virtscsi_cmd_cache); } Loading include/linux/cpuhotplug.h +0 −1 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ enum cpuhp_state { CPUHP_ARM_OMAP_WAKE_DEAD, CPUHP_IRQ_POLL_DEAD, CPUHP_BLOCK_SOFTIRQ_DEAD, CPUHP_VIRT_SCSI_DEAD, CPUHP_ACPI_CPUDRV_DEAD, CPUHP_S390_PFAULT_DEAD, CPUHP_BLK_MQ_DEAD, Loading Loading
drivers/scsi/virtio_scsi.c +12 −114 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <linux/module.h> #include <linux/slab.h> #include <linux/mempool.h> #include <linux/interrupt.h> #include <linux/virtio.h> #include <linux/virtio_ids.h> #include <linux/virtio_config.h> Loading @@ -29,6 +30,7 @@ #include <scsi/scsi_cmnd.h> #include <scsi/scsi_tcq.h> #include <linux/seqlock.h> #include <linux/blk-mq-virtio.h> #define VIRTIO_SCSI_MEMPOOL_SZ 64 #define VIRTIO_SCSI_EVENT_LEN 8 Loading Loading @@ -108,7 +110,6 @@ struct virtio_scsi { bool affinity_hint_set; struct hlist_node node; struct hlist_node node_dead; /* Protected by event_vq lock */ bool stop_events; Loading @@ -118,7 +119,6 @@ struct virtio_scsi { struct virtio_scsi_vq req_vqs[]; }; static enum cpuhp_state virtioscsi_online; static struct kmem_cache *virtscsi_cmd_cache; static mempool_t *virtscsi_cmd_pool; Loading Loading @@ -766,6 +766,13 @@ static void virtscsi_target_destroy(struct scsi_target *starget) kfree(tgt); } static int virtscsi_map_queues(struct Scsi_Host *shost) { struct virtio_scsi *vscsi = shost_priv(shost); return blk_mq_virtio_map_queues(&shost->tag_set, vscsi->vdev, 2); } static struct scsi_host_template virtscsi_host_template_single = { .module = THIS_MODULE, .name = "Virtio SCSI HBA", Loading Loading @@ -801,6 +808,7 @@ static struct scsi_host_template virtscsi_host_template_multi = { .use_clustering = ENABLE_CLUSTERING, .target_alloc = virtscsi_target_alloc, .target_destroy = virtscsi_target_destroy, .map_queues = virtscsi_map_queues, .track_queue_depth = 1, }; Loading @@ -817,80 +825,6 @@ static struct scsi_host_template virtscsi_host_template_multi = { virtio_cwrite(vdev, struct virtio_scsi_config, fld, &__val); \ } while(0) static void __virtscsi_set_affinity(struct virtio_scsi *vscsi, bool affinity) { int i; int cpu; /* In multiqueue mode, when the number of cpu is equal * to the number of request queues, we let the qeueues * to be private to one cpu by setting the affinity hint * to eliminate the contention. */ if ((vscsi->num_queues == 1 || vscsi->num_queues != num_online_cpus()) && affinity) { if (vscsi->affinity_hint_set) affinity = false; else return; } if (affinity) { i = 0; for_each_online_cpu(cpu) { virtqueue_set_affinity(vscsi->req_vqs[i].vq, cpu); i++; } vscsi->affinity_hint_set = true; } else { for (i = 0; i < vscsi->num_queues; i++) { if (!vscsi->req_vqs[i].vq) continue; virtqueue_set_affinity(vscsi->req_vqs[i].vq, -1); } vscsi->affinity_hint_set = false; } } static void virtscsi_set_affinity(struct virtio_scsi *vscsi, bool affinity) { get_online_cpus(); __virtscsi_set_affinity(vscsi, affinity); put_online_cpus(); } static int virtscsi_cpu_online(unsigned int cpu, struct hlist_node *node) { struct virtio_scsi *vscsi = hlist_entry_safe(node, struct virtio_scsi, node); __virtscsi_set_affinity(vscsi, true); return 0; } static int virtscsi_cpu_notif_add(struct virtio_scsi *vi) { int ret; ret = cpuhp_state_add_instance(virtioscsi_online, &vi->node); if (ret) return ret; ret = cpuhp_state_add_instance(CPUHP_VIRT_SCSI_DEAD, &vi->node_dead); if (ret) cpuhp_state_remove_instance(virtioscsi_online, &vi->node); return ret; } static void virtscsi_cpu_notif_remove(struct virtio_scsi *vi) { cpuhp_state_remove_instance_nocalls(virtioscsi_online, &vi->node); cpuhp_state_remove_instance_nocalls(CPUHP_VIRT_SCSI_DEAD, &vi->node_dead); } static void virtscsi_init_vq(struct virtio_scsi_vq *virtscsi_vq, struct virtqueue *vq) { Loading @@ -900,14 +834,8 @@ static void virtscsi_init_vq(struct virtio_scsi_vq *virtscsi_vq, static void virtscsi_remove_vqs(struct virtio_device *vdev) { struct Scsi_Host *sh = virtio_scsi_host(vdev); struct virtio_scsi *vscsi = shost_priv(sh); virtscsi_set_affinity(vscsi, false); /* Stop all the virtqueues. */ vdev->config->reset(vdev); vdev->config->del_vqs(vdev); } Loading @@ -920,6 +848,7 @@ static int virtscsi_init(struct virtio_device *vdev, vq_callback_t **callbacks; const char **names; struct virtqueue **vqs; struct irq_affinity desc = { .pre_vectors = 2 }; num_vqs = vscsi->num_queues + VIRTIO_SCSI_VQ_BASE; vqs = kmalloc(num_vqs * sizeof(struct virtqueue *), GFP_KERNEL); Loading @@ -942,7 +871,7 @@ static int virtscsi_init(struct virtio_device *vdev, /* Discover virtqueues and write information to configuration. */ err = vdev->config->find_vqs(vdev, num_vqs, vqs, callbacks, names, NULL); &desc); if (err) goto out; Loading Loading @@ -1008,10 +937,6 @@ static int virtscsi_probe(struct virtio_device *vdev) if (err) goto virtscsi_init_failed; err = virtscsi_cpu_notif_add(vscsi); if (err) goto scsi_add_host_failed; cmd_per_lun = virtscsi_config_get(vdev, cmd_per_lun) ?: 1; shost->cmd_per_lun = min_t(u32, cmd_per_lun, shost->can_queue); shost->max_sectors = virtscsi_config_get(vdev, max_sectors) ?: 0xFFFF; Loading Loading @@ -1066,9 +991,6 @@ static void virtscsi_remove(struct virtio_device *vdev) virtscsi_cancel_event_work(vscsi); scsi_remove_host(shost); virtscsi_cpu_notif_remove(vscsi); virtscsi_remove_vqs(vdev); scsi_host_put(shost); } Loading @@ -1076,10 +998,6 @@ static void virtscsi_remove(struct virtio_device *vdev) #ifdef CONFIG_PM_SLEEP static int virtscsi_freeze(struct virtio_device *vdev) { struct Scsi_Host *sh = virtio_scsi_host(vdev); struct virtio_scsi *vscsi = shost_priv(sh); virtscsi_cpu_notif_remove(vscsi); virtscsi_remove_vqs(vdev); return 0; } Loading @@ -1094,11 +1012,6 @@ static int virtscsi_restore(struct virtio_device *vdev) if (err) return err; err = virtscsi_cpu_notif_add(vscsi); if (err) { vdev->config->del_vqs(vdev); return err; } virtio_device_ready(vdev); if (virtio_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) Loading Loading @@ -1153,16 +1066,6 @@ static int __init init(void) pr_err("mempool_create() for virtscsi_cmd_pool failed\n"); goto error; } ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, "scsi/virtio:online", virtscsi_cpu_online, NULL); if (ret < 0) goto error; virtioscsi_online = ret; ret = cpuhp_setup_state_multi(CPUHP_VIRT_SCSI_DEAD, "scsi/virtio:dead", NULL, virtscsi_cpu_online); if (ret) goto error; ret = register_virtio_driver(&virtio_scsi_driver); if (ret < 0) goto error; Loading @@ -1178,17 +1081,12 @@ static int __init init(void) kmem_cache_destroy(virtscsi_cmd_cache); virtscsi_cmd_cache = NULL; } if (virtioscsi_online) cpuhp_remove_multi_state(virtioscsi_online); cpuhp_remove_multi_state(CPUHP_VIRT_SCSI_DEAD); return ret; } static void __exit fini(void) { unregister_virtio_driver(&virtio_scsi_driver); cpuhp_remove_multi_state(virtioscsi_online); cpuhp_remove_multi_state(CPUHP_VIRT_SCSI_DEAD); mempool_destroy(virtscsi_cmd_pool); kmem_cache_destroy(virtscsi_cmd_cache); } Loading
include/linux/cpuhotplug.h +0 −1 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ enum cpuhp_state { CPUHP_ARM_OMAP_WAKE_DEAD, CPUHP_IRQ_POLL_DEAD, CPUHP_BLOCK_SOFTIRQ_DEAD, CPUHP_VIRT_SCSI_DEAD, CPUHP_ACPI_CPUDRV_DEAD, CPUHP_S390_PFAULT_DEAD, CPUHP_BLK_MQ_DEAD, Loading