From: Yazen Ghannam <yazen.ghan...@amd.com> There needs to be a list_head outside of a linked list in order to iterate over it and have access to all its elements. This is because the list_for_each* macros iterate starting from head->next rather than head.
Define a list_head for the threshold blocks list in struct threshold_bank since this is the container of the list. Use this list_head as the head instead of the first element in the blocks list. This is needed in a future patch where we read the blocks list in the threshold interrupt handler. Currently, we'll always skip block 0 since it is the head of the list. Signed-off-by: Yazen Ghannam <yazen.ghan...@amd.com> --- arch/x86/include/asm/amd_nb.h | 2 ++ arch/x86/kernel/cpu/mcheck/mce_amd.c | 19 ++++++++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/arch/x86/include/asm/amd_nb.h b/arch/x86/include/asm/amd_nb.h index da181ad..81334b4 100644 --- a/arch/x86/include/asm/amd_nb.h +++ b/arch/x86/include/asm/amd_nb.h @@ -55,6 +55,8 @@ struct threshold_bank { struct kobject *kobj; struct threshold_block *blocks; + struct list_head blocks_head; + /* initialized to the number of CPUs on the node sharing this bank */ refcount_t cpus; }; diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index d11f94e..2074b870 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -1119,15 +1119,15 @@ static int allocate_threshold_blocks(unsigned int cpu, unsigned int bank, threshold_ktype.default_attrs[2] = NULL; } - INIT_LIST_HEAD(&b->miscj); - - if (per_cpu(threshold_banks, cpu)[bank]->blocks) { - list_add(&b->miscj, - &per_cpu(threshold_banks, cpu)[bank]->blocks->miscj); - } else { + if (!per_cpu(threshold_banks, cpu)[bank]->blocks) { + INIT_LIST_HEAD(&per_cpu(threshold_banks, cpu)[bank]->blocks_head); per_cpu(threshold_banks, cpu)[bank]->blocks = b; } + INIT_LIST_HEAD(&b->miscj); + + list_add(&b->miscj, &per_cpu(threshold_banks, cpu)[bank]->blocks_head); + err = kobject_init_and_add(&b->kobj, &threshold_ktype, per_cpu(threshold_banks, cpu)[bank]->kobj, get_name(bank, b)); @@ -1158,7 +1158,7 @@ static int allocate_threshold_blocks(unsigned int cpu, unsigned int bank, static int __threshold_add_blocks(struct threshold_bank *b) { - struct list_head *head = &b->blocks->miscj; + struct list_head *head = &b->blocks_head; struct threshold_block *pos = NULL; struct threshold_block *tmp = NULL; int err = 0; @@ -1256,7 +1256,7 @@ static void deallocate_threshold_block(unsigned int cpu, if (!head) return; - list_for_each_entry_safe(pos, tmp, &head->blocks->miscj, miscj) { + list_for_each_entry_safe(pos, tmp, &head->blocks_head, miscj) { kobject_put(&pos->kobj); list_del(&pos->miscj); kfree(pos); @@ -1273,7 +1273,7 @@ static void __threshold_remove_blocks(struct threshold_bank *b) kobject_del(b->kobj); - list_for_each_entry_safe(pos, tmp, &b->blocks->miscj, miscj) + list_for_each_entry_safe(pos, tmp, &b->blocks_head, miscj) kobject_del(&pos->kobj); } @@ -1307,6 +1307,7 @@ static void threshold_remove_bank(unsigned int cpu, int bank) deallocate_threshold_block(cpu, bank); free_out: + list_del(&b->blocks_head); kobject_del(b->kobj); kobject_put(b->kobj); kfree(b); -- 2.7.4