kernelnewbies.kernelnewbies.org archive mirror
 help / color / mirror / Atom feed
From: "Fabio M. De Francesco" <fmdefrancesco@gmail.com>
To: kernelnewbies@kernelnewbies.org
Cc: Martin Kaiser <lists@kaiser.cx>, martin@kaiser.cx
Subject: Re: workqueue - queue + drain
Date: Tue, 27 Sep 2022 14:50:48 +0200	[thread overview]
Message-ID: <4744153.GXAFRqVoOG@localhost.localdomain> (raw)
In-Reply-To: <20220811160351.urbqbhquu5u74obe@viti.kaiser.cx>

On Thursday, August 11, 2022 6:03:51 PM CEST Martin Kaiser wrote:
> Dear all,
> 
> would you mind helping me understand how workers and workqueues act in a
> seemingly simple scenario? 

Hi Martin,

After long time away from this list, today I just saw your email. I soon 
thought that it's a bit odd that nobody has yet responded, since here many 
experienced developers for sure know how workqueues work :-) (pun intended).

However, I had to read your message several times and I must admit that I'm 
not yet sure about what you are asking for. Perhaps other readers might have 
had the very same problem that I experienced, so that they decided to skip 
your question :-)

Therefore, I won't provide plain responses. Instead I'm going to ask you a 
couple of questions while hoping they may help you to rework your question if 
they cannot help directly with your question...

> I'm calling
> 
> queue_work(my_queue, my_worker)
> 
> to add a worker to a queue that was created by calling
> create_singlethread_workqueue().

create_singlethread_workqueue() This is deprecated. 

Please use alloc_ordered_workqueue(name, WQ_MEM_RECLAIM) from the newer 
Concurrency Managed Workqueues (CMW).
 
> This goes into
> 
> queue_work
>    queue_work_on
>          ...
>          if (!test_and_set_bit(WORK_STRUCT_PENDING_BIT, 
work_data_bits(work))) {
>             __queue_work(cpu, wq, work);
>             ret = true;
>          }
>          ... return false if __queue_work hasn't been called...
> 
> 
> with
> 
> static void __queue_work(int cpu, struct workqueue_struct *wq, struct 
work_struct *work)
>    ...
>    /* if draining, only works from the same workqueue are allowed */
>    if (unlikely(wq->flags & __WQ_DRAINING) &&
>        WARN_ON_ONCE(!is_chained_work(wq)))
>       return;
> 
> 
> If drain_workqueue(my_queue) is running while
> queue_work(my_queue, my_worker)
> is called, my_worker will have WORK_STRUCT_PENDING_BIT set, but it's not
> queued and no error is returned.
> 
> With WORK_STRUCT_PENDING_BIT set, all further attempts to
> queue_work(my_queue, my_worker)
> later, after draining is done, will fail.

Correct, this is what I'd expect to see. I'd be very surprised if it wouldn't  
fail.

Are you aware that, while draining is in progress, only "chain queueing" is 
allowed? "Chain queuing" means that *only* works already in a draining 
workqueue are allowed to queue further tasks.

Furthermore, flush_workqueue() != drain_workqueue(). Can you explain their 
different semantics?

> 
> This code has been unchanged since at least 4.14. Could anyone shed some
> light on this, where am I getting things wrong?
> 
> Thanks and best regards,
> 
>    Martin

Regards,

Fabio

> 
> _______________________________________________
> Kernelnewbies mailing list
> Kernelnewbies@kernelnewbies.org
> https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
> 











_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

      reply	other threads:[~2022-09-27 12:51 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-11 16:03 workqueue - queue + drain Martin Kaiser
2022-09-27 12:50 ` Fabio M. De Francesco [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4744153.GXAFRqVoOG@localhost.localdomain \
    --to=fmdefrancesco@gmail.com \
    --cc=kernelnewbies@kernelnewbies.org \
    --cc=lists@kaiser.cx \
    --cc=martin@kaiser.cx \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).