Re: [PATCH] virtio-scsi: replace target spinlock with seqcount

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, May 28, 2014 at 12:57 AM, Paolo Bonzini <pbonzini@xxxxxxxxxx> wrote:
> Il 27/05/2014 18:50, Venkatesh Srinivas ha scritto:
>
>> Hi,
>>
>> I think this patch has a small race involving just two commands:
>>
>> 1. The first command to a target is in virtscsi_pick_vq(), after
>>    atomic_inc_return(&tgt->tgt_lock)) but before write_seqcount_begin()

Good catch, thanks Venkatesh

And it doesn't happen in my test, so looks it won't be easy to trigger, :-)

>> 2. A second command to the same target enters virtscsi_pick_vq(). It
>>    will hit the same atomic inc, take the upper branch of the
>>    conditional, and read out a stale (or NULL) tgt->req_vq.

Yes, that can't be avoided without spinlock and the 'stale' req_vq is
still fine, and it isn't a big deal since the window is very very small.

>>
>> Specifically:
>>
>> @@ -508,19 +507,33 @@ static struct virtio_scsi_vq
>> *virtscsi_pick_vq(struct virtio_scsi *vscsi,
>>      unsigned long flags;
>>      u32 queue_num;
>>
>> -    spin_lock_irqsave(&tgt->tgt_lock, flags);
>> +    local_irq_save(flags);
>> +    if (atomic_inc_return(&tgt->reqs) > 1) {
>> +        unsigned long seq;
>> +
>> +        do {
>> +            seq = read_seqcount_begin(&tgt->tgt_seq);
>> +            vq = tgt->req_vq;
>> +        } while (read_seqcount_retry(&tgt->tgt_seq, seq));
>> +    } else {
>>
>> A second virtscsi_pick_vq() here will read a stale or NULL tgt->req_vq.
>
>
> The NULL case is true, indeed I was going to send a patch to initialize
> tgt->req_vq but I have not tested it.
>
> diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
> index fc054935eb1f..f0b4cdbfceb0 100644
> --- a/drivers/scsi/virtio_scsi.c
> +++ b/drivers/scsi/virtio_scsi.c
> @@ -618,14 +631,17 @@ static int virtscsi_abort(struct scsi_cmnd *sc)
>
>  static int virtscsi_target_alloc(struct scsi_target *starget)
>  {
> +       struct Scsi_Host *sh = dev_to_shost(starget->dev.parent);
> +       struct virtio_scsi *vscsi = shost_priv(sh);
> +
>         struct virtio_scsi_target_state *tgt =
>                                 kmalloc(sizeof(*tgt), GFP_KERNEL);
>         if (!tgt)
>                 return -ENOMEM;
>
>
>         seqcount_init(&tgt->tgt_seq);
>         atomic_set(&tgt->reqs, 0);
> -       tgt->req_vq = NULL;
> +       tgt->req_vq = &vscsi->req_vqs[0];
>
>         starget->hostdata = tgt;
>         return 0;

Paolo, do you need me to integrate this one into the patch? or
you will make it as one standalone?

>
>
> The case of a stale req_vq is okay and is the (IMO reasonable) price to
> pay for allowing more concurrency.  If you have concurrent requests
> from multiple VCPUs, multiqueue is not great for your workload anyway,
> at least with the current steering algorithm.
>
> Paolo


Thanks,
-- 
Ming Lei
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux