linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jason Wang <jasowang@redhat.com>
To: "Enrico Weigelt, metux IT consult" <info@metux.net>,
	linux-kernel@vger.kernel.org
Cc: corbet@lwn.net, linus.walleij@linaro.org,
	bgolaszewski@baylibre.com, mst@redhat.com,
	linux-doc@vger.kernel.org, linux-gpio@vger.kernel.org,
	virtualization@lists.linux-foundation.org,
	linux-riscv@lists.infradead.org
Subject: Re: [PATCH v2 2/2] drivers: gpio: add virtio-gpio guest driver
Date: Mon, 7 Dec 2020 11:48:54 +0800	[thread overview]
Message-ID: <37a9fbc6-d75f-f6cd-f052-0dd416594a84@redhat.com> (raw)
In-Reply-To: <43f1ee89-89f3-95a3-58f1-7a0a12c2b92f@metux.net>


On 2020/12/4 下午5:36, Enrico Weigelt, metux IT consult wrote:
> On 04.12.20 04:35, Jason Wang wrote:
>
> Hi,
>
>> Is the plan to keep this doc synced with the one in the virtio
>> specification?
> Yes, of course. I'm still in progress of doing the beaurocratic stuff w/
> virtio-tc folks (ID registration, ...) - yet have to see whether they
> wanna add it to their spec documents ...
>
> BTW: if you feel, sometings not good w/ the current spec, please raise
> your voice now.


But, has the spec path posted?


>
>> I think it's better to use u8 ot uint8_t here.Git grep told me the
>> former is more popular under Documentation/.
> thx, I'll fix that
>
>>> +- for version field currently only value 1 supported.
>>> +- the line names block holds a stream of zero-terminated strings,
>>> +  holding the individual line names.
>> I'm not sure but does this mean we don't have a fixed length of config
>> space? Need to check whether it can bring any trouble to
>> migration(compatibility).
> Yes, it depends on how many gpio lines are present and how much space
> their names take up.
>
> A fixed size would either put unpleasent limits on the max number of
> lines or waste a lot space when only few lines present.
>
> Not that virtio-gpio is also meant for small embedded workloads running
> under some hypervisor.
>
>>> +- unspecified fields are reserved for future use and should be zero.
>>> +
>>> +------------------------
>>> +Virtqueues and messages:
>>> +------------------------
>>> +
>>> +- Queue #0: transmission from host to guest
>>> +- Queue #1: transmission from guest to host
>>
>> Virtio became more a popular in the area without virtualization. So I
>> think it's better to use "device/driver" instead of "host/guest" here.
> Good point. But I'd prefer "cpu" instead of "driver" in that case.
>
>> Not a native speaker but event sounds like something driver read from
>> device. Looking at the below lists, most of them except for
>> VIRTIO_GPIO_EV_HOST_LEVEL looks more like a command.
> okay, shall I name it "message" ?


It might be better.


>
>> Another question is, what's the benefit of unifying the message format
>> of the two queues. E.g VIRTIO_GPIO_EV_HOST_LEVEL can only works fro rxq.
> Simplicity. Those fields that aren't really relevant (eg. replies also
> carry the line id), can just be ignored.
>
>> Not familiar with GPIO but I wonder the value of a standalone
>> VIRTIO_GPIO_EV_GUEST_DIRECTION_INPUT/OUTPUT. Can we simply imply them in
>> SET/GET_VALUE?
> Would introduce more complexity. Somewhere I'd have to fit in some extra
> bit for differenciating between line state and line direction. The
> direction tells whether the line currently acts as input or output. The
> "value" (hmm, maybe I should rethink terminology here) is the current
> line level (high/low or active/inactive).


Ok.


>
>>> +----------------------
>>> +Data flow:
>>> +----------------------
>>> +
>>> +- all operations, except ``VIRTIO_GPIO_EV_HOST_LEVEL``, are
>>> guest-initiated
>>> +- host replies ``VIRTIO_GPIO_EV_HOST_LEVEL`` OR'ed to the ``type`` field
>>> +- ``VIRTIO_GPIO_EV_HOST_LEVEL`` is only sent asynchronically from
>>> host to guest
>>> +- in replies, a negative ``value`` field denotes an unix-style errno
>>> code
>>
>> Virtio is in a different scope, so we need to define the error code on
>> our own.
>>
>> E.g for virtio-net we define:
>>
>>
>> #define VIRTIO_NET_OK     0
>> #define VIRTIO_NET_ERR    1
> hmm, so I'd need to define all the error codes that possibly could happen ?


Yes, I think you need.


>
>>>    +config GPIO_VIRTIO
>>> +    tristate "VirtIO GPIO support"
>>> +    depends on VIRTIO
>>
>> Let's use select, since there's no prompt for VIRTIO and it doesn't have
>> any dependencies.
> Ok. I just was under the impression that subsystems and busses should
> not be select'ed, but depends on (eg. some time ago tried that w/ gpio
> subsys and failed).
>
>>> +    help
>>> +      Say Y here to enable guest support for virtio-based GPIOs.
>>> +
>>> +      These virtual GPIOs can be routed to real GPIOs or attached to
>>> +      simulators on the host (qemu).
>>
>> It's better to avoid talking host and qemu here for new virtio devices.
> Ok, dropped that line.
>
>>> +static int virtio_gpio_xmit(struct virtio_gpio_priv *priv, int type,
>>> +                int pin, int value, struct virtio_gpio_event *ev)
>>> +{
>>> +    struct scatterlist sg[1];
>>> +    int ret;
>>> +    unsigned long flags;
>>> +
>>> +    WARN_ON(!ev);
>>> +
>>> +    ev->type = type;
>>> +    ev->pin = pin;
>>> +    ev->value = value;
>>> +
>>> +    sg_init_table(sg, 1);
>>> +    sg_set_buf(&sg[0], ev, sizeof(struct virtio_gpio_event));
>>> +
>>> +    spin_lock_irqsave(&priv->vq_lock, flags);
>>> +    ret = virtqueue_add_outbuf(priv->vq_tx, sg, ARRAY_SIZE(sg),
>>> +                   priv, GFP_KERNEL);
>>> +    if (ret < 0) {
>>> +        dev_err(&priv->vdev->dev,
>>> +            "virtqueue_add_outbuf() failed: %d\n", ret);
>>> +        goto out;
>>
>> So except for the error log, the failure is silently ignored by the
>> caller. Is this intended?
> ups, I've forgotten the error handling in the caller. fixed in v3.
>
>>> +static int virtio_gpio_req(struct virtio_gpio_priv *priv, int type,
>>> +               int pin, int value)
>>> +{
>>> +    struct virtio_gpio_event *ev
>>> +        = kzalloc(&priv->vdev->dev, sizeof(struct virtio_gpio_event),
>>> +              GFP_KERNEL);
>>> +
>>> +    if (!ev)
>>> +        return -ENOMEM;
>>> +
>>> +    clear_event(priv, type);
>>> +    virtio_gpio_xmit(priv, type, pin, value, ev);
>>> +    wait_event_interruptible(priv->waitq, check_event(priv, type));
>>
>> If I read the code correctly, this expects there will be at most a
>> single type of event that can be processed at the same time. E.g can
>> upper layer want to read from different lines in parallel? If yes, we
>> need to deal with that.
> @Linus @Bartosz: can that happen or does gpio subsys already serialize
> requests ?
>
> Initially, I tried to protect it by spinlock (so, only one request may
> run at a time, other calls just wait until the first is finished), but
> it crashed when gpio cdev registration calls into the driver (fetches
> the status) while still in bootup.
>
> Don't recall the exact error anymore, but something like an
> inconsistency in the spinlock calls.
>
> Did I just use the wrong type of lock ?


I'm not sure since I am not familiar with GPIO. But a question is, if at 
most one request is allowed, I'm not sure virtio is the best choice here 
since we don't even need a queue(virtqueue) here.


>
>>> +static void virtio_gpio_data_rx(struct virtqueue *vq)
>>> +{
>>> +    struct virtio_gpio_priv *priv = vq->vdev->priv;
>>> +    void *data;
>>> +    unsigned int len;
>>> +    struct virtio_gpio_event *ev;
>>> +
>>> +    data = virtqueue_get_buf(priv->vq_rx, &len);
>>> +    if (!data || !len) {
>>> +        dev_warn(&vq->vdev->dev, "RX received no data ! %d\n", len);
>>> +        return;
>>> +    }
>>> +
>>> +    ev = data;
>>> +    WARN_ON(data != &priv->rcv_buf);
>>> +
>>> +    memcpy(&priv->last, &priv->rcv_buf, sizeof(struct
>>> virtio_gpio_event));
>>> +
>>> +    switch (ev->type) {
>>> +    case VIRTIO_GPIO_EV_HOST_LEVEL:
>>> +        virtio_gpio_signal(priv, ev->type, ev->pin, ev->value);
>>> +        break;
>>> +    default:
>>> +        wakeup_event(priv, ev->type & ~VIRTIO_GPIO_EV_REPLY);
>>
>> This looks suspicious, it looks to me what is done here is, consider we
>> want to do VIRTIO_GPIO_EV_GUEST_SET_VALUE
>>
>> 1) put the event in txq, wait
>> 2) the result is returned from rxq, wakeup
>>
>> It looks to me this is racy since the device should be able to process a
>> batch of descriptors and there's no guarantee that the descriptor is
>> processed in order from the virtio level.
> Not sure whether we're on the same page, but:
>
> VIRTIO_GPIO_EV_HOST_LEVEL is kinda interrupt - it tells cpu when the
> input has changed level. We can receive this async event, it shouldn't
> matter whether somebody else (another thread) is doing a regular call,
> thus waiting for reply at the same time. The reply will be next in
> queue.
>
> What could go wrong here ?


I think it's still about whether or not we need allow a batch of 
requests via a queue. Consider you've submitted two request A and B, and 
if B is done first, current code won't work. This is because, the reply 
is transported via rxq buffers not just reuse the txq buffer if I read 
the code correctly.


>
>
>> I wonder why not introduce two virtqueues:
>>
>> 1) command vq
>> 2) event vq
>>
>> All commands were sent via command vq and then device can write back to
>> the command buffer as other virtio device did. Then there's no worries
>> of batching or out of order completion.
> I've been under the impression that queues only work in only one
> direction. (at least that's what my web research was telling).
>
> Could you please give an example how bi-directional transmission within
> the same queue could look like ?


You can check how virtio-blk did this in:

https://docs.oasis-open.org/virtio/virtio/v1.1/csprd01/virtio-v1.1-csprd01.html#x1-2500006


>
>>> +        break;
>>> +    }
>>> +    virtio_gpio_prepare_inbuf(priv);
>>
>> This assumes at most one event could be generated, is this how GPIO
>> device expect to behave? I think level could change several times.
> Should I add more buffers ?
>
> Maybe add one new buffer per request and one new per received async
> signal ?


It would be safe to fill the whole rxq and do the refill e.g when half 
of the queue is used.


>
>>> +static int virtio_gpio_probe(struct virtio_device *vdev)
>>> +{
>>> +    struct virtio_gpio_priv *priv;
>>> +    struct virtio_gpio_config cf = {};
>>> +    char *name_buffer;
>>> +    const char **gpio_names = NULL;
>>> +    struct device *dev = &vdev->dev;
>>> +
>>> +    priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
>>> +    if (!priv)
>>> +        return -ENOMEM;
>>
>> Is devres guaranteed to be enabled here?
> How should it not ? Could virtio probing so early that even devm
> isn't working yet ?


I think you are right, I misread the patch.

Thanks


>
>
> --mtx
>


  reply	other threads:[~2020-12-07  3:50 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-03 19:11 [PATCH v2 1/2] drivers: gpio: put virtual gpio device into their own submenu Enrico Weigelt, metux IT consult
2020-12-03 19:11 ` [PATCH v2 2/2] drivers: gpio: add virtio-gpio guest driver Enrico Weigelt, metux IT consult
2020-12-04  3:35   ` Jason Wang
2020-12-04  9:36     ` Enrico Weigelt, metux IT consult
2020-12-07  3:48       ` Jason Wang [this message]
2020-12-07  9:33         ` Enrico Weigelt, metux IT consult
2020-12-08  2:49           ` Jason Wang
2021-04-13 11:07       ` Alex Bennée
2020-12-05  7:59     ` Enrico Weigelt, metux IT consult
2020-12-05 19:32       ` Michael S. Tsirkin
2020-12-05 20:05         ` Enrico Weigelt, metux IT consult
2020-12-07  3:16           ` Jason Wang
2020-12-07 13:52           ` Michael S. Tsirkin
2020-12-07 20:34             ` Enrico Weigelt, metux IT consult
2020-12-07  3:12         ` Jason Wang
2020-12-07 13:53           ` Michael S. Tsirkin
2020-12-08  2:36             ` Jason Wang
2020-12-08  7:02               ` Enrico Weigelt, metux IT consult
2020-12-09  9:31                 ` Jason Wang
2020-12-09 10:33                   ` Enrico Weigelt, metux IT consult
2020-12-08 10:10         ` Michal Suchánek
2020-12-08 12:33           ` Enrico Weigelt, metux IT consult
2020-12-09 10:34             ` Michal Suchánek
2020-12-05 20:15   ` Howto listen to/handle gpio state changes ? " Enrico Weigelt, metux IT consult
2020-12-08  9:38     ` Linus Walleij
2020-12-08 14:04       ` Enrico Weigelt, metux IT consult
2020-12-08 16:15         ` Grygorii Strashko
2020-12-09  8:51         ` Linus Walleij
2020-12-09 11:19           ` Arnd Bergmann
2020-12-09 12:53             ` Linus Walleij
2020-12-09 20:22               ` Grygorii Strashko
2020-12-09 20:38                 ` Arnd Bergmann
2020-12-10 13:32                   ` Grygorii Strashko
2021-05-24 11:27   ` Viresh Kumar
2021-05-25 12:59     ` Enrico Weigelt, metux IT consult
2021-05-26  3:32       ` Viresh Kumar
2021-07-03  8:05         ` Michael S. Tsirkin
2021-07-05  3:51           ` Viresh Kumar
2020-12-07  9:55 ` [PATCH v2 1/2] drivers: gpio: put virtual gpio device into their own submenu Andy Shevchenko
2020-12-07 10:31 ` Bartosz Golaszewski
2020-12-07 11:22   ` Enrico Weigelt, metux IT consult

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=37a9fbc6-d75f-f6cd-f052-0dd416594a84@redhat.com \
    --to=jasowang@redhat.com \
    --cc=bgolaszewski@baylibre.com \
    --cc=corbet@lwn.net \
    --cc=info@metux.net \
    --cc=linus.walleij@linaro.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=mst@redhat.com \
    --cc=virtualization@lists.linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).