aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/connector/connector.c
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2009-02-03 02:22:04 -0500
committerDavid S. Miller <davem@davemloft.net>2009-02-03 02:22:04 -0500
commit1a5645bc901aea6f3f446888061b2b084bbf1ba6 (patch)
tree1100723a5bd190311eaac46ce6eff22bf69a9a86 /drivers/connector/connector.c
parentf15fbcd7d857ca2ea20b57ba6dfe63aab89d0b8b (diff)
connector: create connector workqueue only while needed once
The netlink connector uses its own workqueue to relay the datas sent from userspace to the appropriate callback. If you launch the test from Documentation/connector and change it a bit to send a high flow of data, you will see thousands of events coming to the "cqueue" workqueue by looking at the workqueue tracer. This flow of events can be sent very quickly. So, to not encumber the kevent workqueue and delay other jobs, the "cqueue" workqueue should remain. But this workqueue is pointless most of the time, it will always be created (assuming you have built it of course) although only developpers with specific needs will use it. So avoid this "most of the time useless task", this patch proposes to create this workqueue only when needed once. The first jobs to be sent to connector callbacks will be sent to kevent while the "cqueue" thread creation will be scheduled to kevent too. The following jobs will continue to be scheduled to keventd until the cqueue workqueue is created, and then the rest of the jobs will continue to perform as usual, through this dedicated workqueue. Each time I tested this patch, only the first event was sent to keventd, the rest has been sent to cqueue which have been created quickly. Also, this patch fixes some trailing whitespaces on the connector files. Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Acked-by: Evgeniy Polyakov <zbr@ioremap.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/connector/connector.c')
-rw-r--r--drivers/connector/connector.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index bf4830082a13..fd336c5a9057 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -1,9 +1,9 @@
1/* 1/*
2 * connector.c 2 * connector.c
3 * 3 *
4 * 2004-2005 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru> 4 * 2004-2005 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or 9 * the Free Software Foundation; either version 2 of the License, or
@@ -145,14 +145,13 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v
145 __cbq->data.ddata = data; 145 __cbq->data.ddata = data;
146 __cbq->data.destruct_data = destruct_data; 146 __cbq->data.destruct_data = destruct_data;
147 147
148 if (queue_work(dev->cbdev->cn_queue, 148 if (queue_cn_work(__cbq, &__cbq->work))
149 &__cbq->work))
150 err = 0; 149 err = 0;
151 else 150 else
152 err = -EINVAL; 151 err = -EINVAL;
153 } else { 152 } else {
154 struct cn_callback_data *d; 153 struct cn_callback_data *d;
155 154
156 err = -ENOMEM; 155 err = -ENOMEM;
157 __new_cbq = kzalloc(sizeof(struct cn_callback_entry), GFP_ATOMIC); 156 __new_cbq = kzalloc(sizeof(struct cn_callback_entry), GFP_ATOMIC);
158 if (__new_cbq) { 157 if (__new_cbq) {
@@ -163,10 +162,12 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v
163 d->destruct_data = destruct_data; 162 d->destruct_data = destruct_data;
164 d->free = __new_cbq; 163 d->free = __new_cbq;
165 164
165 __new_cbq->pdev = __cbq->pdev;
166
166 INIT_WORK(&__new_cbq->work, 167 INIT_WORK(&__new_cbq->work,
167 &cn_queue_wrapper); 168 &cn_queue_wrapper);
168 169
169 if (queue_work(dev->cbdev->cn_queue, 170 if (queue_cn_work(__new_cbq,
170 &__new_cbq->work)) 171 &__new_cbq->work))
171 err = 0; 172 err = 0;
172 else { 173 else {
@@ -237,7 +238,7 @@ static void cn_notify(struct cb_id *id, u32 notify_event)
237 238
238 req = (struct cn_notify_req *)ctl->data; 239 req = (struct cn_notify_req *)ctl->data;
239 for (i = 0; i < ctl->idx_notify_num; ++i, ++req) { 240 for (i = 0; i < ctl->idx_notify_num; ++i, ++req) {
240 if (id->idx >= req->first && 241 if (id->idx >= req->first &&
241 id->idx < req->first + req->range) { 242 id->idx < req->first + req->range) {
242 idx_found = 1; 243 idx_found = 1;
243 break; 244 break;
@@ -245,7 +246,7 @@ static void cn_notify(struct cb_id *id, u32 notify_event)
245 } 246 }
246 247
247 for (i = 0; i < ctl->val_notify_num; ++i, ++req) { 248 for (i = 0; i < ctl->val_notify_num; ++i, ++req) {
248 if (id->val >= req->first && 249 if (id->val >= req->first &&
249 id->val < req->first + req->range) { 250 id->val < req->first + req->range) {
250 val_found = 1; 251 val_found = 1;
251 break; 252 break;
@@ -459,7 +460,7 @@ static int __devinit cn_init(void)
459 netlink_kernel_release(dev->nls); 460 netlink_kernel_release(dev->nls);
460 return -EINVAL; 461 return -EINVAL;
461 } 462 }
462 463
463 cn_already_initialized = 1; 464 cn_already_initialized = 1;
464 465
465 err = cn_add_callback(&dev->id, "connector", &cn_callback); 466 err = cn_add_callback(&dev->id, "connector", &cn_callback);