All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] staging: kpc2000: simplify nested conditionals that just return a boolean.
@ 2019-05-24 12:19 Jeremy Sowden
  2019-05-24 14:16 ` Greg KH
  2019-05-25 14:23 ` Dan Carpenter
  0 siblings, 2 replies; 5+ messages in thread
From: Jeremy Sowden @ 2019-05-24 12:19 UTC (permalink / raw)
  To: Linux Driver Project Developer List; +Cc: Greg KH

kp2000_check_uio_irq contained a pair of nested ifs which each evaluated
a bitwise operation.  If both operations yielded true, the function
returned 1; otherwise it returned 0.

Replaced the whole thing with one return statement that evaluates the
combination of both bitwise operations.

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
---
This applies to staging-testing.

I was in two minds whether to send this patch or something less terse:

+	return (interrupt_active & irq_check_mask) &&
+	       (interrupt_mask_inv & irq_check_mask);

 drivers/staging/kpc2000/kpc2000/cell_probe.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/kpc2000/kpc2000/cell_probe.c b/drivers/staging/kpc2000/kpc2000/cell_probe.c
index f731a97c6cac..d10f695b6673 100644
--- a/drivers/staging/kpc2000/kpc2000/cell_probe.c
+++ b/drivers/staging/kpc2000/kpc2000/cell_probe.c
@@ -240,12 +240,10 @@ int  kp2000_check_uio_irq(struct kp2000_device *pcard, u32 irq_num)
 	u64 interrupt_mask_inv = ~readq(pcard->sysinfo_regs_base + REG_INTERRUPT_MASK);
 	u64 irq_check_mask = (1 << irq_num);
 
-	if (interrupt_active & irq_check_mask) { // if it's active (interrupt pending)
-		if (interrupt_mask_inv & irq_check_mask) {    // and if it's not masked off
-			return 1;
-		}
-	}
-	return 0;
+	/*
+	 * Is the IRQ active (interrupt pending) and not masked off?
+	 */
+	return (interrupt_active & interrupt_mask_inv & irq_check_mask) != 0;
 }
 
 static
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] staging: kpc2000: simplify nested conditionals that just return a boolean.
  2019-05-24 12:19 [PATCH] staging: kpc2000: simplify nested conditionals that just return a boolean Jeremy Sowden
@ 2019-05-24 14:16 ` Greg KH
  2019-05-24 16:59   ` Matt Sickler
  2019-05-25 14:23 ` Dan Carpenter
  1 sibling, 1 reply; 5+ messages in thread
From: Greg KH @ 2019-05-24 14:16 UTC (permalink / raw)
  To: Jeremy Sowden; +Cc: Linux Driver Project Developer List

On Fri, May 24, 2019 at 01:19:26PM +0100, Jeremy Sowden wrote:
> kp2000_check_uio_irq contained a pair of nested ifs which each evaluated
> a bitwise operation.  If both operations yielded true, the function
> returned 1; otherwise it returned 0.
> 
> Replaced the whole thing with one return statement that evaluates the
> combination of both bitwise operations.

Does this really do the same thing?

> 
> Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
> ---
> This applies to staging-testing.
> 
> I was in two minds whether to send this patch or something less terse:
> 
> +	return (interrupt_active & irq_check_mask) &&
> +	       (interrupt_mask_inv & irq_check_mask);
> 
>  drivers/staging/kpc2000/kpc2000/cell_probe.c | 10 ++++------
>  1 file changed, 4 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/staging/kpc2000/kpc2000/cell_probe.c b/drivers/staging/kpc2000/kpc2000/cell_probe.c
> index f731a97c6cac..d10f695b6673 100644
> --- a/drivers/staging/kpc2000/kpc2000/cell_probe.c
> +++ b/drivers/staging/kpc2000/kpc2000/cell_probe.c
> @@ -240,12 +240,10 @@ int  kp2000_check_uio_irq(struct kp2000_device *pcard, u32 irq_num)
>  	u64 interrupt_mask_inv = ~readq(pcard->sysinfo_regs_base + REG_INTERRUPT_MASK);
>  	u64 irq_check_mask = (1 << irq_num);
>  
> -	if (interrupt_active & irq_check_mask) { // if it's active (interrupt pending)
> -		if (interrupt_mask_inv & irq_check_mask) {    // and if it's not masked off
> -			return 1;
> -		}
> -	}
> -	return 0;
> +	/*
> +	 * Is the IRQ active (interrupt pending) and not masked off?
> +	 */
> +	return (interrupt_active & interrupt_mask_inv & irq_check_mask) != 0;

I have no idea what these bits really are, but try the above with the
following values:
	interrupt_active = BIT(0);
	interrupt_mask_inv = BIT(1);
	irq_check_mask = (BIT(1) | BIT(0));

So in your new code you have:
	BIT(0) & BIT(1) & (BIT(1) | BIT(0))
which reduces to:
	0 & (BIT(1) | BIT(0))
which then reduces to:
	0

The original if statements will return 1.
Your new one will return 0.

You can't AND interrupt_active with interrupt_mask_inv like you did
here, right?

Or am I reading this all wrong?

And what's wrong with the original code here?  What is complaining about
it (other than the crazy comment style...)?

thanks,

greg k-h
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: [PATCH] staging: kpc2000: simplify nested conditionals that just return a boolean.
  2019-05-24 14:16 ` Greg KH
@ 2019-05-24 16:59   ` Matt Sickler
  2019-05-26  9:13     ` Jeremy Sowden
  0 siblings, 1 reply; 5+ messages in thread
From: Matt Sickler @ 2019-05-24 16:59 UTC (permalink / raw)
  To: Greg KH, Jeremy Sowden; +Cc: Linux Driver Project Developer List

>-----Original Message-----
>From: devel <driverdev-devel-bounces@linuxdriverproject.org> On Behalf Of Greg KH
>On Fri, May 24, 2019 at 01:19:26PM +0100, Jeremy Sowden wrote:
>> kp2000_check_uio_irq contained a pair of nested ifs which each evaluated
>> a bitwise operation.  If both operations yielded true, the function
>> returned 1; otherwise it returned 0.
>>
>> Replaced the whole thing with one return statement that evaluates the
>> combination of both bitwise operations.
>
>Does this really do the same thing?
>
>>
>> Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
>> ---
>> This applies to staging-testing.
>>
>> I was in two minds whether to send this patch or something less terse:
>>
>> +     return (interrupt_active & irq_check_mask) &&
>> +            (interrupt_mask_inv & irq_check_mask);
>>
>>  drivers/staging/kpc2000/kpc2000/cell_probe.c | 10 ++++------
>>  1 file changed, 4 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/staging/kpc2000/kpc2000/cell_probe.c
>b/drivers/staging/kpc2000/kpc2000/cell_probe.c
>> index f731a97c6cac..d10f695b6673 100644
>> --- a/drivers/staging/kpc2000/kpc2000/cell_probe.c
>> +++ b/drivers/staging/kpc2000/kpc2000/cell_probe.c
>> @@ -240,12 +240,10 @@ int  kp2000_check_uio_irq(struct kp2000_device
>*pcard, u32 irq_num)
>>       u64 interrupt_mask_inv = ~readq(pcard->sysinfo_regs_base +
>REG_INTERRUPT_MASK);
>>       u64 irq_check_mask = (1 << irq_num);
>>
>> -     if (interrupt_active & irq_check_mask) { // if it's active (interrupt
>pending)
>> -             if (interrupt_mask_inv & irq_check_mask) {    // and if it's not masked
>off
>> -                     return 1;
>> -             }
>> -     }
>> -     return 0;
>> +     /*
>> +      * Is the IRQ active (interrupt pending) and not masked off?
>> +      */
>> +     return (interrupt_active & interrupt_mask_inv & irq_check_mask) != 0;
>
>I have no idea what these bits really are, but try the above with the
>following values:

interrupt_active indicates which IRQs are active/pending
0 = not pending
1 = pending

irq_check_mask has only a single bit set which is which IRQ we're testing for
Each one is "associated" with one of the UIO "cores" (see core_probe.c for how that association is discovered).

interrupt_mask_inv is a bitwise inversion of the HW register.  The HW register tells the HW which interrupts to ignore.
In the HW register:
0 = pass this IRQ up to the host.
1 = mask the IRQ
In interrupt_mask_inv:
0 = ignore this IRQ
1 = care about this IRQ

This code is checking 3 things:
- Is there an interrupt for this UIO core
- Is that interrupt signaled
- Is the interrupt not masked

Just in case it's not obvious yet: the mask/pending bits allow the HW to catch an interrupt but not signal the host until the interrupt is unmasked.  This allows interrupts that happen while the IRQ is masked to still be handled once the IRQ is un-masked. 

>        interrupt_active = BIT(0);
>        interrupt_mask_inv = BIT(1);
>        irq_check_mask = (BIT(1) | BIT(0));
>
>So in your new code you have:
>        BIT(0) & BIT(1) & (BIT(1) | BIT(0))
>which reduces to:
>        0 & (BIT(1) | BIT(0))
>which then reduces to:
>        0
>
>The original if statements will return 1.
>Your new one will return 0.
>
>You can't AND interrupt_active with interrupt_mask_inv like you did
>here, right?
>
>Or am I reading this all wrong?
>
>And what's wrong with the original code here?  What is complaining about
>it (other than the crazy comment style...)?

I would agree with Greg, if there's nothing complaining about the way the original code was written it should probably be left that way.  This new way seems overly tricky, even if it was proven to do the same thing.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] staging: kpc2000: simplify nested conditionals that just return a boolean.
  2019-05-24 12:19 [PATCH] staging: kpc2000: simplify nested conditionals that just return a boolean Jeremy Sowden
  2019-05-24 14:16 ` Greg KH
@ 2019-05-25 14:23 ` Dan Carpenter
  1 sibling, 0 replies; 5+ messages in thread
From: Dan Carpenter @ 2019-05-25 14:23 UTC (permalink / raw)
  To: Jeremy Sowden; +Cc: Greg KH, Linux Driver Project Developer List

On Fri, May 24, 2019 at 01:19:26PM +0100, Jeremy Sowden wrote:
> kp2000_check_uio_irq contained a pair of nested ifs which each evaluated
> a bitwise operation.  If both operations yielded true, the function
> returned 1; otherwise it returned 0.
> 
> Replaced the whole thing with one return statement that evaluates the
> combination of both bitwise operations.
> 
> Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
> ---
> This applies to staging-testing.
> 
> I was in two minds whether to send this patch or something less terse:
> 
> +	return (interrupt_active & irq_check_mask) &&
> +	       (interrupt_mask_inv & irq_check_mask);

Yeah.  I would prefer this.

regards,
dan carpenter


_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] staging: kpc2000: simplify nested conditionals that just return a boolean.
  2019-05-24 16:59   ` Matt Sickler
@ 2019-05-26  9:13     ` Jeremy Sowden
  0 siblings, 0 replies; 5+ messages in thread
From: Jeremy Sowden @ 2019-05-26  9:13 UTC (permalink / raw)
  To: Matt Sickler; +Cc: Greg KH, Linux Driver Project Developer List

[-- Attachment #1: Type: text/plain, Size: 5011 bytes --]

On 2019-05-24, at 16:59:45 +0000, Matt Sickler wrote:
> From: devel <driverdev-devel-bounces@linuxdriverproject.org> On Behalf Of Greg KH
> > On Fri, May 24, 2019 at 01:19:26PM +0100, Jeremy Sowden wrote:
> > > kp2000_check_uio_irq contained a pair of nested ifs which each
> > > evaluated a bitwise operation.  If both operations yielded true,
> > > the function returned 1; otherwise it returned 0.
> > >
> > > Replaced the whole thing with one return statement that evaluates
> > > the combination of both bitwise operations.
> >
> > Does this really do the same thing?
> >
> > > Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
> > > ---
> > > This applies to staging-testing.
> > >
> > > I was in two minds whether to send this patch or something less terse:
> > >
> > > +     return (interrupt_active & irq_check_mask) &&
> > > +            (interrupt_mask_inv & irq_check_mask);
> > >
> > >  drivers/staging/kpc2000/kpc2000/cell_probe.c | 10 ++++------
> > >  1 file changed, 4 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/drivers/staging/kpc2000/kpc2000/cell_probe.c
> > b/drivers/staging/kpc2000/kpc2000/cell_probe.c
> > > index f731a97c6cac..d10f695b6673 100644
> > > --- a/drivers/staging/kpc2000/kpc2000/cell_probe.c
> > > +++ b/drivers/staging/kpc2000/kpc2000/cell_probe.c
> > > @@ -240,12 +240,10 @@ int  kp2000_check_uio_irq(struct kp2000_device *pcard, u32 irq_num)
> > >       u64 interrupt_mask_inv = ~readq(pcard-> sysinfo_regs_base + REG_INTERRUPT_MASK);
> > >       u64 irq_check_mask = (1 << irq_num);
> > >
> > > -     if (interrupt_active & irq_check_mask) { // if it's active (interrupt pending)
> > > -             if (interrupt_mask_inv & irq_check_mask) {    // and if it's not masked off
> > > -                     return 1;
> > > -             }
> > > -     }
> > > -     return 0;
> > > +     /*
> > > +      * Is the IRQ active (interrupt pending) and not masked off?
> > > +      */
> > > +     return (interrupt_active & interrupt_mask_inv & irq_check_mask) != 0;
> >
> > I have no idea what these bits really are, but try the above with
> > the following values:
>
> interrupt_active indicates which IRQs are active/pending
> 0 = not pending
> 1 = pending
>
> irq_check_mask has only a single bit set which is which IRQ we're
> testing for Each one is "associated" with one of the UIO "cores" (see
> core_probe.c for how that association is discovered).
>
> interrupt_mask_inv is a bitwise inversion of the HW register.  The HW
> register tells the HW which interrupts to ignore.  In the HW register:
> 0 = pass this IRQ up to the host.
> 1 = mask the IRQ
> In interrupt_mask_inv:
> 0 = ignore this IRQ
> 1 = care about this IRQ
>
> This code is checking 3 things:
> - Is there an interrupt for this UIO core
> - Is that interrupt signaled
> - Is the interrupt not masked
>
> Just in case it's not obvious yet: the mask/pending bits allow the HW
> to catch an interrupt but not signal the host until the interrupt is
> unmasked.  This allows interrupts that happen while the IRQ is masked
> to still be handled once the IRQ is un-masked.
>
> >        interrupt_active = BIT(0);
> >        interrupt_mask_inv = BIT(1);
> >        irq_check_mask = (BIT(1) | BIT(0));
> >
> > So in your new code you have:
> >        BIT(0) & BIT(1) & (BIT(1) | BIT(0))
> > which reduces to:
> >        0 & (BIT(1) | BIT(0))
> > which then reduces to:
> >        0
> >
> > The original if statements will return 1.
> > Your new one will return 0.
> >
> > You can't AND interrupt_active with interrupt_mask_inv like you did
> > here, right?
> >
> > Or am I reading this all wrong?

As Matt explained above, irq_check_mask only ever has one bit set:

  u64 irq_check_mask = (1 << irq_num);

So:

  interrupt_mask_inv & irq_check_mask

yields irq_check_mask or 0, and:

  interrupt_active & irq_check_mask

yields irq_check_mask or 0, and:

  interrupt_mask_inv & interrupt_active & irq_check_mask

yields irq_check_mask or 0.

> > And what's wrong with the original code here?  What is complaining about
> > it (other than the crazy comment style...)?
>
> I would agree with Greg, if there's nothing complaining about the way
> the original code was written it should probably be left that way.
> This new way seems overly tricky, even if it was proven to do the same
> thing.

This patch was originally part of a larger series of white-space and
formatting changes to cell_probe.c that I put to one side.  It started
out as a change to the formatting of the comments, IIRC.  I was reminded
of it while looking over the recent series by Simon Sandström (which
have fixed most of the issues that my series would have addressed).
Conditional blocks that contain nothing but statements returing boolean
constants are a (minor) pet peeve of mine, so I sent the patch by
itself.  Clearly it's not a peeve shared by many people. :)

Happy to drop the patch.

J.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2019-05-26  9:13 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-24 12:19 [PATCH] staging: kpc2000: simplify nested conditionals that just return a boolean Jeremy Sowden
2019-05-24 14:16 ` Greg KH
2019-05-24 16:59   ` Matt Sickler
2019-05-26  9:13     ` Jeremy Sowden
2019-05-25 14:23 ` Dan Carpenter

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.