From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from shelob.surriel.com (shelob.surriel.com [96.67.55.147]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 20250C19F2A for ; Thu, 11 Aug 2022 16:04:21 +0000 (UTC) Received: from localhost ([::1] helo=shelob.surriel.com) by shelob.surriel.com with esmtp (Exim 4.95) (envelope-from ) id 1oMAf9-00058V-PY; Thu, 11 Aug 2022 12:03:59 -0400 Received: from viti.kaiser.cx ([2a01:238:43fe:e600:cd0c:bd4a:7a3:8e9f]) by shelob.surriel.com with esmtps (TLS1.2) tls TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1oMAf6-00052t-6Z for kernelnewbies@kernelnewbies.org; Thu, 11 Aug 2022 12:03:56 -0400 Received: from martin by viti.kaiser.cx with local (Exim 4.89) (envelope-from ) id 1oMAf1-0004Eg-NU for kernelnewbies@kernelnewbies.org; Thu, 11 Aug 2022 18:03:51 +0200 Date: Thu, 11 Aug 2022 18:03:51 +0200 From: Martin Kaiser To: kernelnewbies@kernelnewbies.org Subject: workqueue - queue + drain Message-ID: <20220811160351.urbqbhquu5u74obe@viti.kaiser.cx> Mail-Followup-To: kernelnewbies@kernelnewbies.org MIME-Version: 1.0 Content-Disposition: inline User-Agent: NeoMutt/20170113 (1.7.2) X-BeenThere: kernelnewbies@kernelnewbies.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Learn about the Linux kernel List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: kernelnewbies-bounces@kernelnewbies.org Dear all, would you mind helping me understand how workers and workqueues act in a seemingly simple scenario? I'm calling queue_work(my_queue, my_worker) to add a worker to a queue that was created by calling create_singlethread_workqueue(). 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. 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 _______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies