![]() | |||||||||||||
Messages in this thread |
On Thu, 18 Mar 2004, Andrew Morton wrote:
> I would suggest that you look at avoiding the global semaphore. Suppose
> someone has 64 interfaces or something. Is that possible? It might be
> better to put the semaphore into struct capi_ctr so you can at least
> process frames from separate cards in parallel.
>
> > Is there a better way to do user-context work serialized ?
>
> Not really - you've been bitten by the compulsory per-cpuness of the
> workqueue handlers.
>
> You could have a standalone kernel thread or always queue the work onto CPU
> #0 (the function to do this isn't merged, but exists). But both these are
> unscalable.
>
> So apart from moving recv_handler_lock into struct capi_ctr I can't think
> of anything clever.
I think an atomic counter in the workqueue-function would be more efficient.
What do you think about this?
static atomic_t recv_work_count;
static void recv_handler(void *data)
{
if (atomic_inc_and_test(&recv_work_count)) {
do {
/* work to do */
} while (!atomic_add_negative(-1, &recv_work_count));
}
}
static int __init kcapi_init(void)
{
atomic_set(&recv_work_count, -1);
}
A second call to the recv_handler() just results in an additional loop
of the first one and the second CPU goes on with its work.
Unfortunately, the atomic functions are not available on all architechtures.
atomic_dec_and_test() is the only atomic function with return value on all
platforms, right? Which isn't enough for the loop above.
Armin
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
| ||||||||||||
| Last update: 2005-03-22 13:01 [W:0.415 / U:0.080 seconds] ©2003-2008 Jasper Spaans | |||||||||||||