Skip to content
This repository has been archived by the owner on Dec 14, 2022. It is now read-only.

Commit

Permalink
staging: r8712u: Fix leak of skb
Browse files Browse the repository at this point in the history
There are two types of messages queued for RX. The major type, which does
I/O on the device, was being handled properly. The skbs that communicated
with the firmware were being leaked.

While rewriting the code that sets up the skb, it was possible to remove
the private variable indicating that the old skb could be reused.

Signed-off-by: Larry Finger <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
lwfinger authored and gregkh committed Aug 21, 2016
1 parent 74a3b06 commit 78ece0b
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 18 deletions.
1 change: 0 additions & 1 deletion drivers/staging/rtl8712/recv_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ int r8712_os_recvbuf_resource_alloc(struct _adapter *padapter,
if (!precvbuf->purb)
res = _FAIL;
precvbuf->pskb = NULL;
precvbuf->reuse = false;
precvbuf->pallocated_buf = NULL;
precvbuf->pbuf = NULL;
precvbuf->pdata = NULL;
Expand Down
1 change: 0 additions & 1 deletion drivers/staging/rtl8712/rtl8712_recv.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ struct recv_buf {
struct _adapter *adapter;
struct urb *purb;
_pkt *pskb;
u8 reuse;
u8 irp_pending;
u32 transfer_len;
uint len;
Expand Down
24 changes: 8 additions & 16 deletions drivers/staging/rtl8712/usb_ops_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,26 +202,23 @@ static void r8712_usb_read_port_complete(struct urb *purb)
if (purb->status == 0) { /* SUCCESS */
if ((purb->actual_length > (MAX_RECVBUF_SZ)) ||
(purb->actual_length < RXDESC_SIZE)) {
precvbuf->reuse = true;
r8712_read_port(padapter, precvpriv->ff_hwaddr, 0,
(unsigned char *)precvbuf);
} else {
_pkt *pskb = precvbuf->pskb;

precvbuf->transfer_len = purb->actual_length;
pbuf = (uint *)precvbuf->pbuf;
isevt = le32_to_cpu(*(pbuf + 1)) & 0x1ff;
if ((isevt & 0x1ff) == 0x1ff) {
r8712_rxcmd_event_hdl(padapter, pbuf);
precvbuf->reuse = true;
skb_queue_tail(&precvpriv->rx_skb_queue, pskb);
r8712_read_port(padapter, precvpriv->ff_hwaddr,
0, (unsigned char *)precvbuf);
} else {
_pkt *pskb = precvbuf->pskb;

skb_put(pskb, purb->actual_length);
skb_queue_tail(&precvpriv->rx_skb_queue, pskb);
tasklet_hi_schedule(&precvpriv->recv_tasklet);
precvbuf->pskb = NULL;
precvbuf->reuse = false;
r8712_read_port(padapter, precvpriv->ff_hwaddr,
0, (unsigned char *)precvbuf);
}
Expand All @@ -241,7 +238,6 @@ static void r8712_usb_read_port_complete(struct urb *purb)
}
/* Fall through. */
case -EPROTO:
precvbuf->reuse = true;
r8712_read_port(padapter, precvpriv->ff_hwaddr, 0,
(unsigned char *)precvbuf);
break;
Expand Down Expand Up @@ -272,14 +268,11 @@ u32 r8712_usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem)
if (adapter->bDriverStopped || adapter->bSurpriseRemoved ||
adapter->pwrctrlpriv.pnp_bstop_trx || !precvbuf)
return _FAIL;
if (precvbuf->reuse || !precvbuf->pskb) {
precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue);
if (precvbuf->pskb != NULL)
precvbuf->reuse = true;
}
r8712_init_recvbuf(adapter, precvbuf);
/* re-assign for linux based on skb */
if (!precvbuf->reuse || !precvbuf->pskb) {
/* Try to use skb from the free queue */
precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue);

if (!precvbuf->pskb) {
precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev,
MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
if (!precvbuf->pskb)
Expand All @@ -293,13 +286,12 @@ u32 r8712_usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem)
precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
precvbuf->pend = skb_end_pointer(precvbuf->pskb);
precvbuf->pbuf = precvbuf->pskb->data;
} else { /* reuse skb */
} else { /* skb is reused */
precvbuf->phead = precvbuf->pskb->head;
precvbuf->pdata = precvbuf->pskb->data;
precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
precvbuf->pend = skb_end_pointer(precvbuf->pskb);
precvbuf->pbuf = precvbuf->pskb->data;
precvbuf->reuse = false;
}
purb = precvbuf->purb;
/* translate DMA FIFO addr to pipehandle */
Expand Down

0 comments on commit 78ece0b

Please sign in to comment.