Messages in this thread Patch in this message | | | Date | Fri, 03 Oct 2008 12:56:33 +0200 | From | Heiko Carstens <> | Subject | [PATCH/RFC 1/4] stop_machine: atomic update for combined return value |
| |
From: Heiko Carstens <heiko.carstens@de.ibm.com>
Using |= for updating a value which might be updated on several cpus concurrently will not always work since we need to make sure that the update happens atomically. So let's use a cmpxchg loop instead.
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> --- kernel/stop_machine.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
Index: linux-2.6/kernel/stop_machine.c =================================================================== --- linux-2.6.orig/kernel/stop_machine.c +++ linux-2.6/kernel/stop_machine.c @@ -65,6 +65,7 @@ static void ack_state(void) static int stop_cpu(struct stop_machine_data *smdata) { enum stopmachine_state curstate = STOPMACHINE_NONE; + int *frp, fnret, old; /* Simple state machine */ do { @@ -80,7 +81,11 @@ static int stop_cpu(struct stop_machine_ case STOPMACHINE_RUN: /* |= allows error detection if functions on * multiple CPUs. */ - smdata->fnret |= smdata->fn(smdata->data); + fnret = smdata->fn(smdata->data); + frp = &smdata->fnret; + do { + old = *frp; + } while (cmpxchg(frp, old, old | fnret) != old); break; default: break; --
| |