Received: by 2002:a25:e7d8:0:0:0:0:0 with SMTP id e207csp1831919ybh; Sun, 8 Mar 2020 14:24:34 -0700 (PDT) X-Google-Smtp-Source: ADFU+vu4J25/WwNK/yBUXz0LKx1mPyY94iM8fqxdE4r0TwMhuG1uyAGq251gS+SRFSdf4Al55FE4 X-Received: by 2002:aca:d509:: with SMTP id m9mr9572123oig.136.1583702674805; Sun, 08 Mar 2020 14:24:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1583702674; cv=none; d=google.com; s=arc-20160816; b=INd2ebJbc2KZCz6rnUaL4TtW6KAttHC0QnuLkaOcwOpEmiOkBaTRgYjXXperYPivjo zk6V5nejfOt+PfrwN35OEkQrK4zUKuhTYZVpGI834D3HT041jJ5A8Oyh1W2KjkSuXQCH Jfpi15n4tRJLus8XJMG5UwHqBVnbMPqBnAPDqiqdZio3f2iXY+q4g1uok2zsfBK6whSJ q6tIHQTgay/x5/4pYfhMylRvm8yydoobAaLjtSzkb0YGHCEtzngqXf6jKJZ9fow6Zcpd erKY7uWJEf1uD8CdRj10XRdEYtGEVB+5TnpPKRzXyNI/7YvDlewJcSrTqYcbuYkIxnEM EJPw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=+7G2t1iwTc7yOX06jw4/PpAp5dth4rBBETxbRjNkqMg=; b=eyxVxyrkl6IsEE1yCl8/EvQ1OjA/jDaiqLAtaX3QEt7p0ylhyuVa8ZnIJ1rOGYhU4g rXjtClLyh2L1VZ7UH8lXsymlFBvMQ5qSJLGmBJ1rWczYy99p4zOLL3yiurueRhOUdekD lJdeHYw+jGqznthUNSU6RPZudgz2OP3SnHu59FRC/WJgCjxxuVY/VQfhHIRuGJ+9w413 D5aq49q7QpP6j5Y/1+x22bc35/GKGw3nHtvjM52v2/2XrjFM78wVODk1n1peddfcjmY2 UVhnPL81+ltX7cOg7qdj0D3C+Kl5AnwNZU5IEESfhk6VgQj9WTpcSGWyssVsZm1zBc+O VC7A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=X51+NiYv; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 18si3031326oiq.71.2020.03.08.14.24.23; Sun, 08 Mar 2020 14:24:34 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=X51+NiYv; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726556AbgCHVX5 (ORCPT + 99 others); Sun, 8 Mar 2020 17:23:57 -0400 Received: from mail-pl1-f196.google.com ([209.85.214.196]:36504 "EHLO mail-pl1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726446AbgCHVX4 (ORCPT ); Sun, 8 Mar 2020 17:23:56 -0400 Received: by mail-pl1-f196.google.com with SMTP id g12so3161360plo.3 for ; Sun, 08 Mar 2020 14:23:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=+7G2t1iwTc7yOX06jw4/PpAp5dth4rBBETxbRjNkqMg=; b=X51+NiYvbsp4/U/QESyGabg7w/apSTnOug19e0zpzxDNUekpxG8UvSJWzCXz5qhusm DNOi5c1oqifDBUomxTbmU8bh4gu+3JVlyOCm9hXkjLnPI2NkJo3OlQUVnNXSfOqXA+vh FNsYACbAx3ToZ3PXPIK5r2/OPIkMRdMG/sb74= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=+7G2t1iwTc7yOX06jw4/PpAp5dth4rBBETxbRjNkqMg=; b=rcAo4eJebuSDePOyKxFtxyZpidtXtOkg7tZbmXFsyQXoTpHi1itoattpjEQwcNokYY mV5Gn91RBzXk04hdpkfdDqWs5IWENGO+dKj9lvPZ3u7aiRJafJ04sz2jY3JRaRUX6ql1 RlPUhtjmI0msKJ3p6GlqwiTLLSQebToWLfMGVIl8xpEg3Okf6IRgLaW7nxEqjsSvU42c kc4NxIq2u4oy0Q73y25ROiVb24b4QeKM6k59X9nq6IJELxEr9dIcfJiW085D3pbeIRpy QHzSOEqhWcdVpvKZZzgMDu9Y/8BCBvigLfCuN1DPARYjIYQFqcQ4pg6xIVQ2sldtO3gq Mn3Q== X-Gm-Message-State: ANhLgQ1asNzT9rLzteR4afVbktV54jUNQOj24kKTuuSDQ4xVYosoyg6E hOp9FeoSGBS88LO+8Lv/PcOWFQ== X-Received: by 2002:a17:90a:e7c1:: with SMTP id kb1mr13654873pjb.45.1583702635378; Sun, 08 Mar 2020 14:23:55 -0700 (PDT) Received: from apsdesk.mtv.corp.google.com ([2620:15c:202:1:e09a:8d06:a338:aafb]) by smtp.gmail.com with ESMTPSA id k1sm39509228pgt.70.2020.03.08.14.23.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Mar 2020 14:23:54 -0700 (PDT) From: Abhishek Pandit-Subedi To: marcel@holtmann.org, luiz.dentz@gmail.com, alainm@chromium.org Cc: linux-bluetooth@vger.kernel.org, chromeos-bluetooth-upstreaming@chromium.org, Abhishek Pandit-Subedi , "David S. Miller" , Johan Hedberg , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Jakub Kicinski Subject: [RFC PATCH v5 4/5] Bluetooth: Pause discovery and advertising during suspend Date: Sun, 8 Mar 2020 14:23:33 -0700 Message-Id: <20200308142005.RFC.v5.4.Iccdad520469ca3524a7e5966c5f88e5bca756e13@changeid> X-Mailer: git-send-email 2.25.1.481.gfbce0eb801-goog In-Reply-To: <20200308212334.213841-1-abhishekpandit@chromium.org> References: <20200308212334.213841-1-abhishekpandit@chromium.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org To prevent spurious wake ups, we disable any discovery or advertising when we enter suspend and restore it when we exit suspend. While paused, we disable any management requests to modify discovery or advertising. Signed-off-by: Abhishek Pandit-Subedi --- Changes in v5: * Changed BT_DBG to bt_dev_dbg Changes in v4: None Changes in v3: None Changes in v2: * Refactored pause discovery + advertising into its own patch include/net/bluetooth/hci_core.h | 11 ++++++++ net/bluetooth/hci_request.c | 43 ++++++++++++++++++++++++++++++++ net/bluetooth/mgmt.c | 41 ++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 2d58485d0335..d4e28773d378 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -91,6 +91,12 @@ struct discovery_state { #define SUSPEND_NOTIFIER_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */ enum suspend_tasks { + SUSPEND_PAUSE_DISCOVERY, + SUSPEND_UNPAUSE_DISCOVERY, + + SUSPEND_PAUSE_ADVERTISING, + SUSPEND_UNPAUSE_ADVERTISING, + SUSPEND_SCAN_DISABLE, SUSPEND_SCAN_ENABLE, SUSPEND_DISCONNECTING, @@ -410,6 +416,11 @@ struct hci_dev { struct discovery_state discovery; + int discovery_old_state; + bool discovery_paused; + int advertising_old_state; + bool advertising_paused; + struct notifier_block suspend_notifier; struct work_struct suspend_prepare; enum suspended_state suspend_state_next; diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index a234735c04f4..9995f3cc1e74 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c @@ -1039,6 +1039,28 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next) /* Mark device as suspended */ hdev->suspended = true; + /* Pause discovery if not already stopped */ + old_state = hdev->discovery.state; + if (old_state != DISCOVERY_STOPPED) { + set_bit(SUSPEND_PAUSE_DISCOVERY, hdev->suspend_tasks); + hci_discovery_set_state(hdev, DISCOVERY_STOPPING); + queue_work(hdev->req_workqueue, &hdev->discov_update); + } + + hdev->discovery_paused = true; + hdev->discovery_old_state = old_state; + + /* Stop advertising */ + old_state = hci_dev_test_flag(hdev, HCI_ADVERTISING); + if (old_state) { + set_bit(SUSPEND_PAUSE_ADVERTISING, hdev->suspend_tasks); + cancel_delayed_work(&hdev->discov_off); + queue_delayed_work(hdev->req_workqueue, + &hdev->discov_off, 0); + } + + hdev->advertising_paused = true; + hdev->advertising_old_state = old_state; /* Disable page scan */ page_scan = SCAN_DISABLED; hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, 1, &page_scan); @@ -1085,6 +1107,27 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next) hci_req_clear_event_filter(&req); /* Reset passive/background scanning to normal */ hci_req_config_le_suspend_scan(&req); + + /* Unpause advertising */ + hdev->advertising_paused = false; + if (hdev->advertising_old_state) { + set_bit(SUSPEND_UNPAUSE_ADVERTISING, + hdev->suspend_tasks); + hci_dev_set_flag(hdev, HCI_ADVERTISING); + queue_work(hdev->req_workqueue, + &hdev->discoverable_update); + hdev->advertising_old_state = 0; + } + + /* Unpause discovery */ + hdev->discovery_paused = false; + if (hdev->discovery_old_state != DISCOVERY_STOPPED && + hdev->discovery_old_state != DISCOVERY_STOPPING) { + set_bit(SUSPEND_UNPAUSE_DISCOVERY, hdev->suspend_tasks); + hci_discovery_set_state(hdev, DISCOVERY_STARTING); + queue_work(hdev->req_workqueue, &hdev->discov_update); + } + hci_req_run(&req, suspend_req_complete); } diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 4da48618b271..047aea280c84 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1390,6 +1390,12 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data, goto failed; } + if (hdev->advertising_paused) { + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, + MGMT_STATUS_BUSY); + goto failed; + } + if (!hdev_is_powered(hdev)) { bool changed = false; @@ -3929,6 +3935,13 @@ void mgmt_start_discovery_complete(struct hci_dev *hdev, u8 status) } hci_dev_unlock(hdev); + + /* Handle suspend notifier */ + if (test_and_clear_bit(SUSPEND_UNPAUSE_DISCOVERY, + hdev->suspend_tasks)) { + bt_dev_dbg(hdev, "Unpaused discovery"); + wake_up(&hdev->suspend_wait_q); + } } static bool discovery_type_is_valid(struct hci_dev *hdev, uint8_t type, @@ -3990,6 +4003,13 @@ static int start_discovery_internal(struct sock *sk, struct hci_dev *hdev, goto failed; } + /* Can't start discovery when it is paused */ + if (hdev->discovery_paused) { + err = mgmt_cmd_complete(sk, hdev->id, op, MGMT_STATUS_BUSY, + &cp->type, sizeof(cp->type)); + goto failed; + } + /* Clear the discovery filter first to free any previously * allocated memory for the UUID list. */ @@ -4157,6 +4177,12 @@ void mgmt_stop_discovery_complete(struct hci_dev *hdev, u8 status) } hci_dev_unlock(hdev); + + /* Handle suspend notifier */ + if (test_and_clear_bit(SUSPEND_PAUSE_DISCOVERY, hdev->suspend_tasks)) { + bt_dev_dbg(hdev, "Paused discovery"); + wake_up(&hdev->suspend_wait_q); + } } static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data, @@ -4388,6 +4414,17 @@ static void set_advertising_complete(struct hci_dev *hdev, u8 status, if (match.sk) sock_put(match.sk); + /* Handle suspend notifier */ + if (test_and_clear_bit(SUSPEND_PAUSE_ADVERTISING, + hdev->suspend_tasks)) { + bt_dev_dbg(hdev, "Paused advertising"); + wake_up(&hdev->suspend_wait_q); + } else if (test_and_clear_bit(SUSPEND_UNPAUSE_ADVERTISING, + hdev->suspend_tasks)) { + bt_dev_dbg(hdev, "Unpaused advertising"); + wake_up(&hdev->suspend_wait_q); + } + /* If "Set Advertising" was just disabled and instance advertising was * set up earlier, then re-enable multi-instance advertising. */ @@ -4439,6 +4476,10 @@ static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data, return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING, MGMT_STATUS_INVALID_PARAMS); + if (hdev->advertising_paused) + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING, + MGMT_STATUS_BUSY); + hci_dev_lock(hdev); val = !!cp->val; -- 2.25.1.481.gfbce0eb801-goog