Check return from nxsem_wait_initialize()

Resolution of Issue 619 will require multiple steps, this part of the first step in that resolution:  Every call to nxsem_wait_uninterruptible() must handle the return value from nxsem_wait_uninterruptible properly.  This commit is only for those files under graphics/, mm/, net/, sched/, wireless/bluetooth.

Still to do:  Files under fs/, drivers/, and arch.  The last is 116 files and will take some effort.
This commit is contained in:
Gregory Nutt
2020-03-29 11:57:53 -06:00
committed by Abdelatif Guettouche
parent 0558aa0a78
commit 97339e47f1
17 changed files with 544 additions and 459 deletions
+66 -49
View File
@@ -12,29 +12,31 @@
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
@@ -147,9 +149,14 @@ static int conn_tx_kthread(int argc, FAR char *argv[])
{
/* Wait until the controller can accept ACL packets */
wlinfo("calling nxsem_wait\n");
wlinfo("calling nxsem_wait_uninterruptible()\n");
nxsem_wait_uninterruptible(&g_btdev.le_pkts_sem);
ret = nxsem_wait_uninterruptible(&g_btdev.le_pkts_sem);
if (ret < 0)
{
wlerr("nxsem_wait_uninterruptible() failed: %d\n", ret);
break;
}
/* Check for disconnection */
@@ -292,6 +299,7 @@ void bt_conn_receive(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf,
switch (flags)
{
case 0x02:
/* First packet */
hdr = (void *)buf->data;
@@ -316,6 +324,7 @@ void bt_conn_receive(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf,
break;
case 0x01:
/* Continuation */
if (!conn->rx_len)
@@ -560,40 +569,47 @@ void bt_conn_set_state(FAR struct bt_conn_s *conn,
int ret;
ret = bt_queue_open(BT_CONN_TX, O_RDWR | O_CREAT,
CONFIG_BLUETOOTH_TXCONN_NMSGS, &conn->tx_queue);
CONFIG_BLUETOOTH_TXCONN_NMSGS,
&conn->tx_queue);
DEBUGASSERT(ret >= 0 && g_btdev.tx_queue != 0);
UNUSED(ret);
/* Get exclusive access to the handoff structure. The count will be
* zero when we complete this.
/* Get exclusive access to the handoff structure. The count will
* be zero when we complete this.
*/
nxsem_wait_uninterruptible(&g_conn_handoff.sync_sem);
ret = nxsem_wait_uninterruptible(&g_conn_handoff.sync_sem);
if (ret >= 0)
{
/* Start the Tx connection kernel thread */
/* Start the Tx connection kernel thread */
g_conn_handoff.conn = bt_conn_addref(conn);
pid = kthread_create("BT Conn Tx",
CONFIG_BLUETOOTH_TXCONN_PRIORITY,
CONFIG_BLUETOOTH_TXCONN_STACKSIZE,
conn_tx_kthread, NULL);
DEBUGASSERT(pid > 0);
UNUSED(pid);
g_conn_handoff.conn = bt_conn_addref(conn);
pid = kthread_create("BT Conn Tx", CONFIG_BLUETOOTH_TXCONN_PRIORITY,
CONFIG_BLUETOOTH_TXCONN_STACKSIZE,
conn_tx_kthread, NULL);
DEBUGASSERT(pid > 0);
UNUSED(pid);
/* Take the semaphore again. This will force us to wait with
* the sem_count at -1. It will be zero again when we
* continue.
*/
/* Take the semaphore again. This will force us to wait with the
* sem_count at -1. It will be zero again when we continue.
*/
nxsem_wait_uninterruptible(&g_conn_handoff.sync_sem);
nxsem_post(&g_conn_handoff.sync_sem);
ret = nxsem_wait_uninterruptible(&g_conn_handoff.sync_sem);
nxsem_post(&g_conn_handoff.sync_sem);
}
}
break;
case BT_CONN_DISCONNECTED:
/* Send dummy buffer to wake up and stop the Tx thread for states where it
* was running.
/* Send dummy buffer to wake up and stop the Tx thread for states
* where it was running.
*/
if (old_state == BT_CONN_CONNECTED || old_state == BT_CONN_DISCONNECT)
if (old_state == BT_CONN_CONNECTED ||
old_state == BT_CONN_DISCONNECT)
{
bt_queue_send(conn->tx_queue, bt_buf_alloc(BT_DUMMY, NULL, 0),
BT_NORMAL_PRIO);
@@ -809,18 +825,18 @@ FAR const bt_addr_le_t *bt_conn_get_dst(FAR const struct bt_conn_s *conn)
* Name: bt_conn_security
*
* Description:
* This function enable security (encryption) for a connection. If device is
* already paired with sufficiently strong key encryption will be enabled. If
* link is already encrypted with sufficiently strong key this function does
* nothing.
* This function enable security (encryption) for a connection. If device
* is already paired with sufficiently strong key encryption will be
* enabled. If link is already encrypted with sufficiently strong key this
* function does nothing.
*
* If device is not paired pairing will be initiated. If device is paired and
* keys are too weak but input output capabilities allow for strong enough keys
* pairing will be initiated.
* If device is not paired pairing will be initiated. If device is paired
* and keys are too weak but input output capabilities allow for strong
* enough keys pairing will be initiated.
*
* This function may return error if required level of security is not possible
* to achieve due to local or remote device limitation (eg input output
* capabilities).
* This function may return error if required level of security is not
* possible to achieve due to local or remote device limitation (eg input
* output capabilities).
*
* Input Parameters:
* conn - Connection object.
@@ -1058,7 +1074,8 @@ int bt_conn_le_conn_update(FAR struct bt_conn_s *conn, uint16_t min,
return -ENOBUFS;
}
conn_update = bt_buf_extend(buf, sizeof(*conn_update));
conn_update = bt_buf_extend(buf,
sizeof(*conn_update));
memset(conn_update, 0, sizeof(*conn_update));
conn_update->handle = BT_HOST2LE16(conn->handle);
conn_update->conn_interval_min = BT_HOST2LE16(min);
+46 -31
View File
@@ -12,29 +12,31 @@
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
@@ -164,7 +166,8 @@ static void bt_enqueue_bufwork(FAR struct bt_bufferlist_s *list,
*
****************************************************************************/
static FAR struct bt_buf_s *bt_dequeue_bufwork(FAR struct bt_bufferlist_s *list)
static FAR struct bt_buf_s *
bt_dequeue_bufwork(FAR struct bt_bufferlist_s *list)
{
FAR struct bt_buf_s *buf;
irqstate_t flags;
@@ -248,7 +251,8 @@ static void hci_acl(FAR struct bt_buf_s *buf)
if (buf->len != len)
{
wlerr("ERROR: ACL data length mismatch (%u != %u)\n", buf->len, len);
wlerr("ERROR: ACL data length mismatch (%u != %u)\n",
buf->len, len);
bt_buf_release(buf);
return;
}
@@ -256,7 +260,8 @@ static void hci_acl(FAR struct bt_buf_s *buf)
conn = bt_conn_lookup_handle(buf->u.acl.handle);
if (!conn)
{
wlerr("ERROR: Unable to find conn for handle %u\n", buf->u.acl.handle);
wlerr("ERROR: Unable to find conn for handle %u\n",
buf->u.acl.handle);
bt_buf_release(buf);
return;
}
@@ -362,8 +367,8 @@ static void hci_cmd_complete(FAR struct bt_buf_s *buf)
bt_buf_consume(buf, sizeof(*evt));
/* All command return parameters have a 1-byte status in the beginning, so we
* can safely make this generalization.
/* All command return parameters have a 1-byte status in the beginning, so
* we can safely make this generalization.
*/
status = buf->data;
@@ -445,7 +450,8 @@ static void hci_num_completed_packets(FAR struct bt_buf_s *buf)
static void hci_encrypt_key_refresh_complete(FAR struct bt_buf_s *buf)
{
FAR struct bt_hci_evt_encrypt_key_refresh_complete_s *evt = (FAR void *)buf->data;
FAR struct bt_hci_evt_encrypt_key_refresh_complete_s *evt =
(FAR void *)buf->data;
FAR struct bt_conn_s *conn;
uint16_t handle;
@@ -512,8 +518,8 @@ static int bt_hci_start_scanning(uint8_t scan_type, uint8_t scan_filter)
memset(set_param, 0, sizeof(*set_param));
set_param->scan_type = scan_type;
/* for the rest parameters apply default values according to spec 4.2, vol2,
* part E, 7.8.10
/* for the rest parameters apply default values according to spec 4.2,
* vol2, part E, 7.8.10
*/
set_param->interval = BT_HOST2LE16(0x0010);
@@ -522,7 +528,8 @@ static int bt_hci_start_scanning(uint8_t scan_type, uint8_t scan_filter)
set_param->addr_type = 0x00;
bt_hci_cmd_send(BT_HCI_OP_LE_SET_SCAN_PARAMS, buf);
buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_SCAN_ENABLE, sizeof(*scan_enable));
buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_SCAN_ENABLE,
sizeof(*scan_enable));
if (buf == NULL)
{
wlerr("ERROR: Failed to create buffer\n");
@@ -628,7 +635,8 @@ static void hci_disconn_complete(FAR struct bt_buf_s *buf)
uint16_t handle = BT_LE162HOST(evt->handle);
FAR struct bt_conn_s *conn;
wlinfo("status %u handle %u reason %u\n", evt->status, handle, evt->reason);
wlinfo("status %u handle %u reason %u\n",
evt->status, handle, evt->reason);
if (evt->status)
{
@@ -700,8 +708,8 @@ static void le_conn_complete(FAR struct bt_buf_s *buf)
bt_conn_set_state(conn, BT_CONN_DISCONNECTED);
/* Drop the reference got by lookup call in CONNECT state. We are now in
* DISCONNECTED state since no successful LE link been made.
/* Drop the reference got by lookup call in CONNECT state. We are now
* in the DISCONNECTED state since no successful LE link been made.
*/
bt_conn_release(conn);
@@ -824,7 +832,8 @@ static void le_adv_report(FAR struct bt_buf_s *buf)
* according to spec 4.2, Vol 2, Part E, 7.7.65.2.
*/
info = bt_buf_consume(buf, sizeof(*info) + info->length + sizeof(rssi));
info = bt_buf_consume(buf,
sizeof(*info) + info->length + sizeof(rssi));
}
}
@@ -977,7 +986,12 @@ static int hci_tx_kthread(int argc, FAR char *argv[])
/* Wait until ncmd > 0 */
nxsem_wait_uninterruptible(&g_btdev.ncmd_sem);
ret = nxsem_wait_uninterruptible(&g_btdev.ncmd_sem);
if (ret < 0)
{
wlerr("nxsem_wait_uninterruptible() failed: %d\n", ret);
return EXIT_FAILURE;
}
/* Get next command - wait if necessary */
@@ -1525,7 +1539,8 @@ void bt_driver_unregister(FAR const struct bt_driver_s *btdev)
* Description:
* Called by the Bluetooth low-level driver when new data is received from
* the radio. This may be called from the low-level driver and is part of
* the driver interface prototyped in include/nuttx/wireless/bluetooth/bt_driver.h
* the driver interface prototyped in
* include/nuttx/wireless/bluetooth/bt_driver.h
*
* NOTE: This function will defer all real work to the low or to the high
* priority work queues. Therefore, this function may safely be called
+19 -11
View File
@@ -63,6 +63,7 @@
****************************************************************************/
/* These structures encapsulate all globals used by the IOCTL logic. */
/* Scan state variables */
struct btnet_scanstate_s
@@ -149,14 +150,15 @@ static struct btnet_scanstate_s g_scanstate;
*
****************************************************************************/
static void btnet_scan_callback(FAR const bt_addr_le_t *addr, int8_t rssi,
uint8_t adv_type, FAR const uint8_t *adv_data,
uint8_t len)
static void btnet_scan_callback(FAR const bt_addr_le_t *addr,
int8_t rssi, uint8_t adv_type,
FAR const uint8_t *adv_data, uint8_t len)
{
FAR struct bt_scanresponse_s *rsp;
uint8_t nexttail;
uint8_t head;
uint8_t tail;
int ret;
if (!g_scanstate.bs_scanning)
{
@@ -164,15 +166,20 @@ static void btnet_scan_callback(FAR const bt_addr_le_t *addr, int8_t rssi,
return;
}
if (len > CONFIG_BLUETOOTH_MAXSCANDATA)
{
wlerr("ERROR: Scan result is too big: %u\n", len);
return;
}
if (len > CONFIG_BLUETOOTH_MAXSCANDATA)
{
wlerr("ERROR: Scan result is too big: %u\n", len);
return;
}
/* Get exclusive access to the scan data */
nxsem_wait_uninterruptible(&g_scanstate.bs_exclsem);
ret = nxsem_wait_uninterruptible(&g_scanstate.bs_exclsem);
if (ret < 0)
{
wlerr("nxsem_wait_uninterruptible() failed: %d\n", ret);
return;
}
/* Add the scan data to the cache */
@@ -246,7 +253,7 @@ static int btnet_scan_result(FAR struct bt_scanresponse_s *result,
*/
if (scanning)
{
{
/* Get exclusive access to the scan data */
ret = nxsem_wait(&g_scanstate.bs_exclsem);
@@ -514,7 +521,8 @@ int btnet_ioctl(FAR struct net_driver_s *netdev, int cmd, unsigned long arg)
}
else
{
ret = bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
ret = bt_conn_disconnect(conn,
BT_HCI_ERR_REMOTE_USER_TERM_CONN);
if (ret == -ENOTCONN)
{
wlerr("Already disconnected\n");