[PATCH 11/31] dma: add channel request API that supports deferred probe

Dan Williams dan.j.williams at intel.com
Fri Nov 22 01:54:26 EST 2013


On Thu, Nov 21, 2013 at 10:22 AM, Stephen Warren <swarren at wwwdotorg.org> wrote:
> On 11/20/2013 08:22 PM, Dan Williams wrote:
>> On Wed, Nov 20, 2013 at 1:24 PM, Stephen Warren <swarren at wwwdotorg.org> wrote:
>>> On 11/20/2013 01:23 PM, Williams, Dan J wrote:
>>> ...
>>>> Why do the drivers that call dma_request_channel need to convert it to
>>>> an ERR value?  i.e. what's problematic about the below (not compile
>>>> tested)?
>>> ...
>>>> diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c
>>> ...
>>>> @@ -22,16 +22,20 @@ static unsigned samsung_dmadev_request(enum dma_ch dma_ch,
>>>>                               struct samsung_dma_req *param,
>>>>                               struct device *dev, char *ch_name)
>>> ...
>>>> +     if (dev->of_node) {
>>>> +             chan = dma_request_slave_channel(dev, ch_name);
>>>> +             return IS_ERR(chan) ? (unsigned) NULL : (unsigned) chan;
>>>> +     } else {
>>>>               return (unsigned)dma_request_channel(mask, pl330_filter,
>>>>                                                       (void *)dma_ch);
>>>> +     }
>>>
>>> The argument is that if a function returns errors encoded as an ERR
>>> pointer, then callers must assume that any non-IS_ERR value that the
>>> function returns is valid. NULL is one of those values. As such, callers
>>> can no longer check the value against NULL, but must use IS_ERR().
>>> Converting any IS_ERR() returns to NULL theoretically is the act of
>>> converting one valid return value to some other completely random return
>>> value.
>>
>> You describe how IS_ERR() works, but you didn't address the patch.
>> There's nothing random about the changes to samsung_dmadev_request().
>> It still returns NULL or a valid channel just as before.
>
> I was addressing the patch. I guess I should have explained as follows.
>
> First, the following code is technically buggy:

No, it's not, but I think we have different implementations in mind.

>
> +             chan = dma_request_slave_channel(dev, ch_name);
> +             return IS_ERR(chan) ? (unsigned) NULL : (unsigned) chan;
>
> ... since it assumes that dma_request_slave_channel() never returns NULL
> as a valid non-error value. This is specifically prohibited by the fact
> that dma_request_slave_channel() returns either an ERR value or a valid
> value; in that case, NULL is not an ERR value, and hence must be
> considered valid.

Let's stop there and be clear we are talking about the same proposal.

The proposal is dma_request_slave_channel only returns errors or valid
pointers, never NULL.

diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 9162ac80c18f..64c163664b9d 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -593,15 +593,20 @@ EXPORT_SYMBOL_GPL(__dma_request_channel);
  */
 struct dma_chan *dma_request_slave_channel(struct device *dev, const
char *name)
 {
+       struct dma_chan *chan = ERR_PTR(-ENODEV);
+
        /* If device-tree is present get slave info from here */
        if (dev->of_node)
                return of_dma_request_slave_channel(dev->of_node, name);

        /* If device was enumerated by ACPI get slave info from here */
-       if (ACPI_HANDLE(dev))
-               return acpi_dma_request_slave_chan_by_name(dev, name);
+       if (ACPI_HANDLE(dev)) {
+               chan = acpi_dma_request_slave_chan_by_name(dev, name);
+               if (!chan)
+                       chan = ERR_PTR(-ENODEV);
+       }

-       return NULL;
+       return chan;
 }

In the above the assumption is that of_dma_request_slave_channel() is
modified to guarantee it only returns ERR_PTRs or valid pointers never
NULL.  acpi_dma_request_slave_chan_by_name() can continue returning
NULL and dma_request_slave_channel will translate it to an ERR_PTR, or
you can convert it as you do in your patch.  Not much value in
converting acpi_dma_request_slave_chan_by_name as it does not return
EPROBE_DEFER and nothing currently cares about the other error values.



More information about the linux-arm-kernel mailing list