From: Larry Finger <Larry.Finger@lwfinger.net>
To: jerome huang <jerome.syno@gmail.com>
Cc: "Xu, Andiry" <Andiry.Xu@amd.com>,
Sarah Sharp <sarah.a.sharp@linux.intel.com>,
linux-usb@vger.kernel.org, linux-wireless@vger.kernel.org
Subject: Re: rt8192cu on USB3
Date: Fri, 09 Mar 2012 09:04:18 -0600 [thread overview]
Message-ID: <4F5A1BF2.7080102@lwfinger.net> (raw)
In-Reply-To: <CAHaq0gK17axV0uo-EEj4s7=dgOs3vccJ4-icX9YFyBcYGn4u8g@mail.gmail.com>
On 03/09/2012 01:39 AM, jerome huang wrote:
>
> Are other patches recommend besides b0302a?
That is the main one. Others that you might consider, but they probably will not
make any difference:
3eda95d rtlwifi: Remove extra debugging message accidentally left in
4e3c3b8 rtlwifi: Fix breakage in debug functions when built as a module
This fixes a problem caused in commit 481b9606.
ebecdcc rtlwifi: rtl8192c: Prevent sleeping from invalid context in rtl8192cu
The patch below is currently under test. It is not likely to make any difference
with your problem, but it changes USB reads a lot.
Larry
========================================================================
The current version of rtlwifi for USB operations uses kmalloc to
acquire a 32-bit buffer for reading. When _usb_read_sync() is called
with the rcu_lock held, the result is a "sleeping function called
from invalid context" BUG. This is reported for two cases in
https://bugzilla.kernel.org/show_bug.cgi?id=42775. The first case
where the lock originates from within rtlwifi and could be fixed
by rearranging the locking; however, the second originates from
within mac80211. The kmalloc() call is removed from _usb_read_sync()
by creating a ring buffer pointer in the private area and
allocating the buffer data in the probe routine.
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Stable <stable@vger.kernel.org> [This version good for 3.3+ - different
patch for 3.2 - 2.6.39]
---
Index: wireless-testing-new/drivers/net/wireless/rtlwifi/usb.c
===================================================================
--- wireless-testing-new.orig/drivers/net/wireless/rtlwifi/usb.c
+++ wireless-testing-new/drivers/net/wireless/rtlwifi/usb.c
@@ -124,46 +124,38 @@ static int _usbctrl_vendorreq_sync_read(
return status;
}
-static u32 _usb_read_sync(struct usb_device *udev, u32 addr, u16 len)
+static u32 _usb_read_sync(struct rtl_priv *rtlpriv, u32 addr, u16 len)
{
+ struct device *dev = rtlpriv->io.dev;
+ struct usb_device *udev = to_usb_device(dev);
u8 request;
u16 wvalue;
u16 index;
- u32 *data;
- u32 ret;
+ __le32 *data = &rtlpriv->usb_data[rtlpriv->usb_data_index];
- data = kmalloc(sizeof(u32), GFP_KERNEL);
- if (!data)
- return -ENOMEM;
request = REALTEK_USB_VENQT_CMD_REQ;
index = REALTEK_USB_VENQT_CMD_IDX; /* n/a */
wvalue = (u16)addr;
_usbctrl_vendorreq_sync_read(udev, request, wvalue, index, data, len);
- ret = le32_to_cpu(*data);
- kfree(data);
- return ret;
+ if (++rtlpriv->usb_data_index >= RTL_USB_MAX_RX_COUNT)
+ rtlpriv->usb_data_index = 0;
+ return le32_to_cpu(*data);
}
static u8 _usb_read8_sync(struct rtl_priv *rtlpriv, u32 addr)
{
- struct device *dev = rtlpriv->io.dev;
-
- return (u8)_usb_read_sync(to_usb_device(dev), addr, 1);
+ return (u8)_usb_read_sync(rtlpriv, addr, 1);
}
static u16 _usb_read16_sync(struct rtl_priv *rtlpriv, u32 addr)
{
- struct device *dev = rtlpriv->io.dev;
-
- return (u16)_usb_read_sync(to_usb_device(dev), addr, 2);
+ return (u16)_usb_read_sync(rtlpriv, addr, 2);
}
static u32 _usb_read32_sync(struct rtl_priv *rtlpriv, u32 addr)
{
- struct device *dev = rtlpriv->io.dev;
-
- return _usb_read_sync(to_usb_device(dev), addr, 4);
+ return _usb_read_sync(rtlpriv, addr, 4);
}
static void _usb_write_async(struct usb_device *udev, u32 addr, u32 val,
@@ -951,6 +943,13 @@ int __devinit rtl_usb_probe(struct usb_i
return -ENOMEM;
}
rtlpriv = hw->priv;
+ rtlpriv->usb_data = kzalloc(RTL_USB_MAX_RX_COUNT * sizeof(u32),
+ GFP_KERNEL);
+ if (!rtlpriv->usb_data) {
+ RT_ASSERT(false, "USB data buffer allocation failed\n");
+ return -ENOMEM;
+ }
+ rtlpriv->usb_data_index = 0;
init_completion(&rtlpriv->firmware_loading_complete);
SET_IEEE80211_DEV(hw, &intf->dev);
udev = interface_to_usbdev(intf);
@@ -1019,6 +1018,7 @@ void rtl_usb_disconnect(struct usb_inter
/* rtl_deinit_rfkill(hw); */
rtl_usb_deinit(hw);
rtl_deinit_core(hw);
+ kfree(rtlpriv->usb_data);
rtlpriv->cfg->ops->deinit_sw_leds(hw);
rtlpriv->cfg->ops->deinit_sw_vars(hw);
_rtl_usb_io_handler_release(hw);
Index: wireless-testing-new/drivers/net/wireless/rtlwifi/wifi.h
===================================================================
--- wireless-testing-new.orig/drivers/net/wireless/rtlwifi/wifi.h
+++ wireless-testing-new/drivers/net/wireless/rtlwifi/wifi.h
@@ -67,7 +67,7 @@
#define QOS_QUEUE_NUM 4
#define RTL_MAC80211_NUM_QUEUE 5
#define REALTEK_USB_VENQT_MAX_BUF_SIZE 254
-
+#define RTL_USB_MAX_RX_COUNT 100
#define QBSS_LOAD_SIZE 5
#define MAX_WMMELE_LENGTH 64
@@ -1629,6 +1629,10 @@ struct rtl_priv {
interface or hardware */
unsigned long status;
+ /* data buffer pointer for USB reads */
+ __le32 *usb_data;
+ int usb_data_index;
+
/*This must be the last item so
that it points to the data allocated
beyond this structure like:
next prev parent reply other threads:[~2012-03-09 15:04 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-03-08 2:03 rt8192cu on USB3 jerome huang
2012-03-08 2:16 ` jerome huang
2012-03-08 2:35 ` Larry Finger
2012-03-08 6:35 ` jerome huang
2012-03-08 7:06 ` Andiry Xu
2012-03-08 7:11 ` Andiry Xu
[not found] ` <2A76B9D36150BE4293842BC2FE8FF165016A31@SCYBEXDAG04.amd.com>
2012-03-08 10:32 ` jerome huang
2012-03-08 11:26 ` jerome huang
2012-03-08 17:56 ` Larry Finger
2012-03-09 3:28 ` jerome huang
2012-03-09 3:59 ` Larry Finger
2012-03-09 7:39 ` jerome huang
2012-03-09 15:04 ` Larry Finger [this message]
2012-03-09 16:02 ` jerome huang
2012-03-22 22:31 ` Sarah Sharp
2012-03-23 2:24 ` Larry Finger
2012-03-23 20:34 ` Sarah Sharp
2012-03-24 2:16 ` Richard Farina
2012-03-24 4:59 ` Larry Finger
2012-04-05 22:49 ` Sarah Sharp
2012-03-24 4:55 ` Larry Finger
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=4F5A1BF2.7080102@lwfinger.net \
--to=larry.finger@lwfinger.net \
--cc=Andiry.Xu@amd.com \
--cc=jerome.syno@gmail.com \
--cc=linux-usb@vger.kernel.org \
--cc=linux-wireless@vger.kernel.org \
--cc=sarah.a.sharp@linux.intel.com \
/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.