lkml.org 
[lkml]   [2022]   [May]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.17 101/158] NFC: nci: fix sleep in atomic context bugs caused by nci_skb_alloc
    Date
    From: Duoming Zhou <duoming@zju.edu.cn>

    [ Upstream commit 23dd4581350d4ffa23d58976ec46408f8f4c1e16 ]

    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: ed06aeefdac3 ("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>
    ---
    net/nfc/nci/data.c | 2 +-
    net/nfc/nci/hci.c | 4 ++--
    2 files changed, 3 insertions(+), 3 deletions(-)

    diff --git a/net/nfc/nci/data.c b/net/nfc/nci/data.c
    index 6055dc9a82aa..aa5e712adf07 100644
    --- a/net/nfc/nci/data.c
    +++ b/net/nfc/nci/data.c
    @@ -118,7 +118,7 @@ static int nci_queue_tx_data_frags(struct nci_dev *ndev,

    skb_frag = nci_skb_alloc(ndev,
    (NCI_DATA_HDR_SIZE + frag_len),
    - GFP_KERNEL);
    + GFP_ATOMIC);
    if (skb_frag == NULL) {
    rc = -ENOMEM;
    goto free_exit;
    diff --git a/net/nfc/nci/hci.c b/net/nfc/nci/hci.c
    index 19703a649b5a..78c4b6addf15 100644
    --- a/net/nfc/nci/hci.c
    +++ b/net/nfc/nci/hci.c
    @@ -153,7 +153,7 @@ static int nci_hci_send_data(struct nci_dev *ndev, u8 pipe,

    i = 0;
    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)
    return -ENOMEM;

    @@ -184,7 +184,7 @@ static int nci_hci_send_data(struct nci_dev *ndev, u8 pipe,
    if (i < data_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)
    return -ENOMEM;

    --
    2.35.1


    \
     
     \ /
      Last update: 2022-05-23 20:14    [W:4.324 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site