[PATCH 4/9] use smp_call_function_single() in arch/x86/kernel/cpu/mcheck/mce_amd_64.c

From: Rusty Russell
Date: Wed Mar 18 2009 - 00:23:03 EST


From: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>

Attempting to rid us of the problematic work_on_cpu(). Just use
smp_call_function_single() here.

Cc: Ingo Molnar <mingo@xxxxxxx>
Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Cc: "H. Peter Anvin" <hpa@xxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
Signed-off-by: Rusty Russell <rusty@xxxxxxxxxxxxxxx>
---
arch/x86/kernel/cpu/mcheck/mce_amd_64.c | 40 +++++++++++++++++++-------------
1 file changed, 24 insertions(+), 16 deletions(-)

diff -puN arch/x86/kernel/cpu/mcheck/mce_amd_64.c~arch-x86-kernel-cpu-mcheck-mce_amd_64c-avoid-using-work_on_cpu arch/x86/kernel/cpu/mcheck/mce_amd_64.c
--- a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c~arch-x86-kernel-cpu-mcheck-mce_amd_64c-avoid-using-work_on_cpu
+++ a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c
@@ -90,7 +90,8 @@ struct thresh_restart {
};

/* must be called with correct cpu affinity */
-static long threshold_restart_bank(void *_tr)
+/* Called via smp_call_function_single() */
+static void threshold_restart_bank(void *_tr)
{
struct thresh_restart *tr = _tr;
u32 mci_misc_hi, mci_misc_lo;
@@ -117,7 +118,6 @@ static long threshold_restart_bank(void

mci_misc_hi |= MASK_COUNT_EN_HI;
wrmsr(tr->b->address, mci_misc_lo, mci_misc_hi);
- return 0;
}

/* cpu init entry point, called from mce.c with preempt off */
@@ -283,7 +283,7 @@ static ssize_t store_interrupt_enable(st
tr.b = b;
tr.reset = 0;
tr.old_limit = 0;
- work_on_cpu(b->cpu, threshold_restart_bank, &tr);
+ smp_call_function_single(b->cpu, threshold_restart_bank, &tr, 1);

return end - buf;
}
@@ -305,23 +305,32 @@ static ssize_t store_threshold_limit(str
tr.b = b;
tr.reset = 0;

- work_on_cpu(b->cpu, threshold_restart_bank, &tr);
+ smp_call_function_single(b->cpu, threshold_restart_bank, &tr, 1);

return end - buf;
}

-static long local_error_count(void *_b)
+struct threshold_block_cross_cpu {
+ struct threshold_block *tb;
+ long retval;
+};
+
+static void local_error_count_handler(void *_tbcc)
{
- struct threshold_block *b = _b;
+ struct threshold_block_cross_cpu *tbcc = _tbcc;
+ struct threshold_block *b = tbcc->tb;
u32 low, high;

rdmsr(b->address, low, high);
- return (high & 0xFFF) - (THRESHOLD_MAX - b->threshold_limit);
+ tbcc->retval = (high & 0xFFF) - (THRESHOLD_MAX - b->threshold_limit);
}

static ssize_t show_error_count(struct threshold_block *b, char *buf)
{
- return sprintf(buf, "%lx\n", work_on_cpu(b->cpu, local_error_count, b));
+ struct threshold_block_cross_cpu tbcc = { .tb = b, };
+
+ smp_call_function_single(b->cpu, local_error_count_handler, &tbcc, 1);
+ return sprintf(buf, "%lx\n", tbcc.retval);
}

static ssize_t store_error_count(struct threshold_block *b,
@@ -329,7 +338,7 @@ static ssize_t store_error_count(struct
{
struct thresh_restart tr = { .b = b, .reset = 1, .old_limit = 0 };

- work_on_cpu(b->cpu, threshold_restart_bank, &tr);
+ smp_call_function_single(b->cpu, threshold_restart_bank, &tr, 1);
return 1;
}

@@ -398,7 +407,7 @@ static __cpuinit int allocate_threshold_
if ((bank >= NR_BANKS) || (block >= NR_BLOCKS))
return 0;

- if (rdmsr_safe(address, &low, &high))
+ if (rdmsr_safe_on_cpu(cpu, address, &low, &high))
return 0;

if (!(high & MASK_VALID_HI)) {
@@ -462,12 +471,11 @@ out_free:
return err;
}

-static __cpuinit long local_allocate_threshold_blocks(void *_bank)
+static __cpuinit long
+local_allocate_threshold_blocks(int cpu, unsigned int bank)
{
- unsigned int *bank = _bank;
-
- return allocate_threshold_blocks(smp_processor_id(), *bank, 0,
- MSR_IA32_MC0_MISC + *bank * 4);
+ return allocate_threshold_blocks(cpu, bank, 0,
+ MSR_IA32_MC0_MISC + bank * 4);
}

/* symlinks sibling shared banks to first core. first core owns dir/files. */
@@ -525,7 +533,7 @@ static __cpuinit int threshold_create_ba

per_cpu(threshold_banks, cpu)[bank] = b;

- err = work_on_cpu(cpu, local_allocate_threshold_blocks, &bank);
+ err = local_allocate_threshold_blocks(cpu, bank);
if (err)
goto out_free;

_

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/