diff options
author | Max Asbock <masbock@us.ibm.com> | 2005-06-21 20:16:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-21 22:07:35 -0400 |
commit | 8818760512424f60ad9fafb7a087b007a9274eb3 (patch) | |
tree | fb49ce398750f42803d4631a24e4a2ffe35d79d7 /drivers/misc/ibmasm/heartbeat.c | |
parent | 278d72ae8803ffcd16070c95fe1d53f4466dc741 (diff) |
[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 @@ | |||
25 | #include <linux/notifier.h> | 25 | #include <linux/notifier.h> |
26 | #include "ibmasm.h" | 26 | #include "ibmasm.h" |
27 | #include "dot_command.h" | 27 | #include "dot_command.h" |
28 | #include "lowlevel.h" | ||
28 | 29 | ||
29 | static int suspend_heartbeats = 0; | 30 | static int suspend_heartbeats = 0; |
30 | 31 | ||
@@ -62,7 +63,7 @@ void ibmasm_unregister_panic_notifier(void) | |||
62 | 63 | ||
63 | int ibmasm_heartbeat_init(struct service_processor *sp) | 64 | int ibmasm_heartbeat_init(struct service_processor *sp) |
64 | { | 65 | { |
65 | sp->heartbeat = ibmasm_new_command(HEARTBEAT_BUFFER_SIZE); | 66 | sp->heartbeat = ibmasm_new_command(sp, HEARTBEAT_BUFFER_SIZE); |
66 | if (sp->heartbeat == NULL) | 67 | if (sp->heartbeat == NULL) |
67 | return -ENOMEM; | 68 | return -ENOMEM; |
68 | 69 | ||
@@ -71,6 +72,12 @@ int ibmasm_heartbeat_init(struct service_processor *sp) | |||
71 | 72 | ||
72 | void ibmasm_heartbeat_exit(struct service_processor *sp) | 73 | void ibmasm_heartbeat_exit(struct service_processor *sp) |
73 | { | 74 | { |
75 | char tsbuf[32]; | ||
76 | |||
77 | dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf)); | ||
78 | ibmasm_wait_for_response(sp->heartbeat, IBMASM_CMD_TIMEOUT_NORMAL); | ||
79 | dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf)); | ||
80 | suspend_heartbeats = 1; | ||
74 | command_put(sp->heartbeat); | 81 | command_put(sp->heartbeat); |
75 | } | 82 | } |
76 | 83 | ||
@@ -78,14 +85,16 @@ void ibmasm_receive_heartbeat(struct service_processor *sp, void *message, size | |||
78 | { | 85 | { |
79 | struct command *cmd = sp->heartbeat; | 86 | struct command *cmd = sp->heartbeat; |
80 | struct dot_command_header *header = (struct dot_command_header *)cmd->buffer; | 87 | struct dot_command_header *header = (struct dot_command_header *)cmd->buffer; |
88 | char tsbuf[32]; | ||
81 | 89 | ||
90 | dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf)); | ||
82 | if (suspend_heartbeats) | 91 | if (suspend_heartbeats) |
83 | return; | 92 | return; |
84 | 93 | ||
85 | /* return the received dot command to sender */ | 94 | /* return the received dot command to sender */ |
86 | cmd->status = IBMASM_CMD_PENDING; | 95 | cmd->status = IBMASM_CMD_PENDING; |
87 | size = min(size, cmd->buffer_size); | 96 | size = min(size, cmd->buffer_size); |
88 | memcpy(cmd->buffer, message, size); | 97 | memcpy_fromio(cmd->buffer, message, size); |
89 | header->type = sp_write; | 98 | header->type = sp_write; |
90 | ibmasm_exec_command(sp, cmd); | 99 | ibmasm_exec_command(sp, cmd); |
91 | } | 100 | } |