diff options
author | Philipp Reisner <philipp.reisner@linbit.com> | 2007-03-07 15:55:39 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-03-07 19:08:08 -0500 |
commit | 05e52dd7396514648fba6c275eb7b49eca333c6d (patch) | |
tree | 144ecb4d6986128773e6d5aad4e9aae52ce554d1 /drivers/connector/connector.c | |
parent | 151a99317ee9efcfd3e642da62e1edf4f47fcb3e (diff) |
[CONNECTOR]: Bugfix for cn_call_callback()
When system under heavy stress and must allocate new work
instead of reusing old one, new work must use correct
completion callback.
Patch is based on Philipp's and Lars' work.
I only cleaned small stuff (and removed spaces instead of tabs).
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/connector/connector.c')
-rw-r--r-- | drivers/connector/connector.c | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index a44db75bc25b..a905f7820331 100644 --- a/drivers/connector/connector.c +++ b/drivers/connector/connector.c | |||
@@ -128,7 +128,7 @@ EXPORT_SYMBOL_GPL(cn_netlink_send); | |||
128 | */ | 128 | */ |
129 | static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), void *data) | 129 | static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), void *data) |
130 | { | 130 | { |
131 | struct cn_callback_entry *__cbq; | 131 | struct cn_callback_entry *__cbq, *__new_cbq; |
132 | struct cn_dev *dev = &cdev; | 132 | struct cn_dev *dev = &cdev; |
133 | int err = -ENODEV; | 133 | int err = -ENODEV; |
134 | 134 | ||
@@ -148,27 +148,27 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v | |||
148 | } else { | 148 | } else { |
149 | struct cn_callback_data *d; | 149 | struct cn_callback_data *d; |
150 | 150 | ||
151 | __cbq = kzalloc(sizeof(*__cbq), GFP_ATOMIC); | 151 | err = -ENOMEM; |
152 | if (__cbq) { | 152 | __new_cbq = kzalloc(sizeof(struct cn_callback_entry), GFP_ATOMIC); |
153 | d = &__cbq->data; | 153 | if (__new_cbq) { |
154 | d = &__new_cbq->data; | ||
154 | d->callback_priv = msg; | 155 | d->callback_priv = msg; |
155 | d->callback = __cbq->data.callback; | 156 | d->callback = __cbq->data.callback; |
156 | d->ddata = data; | 157 | d->ddata = data; |
157 | d->destruct_data = destruct_data; | 158 | d->destruct_data = destruct_data; |
158 | d->free = __cbq; | 159 | d->free = __new_cbq; |
159 | 160 | ||
160 | INIT_WORK(&__cbq->work, | 161 | INIT_WORK(&__new_cbq->work, |
161 | &cn_queue_wrapper); | 162 | &cn_queue_wrapper); |
162 | 163 | ||
163 | if (queue_work(dev->cbdev->cn_queue, | 164 | if (queue_work(dev->cbdev->cn_queue, |
164 | &__cbq->work)) | 165 | &__new_cbq->work)) |
165 | err = 0; | 166 | err = 0; |
166 | else { | 167 | else { |
167 | kfree(__cbq); | 168 | kfree(__new_cbq); |
168 | err = -EINVAL; | 169 | err = -EINVAL; |
169 | } | 170 | } |
170 | } else | 171 | } |
171 | err = -ENOMEM; | ||
172 | } | 172 | } |
173 | break; | 173 | break; |
174 | } | 174 | } |