Bluetooth: btintel_pcie: Avoid redundant buffer allocation
[ Upstream commit d1af1f02ef8653dea4573e444136c8331189cd59 ]
Reuse the skb buffer provided by the PCIe driver to pass it onto the
stack, instead of copying it to a new skb.
Fixes: c2b636b3f7 ("Bluetooth: btintel_pcie: Add support for PCIe transport")
Signed-off-by: Kiran K <kiran.k@intel.com>
Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
620810ac1f
commit
c7bd5c9ba1
@@ -581,8 +581,10 @@ static int btintel_pcie_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
/* This is a debug event that comes from IML and OP image when it
|
||||
* starts execution. There is no need pass this event to stack.
|
||||
*/
|
||||
if (skb->data[2] == 0x97)
|
||||
if (skb->data[2] == 0x97) {
|
||||
hci_recv_diag(hdev, skb);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return hci_recv_frame(hdev, skb);
|
||||
@@ -598,7 +600,6 @@ static int btintel_pcie_recv_frame(struct btintel_pcie_data *data,
|
||||
u8 pkt_type;
|
||||
u16 plen;
|
||||
u32 pcie_pkt_type;
|
||||
struct sk_buff *new_skb;
|
||||
void *pdata;
|
||||
struct hci_dev *hdev = data->hdev;
|
||||
|
||||
@@ -675,24 +676,20 @@ static int btintel_pcie_recv_frame(struct btintel_pcie_data *data,
|
||||
|
||||
bt_dev_dbg(hdev, "pkt_type: 0x%2.2x len: %u", pkt_type, plen);
|
||||
|
||||
new_skb = bt_skb_alloc(plen, GFP_ATOMIC);
|
||||
if (!new_skb) {
|
||||
bt_dev_err(hdev, "Failed to allocate memory for skb of len: %u",
|
||||
skb->len);
|
||||
ret = -ENOMEM;
|
||||
goto exit_error;
|
||||
}
|
||||
|
||||
hci_skb_pkt_type(new_skb) = pkt_type;
|
||||
skb_put_data(new_skb, skb->data, plen);
|
||||
hci_skb_pkt_type(skb) = pkt_type;
|
||||
hdev->stat.byte_rx += plen;
|
||||
skb_trim(skb, plen);
|
||||
|
||||
if (pcie_pkt_type == BTINTEL_PCIE_HCI_EVT_PKT)
|
||||
ret = btintel_pcie_recv_event(hdev, new_skb);
|
||||
ret = btintel_pcie_recv_event(hdev, skb);
|
||||
else
|
||||
ret = hci_recv_frame(hdev, new_skb);
|
||||
ret = hci_recv_frame(hdev, skb);
|
||||
skb = NULL; /* skb is freed in the callee */
|
||||
|
||||
exit_error:
|
||||
if (skb)
|
||||
kfree_skb(skb);
|
||||
|
||||
if (ret)
|
||||
hdev->stat.err_rx++;
|
||||
|
||||
@@ -706,16 +703,10 @@ static void btintel_pcie_rx_work(struct work_struct *work)
|
||||
struct btintel_pcie_data *data = container_of(work,
|
||||
struct btintel_pcie_data, rx_work);
|
||||
struct sk_buff *skb;
|
||||
int err;
|
||||
struct hci_dev *hdev = data->hdev;
|
||||
|
||||
/* Process the sk_buf in queue and send to the HCI layer */
|
||||
while ((skb = skb_dequeue(&data->rx_skb_q))) {
|
||||
err = btintel_pcie_recv_frame(data, skb);
|
||||
if (err)
|
||||
bt_dev_err(hdev, "Failed to send received frame: %d",
|
||||
err);
|
||||
kfree_skb(skb);
|
||||
btintel_pcie_recv_frame(data, skb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user