[lttng-dev] urcu workqueue thread uses 99% of cpu while workqueue is empty
Mathieu Desnoyers
mathieu.desnoyers at efficios.com
Wed Jun 15 10:15:58 EDT 2022
----- On Jun 14, 2022, at 11:49 PM, Minlan Wang wangminlan at szsandstone.com wrote:
> Hi, Mathieu,
> The commit on branch stable-0.12 correponds to the tarball we downloaded is
> this:
>
> commit d5277e807192178ddb79f56ecbbd5ac3c4994f60 (HEAD -> v0.12.1.b, tag:
> v0.12.1)
> Author: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
> Date: Wed Apr 22 08:51:41 2020 -0400
>
> Version 0.12.1
>
> Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
>
> The OS we are using is CentOS Linux release 7.9.2009 (Core), not CentOS 8.2
> as mentioned before. And the kernel version is: 3.10.0-1160.el7.x86_64.
One more thing: did you apply any changes on top of the v0.12.1 userspace rcu tag ?
Also, can you provide the output of "./configure" on your system ? I'm also interested
in knowing the contents of include/urcu/config.h after building liburcu.
Thanks,
Mathieu
>
> On Tue, Jun 14, 2022 at 11:53:16AM -0400, Mathieu Desnoyers wrote:
>> Also, I notice that you appear to be using an internal liburcu API (not public)
>> from outside of the liburcu project, which is not really expected.
> We are trying to move some linux kernel module function into userspace, and
> found that the urcu internal workqueue.h has all the things we need for a
> replace for kernel workqueue, so we decided to give it a try.
>
>>
>> If your process forks without exec, make sure you wire up the equivalent of
>> rculfhash pthread_atfork functions which call urcu_workqueue_pause_worker(),
>> urcu_workqueue_resume_worker() and urcu_workqueue_create_worker().
> There's no fork/exec in the process who is calling alloc_workqueue, and the
> threads who are enqueue work into the workqueue is created by calling
> pthread_create.
>
>>
>> Also, can you validate of you have many workqueue worker threads trying to
>> dequeue from the same workqueue in parallel ? This is unsupported and would
>> cause the kind of issues you are observing here.
> The workqueue thread is created by calling urcu_workqueue_create in the code
> below, and it is the only thread which will dequeue work from the workqueue.
> Though, there are multiple threads who will enqueue work by calling
> urcu_workqueue_queue_work(wq, work, work->func).
> ---
> static void workqueue_init_fn(struct urcu_workqueue *workqueue, void *priv)
> {
> pthread_t tid;
> const char *name;
> char thread_name[16] = {0};
>
> if (!priv)
> return;
>
> name = (const char *)priv;
> tid = pthread_self();
>
> memcpy(thread_name, name, 15);
> if (pthread_setname_np(tid, thread_name)) {
> pr_err("failed to set thread name for workqueue %s\n", name);
> }
>
> urcu_memb_register_thread();
> }
>
> static void workqueue_finalize_fn(struct urcu_workqueue *workqueue, void
> *priv)
> {
> urcu_memb_unregister_thread();
> if (priv)
> free(priv);
> }
>
> struct workqueue_struct *alloc_workqueue(const char *fmt,
> unsigned int flags,
> int max_active, ...)
> {
> const char *name;
>
> name = strdup(fmt);
> if (!name) {
> pr_err("failed to dup name for workqueue %s\n", fmt);
> return NULL;
> }
>
> return urcu_workqueue_create(0, -1, (void *)name,
> NULL, /* grace */
> workqueue_init_fn, /* init */
> workqueue_finalize_fn, /* finalize */
> NULL, /* before wait */
> NULL, /* after wake up */
> NULL, /* before pasue */
> NULL); /* after resume */
> }
> ---
>
> B.R
> Minlan
--
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com
More information about the lttng-dev
mailing list