linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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
>


  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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).