Re: Sparse false-positive warnings

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

 



On Fri, Apr 6, 2018 at 11:59 AM, Mauro Carvalho Chehab
<mchehab@xxxxxxxxxx> wrote:
> drivers/media/pci/ddbridge/ddbridge-core.c:442:9: warning: context imbalance in 'ddb_output_start' - different lock contexts for basic block
> drivers/media/pci/ddbridge/ddbridge-core.c:457:9: warning: context imbalance in 'ddb_output_stop' - different lock contexts for basic block
> drivers/media/pci/ddbridge/ddbridge-core.c:472:9: warning: context imbalance in 'ddb_input_stop' - different lock contexts for basic block
> drivers/media/pci/ddbridge/ddbridge-core.c:504:9: warning: context imbalance in 'ddb_input_start' - different lock contexts for basic block
>
> IMO, the problem here is at the sparce logic. Basically, this driver can
> work with output->dma filled or with NULL. when it is filled, there's a
> lock to protect the DMA. Otherwise, no lock is needed.

There is possible risk there. What if output->dma get changed
before you try to unlock?

Of course, from the code  context there is no reason to see output->dma
can be changed, from developer point of view. However, for sparse,
there is not way of knowing that.


>
> Patches like the one below would make sparse to stop complaining:
>
> diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c
> index 90687eff5909..69a29d4bf86d 100644
> --- a/drivers/media/pci/ddbridge/ddbridge-core.c
> +++ b/drivers/media/pci/ddbridge/ddbridge-core.c
> @@ -449,15 +449,16 @@ static void ddb_output_stop(struct ddb_output *output)
>  {
>         struct ddb *dev = output->port->dev;
>
> -       if (output->dma)
> +       if (output->dma) {
>                 spin_lock_irq(&output->dma->lock);
>
> -       ddbwritel(dev, 0, TS_CONTROL(output));
> +               ddbwritel(dev, 0, TS_CONTROL(output));
>
> -       if (output->dma) {
>                 ddbwritel(dev, 0, DMA_BUFFER_CONTROL(output->dma));
>                 output->dma->running = 0;
>                 spin_unlock_irq(&output->dma->lock);
> +       } else {
> +               ddbwritel(dev, 0, TS_CONTROL(output));
>         }
>  }

if you change that as:

int locking = output->dma;

if (locking)
        spin_lock_irq();

ddbwritel();

if (locking)
        spin_unlock_irq();

That will take care of the output->dma changing in between.

> The problem here is that sparse is not considering the conditional code
> for output->dma.
>
> I'd appreciate if you could look into it and add a patch fixing it
> there, if possible.


The current balance checking is simple and dumb.
There is possibility that using symbolic execution
to eliminate some of false positive like the above example.

Unfortunately,  there is not much you can do in the more general
complicate case.

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



[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux