Received: by 2002:a05:6358:bb9e:b0:b9:5105:a5b4 with SMTP id df30csp2973105rwb; Mon, 5 Sep 2022 04:40:26 -0700 (PDT) X-Google-Smtp-Source: AA6agR5D94c9eVK+mgCuUL9e6pgm0zFbNkbe9f6p5IK35QorG+0NWOymB4+nDuOKz3R43QX9RZiZ X-Received: by 2002:a05:6402:2949:b0:445:dc8d:44d with SMTP id ed9-20020a056402294900b00445dc8d044dmr43509869edb.60.1662378026292; Mon, 05 Sep 2022 04:40:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1662378026; cv=none; d=google.com; s=arc-20160816; b=TQZ2j7HjV/f12Uy5PC3UlJEGzWpiD0akuvpNIBogOggH/eixyWql6IB9GmllhjDepu TQT4SkNbjsEh69wHkQStU6G/lz02rU+pcBWwfdi2tF+39jdGqKGxYdu1vTcBhSGCy9Xx TfdQilDVeMRtH1kxJBNMRmTIq0LoDT4sydgh9FLMNXwRGmif2QJG5lWKPLNhU1vZIGcz qeC3RcfZP1ANrM1LTY2TG+alTGaw5KwIkx+zj8FblYRJNl36RJn00aCD1bLk9Kdcskte xgA29LkxRVAGUA+CMT1AoCGFbzl6OlBHlmilIkf9I/jcGLceSYWko3t7cPcFNIr5n4sv U4gw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:in-reply-to:from :references:cc:to:content-language:subject:user-agent:mime-version :date:message-id; bh=uD2AVQKlyvXggCRljSN2FfgTXzKzrbWblBjmlW/TDoc=; b=ZlKZKL9yR1jRy4d6gk9ZD3ioTtls29roYxQTLIp52OS//GA5WHOljeHU4laRsFIY9X jxfXqC2DsPNTCDw7CvHuQShNOQEAhhCeu0uSxRwIVae7auASMakAhzM0N9CCoxFpVlmy SmHz24Tviw8s8jRw4P8Hkts5kDPOIFAqJkWehslyWKBSx4pcbyeUnKyg9foaHNccx+fM BCSg6at5FAenfAWGhVaa+HBLdxeAqntnx207R0oCd8rCneAeYhtAeGA+9B0I7yZuFTWo 01a8wzYwc40Np3Jz5FTpJk0w+Fe+/W3bcuFL6yrn1J7PZqlT3H556XdW8ZKYSAOsArsf jEgg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-bluetooth-owner@vger.kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id y7-20020a50eb07000000b004408bac1e2fsi5835171edp.370.2022.09.05.04.39.49; Mon, 05 Sep 2022 04:40:26 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-bluetooth-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236825AbiIELXu (ORCPT + 99 others); Mon, 5 Sep 2022 07:23:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59238 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238198AbiIELXq (ORCPT ); Mon, 5 Sep 2022 07:23:46 -0400 Received: from www262.sakura.ne.jp (www262.sakura.ne.jp [202.181.97.72]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 91BB95B791 for ; Mon, 5 Sep 2022 04:23:43 -0700 (PDT) Received: from fsav314.sakura.ne.jp (fsav314.sakura.ne.jp [153.120.85.145]) by www262.sakura.ne.jp (8.15.2/8.15.2) with ESMTP id 285BNfPJ028744; Mon, 5 Sep 2022 20:23:41 +0900 (JST) (envelope-from penguin-kernel@I-love.SAKURA.ne.jp) Received: from www262.sakura.ne.jp (202.181.97.72) by fsav314.sakura.ne.jp (F-Secure/fsigk_smtp/550/fsav314.sakura.ne.jp); Mon, 05 Sep 2022 20:23:41 +0900 (JST) X-Virus-Status: clean(F-Secure/fsigk_smtp/550/fsav314.sakura.ne.jp) Received: from [192.168.1.9] (M106072142033.v4.enabler.ne.jp [106.72.142.33]) (authenticated bits=0) by www262.sakura.ne.jp (8.15.2/8.15.2) with ESMTPSA id 285BNfiO028741 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NO); Mon, 5 Sep 2022 20:23:41 +0900 (JST) (envelope-from penguin-kernel@I-love.SAKURA.ne.jp) Message-ID: <24660886-da42-c129-77e6-87c344879a3b@I-love.SAKURA.ne.jp> Date: Mon, 5 Sep 2022 20:23:39 +0900 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:102.0) Gecko/20100101 Thunderbird/102.2.1 Subject: Re: [PATCH] Bluetooth: use hdev->workqueue when queuing hdev->{cmd,ncmd}_timer works Content-Language: en-US To: Schspa Shi Cc: Luiz Augusto von Dentz , Marcel Holtmann , Johan Hedberg , syzbot , syzkaller-bugs@googlegroups.com, Lai Jiangshan , "linux-bluetooth@vger.kernel.org" , Tejun Heo References: <00000000000016512d05e76bd837@google.com> <733e6931-aa66-5295-d8a8-49063b7347f1@I-love.SAKURA.ne.jp> <289ba1a9-e4f7-d0b5-545e-a98dcf365c68@I-love.SAKURA.ne.jp> From: Tetsuo Handa In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-3.6 required=5.0 tests=BAYES_00,NICE_REPLY_A, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org On 2022/09/05 17:24, Schspa Shi wrote: > > Tejun Heo writes: > >> Hello, >> >> On Sat, Sep 03, 2022 at 07:11:18PM -0700, Luiz Augusto von Dentz wrote: >>> And we can check for __WQ_DRAINING? Anyway checking >> >> Please don't do that. That's an internal flag. It shouldn't be *that* >> difficult to avoid this without peeking into wq internal state. >> >> Thanks. > > It seems we only need to change hdev->{cmd,ncmd}_timer to > hdev->workqueue, there will be no race because drain_workqueue will > flush all pending work internally. True for queue_work(), not always true for queue_delayed_work(). Explained below. > Any new timeout work will see HCI_CMD_DRAIN_WORKQUEUE flags after we > cancel and flushed all the delayed work. > If you don't mind calling queue_work(&hdev->cmd_work) followed by hci_cmd_work() (case A below) and/or queue_delayed_work(&hdev->ncmd_timer) potentially followed by hci_ncmd_timeout()/hci_reset_dev() (case B and C below) after observing HCI_CMD_DRAIN_WORKQUEUE flag. We need to use RCU protection if you mind one of these. Case A: hci_dev_do_reset() { hci_cmd_work() { if (test_bit(HCI_RESET, &hdev->flags) || hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE)) cancel_delayed_work(&hdev->cmd_timer); else queue_delayed_work(hdev->workqueue, &hdev->cmd_timer, HCI_CMD_TIMEOUT); } else { skb_queue_head(&hdev->cmd_q, skb); hci_dev_set_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE); cancel_delayed_work(&hdev->cmd_timer); cancel_delayed_work(&hdev->ncmd_timer); queue_work(hdev->workqueue, &hdev->cmd_work); // Queuing after setting HCI_CMD_DRAIN_WORKQUEUE despite the intent of HCI_CMD_DRAIN_WORKQUEUE... drain_workqueue(hdev->workqueue); // Will wait for hci_cmd_timeout() queued by queue_work() to complete. } // Actual flush() happens here. hci_dev_clear_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE); } Case B: hci_dev_do_reset() { handle_cmd_cnt_and_timer(struct hci_dev *hdev, u8 ncmd) { if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE)) hci_dev_set_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE); cancel_delayed_work(&hdev->cmd_timer); queue_delayed_work(hdev->workqueue, &hdev->ncmd_timer, HCI_NCMD_TIMEOUT); cancel_delayed_work(&hdev->ncmd_timer); // May or may not cancel hci_ncmd_timeout() queued by queue_delayed_work(). drain_workqueue(hdev->workqueue); // Will wait for hci_ncmd_timeout() queued by queue_delayed_work() to complete if cancel_delayed_work() failed to cancel. } // Actual flush() happens here. hci_dev_clear_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE); } Case C: hci_dev_do_reset() { handle_cmd_cnt_and_timer(struct hci_dev *hdev, u8 ncmd) { if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE)) hci_dev_set_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE); cancel_delayed_work(&hdev->cmd_timer); cancel_delayed_work(&hdev->ncmd_timer); // Does nothing. queue_delayed_work(hdev->workqueue, &hdev->ncmd_timer, HCI_NCMD_TIMEOUT); drain_workqueue(hdev->workqueue); // Will wait for hci_ncmd_timeout() queued by queue_delayed_work() to complete if delay timer has expired. } // Actual flush() happens here, but hci_ncmd_timeout() queued by queue_delayed_work() can be running if delay timer has not expired as of calling drain_workqueue(). hci_dev_clear_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE); }