From: Larry Finger <Larry.Finger@lwfinger.net>
To: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
Cc: linux-wireless@vger.kernel.org, stable@vger.kernel.org
Subject: Re: [PATCH] rtlwifi: usb: allocate URB control message setup_packet and data buffer separately
Date: Sat, 16 Feb 2013 17:48:08 -0600 [thread overview]
Message-ID: <51201AB8.4060700@lwfinger.net> (raw)
In-Reply-To: <20130216230016.15041.99979.stgit@localhost6.localdomain6>
On 02/16/2013 05:00 PM, Jussi Kivilinna wrote:
> rtlwifi allocates both setup_packet and data buffer of control message urb,
> using shared kmalloc in _usbctrl_vendorreq_async_write. Structure used for
> allocating is:
> struct {
> u8 data[254];
> struct usb_ctrlrequest dr;
> };
>
> Because 'struct usb_ctrlrequest' is __packed, setup packet is unaligned and
> DMA mapping of both 'data' and 'dr' confuses ARM/sunxi, leading to memory
> corruptions and freezes.
>
> Patch changes setup packet to be allocated separately.
>
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
The only change I would make is to convert the WARN_ON to WARN_ON_ONCE. In case
something goes wrong, there is no need to spam the logs.
I am not crazy about the overhead in allocating two different blocks for each
output packet, but if it is necessary, then it has to happen.
Larry
> ---
> drivers/net/wireless/rtlwifi/usb.c | 44 +++++++++++++++++++++++-------------
> 1 file changed, 28 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
> index 476eaef..d98fcdb 100644
> --- a/drivers/net/wireless/rtlwifi/usb.c
> +++ b/drivers/net/wireless/rtlwifi/usb.c
> @@ -42,8 +42,12 @@
>
> static void usbctrl_async_callback(struct urb *urb)
> {
> - if (urb)
> - kfree(urb->context);
> + if (urb) {
> + /* free dr */
> + kfree(urb->setup_packet);
> + /* free databuf */
> + kfree(urb->transfer_buffer);
> + }
> }
>
> static int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request,
> @@ -55,39 +59,47 @@ static int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request,
> u8 reqtype;
> struct usb_ctrlrequest *dr;
> struct urb *urb;
> - struct rtl819x_async_write_data {
> - u8 data[REALTEK_USB_VENQT_MAX_BUF_SIZE];
> - struct usb_ctrlrequest dr;
> - } *buf;
> + const u16 databuf_maxlen = REALTEK_USB_VENQT_MAX_BUF_SIZE;
> + u8 *databuf;
> +
> + if (WARN_ON(len > databuf_maxlen))
> + len = databuf_maxlen;
>
> pipe = usb_sndctrlpipe(udev, 0); /* write_out */
> reqtype = REALTEK_USB_VENQT_WRITE;
>
> - buf = kmalloc(sizeof(*buf), GFP_ATOMIC);
> - if (!buf)
> + dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
> + if (!dr)
> return -ENOMEM;
>
> + databuf = kmalloc(databuf_maxlen, GFP_ATOMIC);
> + if (!databuf) {
> + kfree(dr);
> + return -ENOMEM;
> + }
> +
> urb = usb_alloc_urb(0, GFP_ATOMIC);
> if (!urb) {
> - kfree(buf);
> + kfree(databuf);
> + kfree(dr);
> return -ENOMEM;
> }
>
> - dr = &buf->dr;
> -
> dr->bRequestType = reqtype;
> dr->bRequest = request;
> dr->wValue = cpu_to_le16(value);
> dr->wIndex = cpu_to_le16(index);
> dr->wLength = cpu_to_le16(len);
> /* data are already in little-endian order */
> - memcpy(buf, pdata, len);
> + memcpy(databuf, pdata, len);
> usb_fill_control_urb(urb, udev, pipe,
> - (unsigned char *)dr, buf, len,
> - usbctrl_async_callback, buf);
> + (unsigned char *)dr, databuf, len,
> + usbctrl_async_callback, NULL);
> rc = usb_submit_urb(urb, GFP_ATOMIC);
> - if (rc < 0)
> - kfree(buf);
> + if (rc < 0) {
> + kfree(databuf);
> + kfree(dr);
> + }
> usb_free_urb(urb);
> return rc;
> }
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
next prev parent reply other threads:[~2013-02-16 23:48 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-02-16 23:00 [PATCH] rtlwifi: usb: allocate URB control message setup_packet and data buffer separately Jussi Kivilinna
2013-02-16 23:48 ` Larry Finger [this message]
2013-02-17 1:51 ` Dave Kilroy
2013-02-17 8:38 ` Jussi Kivilinna
2013-02-17 8:39 ` Jussi Kivilinna
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=51201AB8.4060700@lwfinger.net \
--to=larry.finger@lwfinger.net \
--cc=jussi.kivilinna@mbnet.fi \
--cc=linux-wireless@vger.kernel.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.