The driver may sleep while holding a spinlock. The function call path (from bottom to top) in Linux 4.19 is: drivers/net/wireless/ath/ath9k/hif_usb.c, 108: usb_alloc_urb(GFP_KERNEL) in hif_usb_send_regout drivers/net/wireless/ath/ath9k/hif_usb.c, 470: hif_usb_send_regout in hif_usb_send drivers/net/wireless/ath/ath9k/htc_hst.c, 34: (FUNC_PTR)hif_usb_send in htc_issue_send drivers/net/wireless/ath/ath9k/htc_hst.c, 295: htc_issue_send in htc_send drivers/net/wireless/ath/ath9k/htc_drv_beacon.c, 250: htc_send in ath9k_htc_send_beacon drivers/net/wireless/ath/ath9k/htc_drv_beacon.c, 207: spin_lock_bh in ath9k_htc_send_beacon drivers/net/wireless/ath/ath9k/hif_usb.c, 112: kzalloc(GFP_KERNEL) in hif_usb_send_regout drivers/net/wireless/ath/ath9k/hif_usb.c, 470: hif_usb_send_regout in hif_usb_send drivers/net/wireless/ath/ath9k/htc_hst.c, 34: (FUNC_PTR)hif_usb_send in htc_issue_send drivers/net/wireless/ath/ath9k/htc_hst.c, 295: htc_issue_send in htc_send drivers/net/wireless/ath/ath9k/htc_drv_beacon.c, 250: htc_send in ath9k_htc_send_beacon drivers/net/wireless/ath/ath9k/htc_drv_beacon.c, 207: spin_lock_bh in ath9k_htc_send_beacon drivers/net/wireless/ath/ath9k/hif_usb.c, 127: usb_submit_urb(GFP_KERNEL) in hif_usb_send_regout drivers/net/wireless/ath/ath9k/hif_usb.c, 470: hif_usb_send_regout in hif_usb_send drivers/net/wireless/ath/ath9k/htc_hst.c, 34: (FUNC_PTR)hif_usb_send in htc_issue_send drivers/net/wireless/ath/ath9k/htc_hst.c, 295: htc_issue_send in htc_send drivers/net/wireless/ath/ath9k/htc_drv_beacon.c, 250: htc_send in ath9k_htc_send_beacon drivers/net/wireless/ath/ath9k/htc_drv_beacon.c, 207: spin_lock_bh in ath9k_htc_send_beacon (FUNC_PTR) means a function pointer is called. To fix these bugs, GFP_KERNEL is replaced with GFP_ATOMIC. These bugs are found by a static analysis tool STCheck written by myself. Signed-off-by: Jia-Ju Bai <baijiaju1990@xxxxxxxxx> --- drivers/net/wireless/ath/ath9k/hif_usb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index fb649d85b8fc..37231fde102d 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -105,11 +105,11 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev, struct cmd_buf *cmd; int ret = 0; - urb = usb_alloc_urb(0, GFP_KERNEL); + urb = usb_alloc_urb(0, GFP_ATOMIC); if (urb == NULL) return -ENOMEM; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC); if (cmd == NULL) { usb_free_urb(urb); return -ENOMEM; @@ -124,7 +124,7 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev, hif_usb_regout_cb, cmd, 1); usb_anchor_urb(urb, &hif_dev->regout_submitted); - ret = usb_submit_urb(urb, GFP_KERNEL); + ret = usb_submit_urb(urb, GFP_ATOMIC); if (ret) { usb_unanchor_urb(urb); kfree(cmd); -- 2.17.1