Hi Marc, On 27/09/21 8:15 pm, Marc Zyngier wrote: > On Wed, 22 Sep 2021 02:26:09 +0100, > Kishon Vijay Abraham I <kishon@xxxxxx> wrote: >> >>>>>> -void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), >>>>>> - void *userdata) >>>>>> +void __pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), >>>>>> + void *userdata, u32 rid, u32 mask) >>>>>> { >>>>>> struct pci_dev *dev; >>>>>> struct pci_bus *bus; >>>>>> @@ -399,13 +401,16 @@ void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), >>>>>> } else >>>>>> next = dev->bus_list.next; >>>>>> >>>>>> + if (mask != 0xffff && ((pci_dev_id(dev) & mask) != rid)) >>>>> >>>>> Why the check for the mask? I also wonder whether the mask should apply >>>>> to the rid as well: >>>> >>>> If the mask is set for all 16bits, then there is not going to be two PCIe >>>> devices which gets the same ITS device ID right? So no need for calculating >>>> total number of vectors? >>> >>> Are we really arguing about the cost of a compare+branch vs some >>> readability? Or is there an actual correctness issue here? >> >> It is for correctness. So existing pci_walk_bus() doesn't invoke cb based on >> rid. So when we convert to __pci_walk_bus(), existing callers of pci_walk_bus() >> might not invoke cb for some devices without the check. >>> >>>>> >>>>> if ((pci_dev_id(dev) & mask) != (rid & mask)) >>> >>> Because I think the above expression is a lot more readable (and >>> likely more correct) than what you are suggesting. >> >> That would result in existing pci_walk_bus() behave differently from what was >> before this patch no? >> >> I'm having something like this below >> +#define pci_walk_bus(top, cb, userdata) \ >> + __pci_walk_bus((top), (cb), (userdata), 0x0, 0xffff) >> >> So if we add only "if ((pci_dev_id(dev) & mask) != (rid & mask))", >> the callback will not be invoked for any devices (other than one >> with rid = 0) > > But that *is* the bug, isn't it? If you want to parse all the devices, > a mask of 0 is what you need. The mask defines the bits that you want > to match against the RID you passed as a parameter. If you don't want > to check any bit, don't pass any! Indeed! Thanks for explaining. Regards, Kishon