2020-11-04 15:34:05

by Alexander Lobakin

[permalink] [raw]
Subject: [PATCH virtio] virtio: virtio_console: fix DMA memory allocation for rproc serial

Since commit 086d08725d34 ("remoteproc: create vdev subdevice with
specific dma memory pool"), every remoteproc has a DMA subdevice
("remoteprocX#vdevYbuffer") for each virtio device, which inherits
DMA capabilities from the corresponding platform device. This allowed
to associate different DMA pools with each vdev, and required from
virtio drivers to perform DMA operations with the parent device
(vdev->dev.parent) instead of grandparent (vdev->dev.parent->parent).

virtio_rpmsg_bus was already changed in the same merge cycle with
commit d999b622fcfb ("rpmsg: virtio: allocate buffer from parent"),
but virtio_console did not. In fact, operations using the grandparent
worked fine while the grandparent was the platform device, but since
commit c774ad010873 ("remoteproc: Fix and restore the parenting
hierarchy for vdev") this was changed, and now the grandparent device
is the remoteproc device without any DMA capabilities.
So, starting v5.8-rc1 the following warning is observed:

[ 2.483925] ------------[ cut here ]------------
[ 2.489148] WARNING: CPU: 3 PID: 101 at kernel/dma/mapping.c:427 0x80e7eee8
[ 2.489152] Modules linked in: virtio_console(+)
[ 2.503737] virtio_rpmsg_bus rpmsg_core
[ 2.508903]
[ 2.528898] <Other modules, stack and call trace here>
[ 2.913043]
[ 2.914907] ---[ end trace 93ac8746beab612c ]---
[ 2.920102] virtio-ports vport1p0: Error allocating inbufs

kernel/dma/mapping.c:427 is:

WARN_ON_ONCE(!dev->coherent_dma_mask);

obviously because the grandparent now is remoteproc dev without any
DMA caps:

[ 3.104943] Parent: remoteproc0#vdev1buffer, grandparent: remoteproc0

Fix this the same way as it was for virtio_rpmsg_bus, using just the
parent device (vdev->dev.parent, "remoteprocX#vdevYbuffer") for DMA
operations.
This also allows now to reserve DMA pools/buffers for rproc serial
via Device Tree.

Fixes: c774ad010873 ("remoteproc: Fix and restore the parenting hierarchy for vdev")
Cc: [email protected] # 5.1+
Signed-off-by: Alexander Lobakin <[email protected]>
---
drivers/char/virtio_console.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index a2da8f768b94..1836cc56e357 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -435,12 +435,12 @@ static struct port_buffer *alloc_buf(struct virtio_device *vdev, size_t buf_size
/*
* Allocate DMA memory from ancestor. When a virtio
* device is created by remoteproc, the DMA memory is
- * associated with the grandparent device:
- * vdev => rproc => platform-dev.
+ * associated with the parent device:
+ * virtioY => remoteprocX#vdevYbuffer.
*/
- if (!vdev->dev.parent || !vdev->dev.parent->parent)
+ buf->dev = vdev->dev.parent;
+ if (!buf->dev)
goto free_buf;
- buf->dev = vdev->dev.parent->parent;

/* Increase device refcnt to avoid freeing it */
get_device(buf->dev);
--
2.29.2



2020-11-04 20:37:31

by Mathieu Poirier

[permalink] [raw]
Subject: Re: [PATCH virtio] virtio: virtio_console: fix DMA memory allocation for rproc serial

On Wed, Nov 04, 2020 at 03:31:36PM +0000, Alexander Lobakin wrote:
> Since commit 086d08725d34 ("remoteproc: create vdev subdevice with
> specific dma memory pool"), every remoteproc has a DMA subdevice
> ("remoteprocX#vdevYbuffer") for each virtio device, which inherits
> DMA capabilities from the corresponding platform device. This allowed
> to associate different DMA pools with each vdev, and required from
> virtio drivers to perform DMA operations with the parent device
> (vdev->dev.parent) instead of grandparent (vdev->dev.parent->parent).
>
> virtio_rpmsg_bus was already changed in the same merge cycle with
> commit d999b622fcfb ("rpmsg: virtio: allocate buffer from parent"),
> but virtio_console did not. In fact, operations using the grandparent
> worked fine while the grandparent was the platform device, but since
> commit c774ad010873 ("remoteproc: Fix and restore the parenting
> hierarchy for vdev") this was changed, and now the grandparent device
> is the remoteproc device without any DMA capabilities.
> So, starting v5.8-rc1 the following warning is observed:
>
> [ 2.483925] ------------[ cut here ]------------
> [ 2.489148] WARNING: CPU: 3 PID: 101 at kernel/dma/mapping.c:427 0x80e7eee8
> [ 2.489152] Modules linked in: virtio_console(+)
> [ 2.503737] virtio_rpmsg_bus rpmsg_core
> [ 2.508903]
> [ 2.528898] <Other modules, stack and call trace here>
> [ 2.913043]
> [ 2.914907] ---[ end trace 93ac8746beab612c ]---
> [ 2.920102] virtio-ports vport1p0: Error allocating inbufs
>
> kernel/dma/mapping.c:427 is:
>
> WARN_ON_ONCE(!dev->coherent_dma_mask);
>
> obviously because the grandparent now is remoteproc dev without any
> DMA caps:

You are correct.

>
> [ 3.104943] Parent: remoteproc0#vdev1buffer, grandparent: remoteproc0
>
> Fix this the same way as it was for virtio_rpmsg_bus, using just the
> parent device (vdev->dev.parent, "remoteprocX#vdevYbuffer") for DMA
> operations.
> This also allows now to reserve DMA pools/buffers for rproc serial
> via Device Tree.
>
> Fixes: c774ad010873 ("remoteproc: Fix and restore the parenting hierarchy for vdev")
> Cc: [email protected] # 5.1+
> Signed-off-by: Alexander Lobakin <[email protected]>
> ---
> drivers/char/virtio_console.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
> index a2da8f768b94..1836cc56e357 100644
> --- a/drivers/char/virtio_console.c
> +++ b/drivers/char/virtio_console.c
> @@ -435,12 +435,12 @@ static struct port_buffer *alloc_buf(struct virtio_device *vdev, size_t buf_size
> /*
> * Allocate DMA memory from ancestor. When a virtio
> * device is created by remoteproc, the DMA memory is
> - * associated with the grandparent device:
> - * vdev => rproc => platform-dev.
> + * associated with the parent device:
> + * virtioY => remoteprocX#vdevYbuffer.
> */
> - if (!vdev->dev.parent || !vdev->dev.parent->parent)
> + buf->dev = vdev->dev.parent;
> + if (!buf->dev)
> goto free_buf;
> - buf->dev = vdev->dev.parent->parent;

Reviewed-by: Mathieu Poirier <[email protected]>

>
> /* Increase device refcnt to avoid freeing it */
> get_device(buf->dev);
> --
> 2.29.2
>
>

2020-11-05 06:38:15

by Jason Wang

[permalink] [raw]
Subject: Re: [PATCH virtio] virtio: virtio_console: fix DMA memory allocation for rproc serial


On 2020/11/4 下午11:31, Alexander Lobakin wrote:
> Since commit 086d08725d34 ("remoteproc: create vdev subdevice with
> specific dma memory pool"), every remoteproc has a DMA subdevice
> ("remoteprocX#vdevYbuffer") for each virtio device, which inherits
> DMA capabilities from the corresponding platform device. This allowed
> to associate different DMA pools with each vdev, and required from
> virtio drivers to perform DMA operations with the parent device
> (vdev->dev.parent) instead of grandparent (vdev->dev.parent->parent).
>
> virtio_rpmsg_bus was already changed in the same merge cycle with
> commit d999b622fcfb ("rpmsg: virtio: allocate buffer from parent"),
> but virtio_console did not. In fact, operations using the grandparent
> worked fine while the grandparent was the platform device, but since
> commit c774ad010873 ("remoteproc: Fix and restore the parenting
> hierarchy for vdev") this was changed, and now the grandparent device
> is the remoteproc device without any DMA capabilities.
> So, starting v5.8-rc1 the following warning is observed:
>
> [ 2.483925] ------------[ cut here ]------------
> [ 2.489148] WARNING: CPU: 3 PID: 101 at kernel/dma/mapping.c:427 0x80e7eee8
> [ 2.489152] Modules linked in: virtio_console(+)
> [ 2.503737] virtio_rpmsg_bus rpmsg_core
> [ 2.508903]
> [ 2.528898] <Other modules, stack and call trace here>
> [ 2.913043]
> [ 2.914907] ---[ end trace 93ac8746beab612c ]---
> [ 2.920102] virtio-ports vport1p0: Error allocating inbufs
>
> kernel/dma/mapping.c:427 is:
>
> WARN_ON_ONCE(!dev->coherent_dma_mask);
>
> obviously because the grandparent now is remoteproc dev without any
> DMA caps:
>
> [ 3.104943] Parent: remoteproc0#vdev1buffer, grandparent: remoteproc0
>
> Fix this the same way as it was for virtio_rpmsg_bus, using just the
> parent device (vdev->dev.parent, "remoteprocX#vdevYbuffer") for DMA
> operations.
> This also allows now to reserve DMA pools/buffers for rproc serial
> via Device Tree.
>
> Fixes: c774ad010873 ("remoteproc: Fix and restore the parenting hierarchy for vdev")
> Cc: [email protected] # 5.1+
> Signed-off-by: Alexander Lobakin <[email protected]>
> ---
> drivers/char/virtio_console.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
> index a2da8f768b94..1836cc56e357 100644
> --- a/drivers/char/virtio_console.c
> +++ b/drivers/char/virtio_console.c
> @@ -435,12 +435,12 @@ static struct port_buffer *alloc_buf(struct virtio_device *vdev, size_t buf_size
> /*
> * Allocate DMA memory from ancestor. When a virtio
> * device is created by remoteproc, the DMA memory is
> - * associated with the grandparent device:
> - * vdev => rproc => platform-dev.
> + * associated with the parent device:
> + * virtioY => remoteprocX#vdevYbuffer.
> */
> - if (!vdev->dev.parent || !vdev->dev.parent->parent)
> + buf->dev = vdev->dev.parent;
> + if (!buf->dev)
> goto free_buf;
> - buf->dev = vdev->dev.parent->parent;


I wonder it could be the right time to introduce dma_dev for virtio
instead of depending on something magic via parent.

(Btw I don't even notice that there's transport specific code in virtio
console, it's better to avoid it)

Thanks


>
> /* Increase device refcnt to avoid freeing it */
> get_device(buf->dev);

2020-11-05 12:24:18

by Alexander Lobakin

[permalink] [raw]
Subject: Re: [PATCH virtio] virtio: virtio_console: fix DMA memory allocation for rproc serial

From: Jason Wang <[email protected]>
Date: Thu, 5 Nov 2020 11:10:24 +0800

Hi Jason,

> On 2020/11/4 下午11:31, Alexander Lobakin wrote:
>> Since commit 086d08725d34 ("remoteproc: create vdev subdevice with
>> specific dma memory pool"), every remoteproc has a DMA subdevice
>> ("remoteprocX#vdevYbuffer") for each virtio device, which inherits
>> DMA capabilities from the corresponding platform device. This allowed
>> to associate different DMA pools with each vdev, and required from
>> virtio drivers to perform DMA operations with the parent device
>> (vdev->dev.parent) instead of grandparent (vdev->dev.parent->parent).
>>
>> virtio_rpmsg_bus was already changed in the same merge cycle with
>> commit d999b622fcfb ("rpmsg: virtio: allocate buffer from parent"),
>> but virtio_console did not. In fact, operations using the grandparent
>> worked fine while the grandparent was the platform device, but since
>> commit c774ad010873 ("remoteproc: Fix and restore the parenting
>> hierarchy for vdev") this was changed, and now the grandparent device
>> is the remoteproc device without any DMA capabilities.
>> So, starting v5.8-rc1 the following warning is observed:
>>
>> [ 2.483925] ------------[ cut here ]------------
>> [ 2.489148] WARNING: CPU: 3 PID: 101 at kernel/dma/mapping.c:427 0x80e7eee8
>> [ 2.489152] Modules linked in: virtio_console(+)
>> [ 2.503737] virtio_rpmsg_bus rpmsg_core
>> [ 2.508903]
>> [ 2.528898] <Other modules, stack and call trace here>
>> [ 2.913043]
>> [ 2.914907] ---[ end trace 93ac8746beab612c ]---
>> [ 2.920102] virtio-ports vport1p0: Error allocating inbufs
>>
>> kernel/dma/mapping.c:427 is:
>>
>> WARN_ON_ONCE(!dev->coherent_dma_mask);
>>
>> obviously because the grandparent now is remoteproc dev without any
>> DMA caps:
>>
>> [ 3.104943] Parent: remoteproc0#vdev1buffer, grandparent: remoteproc0
>>
>> Fix this the same way as it was for virtio_rpmsg_bus, using just the
>> parent device (vdev->dev.parent, "remoteprocX#vdevYbuffer") for DMA
>> operations.
>> This also allows now to reserve DMA pools/buffers for rproc serial
>> via Device Tree.
>>
>> Fixes: c774ad010873 ("remoteproc: Fix and restore the parenting hierarchy for vdev")
>> Cc: [email protected] # 5.1+
>> Signed-off-by: Alexander Lobakin <[email protected]>
>> ---
>> drivers/char/virtio_console.c | 8 ++++----
>> 1 file changed, 4 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
>> index a2da8f768b94..1836cc56e357 100644
>> --- a/drivers/char/virtio_console.c
>> +++ b/drivers/char/virtio_console.c
>> @@ -435,12 +435,12 @@ static struct port_buffer *alloc_buf(struct virtio_device *vdev, size_t buf_size
>> /*
>> * Allocate DMA memory from ancestor. When a virtio
>> * device is created by remoteproc, the DMA memory is
>> - * associated with the grandparent device:
>> - * vdev => rproc => platform-dev.
>> + * associated with the parent device:
>> + * virtioY => remoteprocX#vdevYbuffer.
>> */
>> - if (!vdev->dev.parent || !vdev->dev.parent->parent)
>> + buf->dev = vdev->dev.parent;
>> + if (!buf->dev)
>> goto free_buf;
>> - buf->dev = vdev->dev.parent->parent;
>
>
> I wonder it could be the right time to introduce dma_dev for virtio
> instead of depending on something magic via parent.

This patch are meant to hit RC window and stable trees as a fix of
the bug that is present since v5.8-rc1. So any new features are out
of scope of this particular fix.

The idea of DMAing through "dev->parent" is that "virtioX" itself is a
logical dev, not the real one, but its parent *is*. This logic is used
across the whole tree -- every subsystem creates its own logical device,
but drivers should always use the backing PCI/platform/etc. devices for
DMA operations, which represent the real hardware.

> (Btw I don't even notice that there's transport specific code in virtio
> console, it's better to avoid it)
>
> Thanks

Thanks,
Al

>>
>> /* Increase device refcnt to avoid freeing it */
>> get_device(buf->dev);

2020-11-09 06:09:15

by Jason Wang

[permalink] [raw]
Subject: Re: [PATCH virtio] virtio: virtio_console: fix DMA memory allocation for rproc serial


On 2020/11/5 下午8:22, Alexander Lobakin wrote:
> From: Jason Wang <[email protected]>
> Date: Thu, 5 Nov 2020 11:10:24 +0800
>
> Hi Jason,
>
>> On 2020/11/4 下午11:31, Alexander Lobakin wrote:
>>> Since commit 086d08725d34 ("remoteproc: create vdev subdevice with
>>> specific dma memory pool"), every remoteproc has a DMA subdevice
>>> ("remoteprocX#vdevYbuffer") for each virtio device, which inherits
>>> DMA capabilities from the corresponding platform device. This allowed
>>> to associate different DMA pools with each vdev, and required from
>>> virtio drivers to perform DMA operations with the parent device
>>> (vdev->dev.parent) instead of grandparent (vdev->dev.parent->parent).
>>>
>>> virtio_rpmsg_bus was already changed in the same merge cycle with
>>> commit d999b622fcfb ("rpmsg: virtio: allocate buffer from parent"),
>>> but virtio_console did not. In fact, operations using the grandparent
>>> worked fine while the grandparent was the platform device, but since
>>> commit c774ad010873 ("remoteproc: Fix and restore the parenting
>>> hierarchy for vdev") this was changed, and now the grandparent device
>>> is the remoteproc device without any DMA capabilities.
>>> So, starting v5.8-rc1 the following warning is observed:
>>>
>>> [ 2.483925] ------------[ cut here ]------------
>>> [ 2.489148] WARNING: CPU: 3 PID: 101 at kernel/dma/mapping.c:427 0x80e7eee8
>>> [ 2.489152] Modules linked in: virtio_console(+)
>>> [ 2.503737] virtio_rpmsg_bus rpmsg_core
>>> [ 2.508903]
>>> [ 2.528898] <Other modules, stack and call trace here>
>>> [ 2.913043]
>>> [ 2.914907] ---[ end trace 93ac8746beab612c ]---
>>> [ 2.920102] virtio-ports vport1p0: Error allocating inbufs
>>>
>>> kernel/dma/mapping.c:427 is:
>>>
>>> WARN_ON_ONCE(!dev->coherent_dma_mask);
>>>
>>> obviously because the grandparent now is remoteproc dev without any
>>> DMA caps:
>>>
>>> [ 3.104943] Parent: remoteproc0#vdev1buffer, grandparent: remoteproc0
>>>
>>> Fix this the same way as it was for virtio_rpmsg_bus, using just the
>>> parent device (vdev->dev.parent, "remoteprocX#vdevYbuffer") for DMA
>>> operations.
>>> This also allows now to reserve DMA pools/buffers for rproc serial
>>> via Device Tree.
>>>
>>> Fixes: c774ad010873 ("remoteproc: Fix and restore the parenting hierarchy for vdev")
>>> Cc: [email protected] # 5.1+
>>> Signed-off-by: Alexander Lobakin <[email protected]>
>>> ---
>>> drivers/char/virtio_console.c | 8 ++++----
>>> 1 file changed, 4 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
>>> index a2da8f768b94..1836cc56e357 100644
>>> --- a/drivers/char/virtio_console.c
>>> +++ b/drivers/char/virtio_console.c
>>> @@ -435,12 +435,12 @@ static struct port_buffer *alloc_buf(struct virtio_device *vdev, size_t buf_size
>>> /*
>>> * Allocate DMA memory from ancestor. When a virtio
>>> * device is created by remoteproc, the DMA memory is
>>> - * associated with the grandparent device:
>>> - * vdev => rproc => platform-dev.
>>> + * associated with the parent device:
>>> + * virtioY => remoteprocX#vdevYbuffer.
>>> */
>>> - if (!vdev->dev.parent || !vdev->dev.parent->parent)
>>> + buf->dev = vdev->dev.parent;
>>> + if (!buf->dev)
>>> goto free_buf;
>>> - buf->dev = vdev->dev.parent->parent;
>>
>> I wonder it could be the right time to introduce dma_dev for virtio
>> instead of depending on something magic via parent.
> This patch are meant to hit RC window and stable trees as a fix of
> the bug that is present since v5.8-rc1. So any new features are out
> of scope of this particular fix.


Right.


>
> The idea of DMAing through "dev->parent" is that "virtioX" itself is a
> logical dev, not the real one, but its parent *is*. This logic is used
> across the whole tree -- every subsystem creates its own logical device,
> but drivers should always use the backing PCI/platform/etc. devices for
> DMA operations, which represent the real hardware.


Yes, so what I meant is to use different variables for DMA and
hierarchy. So it's the responsibility of the lower layer to pass a
correct "dma_dev" to the upper layer instead of depending parent.

Anyway for this patch.

Acked-by: Jason Wang <[email protected]>

Thanks


>
>> (Btw I don't even notice that there's transport specific code in virtio
>> console, it's better to avoid it)
>>
>> Thanks
> Thanks,
> Al
>
>>> /* Increase device refcnt to avoid freeing it */
>>> get_device(buf->dev);

2020-11-16 09:56:16

by Michael S. Tsirkin

[permalink] [raw]
Subject: Re: [PATCH virtio] virtio: virtio_console: fix DMA memory allocation for rproc serial

On Mon, Nov 16, 2020 at 09:19:50AM +0000, Christoph Hellwig wrote:
> I just noticed this showing up in Linus' tree and I'm not happy.
>
> This whole model of the DMA subdevices in remoteproc is simply broken.
>
> We really need to change the virtio code pass an expicit DMA device (
> similar to what e.g. the USB and RDMA code does),

Could you point me at an example or two please?

Thanks!

> instead of faking up
> devices with broken adhoc inheritance of DMA properties and magic poking
> into device parent relationships.
>
> Bjorn, I thought you were going to look into this a while ago?
>
>
> On Wed, Nov 04, 2020 at 03:31:36PM +0000, Alexander Lobakin wrote:
> > Since commit 086d08725d34 ("remoteproc: create vdev subdevice with
> > specific dma memory pool"), every remoteproc has a DMA subdevice
> > ("remoteprocX#vdevYbuffer") for each virtio device, which inherits
> > DMA capabilities from the corresponding platform device. This allowed
> > to associate different DMA pools with each vdev, and required from
> > virtio drivers to perform DMA operations with the parent device
> > (vdev->dev.parent) instead of grandparent (vdev->dev.parent->parent).
> >
> > virtio_rpmsg_bus was already changed in the same merge cycle with
> > commit d999b622fcfb ("rpmsg: virtio: allocate buffer from parent"),
> > but virtio_console did not. In fact, operations using the grandparent
> > worked fine while the grandparent was the platform device, but since
> > commit c774ad010873 ("remoteproc: Fix and restore the parenting
> > hierarchy for vdev") this was changed, and now the grandparent device
> > is the remoteproc device without any DMA capabilities.
> > So, starting v5.8-rc1 the following warning is observed:
> >
> > [ 2.483925] ------------[ cut here ]------------
> > [ 2.489148] WARNING: CPU: 3 PID: 101 at kernel/dma/mapping.c:427 0x80e7eee8
> > [ 2.489152] Modules linked in: virtio_console(+)
> > [ 2.503737] virtio_rpmsg_bus rpmsg_core
> > [ 2.508903]
> > [ 2.528898] <Other modules, stack and call trace here>
> > [ 2.913043]
> > [ 2.914907] ---[ end trace 93ac8746beab612c ]---
> > [ 2.920102] virtio-ports vport1p0: Error allocating inbufs
> >
> > kernel/dma/mapping.c:427 is:
> >
> > WARN_ON_ONCE(!dev->coherent_dma_mask);
> >
> > obviously because the grandparent now is remoteproc dev without any
> > DMA caps:
> >
> > [ 3.104943] Parent: remoteproc0#vdev1buffer, grandparent: remoteproc0
> >
> > Fix this the same way as it was for virtio_rpmsg_bus, using just the
> > parent device (vdev->dev.parent, "remoteprocX#vdevYbuffer") for DMA
> > operations.
> > This also allows now to reserve DMA pools/buffers for rproc serial
> > via Device Tree.
> >
> > Fixes: c774ad010873 ("remoteproc: Fix and restore the parenting hierarchy for vdev")
> > Cc: [email protected] # 5.1+
> > Signed-off-by: Alexander Lobakin <[email protected]>
> > ---
> > drivers/char/virtio_console.c | 8 ++++----
> > 1 file changed, 4 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
> > index a2da8f768b94..1836cc56e357 100644
> > --- a/drivers/char/virtio_console.c
> > +++ b/drivers/char/virtio_console.c
> > @@ -435,12 +435,12 @@ static struct port_buffer *alloc_buf(struct virtio_device *vdev, size_t buf_size
> > /*
> > * Allocate DMA memory from ancestor. When a virtio
> > * device is created by remoteproc, the DMA memory is
> > - * associated with the grandparent device:
> > - * vdev => rproc => platform-dev.
> > + * associated with the parent device:
> > + * virtioY => remoteprocX#vdevYbuffer.
> > */
> > - if (!vdev->dev.parent || !vdev->dev.parent->parent)
> > + buf->dev = vdev->dev.parent;
> > + if (!buf->dev)
> > goto free_buf;
> > - buf->dev = vdev->dev.parent->parent;
> >
> > /* Increase device refcnt to avoid freeing it */
> > get_device(buf->dev);
> > --
> > 2.29.2
> >
> >
> ---end quoted text---

2020-11-16 10:49:27

by Arnaud POULIQUEN

[permalink] [raw]
Subject: Re: [PATCH virtio] virtio: virtio_console: fix DMA memory allocation for rproc serial

Hi all,

On 11/16/20 10:19 AM, Christoph Hellwig wrote:
> I just noticed this showing up in Linus' tree and I'm not happy.
>
> This whole model of the DMA subdevices in remoteproc is simply broken.
>
> We really need to change the virtio code pass an expicit DMA device (
> similar to what e.g. the USB and RDMA code does), instead of faking up
> devices with broken adhoc inheritance of DMA properties and magic poking
> into device parent relationships.

For your formation I started some stuff on my side to be able to declare the
virtio device in DT as a remoteproc child node.

https://lkml.org/lkml/2020/4/16/1817

Quite big refactoring, but could be a way to answer...

Regards,
Arnaud

>
> Bjorn, I thought you were going to look into this a while ago?


>
>
> On Wed, Nov 04, 2020 at 03:31:36PM +0000, Alexander Lobakin wrote:
>> Since commit 086d08725d34 ("remoteproc: create vdev subdevice with
>> specific dma memory pool"), every remoteproc has a DMA subdevice
>> ("remoteprocX#vdevYbuffer") for each virtio device, which inherits
>> DMA capabilities from the corresponding platform device. This allowed
>> to associate different DMA pools with each vdev, and required from
>> virtio drivers to perform DMA operations with the parent device
>> (vdev->dev.parent) instead of grandparent (vdev->dev.parent->parent).
>>
>> virtio_rpmsg_bus was already changed in the same merge cycle with
>> commit d999b622fcfb ("rpmsg: virtio: allocate buffer from parent"),
>> but virtio_console did not. In fact, operations using the grandparent
>> worked fine while the grandparent was the platform device, but since
>> commit c774ad010873 ("remoteproc: Fix and restore the parenting
>> hierarchy for vdev") this was changed, and now the grandparent device
>> is the remoteproc device without any DMA capabilities.
>> So, starting v5.8-rc1 the following warning is observed:
>>
>> [ 2.483925] ------------[ cut here ]------------
>> [ 2.489148] WARNING: CPU: 3 PID: 101 at kernel/dma/mapping.c:427 0x80e7eee8
>> [ 2.489152] Modules linked in: virtio_console(+)
>> [ 2.503737] virtio_rpmsg_bus rpmsg_core
>> [ 2.508903]
>> [ 2.528898] <Other modules, stack and call trace here>
>> [ 2.913043]
>> [ 2.914907] ---[ end trace 93ac8746beab612c ]---
>> [ 2.920102] virtio-ports vport1p0: Error allocating inbufs
>>
>> kernel/dma/mapping.c:427 is:
>>
>> WARN_ON_ONCE(!dev->coherent_dma_mask);
>>
>> obviously because the grandparent now is remoteproc dev without any
>> DMA caps:
>>
>> [ 3.104943] Parent: remoteproc0#vdev1buffer, grandparent: remoteproc0
>>
>> Fix this the same way as it was for virtio_rpmsg_bus, using just the
>> parent device (vdev->dev.parent, "remoteprocX#vdevYbuffer") for DMA
>> operations.
>> This also allows now to reserve DMA pools/buffers for rproc serial
>> via Device Tree.
>>
>> Fixes: c774ad010873 ("remoteproc: Fix and restore the parenting hierarchy for vdev")
>> Cc: [email protected] # 5.1+
>> Signed-off-by: Alexander Lobakin <[email protected]>
>> ---
>> drivers/char/virtio_console.c | 8 ++++----
>> 1 file changed, 4 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
>> index a2da8f768b94..1836cc56e357 100644
>> --- a/drivers/char/virtio_console.c
>> +++ b/drivers/char/virtio_console.c
>> @@ -435,12 +435,12 @@ static struct port_buffer *alloc_buf(struct virtio_device *vdev, size_t buf_size
>> /*
>> * Allocate DMA memory from ancestor. When a virtio
>> * device is created by remoteproc, the DMA memory is
>> - * associated with the grandparent device:
>> - * vdev => rproc => platform-dev.
>> + * associated with the parent device:
>> + * virtioY => remoteprocX#vdevYbuffer.
>> */
>> - if (!vdev->dev.parent || !vdev->dev.parent->parent)
>> + buf->dev = vdev->dev.parent;
>> + if (!buf->dev)
>> goto free_buf;
>> - buf->dev = vdev->dev.parent->parent;
>>
>> /* Increase device refcnt to avoid freeing it */
>> get_device(buf->dev);
>> --
>> 2.29.2
>>
>>
> ---end quoted text---
>

2020-11-16 12:28:44

by Michael S. Tsirkin

[permalink] [raw]
Subject: Re: [PATCH virtio] virtio: virtio_console: fix DMA memory allocation for rproc serial

On Mon, Nov 16, 2020 at 09:19:50AM +0000, Christoph Hellwig wrote:
> I just noticed this showing up in Linus' tree and I'm not happy.

Are you sure? I think it's in next.

> This whole model of the DMA subdevices in remoteproc is simply broken.
>
> We really need to change the virtio code pass an expicit DMA device (
> similar to what e.g. the USB and RDMA code does), instead of faking up
> devices with broken adhoc inheritance of DMA properties and magic poking
> into device parent relationships.

OK but we do have a regression since 5.7 and this looks like
a fix appropriate for e.g. stable, right?

> Bjorn, I thought you were going to look into this a while ago?
>
>
> On Wed, Nov 04, 2020 at 03:31:36PM +0000, Alexander Lobakin wrote:
> > Since commit 086d08725d34 ("remoteproc: create vdev subdevice with
> > specific dma memory pool"), every remoteproc has a DMA subdevice
> > ("remoteprocX#vdevYbuffer") for each virtio device, which inherits
> > DMA capabilities from the corresponding platform device. This allowed
> > to associate different DMA pools with each vdev, and required from
> > virtio drivers to perform DMA operations with the parent device
> > (vdev->dev.parent) instead of grandparent (vdev->dev.parent->parent).
> >
> > virtio_rpmsg_bus was already changed in the same merge cycle with
> > commit d999b622fcfb ("rpmsg: virtio: allocate buffer from parent"),
> > but virtio_console did not. In fact, operations using the grandparent
> > worked fine while the grandparent was the platform device, but since
> > commit c774ad010873 ("remoteproc: Fix and restore the parenting
> > hierarchy for vdev") this was changed, and now the grandparent device
> > is the remoteproc device without any DMA capabilities.
> > So, starting v5.8-rc1 the following warning is observed:
> >
> > [ 2.483925] ------------[ cut here ]------------
> > [ 2.489148] WARNING: CPU: 3 PID: 101 at kernel/dma/mapping.c:427 0x80e7eee8
> > [ 2.489152] Modules linked in: virtio_console(+)
> > [ 2.503737] virtio_rpmsg_bus rpmsg_core
> > [ 2.508903]
> > [ 2.528898] <Other modules, stack and call trace here>
> > [ 2.913043]
> > [ 2.914907] ---[ end trace 93ac8746beab612c ]---
> > [ 2.920102] virtio-ports vport1p0: Error allocating inbufs
> >
> > kernel/dma/mapping.c:427 is:
> >
> > WARN_ON_ONCE(!dev->coherent_dma_mask);
> >
> > obviously because the grandparent now is remoteproc dev without any
> > DMA caps:
> >
> > [ 3.104943] Parent: remoteproc0#vdev1buffer, grandparent: remoteproc0
> >
> > Fix this the same way as it was for virtio_rpmsg_bus, using just the
> > parent device (vdev->dev.parent, "remoteprocX#vdevYbuffer") for DMA
> > operations.
> > This also allows now to reserve DMA pools/buffers for rproc serial
> > via Device Tree.
> >
> > Fixes: c774ad010873 ("remoteproc: Fix and restore the parenting hierarchy for vdev")
> > Cc: [email protected] # 5.1+
> > Signed-off-by: Alexander Lobakin <[email protected]>
> > ---
> > drivers/char/virtio_console.c | 8 ++++----
> > 1 file changed, 4 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
> > index a2da8f768b94..1836cc56e357 100644
> > --- a/drivers/char/virtio_console.c
> > +++ b/drivers/char/virtio_console.c
> > @@ -435,12 +435,12 @@ static struct port_buffer *alloc_buf(struct virtio_device *vdev, size_t buf_size
> > /*
> > * Allocate DMA memory from ancestor. When a virtio
> > * device is created by remoteproc, the DMA memory is
> > - * associated with the grandparent device:
> > - * vdev => rproc => platform-dev.
> > + * associated with the parent device:
> > + * virtioY => remoteprocX#vdevYbuffer.
> > */
> > - if (!vdev->dev.parent || !vdev->dev.parent->parent)
> > + buf->dev = vdev->dev.parent;
> > + if (!buf->dev)
> > goto free_buf;
> > - buf->dev = vdev->dev.parent->parent;
> >
> > /* Increase device refcnt to avoid freeing it */
> > get_device(buf->dev);
> > --
> > 2.29.2
> >
> >
> ---end quoted text---

2020-11-16 13:09:59

by Alexander Lobakin

[permalink] [raw]
Subject: Re: [PATCH virtio] virtio: virtio_console: fix DMA memory allocation for rproc serial

From: "Michael S. Tsirkin" <[email protected]>
Date: Mon, 16 Nov 2020 07:25:31 -0500

> On Mon, Nov 16, 2020 at 09:19:50AM +0000, Christoph Hellwig wrote:
>> I just noticed this showing up in Linus' tree and I'm not happy.
>
> Are you sure? I think it's in next.

Nope, it goes to fixes since it just fixes the regression introduced
in 5.7.
That's why it's not about any refactoring or rethinking the whole
model.

>> This whole model of the DMA subdevices in remoteproc is simply broken.
>>
>> We really need to change the virtio code pass an expicit DMA device (
>> similar to what e.g. the USB and RDMA code does), instead of faking up
>> devices with broken adhoc inheritance of DMA properties and magic poking
>> into device parent relationships.

But lots of subsystems like netdev for example uses dev->parent for
DMA operations. I know that their pointers go directly to the
platform/PCI/etc. device, but still.

The only reason behind "fake" DMA devices for rproc is to be able to
reserve DMA memory through the Device Tree exclusively for only one
virtio dev like virtio_console or virtio_rpmsg_bus. That's why
they are present, are coercing DMA caps from physical dev
representor, and why questinable dma_declare_coherent_memory()
is still here and doesn't allow to build rproc core as a module.
I agree that this is not the best model obviously, and we should take
a look at it.

> OK but we do have a regression since 5.7 and this looks like
> a fix appropriate for e.g. stable, right?
>
>> Bjorn, I thought you were going to look into this a while ago?
>>
>>
>> On Wed, Nov 04, 2020 at 03:31:36PM +0000, Alexander Lobakin wrote:
>>> Since commit 086d08725d34 ("remoteproc: create vdev subdevice with
>>> specific dma memory pool"), every remoteproc has a DMA subdevice
>>> ("remoteprocX#vdevYbuffer") for each virtio device, which inherits
>>> DMA capabilities from the corresponding platform device. This allowed
>>> to associate different DMA pools with each vdev, and required from
>>> virtio drivers to perform DMA operations with the parent device
>>> (vdev->dev.parent) instead of grandparent (vdev->dev.parent->parent).
>>>
>>> virtio_rpmsg_bus was already changed in the same merge cycle with
>>> commit d999b622fcfb ("rpmsg: virtio: allocate buffer from parent"),
>>> but virtio_console did not. In fact, operations using the grandparent
>>> worked fine while the grandparent was the platform device, but since
>>> commit c774ad010873 ("remoteproc: Fix and restore the parenting
>>> hierarchy for vdev") this was changed, and now the grandparent device
>>> is the remoteproc device without any DMA capabilities.
>>> So, starting v5.8-rc1 the following warning is observed:
>>>
>>> [ 2.483925] ------------[ cut here ]------------
>>> [ 2.489148] WARNING: CPU: 3 PID: 101 at kernel/dma/mapping.c:427 0x80e7eee8
>>> [ 2.489152] Modules linked in: virtio_console(+)
>>> [ 2.503737] virtio_rpmsg_bus rpmsg_core
>>> [ 2.508903]
>>> [ 2.528898] <Other modules, stack and call trace here>
>>> [ 2.913043]
>>> [ 2.914907] ---[ end trace 93ac8746beab612c ]---
>>> [ 2.920102] virtio-ports vport1p0: Error allocating inbufs
>>>
>>> kernel/dma/mapping.c:427 is:
>>>
>>> WARN_ON_ONCE(!dev->coherent_dma_mask);
>>>
>>> obviously because the grandparent now is remoteproc dev without any
>>> DMA caps:
>>>
>>> [ 3.104943] Parent: remoteproc0#vdev1buffer, grandparent: remoteproc0
>>>
>>> Fix this the same way as it was for virtio_rpmsg_bus, using just the
>>> parent device (vdev->dev.parent, "remoteprocX#vdevYbuffer") for DMA
>>> operations.
>>> This also allows now to reserve DMA pools/buffers for rproc serial
>>> via Device Tree.
>>>
>>> Fixes: c774ad010873 ("remoteproc: Fix and restore the parenting hierarchy for vdev")
>>> Cc: [email protected] # 5.1+
>>> Signed-off-by: Alexander Lobakin <[email protected]>
>>> ---
>>> drivers/char/virtio_console.c | 8 ++++----
>>> 1 file changed, 4 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
>>> index a2da8f768b94..1836cc56e357 100644
>>> --- a/drivers/char/virtio_console.c
>>> +++ b/drivers/char/virtio_console.c
>>> @@ -435,12 +435,12 @@ static struct port_buffer *alloc_buf(struct virtio_device *vdev, size_t buf_size
>>> /*
>>> * Allocate DMA memory from ancestor. When a virtio
>>> * device is created by remoteproc, the DMA memory is
>>> - * associated with the grandparent device:
>>> - * vdev => rproc => platform-dev.
>>> + * associated with the parent device:
>>> + * virtioY => remoteprocX#vdevYbuffer.
>>> */
>>> - if (!vdev->dev.parent || !vdev->dev.parent->parent)
>>> + buf->dev = vdev->dev.parent;
>>> + if (!buf->dev)
>>> goto free_buf;
>>> - buf->dev = vdev->dev.parent->parent;
>>>
>>> /* Increase device refcnt to avoid freeing it */
>>> get_device(buf->dev);
>>> --
>>> 2.29.2
>>>
>>>
>> ---end quoted text---

Thanks,
Al

2020-11-16 13:15:43

by Michael S. Tsirkin

[permalink] [raw]
Subject: Re: [PATCH virtio] virtio: virtio_console: fix DMA memory allocation for rproc serial

On Mon, Nov 16, 2020 at 01:07:28PM +0000, Alexander Lobakin wrote:
> From: "Michael S. Tsirkin" <[email protected]>
> Date: Mon, 16 Nov 2020 07:25:31 -0500
>
> > On Mon, Nov 16, 2020 at 09:19:50AM +0000, Christoph Hellwig wrote:
> >> I just noticed this showing up in Linus' tree and I'm not happy.
> >
> > Are you sure? I think it's in next.
>
> Nope, it goes to fixes since it just fixes the regression introduced
> in 5.7.

Oh you are right, Greg merged it and I didn't notice because I didn't
rebase my tree.

> That's why it's not about any refactoring or rethinking the whole
> model.
>
> >> This whole model of the DMA subdevices in remoteproc is simply broken.
> >>
> >> We really need to change the virtio code pass an expicit DMA device (
> >> similar to what e.g. the USB and RDMA code does), instead of faking up
> >> devices with broken adhoc inheritance of DMA properties and magic poking
> >> into device parent relationships.
>
> But lots of subsystems like netdev for example uses dev->parent for
> DMA operations. I know that their pointers go directly to the
> platform/PCI/etc. device, but still.
>
> The only reason behind "fake" DMA devices for rproc is to be able to
> reserve DMA memory through the Device Tree exclusively for only one
> virtio dev like virtio_console or virtio_rpmsg_bus. That's why
> they are present, are coercing DMA caps from physical dev
> representor, and why questinable dma_declare_coherent_memory()
> is still here and doesn't allow to build rproc core as a module.
> I agree that this is not the best model obviously, and we should take
> a look at it.
>
> > OK but we do have a regression since 5.7 and this looks like
> > a fix appropriate for e.g. stable, right?
> >
> >> Bjorn, I thought you were going to look into this a while ago?
> >>
> >>
> >> On Wed, Nov 04, 2020 at 03:31:36PM +0000, Alexander Lobakin wrote:
> >>> Since commit 086d08725d34 ("remoteproc: create vdev subdevice with
> >>> specific dma memory pool"), every remoteproc has a DMA subdevice
> >>> ("remoteprocX#vdevYbuffer") for each virtio device, which inherits
> >>> DMA capabilities from the corresponding platform device. This allowed
> >>> to associate different DMA pools with each vdev, and required from
> >>> virtio drivers to perform DMA operations with the parent device
> >>> (vdev->dev.parent) instead of grandparent (vdev->dev.parent->parent).
> >>>
> >>> virtio_rpmsg_bus was already changed in the same merge cycle with
> >>> commit d999b622fcfb ("rpmsg: virtio: allocate buffer from parent"),
> >>> but virtio_console did not. In fact, operations using the grandparent
> >>> worked fine while the grandparent was the platform device, but since
> >>> commit c774ad010873 ("remoteproc: Fix and restore the parenting
> >>> hierarchy for vdev") this was changed, and now the grandparent device
> >>> is the remoteproc device without any DMA capabilities.
> >>> So, starting v5.8-rc1 the following warning is observed:
> >>>
> >>> [ 2.483925] ------------[ cut here ]------------
> >>> [ 2.489148] WARNING: CPU: 3 PID: 101 at kernel/dma/mapping.c:427 0x80e7eee8
> >>> [ 2.489152] Modules linked in: virtio_console(+)
> >>> [ 2.503737] virtio_rpmsg_bus rpmsg_core
> >>> [ 2.508903]
> >>> [ 2.528898] <Other modules, stack and call trace here>
> >>> [ 2.913043]
> >>> [ 2.914907] ---[ end trace 93ac8746beab612c ]---
> >>> [ 2.920102] virtio-ports vport1p0: Error allocating inbufs
> >>>
> >>> kernel/dma/mapping.c:427 is:
> >>>
> >>> WARN_ON_ONCE(!dev->coherent_dma_mask);
> >>>
> >>> obviously because the grandparent now is remoteproc dev without any
> >>> DMA caps:
> >>>
> >>> [ 3.104943] Parent: remoteproc0#vdev1buffer, grandparent: remoteproc0
> >>>
> >>> Fix this the same way as it was for virtio_rpmsg_bus, using just the
> >>> parent device (vdev->dev.parent, "remoteprocX#vdevYbuffer") for DMA
> >>> operations.
> >>> This also allows now to reserve DMA pools/buffers for rproc serial
> >>> via Device Tree.
> >>>
> >>> Fixes: c774ad010873 ("remoteproc: Fix and restore the parenting hierarchy for vdev")
> >>> Cc: [email protected] # 5.1+
> >>> Signed-off-by: Alexander Lobakin <[email protected]>
> >>> ---
> >>> drivers/char/virtio_console.c | 8 ++++----
> >>> 1 file changed, 4 insertions(+), 4 deletions(-)
> >>>
> >>> diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
> >>> index a2da8f768b94..1836cc56e357 100644
> >>> --- a/drivers/char/virtio_console.c
> >>> +++ b/drivers/char/virtio_console.c
> >>> @@ -435,12 +435,12 @@ static struct port_buffer *alloc_buf(struct virtio_device *vdev, size_t buf_size
> >>> /*
> >>> * Allocate DMA memory from ancestor. When a virtio
> >>> * device is created by remoteproc, the DMA memory is
> >>> - * associated with the grandparent device:
> >>> - * vdev => rproc => platform-dev.
> >>> + * associated with the parent device:
> >>> + * virtioY => remoteprocX#vdevYbuffer.
> >>> */
> >>> - if (!vdev->dev.parent || !vdev->dev.parent->parent)
> >>> + buf->dev = vdev->dev.parent;
> >>> + if (!buf->dev)
> >>> goto free_buf;
> >>> - buf->dev = vdev->dev.parent->parent;
> >>>
> >>> /* Increase device refcnt to avoid freeing it */
> >>> get_device(buf->dev);
> >>> --
> >>> 2.29.2
> >>>
> >>>
> >> ---end quoted text---
>
> Thanks,
> Al

2020-11-16 16:29:48

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH virtio] virtio: virtio_console: fix DMA memory allocation for rproc serial

On Mon, Nov 16, 2020 at 04:51:49AM -0500, Michael S. Tsirkin wrote:
> On Mon, Nov 16, 2020 at 09:19:50AM +0000, Christoph Hellwig wrote:
> > I just noticed this showing up in Linus' tree and I'm not happy.
> >
> > This whole model of the DMA subdevices in remoteproc is simply broken.
> >
> > We really need to change the virtio code pass an expicit DMA device (
> > similar to what e.g. the USB and RDMA code does),
>
> Could you point me at an example or two please?

Take a look at the ib_dma_* helper in include/rdma/ib_verbs.h and
dma_device member in struct ib_device for the best example.

2020-11-16 16:31:14

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH virtio] virtio: virtio_console: fix DMA memory allocation for rproc serial

On Mon, Nov 16, 2020 at 11:46:59AM +0100, Arnaud POULIQUEN wrote:
> Hi all,
>
> On 11/16/20 10:19 AM, Christoph Hellwig wrote:
> > I just noticed this showing up in Linus' tree and I'm not happy.
> >
> > This whole model of the DMA subdevices in remoteproc is simply broken.
> >
> > We really need to change the virtio code pass an expicit DMA device (
> > similar to what e.g. the USB and RDMA code does), instead of faking up
> > devices with broken adhoc inheritance of DMA properties and magic poking
> > into device parent relationships.
>
> For your formation I started some stuff on my side to be able to declare the
> virtio device in DT as a remoteproc child node.
>
> https://lkml.org/lkml/2020/4/16/1817
>
> Quite big refactoring, but could be a way to answer...

Yes, that series is exactly what we need to do conceptually (can't
comment on all the nitty grity details as I'm not too familiar with
the remoteproc code).

2020-11-16 16:32:38

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH virtio] virtio: virtio_console: fix DMA memory allocation for rproc serial

On Mon, Nov 16, 2020 at 01:07:28PM +0000, Alexander Lobakin wrote:
> But lots of subsystems like netdev for example uses dev->parent for
> DMA operations. I know that their pointers go directly to the
> platform/PCI/etc. device, but still.

Oh, every drivers is perfectly fine to use ->parent as it suits. The
problem is when we have layered architectures, where this pokes a
massive hole into the layering.

> The only reason behind "fake" DMA devices for rproc is to be able to
> reserve DMA memory through the Device Tree exclusively for only one
> virtio dev like virtio_console or virtio_rpmsg_bus. That's why
> they are present, are coercing DMA caps from physical dev
> representor, and why questinable dma_declare_coherent_memory()
> is still here and doesn't allow to build rproc core as a module.
> I agree that this is not the best model obviously, and we should take
> a look at it.

As far as I can tell the series from Arnaud does the right thing here.

2020-11-16 16:42:01

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH virtio] virtio: virtio_console: fix DMA memory allocation for rproc serial

Btw, I also still don't understand why remoteproc is using
dma_declare_coherent_memory to start with. The virtio code has exactly
one call to dma_alloc_coherent vring_alloc_queue, a function that
already switches between two different allocators. Why can't we just
add a third allocator specifically for these remoteproc memory carveouts
and bypass dma_declare_coherent_memory entirely?

2020-11-17 01:43:27

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH virtio] virtio: virtio_console: fix DMA memory allocation for rproc serial

I just noticed this showing up in Linus' tree and I'm not happy.

This whole model of the DMA subdevices in remoteproc is simply broken.

We really need to change the virtio code pass an expicit DMA device (
similar to what e.g. the USB and RDMA code does), instead of faking up
devices with broken adhoc inheritance of DMA properties and magic poking
into device parent relationships.

Bjorn, I thought you were going to look into this a while ago?


On Wed, Nov 04, 2020 at 03:31:36PM +0000, Alexander Lobakin wrote:
> Since commit 086d08725d34 ("remoteproc: create vdev subdevice with
> specific dma memory pool"), every remoteproc has a DMA subdevice
> ("remoteprocX#vdevYbuffer") for each virtio device, which inherits
> DMA capabilities from the corresponding platform device. This allowed
> to associate different DMA pools with each vdev, and required from
> virtio drivers to perform DMA operations with the parent device
> (vdev->dev.parent) instead of grandparent (vdev->dev.parent->parent).
>
> virtio_rpmsg_bus was already changed in the same merge cycle with
> commit d999b622fcfb ("rpmsg: virtio: allocate buffer from parent"),
> but virtio_console did not. In fact, operations using the grandparent
> worked fine while the grandparent was the platform device, but since
> commit c774ad010873 ("remoteproc: Fix and restore the parenting
> hierarchy for vdev") this was changed, and now the grandparent device
> is the remoteproc device without any DMA capabilities.
> So, starting v5.8-rc1 the following warning is observed:
>
> [ 2.483925] ------------[ cut here ]------------
> [ 2.489148] WARNING: CPU: 3 PID: 101 at kernel/dma/mapping.c:427 0x80e7eee8
> [ 2.489152] Modules linked in: virtio_console(+)
> [ 2.503737] virtio_rpmsg_bus rpmsg_core
> [ 2.508903]
> [ 2.528898] <Other modules, stack and call trace here>
> [ 2.913043]
> [ 2.914907] ---[ end trace 93ac8746beab612c ]---
> [ 2.920102] virtio-ports vport1p0: Error allocating inbufs
>
> kernel/dma/mapping.c:427 is:
>
> WARN_ON_ONCE(!dev->coherent_dma_mask);
>
> obviously because the grandparent now is remoteproc dev without any
> DMA caps:
>
> [ 3.104943] Parent: remoteproc0#vdev1buffer, grandparent: remoteproc0
>
> Fix this the same way as it was for virtio_rpmsg_bus, using just the
> parent device (vdev->dev.parent, "remoteprocX#vdevYbuffer") for DMA
> operations.
> This also allows now to reserve DMA pools/buffers for rproc serial
> via Device Tree.
>
> Fixes: c774ad010873 ("remoteproc: Fix and restore the parenting hierarchy for vdev")
> Cc: [email protected] # 5.1+
> Signed-off-by: Alexander Lobakin <[email protected]>
> ---
> drivers/char/virtio_console.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
> index a2da8f768b94..1836cc56e357 100644
> --- a/drivers/char/virtio_console.c
> +++ b/drivers/char/virtio_console.c
> @@ -435,12 +435,12 @@ static struct port_buffer *alloc_buf(struct virtio_device *vdev, size_t buf_size
> /*
> * Allocate DMA memory from ancestor. When a virtio
> * device is created by remoteproc, the DMA memory is
> - * associated with the grandparent device:
> - * vdev => rproc => platform-dev.
> + * associated with the parent device:
> + * virtioY => remoteprocX#vdevYbuffer.
> */
> - if (!vdev->dev.parent || !vdev->dev.parent->parent)
> + buf->dev = vdev->dev.parent;
> + if (!buf->dev)
> goto free_buf;
> - buf->dev = vdev->dev.parent->parent;
>
> /* Increase device refcnt to avoid freeing it */
> get_device(buf->dev);
> --
> 2.29.2
>
>
---end quoted text---

2020-11-17 01:56:04

by Alexander Lobakin

[permalink] [raw]
Subject: Re: [PATCH virtio] virtio: virtio_console: fix DMA memory allocation for rproc serial

From: Christoph Hellwig <[email protected]>
Date: Mon, 16 Nov 2020 16:27:44 +0000

> On Mon, Nov 16, 2020 at 04:51:49AM -0500, Michael S. Tsirkin wrote:
>> On Mon, Nov 16, 2020 at 09:19:50AM +0000, Christoph Hellwig wrote:
>>> I just noticed this showing up in Linus' tree and I'm not happy.
>>>
>>> This whole model of the DMA subdevices in remoteproc is simply broken.
>>>
>>> We really need to change the virtio code pass an expicit DMA device (
>>> similar to what e.g. the USB and RDMA code does),
>>
>> Could you point me at an example or two please?
>
> Take a look at the ib_dma_* helper in include/rdma/ib_verbs.h and
> dma_device member in struct ib_device for the best example.

Oh, best example indeed. I did really love these helpers and kinda
wish there were such for Ethernet and wireless networking. They'd
allow to keep the code more readable and clean and prevent from
several sorts of silly mistakes.

This could be done in e.g. 4 steps:
- introduce such helpers for netdev/mac80211;
- add checkpatch warnings to discourage usage of old methods like
SET_NETDEV_DEV() and direct dereferencing of netdev->dev.parent;
- slowly convert existing drivers to the new model;
- remove the old way entirely along with checkpatch remnants.

I could take this if there'll be enough votes :)

Al

2020-11-17 14:04:11

by Arnaud POULIQUEN

[permalink] [raw]
Subject: Re: [PATCH virtio] virtio: virtio_console: fix DMA memory allocation for rproc serial



On 11/16/20 5:39 PM, Christoph Hellwig wrote:
> Btw, I also still don't understand why remoteproc is using
> dma_declare_coherent_memory to start with. The virtio code has exactly
> one call to dma_alloc_coherent vring_alloc_queue, a function that
> already switches between two different allocators. Why can't we just
> add a third allocator specifically for these remoteproc memory carveouts
> and bypass dma_declare_coherent_memory entirely?
>

The dma_declare_coherent_memory allows to associate vdev0buffer memory region
to the remoteproc virtio device (vdev parent). This region is used to allocated
the rpmsg buffers.
The memory for the rpmsg buffer is allocated by the rpmsg_virtio device in
rpmsg_virtio_bus[1]. The size depends on the total size needed for the rpmsg
buffers.

The vrings are allocated directly by the remoteproc device.

[1]
https://elixir.bootlin.com/linux/v5.10-rc3/source/drivers/rpmsg/virtio_rpmsg_bus.c#L925

2020-11-17 14:06:21

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH virtio] virtio: virtio_console: fix DMA memory allocation for rproc serial

On Tue, Nov 17, 2020 at 03:00:32PM +0100, Arnaud POULIQUEN wrote:
> The dma_declare_coherent_memory allows to associate vdev0buffer memory region
> to the remoteproc virtio device (vdev parent). This region is used to allocated
> the rpmsg buffers.
> The memory for the rpmsg buffer is allocated by the rpmsg_virtio device in
> rpmsg_virtio_bus[1]. The size depends on the total size needed for the rpmsg
> buffers.
>
> The vrings are allocated directly by the remoteproc device.

Weird. I thought virtio was pretty strict in not allowing diret DMA
API usage in drivers to support the legacy no-mapping case.

Either way, the point stands: if you want these magic buffers handed
out to specific rpmsg instances I think not having to detour through the
DMA API is going to make everyones life easier.

2020-11-18 10:18:30

by Michael S. Tsirkin

[permalink] [raw]
Subject: Re: [PATCH virtio] virtio: virtio_console: fix DMA memory allocation for rproc serial

On Tue, Nov 17, 2020 at 02:02:30PM +0000, Christoph Hellwig wrote:
> On Tue, Nov 17, 2020 at 03:00:32PM +0100, Arnaud POULIQUEN wrote:
> > The dma_declare_coherent_memory allows to associate vdev0buffer memory region
> > to the remoteproc virtio device (vdev parent). This region is used to allocated
> > the rpmsg buffers.
> > The memory for the rpmsg buffer is allocated by the rpmsg_virtio device in
> > rpmsg_virtio_bus[1]. The size depends on the total size needed for the rpmsg
> > buffers.
> >
> > The vrings are allocated directly by the remoteproc device.
>
> Weird. I thought virtio was pretty strict in not allowing diret DMA
> API usage in drivers to support the legacy no-mapping case.

Well remoteproc is weird in that it's use of DMA API precedes
standartization efforts, and it was never standardized in the virtio
spec ..

> Either way, the point stands: if you want these magic buffers handed
> out to specific rpmsg instances I think not having to detour through the
> DMA API is going to make everyones life easier.