From: Christian Lamparter <chunkeey@web.de>
To: Artur Skawina <art.08.09@gmail.com>
Cc: Johannes Berg <johannes@sipsolutions.net>,
Larry Finger <Larry.Finger@lwfinger.net>,
linux-wireless@vger.kernel.org
Subject: Re: wireless-testing, p54 and sinus 154 data no longer works
Date: Mon, 19 Jan 2009 23:38:09 +0100 [thread overview]
Message-ID: <200901192338.09646.chunkeey@web.de> (raw)
In-Reply-To: <4974F63F.4050302@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2254 bytes --]
On Monday 19 January 2009 22:53:03 Artur Skawina wrote:
> Christian Lamparter wrote:
> > On Monday 19 January 2009 19:15:09 Artur Skawina wrote:
> >> Christian Lamparter wrote:
> >>> On Monday 19 January 2009 00:27:02 Artur Skawina wrote:
> >>>> Artur Skawina wrote:
> >>>>> didn't trigger anything here, just the usual:
> >>>>>
> >>>>> BUG kmalloc-4096: Poison overwritten
> >>>> This is almost 100% reproducible; sometimes the machine freezes instead.
> >> Here's an interesting sequence:
> >>
> >> 1) a TX urb is submitted.
> >> 2) p54u_rx_cb() => p54_rx_frame_sent(), which does kfree_skb( the_skb_in_(1) ).
> >> 3) p54u_tx_cb() for (1) is called with the same, now freed, skb. kaboom.
> >>
> >> IOW the skb is freed before the usb completion runs.
> >
> > Well, the sequence should be:
> >
> > 1) p54_tx gets called
> > 1.1) one IRQ urb is submitted
> > 1.2) one BULK urb is submitted
> > 2) the firmware acks that it got the urbs
> > 2.1) p54u_tx_cb is called for the IRQ urb. which frees the small buffer
> > 2.2) p54u_tx_cb is called for the BULK urb. which only removes the net2280_tx_hdr from the skb.
> > [time passes]
> > 3) firmware is finished sending.
> > 3.1) p54u_rx_cb gets called
> > => p54_rx_frame_sent passed the feedback to mac80211
>
> That's what one would expect, and is probably why i couldn't see anything
> wrong in the code despite going over it several times. Until i got a crash
> which left no doubt as to what happened, and made me notice the "wrong"
> completion order, log attached [1].
> In theory, theory and practice do not differ, in practice...
>
> >> Somehow i don't think this is the reason for the corruption, but it certainly
> >> seems to be responsible for some, if not all, of the crashes/panics.
> > dunno... we should see a bit more fallout, because skb_pull changes skb->data and skb->len.
>
> Doing an skb_pull in p54u_tx_cb on skbs that have already been given to mac80211
> cannot be good.
> We can move the FREE_AFTER_TX(skb) check from the completion to the submission
> path, right? Then find a way to do the pull _before_ giving away the skbs.
> I can't shutdown the machine where i can reproduce this today, so it will have
> to wait until at least tomorrow.
>
> artur
Like this?
[-- Attachment #2: p54-diff --]
[-- Type: text/x-diff, Size: 3664 bytes --]
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index 3bfee58..364ef39 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -144,11 +144,8 @@ static void p54u_tx_cb(struct urb *urb)
struct sk_buff *skb = urb->context;
struct ieee80211_hw *dev = (struct ieee80211_hw *)
usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
- struct p54u_priv *priv = dev->priv;
- skb_pull(skb, priv->common.tx_hdr_len);
- if (FREE_AFTER_TX(skb))
- p54_free_skb(dev, skb);
+ p54_free_skb(dev, skb);
}
static void p54u_tx_dummy_cb(struct urb *urb) { }
@@ -230,7 +227,8 @@ static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb)
p54u_tx_dummy_cb, dev);
usb_fill_bulk_urb(data_urb, priv->udev,
usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
- skb->data, skb->len, p54u_tx_cb, skb);
+ skb->data, skb->len, FREE_AFTER_TX(skb) ?
+ p54u_tx_cb : p54u_tx_dummy_cb, skb);
usb_anchor_urb(addr_urb, &priv->submitted);
err = usb_submit_urb(addr_urb, GFP_ATOMIC);
@@ -269,28 +267,24 @@ static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb)
{
struct p54u_priv *priv = dev->priv;
struct urb *data_urb;
- struct lm87_tx_hdr *hdr;
- __le32 checksum;
- __le32 addr = ((struct p54_hdr *)skb->data)->req_id;
+ struct lm87_tx_hdr *hdr = (void *)skb->data - sizeof(*hdr);
data_urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!data_urb)
return;
- checksum = p54u_lm87_chksum((__le32 *)skb->data, skb->len);
- hdr = (struct lm87_tx_hdr *)skb_push(skb, sizeof(*hdr));
- hdr->chksum = checksum;
- hdr->device_addr = addr;
+ hdr->chksum = p54u_lm87_chksum((__le32 *)skb->data, skb->len);
+ hdr->device_addr = ((struct p54_hdr *)skb->data)->req_id;
usb_fill_bulk_urb(data_urb, priv->udev,
usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
- skb->data, skb->len, p54u_tx_cb, skb);
+ hdr, skb->len + sizeof(*hdr), FREE_AFTER_TX(skb) ?
+ p54u_tx_cb : p54u_tx_dummy_cb, skb);
data_urb->transfer_flags |= URB_ZERO_PACKET;
usb_anchor_urb(data_urb, &priv->submitted);
if (usb_submit_urb(data_urb, GFP_ATOMIC)) {
usb_unanchor_urb(data_urb);
- skb_pull(skb, sizeof(*hdr));
p54_free_skb(dev, skb);
}
usb_free_urb(data_urb);
@@ -300,11 +294,9 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb)
{
struct p54u_priv *priv = dev->priv;
struct urb *int_urb, *data_urb;
- struct net2280_tx_hdr *hdr;
+ struct net2280_tx_hdr *hdr = (void *)skb->data - sizeof(*hdr);
struct net2280_reg_write *reg;
int err = 0;
- __le32 addr = ((struct p54_hdr *) skb->data)->req_id;
- __le16 len = cpu_to_le16(skb->len);
reg = kmalloc(sizeof(*reg), GFP_ATOMIC);
if (!reg)
@@ -327,10 +319,9 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb)
reg->addr = cpu_to_le32(P54U_DEV_BASE);
reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
- hdr = (void *)skb_push(skb, sizeof(*hdr));
memset(hdr, 0, sizeof(*hdr));
- hdr->len = len;
- hdr->device_addr = addr;
+ hdr->len = cpu_to_le16(skb->len);
+ hdr->device_addr = ((struct p54_hdr *) skb->data)->req_id;
usb_fill_bulk_urb(int_urb, priv->udev,
usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg),
@@ -345,7 +336,8 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb)
usb_fill_bulk_urb(data_urb, priv->udev,
usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
- skb->data, skb->len, p54u_tx_cb, skb);
+ hdr, skb->len + sizeof(*hdr), FREE_AFTER_TX(skb) ?
+ p54u_tx_cb : p54u_tx_dummy_cb, skb);
usb_anchor_urb(int_urb, &priv->submitted);
err = usb_submit_urb(int_urb, GFP_ATOMIC);
next prev parent reply other threads:[~2009-01-19 22:38 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-12-15 17:49 wireless-testing, p54 and sinus 154 data no longer works Artur Skawina
2008-12-15 18:41 ` Larry Finger
2008-12-15 19:43 ` Christian Lamparter
2008-12-15 20:20 ` Artur Skawina
2008-12-15 23:03 ` Artur Skawina
2008-12-15 23:24 ` Christian Lamparter
[not found] ` <49477A2A.7030406@gmail.com>
[not found] ` <200812161415.09365.chunkeey@web.de>
2008-12-16 13:49 ` Artur Skawina
2008-12-16 14:10 ` Christian Lamparter
2009-01-12 17:09 ` Artur Skawina
2009-01-13 13:49 ` Christian Lamparter
2009-01-13 16:45 ` Artur Skawina
2009-01-13 18:06 ` Christian Lamparter
2009-01-13 19:02 ` Artur Skawina
2009-01-13 21:39 ` Artur Skawina
2009-01-13 22:31 ` Artur Skawina
2009-01-15 17:55 ` Artur Skawina
2009-01-15 18:53 ` Christian Lamparter
2009-01-15 19:12 ` Artur Skawina
2009-01-15 19:42 ` Christian Lamparter
2009-01-15 20:06 ` Artur Skawina
2009-01-15 22:41 ` Christian Lamparter
2009-01-15 23:59 ` Artur Skawina
2009-01-16 3:18 ` Larry Finger
2009-01-16 3:31 ` Artur Skawina
2009-01-16 9:13 ` Johannes Berg
2009-01-16 20:38 ` Christian Lamparter
2009-01-16 22:10 ` Artur Skawina
2009-01-16 22:52 ` Christian Lamparter
2009-01-16 23:46 ` Artur Skawina
2009-01-18 23:27 ` Artur Skawina
2009-01-19 0:26 ` Christian Lamparter
2009-01-19 1:17 ` Artur Skawina
2009-01-19 18:15 ` Artur Skawina
2009-01-19 18:48 ` Christian Lamparter
2009-01-19 21:53 ` Artur Skawina
2009-01-19 22:38 ` Christian Lamparter [this message]
2009-01-19 22:54 ` Artur Skawina
2009-01-19 23:17 ` Artur Skawina
2009-01-19 23:32 ` Christian Lamparter
2009-01-20 20:18 ` Artur Skawina
2009-01-20 20:50 ` Christian Lamparter
2009-01-20 21:18 ` Artur Skawina
2009-01-19 18:52 ` Artur Skawina
2009-01-15 20:07 ` [PATCH] p54: set_tim must be atomic Artur Skawina
2009-01-15 18:56 ` wireless-testing, p54 and sinus 154 data no longer works Artur Skawina
2009-01-13 22:47 ` Christian Lamparter
2009-01-13 19:59 ` 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=200901192338.09646.chunkeey@web.de \
--to=chunkeey@web.de \
--cc=Larry.Finger@lwfinger.net \
--cc=art.08.09@gmail.com \
--cc=johannes@sipsolutions.net \
--cc=linux-wireless@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).