lkml.org 
[lkml]   [2013]   [Feb]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v3 5/5] virtio-scsi: reset virtqueue affinity when doing cpu hotplug
    Date
    From: Wanlong Gao <gaowanlong@cn.fujitsu.com>

    Add hot cpu notifier to reset the request virtqueue affinity
    when doing cpu hotplug.

    Cc: linux-scsi@vger.kernel.org
    Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
    [ The version that doesn't get/put_online_cpus is now called
    __virtscsi_set_affinity - Paolo ]
    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
    ---
    drivers/scsi/virtio_scsi.c | 31 +++++++++++++++++++++++++++++++
    1 files changed, 31 insertions(+), 0 deletions(-)

    diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
    index a2bdae1..733307a 100644
    --- a/drivers/scsi/virtio_scsi.c
    +++ b/drivers/scsi/virtio_scsi.c
    @@ -20,6 +20,7 @@
    #include <linux/virtio_ids.h>
    #include <linux/virtio_config.h>
    #include <linux/virtio_scsi.h>
    +#include <linux/cpu.h>
    #include <scsi/scsi_host.h>
    #include <scsi/scsi_device.h>
    #include <scsi/scsi_cmnd.h>
    @@ -109,6 +110,9 @@ struct virtio_scsi {
    /* Does the affinity hint is set for virtqueues? */
    bool affinity_hint_set;

    + /* CPU hotplug notifier */
    + struct notifier_block nb;
    +
    struct virtio_scsi_vq ctrl_vq;
    struct virtio_scsi_vq event_vq;
    struct virtio_scsi_vq req_vqs[];
    @@ -734,6 +738,7 @@ static void __virtscsi_set_affinity(struct virtio_scsi *vscsi, bool affinity)
    }
    }

    +
    static void virtscsi_set_affinity(struct virtio_scsi *vscsi, bool affinity)
    {
    get_online_cpus();
    @@ -741,6 +746,23 @@ static void virtscsi_set_affinity(struct virtio_scsi *vscsi, bool affinity)
    put_online_cpus();
    }

    +static int virtscsi_cpu_callback(struct notifier_block *nfb,
    + unsigned long action, void *hcpu)
    +{
    + struct virtio_scsi *vscsi = container_of(nfb, struct virtio_scsi, nb);
    + switch(action) {
    + case CPU_ONLINE:
    + case CPU_ONLINE_FROZEN:
    + case CPU_DEAD:
    + case CPU_DEAD_FROZEN:
    + __virtscsi_set_affinity(vscsi, true);
    + break;
    + default:
    + break;
    + }
    + return NOTIFY_OK;
    +}
    +
    static void virtscsi_init_vq(struct virtio_scsi_vq *virtscsi_vq,
    struct virtqueue *vq)
    {
    @@ -885,6 +907,13 @@ static int virtscsi_probe(struct virtio_device *vdev)
    if (err)
    goto virtscsi_init_failed;

    + vscsi->nb.notifier_call = &virtscsi_cpu_callback;
    + err = register_hotcpu_notifier(&vscsi->nb);
    + if (err) {
    + pr_err("virtio_scsi: registering cpu notifier failed\n");
    + 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;
    @@ -922,6 +951,8 @@ static void virtscsi_remove(struct virtio_device *vdev)

    scsi_remove_host(shost);

    + unregister_hotcpu_notifier(&vscsi->nb);
    +
    virtscsi_remove_vqs(vdev);
    scsi_host_put(shost);
    }
    --
    1.7.1


    \
     
     \ /
      Last update: 2013-02-12 14:21    [W:5.821 / U:0.852 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site