Received: by 2002:a05:6358:51dd:b0:131:369:b2a3 with SMTP id 29csp214055rwl; Wed, 9 Aug 2023 13:25:11 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHazyYP4S3pUykJTWZSU09/VFJ2acDLX7qkFt+cIIvvzBxPutxh5UR4Z3v16JeCnlg90euf X-Received: by 2002:a9d:6a83:0:b0:6bd:af4:274d with SMTP id l3-20020a9d6a83000000b006bd0af4274dmr165495otq.8.1691612710969; Wed, 09 Aug 2023 13:25:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691612710; cv=none; d=google.com; s=arc-20160816; b=gntEnxLuJI2pc3roBInxy70k1d17ogcrDAOriUlnkyTagFUmgZEjQUVODfUJDbJPZi 1agEETAqCQkoMb5uHGzQ4DQ7h6lKJO1rmqkzXji/TRFc7BTGLYyRd7JiSHCMpkcUE+ZE y72wbEXOPGDTmcWnoARlXNK9vWNd4LizWLmlU2ASWbSfrSp5CDGuC4s0TCOoyOi23fIL YDV2vwOPlTQYQDtVD+hjddqAxT81PFhhG/0hQW3y3QKfg5DrIWiZbQyulvYZRP2RaFt9 5b8Nr9FI38cyx+39WiTqrtaGP/B+vjLxjepKlaJCt6eSh0ZYEr6Q1t8cWBmLDdp7/Naj uZyw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:content-transfer-encoding :references:in-reply-to:date:cc:to:from:subject:message-id; bh=KCIUCuTR2JfgHq+HOnu8ezlnWCGkiei3QHrUHnX3sw4=; fh=Ny21H2BzzfdO1ejjvbyZq4/RBRQjXE7ntloLSg2XeFM=; b=0t0y5sIQe5fl31L8+Z4In8Q5uXjdBs7WUYj3afkkfXxfnYCczdTuedwePgjhY0vvNw qAPPLDXNG/7NcSgpQen2nH1MxGZ0xvpFeGXfV3CuE2EBpruv1WJ4tdBPUzOICCRCJvN4 gVdukfOcdVR08ULKXrbqX71Ey3/P9EIK3r+LN8EcvSpRCh6Ff/nFhxta4+bwzwCTBF3y jaP88odWWYg9X+bXFMDbnJKRRU4vTl18a02N6ZA215AFk+qfYwtTqlkY/kGvu37dOc8r yyH+Iw7h/AOMvsjfUeOSqijc95eHBOtyE6A+wW5M9p9la9cUfD1oWg76iRKB/HUwB5Yv YV0A== 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 h184-20020a6383c1000000b00563522a7b7asi16604pge.14.2023.08.09.13.24.56; Wed, 09 Aug 2023 13:25:10 -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 S230190AbjHIUFj convert rfc822-to-8bit (ORCPT + 99 others); Wed, 9 Aug 2023 16:05:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42826 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231491AbjHIUFi (ORCPT ); Wed, 9 Aug 2023 16:05:38 -0400 Received: from mout02.posteo.de (mout02.posteo.de [185.67.36.142]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 93A28210B for ; Wed, 9 Aug 2023 13:05:30 -0700 (PDT) Received: from submission (posteo.de [185.67.36.169]) by mout02.posteo.de (Postfix) with ESMTPS id 553B5240101 for ; Wed, 9 Aug 2023 22:05:28 +0200 (CEST) Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4RLgyv5ST5z9rxN; Wed, 9 Aug 2023 22:05:27 +0200 (CEST) Message-ID: <9caafe989acc5b6b63424ac45e0a92c1dc0e5569.camel@iki.fi> Subject: Re: [PATCH BlueZ] adapter: wait for kernel exp features in adapter initialization From: Pauli Virtanen To: Luiz Augusto von Dentz Cc: linux-bluetooth@vger.kernel.org Date: Wed, 09 Aug 2023 20:05:27 +0000 In-Reply-To: References: <429cbc5a4fcdb150c62cf368c928e1174016eefb.1691606987.git.pav@iki.fi> Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8BIT MIME-Version: 1.0 X-Spam-Status: No, score=-1.1 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_NEUTRAL autolearn=no 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 Hi Luiz, ke, 2023-08-09 kello 12:52 -0700, Luiz Augusto von Dentz kirjoitti: > Hi Pauli, > > On Wed, Aug 9, 2023 at 12:14 PM Pauli Virtanen wrote: > > > > Things like BAP depend on ISO sockets being enabled in kernel. It is > > possible the MGMT commands enabling experimental kernel features do not > > complete, before BAP etc. initialization and probing starts, in which > > case BAP will be mostly nonfunctional. > > > > This was observed to occur always when running BlueZ in a Fedora VM, > > requiring bluetoothd restart after every boot for BAP to work, > > log containing lines in the order: > > > > bluetoothd[981]: src/adapter.c:read_exp_features_complete() 6fbaf188-05e0-496a-9885-d6ddfdb4e03e flags 0 action 1 > > bluetoothd[981]: src/adapter.c:read_info_complete() index 0 status 0x00 > > bluetoothd[981]: profiles/audio/bap.c:bap_probe() BAP requires ISO Socket which is not enabled > > bluetoothd[981]: src/adapter.c:iso_socket_complete() ISO Socket successfully set > > > > Fix by waiting in adapter initialization that all MGMT exp feature > > requests are done, before proceeding to read adapter information. > > > > Also fix canceling MGMT_OP_SET_EXP_FEATURE for ISO sockets. > > --- > > src/adapter.c | 90 ++++++++++++++++++++++++++++++++++++++++----------- > > 1 file changed, 71 insertions(+), 19 deletions(-) > > > > diff --git a/src/adapter.c b/src/adapter.c > > index 004062e7c..608c06f9e 100644 > > --- a/src/adapter.c > > +++ b/src/adapter.c > > @@ -331,6 +331,8 @@ struct btd_adapter { > > > > bool is_default; /* true if adapter is default one */ > > > > + unsigned int set_exp_iso_id; > > + unsigned int exp_pending; > > Lets use a struct queue to store these ids, since there could be more > than one pending and there could be more of these races with other > drivers. Ack, I can do that maybe it is simpler. Note though the current version does wait for all mgmt calls, and cleanup should also be right. set_exp_iso_id is special since that's on MGMT_INDEX_NONE so the mgmt_cancel_index cleanup in adapter_free won't cancel it. > > > struct queue *exps; > > }; > > > > @@ -5782,6 +5784,8 @@ static void adapter_free(gpointer user_data) > > g_queue_free(adapter->auths); > > queue_destroy(adapter->exps, NULL); > > > > + adapter->exp_pending = 0; > > + > > /* > > * Unregister all handlers for this specific index since > > * the adapter bound to them is no longer valid. > > @@ -5796,6 +5800,8 @@ static void adapter_free(gpointer user_data) > > * since the adapter bound to them is no longer valid. > > */ > > mgmt_cancel_index(adapter->mgmt, adapter->dev_id); > > + if (adapter->set_exp_iso_id) > > + mgmt_cancel(adapter->mgmt, adapter->set_exp_iso_id); > > > > mgmt_unref(adapter->mgmt); > > > > @@ -6895,6 +6901,8 @@ static void adapter_remove(struct btd_adapter *adapter) > > > > g_slist_free(adapter->msd_callbacks); > > adapter->msd_callbacks = NULL; > > + > > + adapter->exp_pending = 0; > > } > > > > const char *adapter_get_path(struct btd_adapter *adapter) > > @@ -9824,6 +9832,8 @@ static bool set_blocked_keys(struct btd_adapter *adapter) > > .func = _func, \ > > } > > > > +static void exp_complete(void *user_data); > > + > > static void set_exp_debug_complete(uint8_t status, uint16_t len, > > const void *param, void *user_data) > > { > > @@ -9854,8 +9864,10 @@ static void exp_debug_func(struct btd_adapter *adapter, uint8_t action) > > > > if (mgmt_send(adapter->mgmt, MGMT_OP_SET_EXP_FEATURE, > > adapter->dev_id, sizeof(cp), &cp, > > - set_exp_debug_complete, adapter, NULL) > 0) > > + set_exp_debug_complete, adapter, exp_complete) > 0) { > > + ++adapter->exp_pending; > > return; > > + } > > > > btd_error(adapter->dev_id, "Failed to set exp debug"); > > } > > @@ -9904,8 +9916,11 @@ static void rpa_resolution_func(struct btd_adapter *adapter, uint8_t action) > > > > if (mgmt_send(adapter->mgmt, MGMT_OP_SET_EXP_FEATURE, > > adapter->dev_id, sizeof(cp), &cp, > > - set_rpa_resolution_complete, adapter, NULL) > 0) > > + set_rpa_resolution_complete, adapter, > > + exp_complete) > 0) { > > + ++adapter->exp_pending; > > return; > > + } > > > > btd_error(adapter->dev_id, "Failed to set RPA Resolution"); > > } > > @@ -9940,12 +9955,22 @@ static void codec_offload_func(struct btd_adapter *adapter, uint8_t action) > > > > if (mgmt_send(adapter->mgmt, MGMT_OP_SET_EXP_FEATURE, > > adapter->dev_id, sizeof(cp), &cp, > > - codec_offload_complete, adapter, NULL) > 0) > > + codec_offload_complete, adapter, exp_complete) > 0) { > > + ++adapter->exp_pending; > > return; > > + } > > > > btd_error(adapter->dev_id, "Failed to set Codec Offload"); > > } > > > > +static void iso_socket_done(void *user_data) > > +{ > > + struct btd_adapter *adapter = user_data; > > + > > + adapter->set_exp_iso_id = 0; > > + exp_complete(adapter); > > +} > > + > > static void iso_socket_complete(uint8_t status, uint16_t len, > > const void *param, void *user_data) > > { > > @@ -9969,15 +9994,20 @@ static void iso_socket_complete(uint8_t status, uint16_t len, > > static void iso_socket_func(struct btd_adapter *adapter, uint8_t action) > > { > > struct mgmt_cp_set_exp_feature cp; > > + unsigned int id; > > > > memset(&cp, 0, sizeof(cp)); > > memcpy(cp.uuid, iso_socket_uuid.val, 16); > > cp.action = action; > > > > - if (mgmt_send(adapter->mgmt, MGMT_OP_SET_EXP_FEATURE, > > - MGMT_INDEX_NONE, sizeof(cp), &cp, > > - iso_socket_complete, adapter, NULL) > 0) > > + id = mgmt_send(adapter->mgmt, MGMT_OP_SET_EXP_FEATURE, MGMT_INDEX_NONE, > > + sizeof(cp), &cp, iso_socket_complete, adapter, > > + iso_socket_done); > > + if (id > 0) { > > + adapter->set_exp_iso_id = id; > > + ++adapter->exp_pending; > > return; > > + } > > > > btd_error(adapter->dev_id, "Failed to set ISO Socket"); > > } > > @@ -10063,8 +10093,10 @@ static void read_exp_features(struct btd_adapter *adapter) > > { > > if (mgmt_send(adapter->mgmt, MGMT_OP_READ_EXP_FEATURES_INFO, > > adapter->dev_id, 0, NULL, read_exp_features_complete, > > - adapter, NULL) > 0) > > + adapter, exp_complete) > 0) { > > + ++adapter->exp_pending; > > return; > > + } > > > > btd_error(adapter->dev_id, "Failed to read exp features info"); > > } > > @@ -10389,6 +10421,36 @@ static void reset_adv_monitors(uint16_t index) > > error("Failed to reset Adv Monitors"); > > } > > > > +static void read_info(struct btd_adapter *adapter) > > +{ > > + DBG("sending read info command for index %u", adapter->dev_id); > > + > > + if (mgmt_send(mgmt_primary, MGMT_OP_READ_INFO, adapter->dev_id, 0, NULL, > > + read_info_complete, adapter, NULL) > 0) > > + return; > > + > > + btd_error(adapter->dev_id, > > + "Failed to read controller info for index %u", > > + adapter->dev_id); > > + > > + adapter_list = g_list_remove(adapter_list, adapter); > > + > > + btd_adapter_unref(adapter); > > +} > > + > > +static void exp_complete(void *user_data) > > +{ > > + struct btd_adapter *adapter = user_data; > > + > > + adapter->exp_pending--; > > + > > + DBG("index %u has %u pending MGMT EXP requests", adapter->dev_id, > > + adapter->exp_pending); > > + > > + if (!adapter->exp_pending) > > + read_info(adapter); > > +} > > + > > static void index_added(uint16_t index, uint16_t length, const void *param, > > void *user_data) > > { > > @@ -10435,18 +10497,8 @@ static void index_added(uint16_t index, uint16_t length, const void *param, > > */ > > adapter_list = g_list_append(adapter_list, adapter); > > > > - DBG("sending read info command for index %u", index); > > - > > - if (mgmt_send(mgmt_primary, MGMT_OP_READ_INFO, index, 0, NULL, > > - read_info_complete, adapter, NULL) > 0) > > - return; > > - > > - btd_error(adapter->dev_id, > > - "Failed to read controller info for index %u", index); > > - > > - adapter_list = g_list_remove(adapter_list, adapter); > > - > > - btd_adapter_unref(adapter); > > + if (!adapter->exp_pending) > > + read_info(adapter); > > } > > > > static void index_removed(uint16_t index, uint16_t length, const void *param, > > -- > > 2.41.0 > > > >