Message ID | 20190827151823.75312-1-andriy.shevchenko@linux.intel.com (mailing list archive) |
---|---|
State | Mainlined, archived |
Commit | 6a8c97345a15f9c60ff6c6ac1629a3e9ec140320 |
Headers | show |
Series | [v1,1/2] PCI/AER: Use for_each_set_bit() | expand |
On 8/27/19 8:18 AM, Andy Shevchenko wrote: > This simplifies and standardizes slot manipulation code > by using for_each_set_bit() library function. > > Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> > --- > drivers/pci/pcie/aer.c | 19 ++++++++----------- > 1 file changed, 8 insertions(+), 11 deletions(-) > > diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c > index b45bc47d04fe..f883f81d759a 100644 > --- a/drivers/pci/pcie/aer.c > +++ b/drivers/pci/pcie/aer.c > @@ -15,6 +15,7 @@ > #define pr_fmt(fmt) "AER: " fmt > #define dev_fmt pr_fmt > > +#include <linux/bitops.h> > #include <linux/cper.h> > #include <linux/pci.h> > #include <linux/pci-acpi.h> > @@ -657,7 +658,8 @@ const struct attribute_group aer_stats_attr_group = { > static void pci_dev_aer_stats_incr(struct pci_dev *pdev, > struct aer_err_info *info) > { > - int status, i, max = -1; > + unsigned long status = info->status & ~info->mask; > + int i, max = -1; > u64 *counter = NULL; > struct aer_stats *aer_stats = pdev->aer_stats; > > @@ -682,10 +684,8 @@ static void pci_dev_aer_stats_incr(struct pci_dev *pdev, > break; > } > > - status = (info->status & ~info->mask); > - for (i = 0; i < max; i++) > - if (status & (1 << i)) > - counter[i]++; > + for_each_set_bit(i, &status, max) > + counter[i]++; > } > > static void pci_rootport_aer_stats_incr(struct pci_dev *pdev, > @@ -717,14 +717,11 @@ static void __print_tlp_header(struct pci_dev *dev, > static void __aer_print_error(struct pci_dev *dev, > struct aer_err_info *info) > { > - int i, status; > + unsigned long status = info->status & ~info->mask; > const char *errmsg = NULL; > - status = (info->status & ~info->mask); > - > - for (i = 0; i < 32; i++) { > - if (!(status & (1 << i))) > - continue; > + int i; > > + for_each_set_bit(i, &status, 32) { > if (info->severity == AER_CORRECTABLE) > errmsg = i < ARRAY_SIZE(aer_correctable_error_string) ? > aer_correctable_error_string[i] : NULL;
On Tue, Aug 27, 2019 at 06:18:22PM +0300, Andy Shevchenko wrote: > This simplifies and standardizes slot manipulation code > by using for_each_set_bit() library function. > > Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Applied both with Kuppuswamy's reviewed-by to pci/aer for v5.5, thanks! > --- > drivers/pci/pcie/aer.c | 19 ++++++++----------- > 1 file changed, 8 insertions(+), 11 deletions(-) > > diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c > index b45bc47d04fe..f883f81d759a 100644 > --- a/drivers/pci/pcie/aer.c > +++ b/drivers/pci/pcie/aer.c > @@ -15,6 +15,7 @@ > #define pr_fmt(fmt) "AER: " fmt > #define dev_fmt pr_fmt > > +#include <linux/bitops.h> > #include <linux/cper.h> > #include <linux/pci.h> > #include <linux/pci-acpi.h> > @@ -657,7 +658,8 @@ const struct attribute_group aer_stats_attr_group = { > static void pci_dev_aer_stats_incr(struct pci_dev *pdev, > struct aer_err_info *info) > { > - int status, i, max = -1; > + unsigned long status = info->status & ~info->mask; > + int i, max = -1; > u64 *counter = NULL; > struct aer_stats *aer_stats = pdev->aer_stats; > > @@ -682,10 +684,8 @@ static void pci_dev_aer_stats_incr(struct pci_dev *pdev, > break; > } > > - status = (info->status & ~info->mask); > - for (i = 0; i < max; i++) > - if (status & (1 << i)) > - counter[i]++; > + for_each_set_bit(i, &status, max) > + counter[i]++; > } > > static void pci_rootport_aer_stats_incr(struct pci_dev *pdev, > @@ -717,14 +717,11 @@ static void __print_tlp_header(struct pci_dev *dev, > static void __aer_print_error(struct pci_dev *dev, > struct aer_err_info *info) > { > - int i, status; > + unsigned long status = info->status & ~info->mask; > const char *errmsg = NULL; > - status = (info->status & ~info->mask); > - > - for (i = 0; i < 32; i++) { > - if (!(status & (1 << i))) > - continue; > + int i; > > + for_each_set_bit(i, &status, 32) { > if (info->severity == AER_CORRECTABLE) > errmsg = i < ARRAY_SIZE(aer_correctable_error_string) ? > aer_correctable_error_string[i] : NULL; > -- > 2.23.0.rc1 >
On Tue, Aug 27, 2019 at 06:18:22PM +0300, Andy Shevchenko wrote: > This simplifies and standardizes slot manipulation code > by using for_each_set_bit() library function. > > Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> > --- > drivers/pci/pcie/aer.c | 19 ++++++++----------- > 1 file changed, 8 insertions(+), 11 deletions(-) > > diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c > index b45bc47d04fe..f883f81d759a 100644 > --- a/drivers/pci/pcie/aer.c > +++ b/drivers/pci/pcie/aer.c > @@ -15,6 +15,7 @@ > #define pr_fmt(fmt) "AER: " fmt > #define dev_fmt pr_fmt > > +#include <linux/bitops.h> > #include <linux/cper.h> > #include <linux/pci.h> > #include <linux/pci-acpi.h> > @@ -657,7 +658,8 @@ const struct attribute_group aer_stats_attr_group = { > static void pci_dev_aer_stats_incr(struct pci_dev *pdev, > struct aer_err_info *info) > { > - int status, i, max = -1; > + unsigned long status = info->status & ~info->mask; > + int i, max = -1; > u64 *counter = NULL; > struct aer_stats *aer_stats = pdev->aer_stats; > > @@ -682,10 +684,8 @@ static void pci_dev_aer_stats_incr(struct pci_dev *pdev, > break; > } > > - status = (info->status & ~info->mask); > - for (i = 0; i < max; i++) > - if (status & (1 << i)) > - counter[i]++; > + for_each_set_bit(i, &status, max) I applied this, but I confess to being a little ambivalent. It's arguably a little easier to read, but it's not nearly as efficient (not a great concern here) and more importantly much harder to verify that it's correct because you have to chase through for_each_set_bit(), find_first_bit(), _ffs(), etc, etc. No doubt it's great for bitmaps of arbitrary size, but for a simple 32-bit register I'm a little hesitant. But I applied it anyway. > + counter[i]++; > } > > static void pci_rootport_aer_stats_incr(struct pci_dev *pdev, > @@ -717,14 +717,11 @@ static void __print_tlp_header(struct pci_dev *dev, > static void __aer_print_error(struct pci_dev *dev, > struct aer_err_info *info) > { > - int i, status; > + unsigned long status = info->status & ~info->mask; > const char *errmsg = NULL; > - status = (info->status & ~info->mask); > - > - for (i = 0; i < 32; i++) { > - if (!(status & (1 << i))) > - continue; > + int i; > > + for_each_set_bit(i, &status, 32) { > if (info->severity == AER_CORRECTABLE) > errmsg = i < ARRAY_SIZE(aer_correctable_error_string) ? > aer_correctable_error_string[i] : NULL; > -- > 2.23.0.rc1 >
On Fri, Sep 27, 2019 at 07:39:13AM -0500, Bjorn Helgaas wrote: > On Tue, Aug 27, 2019 at 06:18:22PM +0300, Andy Shevchenko wrote: > > This simplifies and standardizes slot manipulation code > > by using for_each_set_bit() library function. > > + unsigned long status = info->status & ~info->mask; > > + int i, max = -1; > > - for (i = 0; i < max; i++) > > - if (status & (1 << i)) > > - counter[i]++; > > + for_each_set_bit(i, &status, max) > > I applied this, Thank you! > but I confess to being a little ambivalent. It's > arguably a little easier to read, I have another opinion here. Instead of parsing body of for-loop, the name of the function tells you exactly what it's done. Besides the fact that reading and parsing two lines, with zero conditionals, is faster. > but it's not nearly as efficient > (not a great concern here) David, do you know why for_each_set_bit() has no optimization for the cases when nbits <= BITS_PER_LONG? (Actually find_*bit() family of functions) > and more importantly much harder to verify > that it's correct because you have to chase through > for_each_set_bit(), find_first_bit(), _ffs(), etc, etc. If for_each_set_bit() or any other fundamental bit operation helper is broken, PCI subsystem is a little concern here. > No doubt it's > great for bitmaps of arbitrary size, but for a simple 32-bit register > I'm a little hesitant. But I applied it anyway. > > > + counter[i]++;
Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote: > > but I confess to being a little ambivalent. It's > > arguably a little easier to read, > > I have another opinion here. Instead of parsing body of for-loop, the name of > the function tells you exactly what it's done. Besides the fact that reading > and parsing two lines, with zero conditionals, is faster. > > > but it's not nearly as efficient > > (not a great concern here) > > David, do you know why for_each_set_bit() has no optimization for the cases > when nbits <= BITS_PER_LONG? (Actually find_*bit() family of functions) I've not had anything to do with for_each_set_bit() itself. By 'nbits', I presume you mean the size parameter - max in the sample bit of code. It would need per-arch optimisation. Some arches have an instruction to find the next bit and some don't. Using for_each_set_bit() like this is definitely suboptimal, since find_first_bit() and find_next_bit() may well be out of line. It should probably be using something like __ffs() if size <= BITS_PER_LONG. David
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c index b45bc47d04fe..f883f81d759a 100644 --- a/drivers/pci/pcie/aer.c +++ b/drivers/pci/pcie/aer.c @@ -15,6 +15,7 @@ #define pr_fmt(fmt) "AER: " fmt #define dev_fmt pr_fmt +#include <linux/bitops.h> #include <linux/cper.h> #include <linux/pci.h> #include <linux/pci-acpi.h> @@ -657,7 +658,8 @@ const struct attribute_group aer_stats_attr_group = { static void pci_dev_aer_stats_incr(struct pci_dev *pdev, struct aer_err_info *info) { - int status, i, max = -1; + unsigned long status = info->status & ~info->mask; + int i, max = -1; u64 *counter = NULL; struct aer_stats *aer_stats = pdev->aer_stats; @@ -682,10 +684,8 @@ static void pci_dev_aer_stats_incr(struct pci_dev *pdev, break; } - status = (info->status & ~info->mask); - for (i = 0; i < max; i++) - if (status & (1 << i)) - counter[i]++; + for_each_set_bit(i, &status, max) + counter[i]++; } static void pci_rootport_aer_stats_incr(struct pci_dev *pdev, @@ -717,14 +717,11 @@ static void __print_tlp_header(struct pci_dev *dev, static void __aer_print_error(struct pci_dev *dev, struct aer_err_info *info) { - int i, status; + unsigned long status = info->status & ~info->mask; const char *errmsg = NULL; - status = (info->status & ~info->mask); - - for (i = 0; i < 32; i++) { - if (!(status & (1 << i))) - continue; + int i; + for_each_set_bit(i, &status, 32) { if (info->severity == AER_CORRECTABLE) errmsg = i < ARRAY_SIZE(aer_correctable_error_string) ? aer_correctable_error_string[i] : NULL;
This simplifies and standardizes slot manipulation code by using for_each_set_bit() library function. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> --- drivers/pci/pcie/aer.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-)