NFC: nci: fix sleep in atomic context bugs caused by nci_skb_alloc
[ Upstream commit23dd458135] There are sleep in atomic context bugs when the request to secure element of st-nci is timeout. The root cause is that nci_skb_alloc with GFP_KERNEL parameter is called in st_nci_se_wt_timeout which is a timer handler. The call paths that could trigger bugs are shown below: (interrupt context 1) st_nci_se_wt_timeout nci_hci_send_event nci_hci_send_data nci_skb_alloc(..., GFP_KERNEL) //may sleep (interrupt context 2) st_nci_se_wt_timeout nci_hci_send_event nci_hci_send_data nci_send_data nci_queue_tx_data_frags nci_skb_alloc(..., GFP_KERNEL) //may sleep This patch changes allocation mode of nci_skb_alloc from GFP_KERNEL to GFP_ATOMIC in order to prevent atomic context sleeping. The GFP_ATOMIC flag makes memory allocation operation could be used in atomic context. Fixes:ed06aeefda("nfc: st-nci: Rename st21nfcb to st-nci") Signed-off-by: Duoming Zhou <duoming@zju.edu.cn> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Link: https://lore.kernel.org/r/20220517012530.75714-1-duoming@zju.edu.cn Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
42d4287cc1
commit
b503d0228c
@@ -118,7 +118,7 @@ static int nci_queue_tx_data_frags(struct nci_dev *ndev,
|
|||||||
|
|
||||||
skb_frag = nci_skb_alloc(ndev,
|
skb_frag = nci_skb_alloc(ndev,
|
||||||
(NCI_DATA_HDR_SIZE + frag_len),
|
(NCI_DATA_HDR_SIZE + frag_len),
|
||||||
GFP_KERNEL);
|
GFP_ATOMIC);
|
||||||
if (skb_frag == NULL) {
|
if (skb_frag == NULL) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto free_exit;
|
goto free_exit;
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ static int nci_hci_send_data(struct nci_dev *ndev, u8 pipe,
|
|||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
skb = nci_skb_alloc(ndev, conn_info->max_pkt_payload_len +
|
skb = nci_skb_alloc(ndev, conn_info->max_pkt_payload_len +
|
||||||
NCI_DATA_HDR_SIZE, GFP_KERNEL);
|
NCI_DATA_HDR_SIZE, GFP_ATOMIC);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@@ -186,7 +186,7 @@ static int nci_hci_send_data(struct nci_dev *ndev, u8 pipe,
|
|||||||
if (i < data_len) {
|
if (i < data_len) {
|
||||||
skb = nci_skb_alloc(ndev,
|
skb = nci_skb_alloc(ndev,
|
||||||
conn_info->max_pkt_payload_len +
|
conn_info->max_pkt_payload_len +
|
||||||
NCI_DATA_HDR_SIZE, GFP_KERNEL);
|
NCI_DATA_HDR_SIZE, GFP_ATOMIC);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user