diff options
author | Max Asbock <masbock@us.ibm.com> | 2005-06-21 17:16:36 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-21 19:07:35 -0700 |
commit | 8818760512424f60ad9fafb7a087b007a9274eb3 (patch) | |
tree | fb49ce398750f42803d4631a24e4a2ffe35d79d7 /drivers/misc/ibmasm/heartbeat.c | |
parent | 278d72ae8803ffcd16070c95fe1d53f4466dc741 (diff) | |
download | linux-8818760512424f60ad9fafb7a087b007a9274eb3.tar.bz2 |
[PATCH] ibmasm driver: fix race in command refcount logic
This patch fixes a race in the command reference counting logic by putting
spinlocks around kobject_put() in the command_put function.
- Also added debug messages.
- Changed a memcpy to memcpy_fromio since we are reading from io space.
Signed-off-by: Max Asbock <masbock@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/misc/ibmasm/heartbeat.c')
-rw-r--r-- | drivers/misc/ibmasm/heartbeat.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/misc/ibmasm/heartbeat.c b/drivers/misc/ibmasm/heartbeat.c index ce09309174d6..f295401fac21 100644 --- a/drivers/misc/ibmasm/heartbeat.c +++ b/drivers/misc/ibmasm/heartbeat.c @@ -25,6 +25,7 @@ #include <linux/notifier.h> #include "ibmasm.h" #include "dot_command.h" +#include "lowlevel.h" static int suspend_heartbeats = 0; @@ -62,7 +63,7 @@ void ibmasm_unregister_panic_notifier(void) int ibmasm_heartbeat_init(struct service_processor *sp) { - sp->heartbeat = ibmasm_new_command(HEARTBEAT_BUFFER_SIZE); + sp->heartbeat = ibmasm_new_command(sp, HEARTBEAT_BUFFER_SIZE); if (sp->heartbeat == NULL) return -ENOMEM; @@ -71,6 +72,12 @@ int ibmasm_heartbeat_init(struct service_processor *sp) void ibmasm_heartbeat_exit(struct service_processor *sp) { + char tsbuf[32]; + + dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf)); + ibmasm_wait_for_response(sp->heartbeat, IBMASM_CMD_TIMEOUT_NORMAL); + dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf)); + suspend_heartbeats = 1; command_put(sp->heartbeat); } @@ -78,14 +85,16 @@ void ibmasm_receive_heartbeat(struct service_processor *sp, void *message, size { struct command *cmd = sp->heartbeat; struct dot_command_header *header = (struct dot_command_header *)cmd->buffer; + char tsbuf[32]; + dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf)); if (suspend_heartbeats) return; /* return the received dot command to sender */ cmd->status = IBMASM_CMD_PENDING; size = min(size, cmd->buffer_size); - memcpy(cmd->buffer, message, size); + memcpy_fromio(cmd->buffer, message, size); header->type = sp_write; ibmasm_exec_command(sp, cmd); } |