On Fri, Nov 02, 2018 at 06:11:07PM +0000, Woods, Brian wrote: > Add support for new processors which have multiple PCI root complexes > per data fabric/SMN interface. Please write out abbreviations. I believe it is only you and I who know what SMN means. :) > The interfaces per root complex are redundant and should be skipped. And I believe it is only you who understands that sentence. :) Please elaborate why interfaces need to be skipped, *which* interfaces need to be skipped and which is the correct interface to access DF/SMN through? > This makes sure the DF/SMN interfaces get accessed via the correct > root complex. > > Ex: > DF/SMN 0 -> 60 > 40 > 20 > 00 > DF/SMN 1 -> e0 > c0 > a0 > 80 > > Signed-off-by: Brian Woods <brian.woods@xxxxxxx> > --- > arch/x86/kernel/amd_nb.c | 41 +++++++++++++++++++++++++++++++++++------ > 1 file changed, 35 insertions(+), 6 deletions(-) > > diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c > index 19d489ee2b1e..c0bf26aeb7c3 100644 > --- a/arch/x86/kernel/amd_nb.c > +++ b/arch/x86/kernel/amd_nb.c > @@ -213,7 +213,10 @@ int amd_cache_northbridges(void) > const struct pci_device_id *root_ids = amd_root_ids; > struct pci_dev *root, *misc, *link; > struct amd_northbridge *nb; > - u16 i = 0; > + u16 roots_per_misc = 0; > + u16 misc_count = 0; > + u16 root_count = 0; > + u16 i, j; > > if (amd_northbridges.num) > return 0; > @@ -226,26 +229,52 @@ int amd_cache_northbridges(void) > > misc = NULL; > while ((misc = next_northbridge(misc, misc_ids)) != NULL) > - i++; > + misc_count++; > > - if (!i) > + root = NULL; > + while ((root = next_northbridge(root, root_ids)) != NULL) > + root_count++; > + > + if (!misc_count) > return -ENODEV; So you're doing the root_count above but returning in the !misc_count case. So that root_count iteration was unnecessary work. IOW, you should keep the misc_count check after its loop. > > - nb = kcalloc(i, sizeof(struct amd_northbridge), GFP_KERNEL); > + if (root_count) { > + roots_per_misc = root_count / misc_count; > + > + /* > + * There should be _exactly_ N roots for each DF/SMN > + * interface. > + */ > + if (!roots_per_misc || (root_count % roots_per_misc)) { > + pr_info("Unsupported AMD DF/PCI configuration found\n"); > + return -ENODEV; > + } > + } > + > + nb = kcalloc(misc_count, sizeof(struct amd_northbridge), GFP_KERNEL); > if (!nb) > return -ENOMEM; > > amd_northbridges.nb = nb; > - amd_northbridges.num = i; > + amd_northbridges.num = misc_count; > > link = misc = root = NULL; > - for (i = 0; i != amd_northbridges.num; i++) { > + for (i = 0; i < amd_northbridges.num; i++) { > node_to_amd_nb(i)->root = root = > next_northbridge(root, root_ids); > node_to_amd_nb(i)->misc = misc = > next_northbridge(misc, misc_ids); > node_to_amd_nb(i)->link = link = > next_northbridge(link, link_ids); > + > + /* > + * If there are more root devices than data fabric/SMN, > + * interfaces, then the root devices per DF/SMN > + * interface are redundant and N-1 should be skipped so > + * they aren't mapped incorrectly. > + */ This text is trying to explain it a bit better but you still still need to specify which are the redundant ones. All N-1 or is there a special root device through which the DF/SMN gets accessed or? Thx. -- Regards/Gruss, Boris. Good mailing practices for 400: avoid top-posting and trim the reply.