All of lore.kernel.org
 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 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.