* 2.6.19 lot's of oops in mmx_copy_page/ mmx_clear_page functions
@ 2006-12-10 11:32 matthieu castet
2006-12-10 19:02 ` Maxime Austruy
0 siblings, 1 reply; 3+ messages in thread
From: matthieu castet @ 2006-12-10 11:32 UTC (permalink / raw)
To: Linux Kernel list
Hi,
with 2.6.19 I got some random crash and I got kernel opps.
There all happens in mmx_copy_page/ mmx_clear_page functions with
differents process : Xorg, cat, mozilla, ...
What could be the cause of these crashes ?
What can I provide in order to debug this ?
Thanks
Matthieu CASTET
BUG: unable to handle kernel paging request at virtual address fffb9000
printing eip:
c01be1bd
*pde = 00002067
Oops: 0000 [#1]
PREEMPT
Modules linked in: michael_mic arc4 ecb ieee80211_crypt_tkip ehci_hcd
videodev v4l1_compat v4l2_common nfs nfsd exportfs lockd sunrpc sd_mod
sg sr_mod ppdev lp autofs4 button processor ipt_TOS ipt_MASQUERADE
ipt_ULOG ipt_LOG xt_tcpudp xt_state ipt_REJECT ipt_iprange xt_conntrack
iptable_mangle ip_nat_irc ip_nat_ftp iptable_nat ip_nat ip_conntrack_irc
ip_conntrack_ftp ip_conntrack iptable_filter ip_tables x_tables ide_cd
cdrom pcspkr snd_mpu401 ns558 parport_pc parport 8250_pnp 8250
serial_core floppy snd_via82xx snd_mpu401_uart emu10k1_gp gameport
snd_emu10k1_synth snd_emux_synth snd_seq_virmidi snd_seq_midi_emul
snd_seq_oss snd_seq_midi snd_seq_midi_event snd_seq snd_emu10k1
snd_rawmidi snd_ac97_codec snd_ac97_bus snd_pcm_oss snd_mixer_oss
snd_pcm snd_seq_device snd_timer snd_page_alloc snd_util_mem snd_hwdep
snd soundcore mii zd1211rw firmware_class ieee80211softmac ieee80211
ieee80211_crypt via_agp agpgart clip atm nls_iso8859_1 nls_cp437 vfat
fat nls_base reiserfs w83627hf hwmon_vid i2c_isa i2c_core evdev rtc
CPU: 0
EIP: 0060:[<c01be1bd>] Not tainted VLI
EFLAGS: 00010246 (2.6.19 #1)
EIP is at mmx_copy_page+0x51/0x123
eax: fffb9000 ebx: e2db9000 ecx: 00000000 edx: e2db9000
esi: fffb9000 edi: e2db9000 ebp: c17e6040 esp: f671defc
ds: 007b es: 007b ss: 0068
Process automount (pid: 11921, ti=f671c000 task=f7cf0050 task.ti=f671c000)
Stack: fffb9000 eb216040 c0140045 8001003c f5c95e40 f4ee2abc c145b720
00000000
3f302065 f4ee2afc eb216040 f5c95e40 c014145f eb216040 f4f8a800
f4ee2afc
3f302065 393b4393 8001003c f4ee2abc 00000040 f4f8a800 00000000
f671df94
Call Trace:
[<c0140045>] do_wp_page+0x291/0x414
[<c014145f>] __handle_mm_fault+0x7d2/0x873
[<c0112593>] do_page_fault+0x213/0x4dc
[<c0112380>] do_page_fault+0x0/0x4dc
[<c02a01e1>] error_code+0x39/0x40
=======================
Code: f4 ff 0f 0d 06 0f 0d 46 40 0f 0d 86 80 00 00 00 0f 0d 86 c0 00 00
00 0f 0d 86 00 01 00 00 31 c9 89 fa 89 f0 0f 0d 80 40 01 00 00 <0f> 6f
00 0f e7 02 0f 6f 48 08 0f e7 4a 08 0f 6f 50 10 0f e7 52
EIP: [<c01be1bd>] mmx_copy_page+0x51/0x123 SS:ESP 0068:f671defc
<6>note: automount[11921] exited with preempt_count 3
Sumary of Others failures :
/var/log/syslog:Dec 10 10:40:14 localhost kernel: BUG: unable to handle
kernel paging request at virtual address fffb9b20
/var/log/syslog:Dec 10 10:40:14 localhost kernel: EIP is at
mmx_clear_page+0x38/0x7e
/var/log/syslog:Dec 10 10:40:14 localhost kernel: Process iceape-bin
(pid: 7061, ti=f7410000 task=eeb5a070 task.ti=f7410000)
/var/log/syslog:Dec 10 10:40:14 localhost kernel: EIP: [<c01be406>]
mmx_clear_page+0x38/0x7e SS:ESP 0068:f7411eb0
/var/log/syslog:Dec 10 10:40:24 localhost kernel: BUG: unable to handle
kernel paging request at virtual address fffb9a60
/var/log/syslog:Dec 10 10:40:24 localhost kernel: EIP is at
mmx_clear_page+0x38/0x7e
/var/log/syslog:Dec 10 10:40:24 localhost kernel: Process cc1 (pid:
21797, ti=d62ea000 task=e86eb070 task.ti=d62ea000)
/var/log/syslog:Dec 10 10:40:24 localhost kernel: EIP: [<c01be406>]
mmx_clear_page+0x38/0x7e SS:ESP 0068:d62ebeb0
/var/log/syslog:Dec 10 11:12:37 localhost kernel: BUG: unable to handle
kernel paging request at virtual address fffb9000
/var/log/syslog:Dec 10 11:12:37 localhost kernel: EIP is at
mmx_copy_page+0x51/0x123
/var/log/syslog:Dec 10 11:12:37 localhost kernel: Process automount
(pid: 11921, ti=f671c000 task=f7cf0050 task.ti=f671c000)
/var/log/syslog:Dec 10 11:12:37 localhost kernel: EIP: [<c01be1bd>]
mmx_copy_page+0x51/0x123 SS:ESP 0068:f671defc
/var/log/syslog.0:Dec 9 19:21:50 localhost kernel: Process modprobe
(pid: 20516, ti=ee3d8000 task=f649f580 task.ti=ee3d8000)
/var/log/syslog.0:Dec 9 22:15:15 localhost kernel: BUG: unable to
handle kernel paging request at virtual address fffb9000
/var/log/syslog.0:Dec 9 22:15:15 localhost kernel: EIP is at
mmx_clear_page+0x29/0x7e
/var/log/syslog.0:Dec 9 22:15:15 localhost kernel: Process Xorg (pid:
9479, ti=d4ae0000 task=f671ca90 task.ti=d4ae0000)
/var/log/syslog.0:Dec 9 22:15:15 localhost kernel: EIP: [<c01be3f7>]
mmx_clear_page+0x29/0x7e SS:ESP 0068:d4ae1eb0
/var/log/syslog.0:Dec 9 22:15:15 localhost kernel: [<c01be3f7>]
mmx_clear_page+0x29/0x7e
/var/log/syslog.0:Dec 9 22:15:15 localhost kernel: [<c01be3f7>]
mmx_clear_page+0x29/0x7e
/var/log/syslog.0:Dec 10 00:06:31 localhost kernel: BUG: unable to
handle kernel paging request at virtual address fffb9340
/var/log/syslog.0:Dec 10 00:06:31 localhost kernel: EIP is at
mmx_clear_page+0x29/0x7e
/var/log/syslog.0:Dec 10 00:06:31 localhost kernel: Process Xorg (pid:
10450, ti=c758e000 task=d42fa030 task.ti=c758e000)
/var/log/syslog.0:Dec 10 00:06:31 localhost kernel: EIP: [<c01be3f7>]
mmx_clear_page+0x29/0x7e SS:ESP 0068:c758feb0
/var/log/syslog.0:Dec 10 00:06:31 localhost kernel: [<c01be3f7>]
mmx_clear_page+0x29/0x7e
/var/log/syslog.0:Dec 10 00:06:31 localhost kernel: [<c01be3f7>]
mmx_clear_page+0x29/0x7e
/var/log/syslog.0:Dec 10 10:23:00 localhost kernel: BUG: unable to
handle kernel paging request at virtual address fffb9000
/var/log/syslog.0:Dec 10 10:23:00 localhost kernel: EIP is at
mmx_copy_page+0x51/0x123
/var/log/syslog.0:Dec 10 10:23:00 localhost kernel: Process cat (pid:
8977, ti=db79c000 task=df987030 task.ti=db79c000)
/var/log/syslog.0:Dec 10 10:23:00 localhost kernel: EIP: [<c01be1bd>]
mmx_copy_page+0x51/0x123 SS:ESP 0068:db79ddc8
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: 2.6.19 lot's of oops in mmx_copy_page/ mmx_clear_page functions 2006-12-10 11:32 2.6.19 lot's of oops in mmx_copy_page/ mmx_clear_page functions matthieu castet @ 2006-12-10 19:02 ` Maxime Austruy 2006-12-10 19:25 ` Ulrich Kunitz 0 siblings, 1 reply; 3+ messages in thread From: Maxime Austruy @ 2006-12-10 19:02 UTC (permalink / raw) To: matthieu castet; +Cc: Linux Kernel list, Daniel Drake, Ulrich Kunitz Matthieu, On Sun, Dec 10, 2006 at 12:32:08PM +0100, matthieu castet wrote: > Hi, > > with 2.6.19 I got some random crash and I got kernel opps. > There all happens in mmx_copy_page/ mmx_clear_page functions with > differents process : Xorg, cat, mozilla, ... > > > What could be the cause of these crashes ? > What can I provide in order to debug this ? FWIW, I've seen the same oops on my box. My instance was caused by a combination of: . zd1211rw calling ieee80211_rx in irq context while it's supposed to be called in softirq, . crypto code only expecting to be called in softirq/user context but not enforcing it. Consequently, it ends up doing v = kmap_atomic(..., KM_USER0); even when invoked by the zd1211rw driver in irq context, causing some corruption. Given that you have zd1211rw insmod'd, that could be it. I have some hacks that work around this bug, but Ulrich has a patch ready that should fix this. Thanks, Max > > > Thanks > > Matthieu CASTET > > > > BUG: unable to handle kernel paging request at virtual address fffb9000 > printing eip: > c01be1bd > *pde = 00002067 > Oops: 0000 [#1] > PREEMPT > Modules linked in: michael_mic arc4 ecb ieee80211_crypt_tkip ehci_hcd > videodev v4l1_compat v4l2_common nfs nfsd exportfs lockd sunrpc sd_mod > sg sr_mod ppdev lp autofs4 button processor ipt_TOS ipt_MASQUERADE > ipt_ULOG ipt_LOG xt_tcpudp xt_state ipt_REJECT ipt_iprange xt_conntrack > iptable_mangle ip_nat_irc ip_nat_ftp iptable_nat ip_nat ip_conntrack_irc > ip_conntrack_ftp ip_conntrack iptable_filter ip_tables x_tables ide_cd > cdrom pcspkr snd_mpu401 ns558 parport_pc parport 8250_pnp 8250 > serial_core floppy snd_via82xx snd_mpu401_uart emu10k1_gp gameport > snd_emu10k1_synth snd_emux_synth snd_seq_virmidi snd_seq_midi_emul > snd_seq_oss snd_seq_midi snd_seq_midi_event snd_seq snd_emu10k1 > snd_rawmidi snd_ac97_codec snd_ac97_bus snd_pcm_oss snd_mixer_oss > snd_pcm snd_seq_device snd_timer snd_page_alloc snd_util_mem snd_hwdep > snd soundcore mii zd1211rw firmware_class ieee80211softmac ieee80211 > ieee80211_crypt via_agp agpgart clip atm nls_iso8859_1 nls_cp437 vfat > fat nls_base reiserfs w83627hf hwmon_vid i2c_isa i2c_core evdev rtc > CPU: 0 > EIP: 0060:[<c01be1bd>] Not tainted VLI > EFLAGS: 00010246 (2.6.19 #1) > EIP is at mmx_copy_page+0x51/0x123 > eax: fffb9000 ebx: e2db9000 ecx: 00000000 edx: e2db9000 > esi: fffb9000 edi: e2db9000 ebp: c17e6040 esp: f671defc > ds: 007b es: 007b ss: 0068 > Process automount (pid: 11921, ti=f671c000 task=f7cf0050 task.ti=f671c000) > Stack: fffb9000 eb216040 c0140045 8001003c f5c95e40 f4ee2abc c145b720 > 00000000 > 3f302065 f4ee2afc eb216040 f5c95e40 c014145f eb216040 f4f8a800 > f4ee2afc > 3f302065 393b4393 8001003c f4ee2abc 00000040 f4f8a800 00000000 > f671df94 > Call Trace: > [<c0140045>] do_wp_page+0x291/0x414 > [<c014145f>] __handle_mm_fault+0x7d2/0x873 > [<c0112593>] do_page_fault+0x213/0x4dc > [<c0112380>] do_page_fault+0x0/0x4dc > [<c02a01e1>] error_code+0x39/0x40 > ======================= > Code: f4 ff 0f 0d 06 0f 0d 46 40 0f 0d 86 80 00 00 00 0f 0d 86 c0 00 00 > 00 0f 0d 86 00 01 00 00 31 c9 89 fa 89 f0 0f 0d 80 40 01 00 00 <0f> 6f > 00 0f e7 02 0f 6f 48 08 0f e7 4a 08 0f 6f 50 10 0f e7 52 > EIP: [<c01be1bd>] mmx_copy_page+0x51/0x123 SS:ESP 0068:f671defc > <6>note: automount[11921] exited with preempt_count 3 > > > > Sumary of Others failures : > /var/log/syslog:Dec 10 10:40:14 localhost kernel: BUG: unable to handle > kernel paging request at virtual address fffb9b20 > /var/log/syslog:Dec 10 10:40:14 localhost kernel: EIP is at > mmx_clear_page+0x38/0x7e > /var/log/syslog:Dec 10 10:40:14 localhost kernel: Process iceape-bin > (pid: 7061, ti=f7410000 task=eeb5a070 task.ti=f7410000) > /var/log/syslog:Dec 10 10:40:14 localhost kernel: EIP: [<c01be406>] > mmx_clear_page+0x38/0x7e SS:ESP 0068:f7411eb0 > /var/log/syslog:Dec 10 10:40:24 localhost kernel: BUG: unable to handle > kernel paging request at virtual address fffb9a60 > /var/log/syslog:Dec 10 10:40:24 localhost kernel: EIP is at > mmx_clear_page+0x38/0x7e > /var/log/syslog:Dec 10 10:40:24 localhost kernel: Process cc1 (pid: > 21797, ti=d62ea000 task=e86eb070 task.ti=d62ea000) > /var/log/syslog:Dec 10 10:40:24 localhost kernel: EIP: [<c01be406>] > mmx_clear_page+0x38/0x7e SS:ESP 0068:d62ebeb0 > /var/log/syslog:Dec 10 11:12:37 localhost kernel: BUG: unable to handle > kernel paging request at virtual address fffb9000 > /var/log/syslog:Dec 10 11:12:37 localhost kernel: EIP is at > mmx_copy_page+0x51/0x123 > /var/log/syslog:Dec 10 11:12:37 localhost kernel: Process automount > (pid: 11921, ti=f671c000 task=f7cf0050 task.ti=f671c000) > /var/log/syslog:Dec 10 11:12:37 localhost kernel: EIP: [<c01be1bd>] > mmx_copy_page+0x51/0x123 SS:ESP 0068:f671defc > /var/log/syslog.0:Dec 9 19:21:50 localhost kernel: Process modprobe > (pid: 20516, ti=ee3d8000 task=f649f580 task.ti=ee3d8000) > /var/log/syslog.0:Dec 9 22:15:15 localhost kernel: BUG: unable to > handle kernel paging request at virtual address fffb9000 > /var/log/syslog.0:Dec 9 22:15:15 localhost kernel: EIP is at > mmx_clear_page+0x29/0x7e > /var/log/syslog.0:Dec 9 22:15:15 localhost kernel: Process Xorg (pid: > 9479, ti=d4ae0000 task=f671ca90 task.ti=d4ae0000) > /var/log/syslog.0:Dec 9 22:15:15 localhost kernel: EIP: [<c01be3f7>] > mmx_clear_page+0x29/0x7e SS:ESP 0068:d4ae1eb0 > /var/log/syslog.0:Dec 9 22:15:15 localhost kernel: [<c01be3f7>] > mmx_clear_page+0x29/0x7e > /var/log/syslog.0:Dec 9 22:15:15 localhost kernel: [<c01be3f7>] > mmx_clear_page+0x29/0x7e > /var/log/syslog.0:Dec 10 00:06:31 localhost kernel: BUG: unable to > handle kernel paging request at virtual address fffb9340 > /var/log/syslog.0:Dec 10 00:06:31 localhost kernel: EIP is at > mmx_clear_page+0x29/0x7e > /var/log/syslog.0:Dec 10 00:06:31 localhost kernel: Process Xorg (pid: > 10450, ti=c758e000 task=d42fa030 task.ti=c758e000) > /var/log/syslog.0:Dec 10 00:06:31 localhost kernel: EIP: [<c01be3f7>] > mmx_clear_page+0x29/0x7e SS:ESP 0068:c758feb0 > /var/log/syslog.0:Dec 10 00:06:31 localhost kernel: [<c01be3f7>] > mmx_clear_page+0x29/0x7e > /var/log/syslog.0:Dec 10 00:06:31 localhost kernel: [<c01be3f7>] > mmx_clear_page+0x29/0x7e > /var/log/syslog.0:Dec 10 10:23:00 localhost kernel: BUG: unable to > handle kernel paging request at virtual address fffb9000 > /var/log/syslog.0:Dec 10 10:23:00 localhost kernel: EIP is at > mmx_copy_page+0x51/0x123 > /var/log/syslog.0:Dec 10 10:23:00 localhost kernel: Process cat (pid: > 8977, ti=db79c000 task=df987030 task.ti=db79c000) > /var/log/syslog.0:Dec 10 10:23:00 localhost kernel: EIP: [<c01be1bd>] > mmx_copy_page+0x51/0x123 SS:ESP 0068:db79ddc8 > - > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ > ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: 2.6.19 lot's of oops in mmx_copy_page/ mmx_clear_page functions 2006-12-10 19:02 ` Maxime Austruy @ 2006-12-10 19:25 ` Ulrich Kunitz 0 siblings, 0 replies; 3+ messages in thread From: Ulrich Kunitz @ 2006-12-10 19:25 UTC (permalink / raw) To: Maxime Austruy Cc: zd1211-devs, matthieu castet, Linux Kernel list, Daniel Drake On 06-12-10 11:02 Maxime Austruy wrote: > > Matthieu, > > On Sun, Dec 10, 2006 at 12:32:08PM +0100, matthieu castet wrote: > > Hi, > > > > with 2.6.19 I got some random crash and I got kernel opps. > > There all happens in mmx_copy_page/ mmx_clear_page functions with > > differents process : Xorg, cat, mozilla, ... > > > > > > What could be the cause of these crashes ? > > What can I provide in order to debug this ? > > FWIW, I've seen the same oops on my box. My instance was caused by a > combination of: > . zd1211rw calling ieee80211_rx in irq context while it's supposed to > be called in softirq, > . crypto code only expecting to be called in softirq/user context but > not enforcing it. Consequently, it ends up doing > v = kmap_atomic(..., KM_USER0); > even when invoked by the zd1211rw driver in irq context, causing some > corruption. > > Given that you have zd1211rw insmod'd, that could be it. I have some > hacks that work around this bug, but Ulrich has a patch ready that > should fix this. Thanks, > > Max Here is the patch against vanilla 2.6.19. For Linus' latest tree I have sent also patches on netdev. Users of my out-of-kernel git tree, should look at the branch rx. Uli [PATCH] zd1211rw: Call ieee80211_rx in tasklet The driver called ieee80211_rx in hardware irq context. This caused a problem withe crypto libraries and was against the documentation/intention of the ieee80211_rx function. This patch fixes that. Signed-off-by: Ulrich Kunitz <kune@deine-taler.de> --- drivers/net/wireless/zd1211rw/zd_mac.c | 88 ++++++++++++++++++++++++-------- drivers/net/wireless/zd1211rw/zd_mac.h | 6 ++ drivers/net/wireless/zd1211rw/zd_usb.c | 4 + 3 files changed, 72 insertions(+), 26 deletions(-) diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index a7d29bd..f52dd3a 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -37,6 +37,8 @@ static void housekeeping_init(struct zd_ static void housekeeping_enable(struct zd_mac *mac); static void housekeeping_disable(struct zd_mac *mac); +static void do_rx(unsigned long mac_ptr); + int zd_mac_init(struct zd_mac *mac, struct net_device *netdev, struct usb_interface *intf) @@ -47,6 +49,10 @@ int zd_mac_init(struct zd_mac *mac, spin_lock_init(&mac->lock); mac->netdev = netdev; + skb_queue_head_init(&mac->rx_queue); + tasklet_init(&mac->rx_tasklet, do_rx, (unsigned long)mac); + tasklet_disable(&mac->rx_tasklet); + ieee_init(ieee); softmac_init(ieee80211_priv(netdev)); zd_chip_init(&mac->chip, netdev, intf); @@ -132,6 +138,8 @@ out: void zd_mac_clear(struct zd_mac *mac) { + skb_queue_purge(&mac->rx_queue); + tasklet_kill(&mac->rx_tasklet); zd_chip_clear(&mac->chip); ZD_ASSERT(!spin_is_locked(&mac->lock)); ZD_MEMCLEAR(mac, sizeof(struct zd_mac)); @@ -160,6 +168,8 @@ int zd_mac_open(struct net_device *netde struct zd_chip *chip = &mac->chip; int r; + tasklet_enable(&mac->rx_tasklet); + r = zd_chip_enable_int(chip); if (r < 0) goto out; @@ -210,6 +220,8 @@ int zd_mac_stop(struct net_device *netde */ zd_chip_disable_rx(chip); + skb_queue_purge(&mac->rx_queue); + tasklet_disable(&mac->rx_tasklet); housekeeping_disable(mac); ieee80211softmac_stop(netdev); @@ -873,45 +885,75 @@ static int fill_rx_stats(struct ieee8021 return 0; } -int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length) +static void zd_mac_rx(struct zd_mac *mac, struct sk_buff *skb) { int r; struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); struct ieee80211_rx_stats stats; const struct rx_status *status; - struct sk_buff *skb; - if (length < ZD_PLCP_HEADER_SIZE + IEEE80211_1ADDR_LEN + - IEEE80211_FCS_LEN + sizeof(struct rx_status)) - return -EINVAL; + if (skb->len < ZD_PLCP_HEADER_SIZE + IEEE80211_1ADDR_LEN + + IEEE80211_FCS_LEN + sizeof(struct rx_status)) + { + dev_warn(zd_mac_dev(mac), "Packet with length %u to small.\n", + skb->len); + goto free_skb; + } - r = fill_rx_stats(&stats, &status, mac, buffer, length); - if (r) - return r; + r = fill_rx_stats(&stats, &status, mac, skb->data, skb->len); + if (r) { + /* Only packets with rx errors are included here. */ + goto free_skb; + } - length -= ZD_PLCP_HEADER_SIZE+IEEE80211_FCS_LEN+ - sizeof(struct rx_status); - buffer += ZD_PLCP_HEADER_SIZE; + __skb_pull(skb, ZD_PLCP_HEADER_SIZE); + __skb_trim(skb, skb->len - + (IEEE80211_FCS_LEN + sizeof(struct rx_status))); - update_qual_rssi(mac, buffer, length, stats.signal, stats.rssi); + update_qual_rssi(mac, skb->data, skb->len, stats.signal, + status->signal_strength); - r = filter_rx(ieee, buffer, length, &stats); - if (r <= 0) - return r; + r = filter_rx(ieee, skb->data, skb->len, &stats); + if (r <= 0) { + if (r < 0) + dev_dbg_f(zd_mac_dev(mac), "Error in packet.\n"); + goto free_skb; + } - skb = dev_alloc_skb(sizeof(struct zd_rt_hdr) + length); - if (!skb) - return -ENOMEM; if (ieee->iw_mode == IW_MODE_MONITOR) - fill_rt_header(skb_put(skb, sizeof(struct zd_rt_hdr)), mac, + fill_rt_header(skb_push(skb, sizeof(struct zd_rt_hdr)), mac, &stats, status); - memcpy(skb_put(skb, length), buffer, length); r = ieee80211_rx(ieee, skb, &stats); - if (!r) { - ZD_ASSERT(in_irq()); - dev_kfree_skb_irq(skb); + if (r) + return; +free_skb: + /* We are always in a soft irq. */ + dev_kfree_skb(skb); +} + +static void do_rx(unsigned long mac_ptr) +{ + struct zd_mac *mac = (struct zd_mac *)mac_ptr; + struct sk_buff *skb; + + while ((skb = skb_dequeue(&mac->rx_queue)) != NULL) + zd_mac_rx(mac, skb); +} + +int zd_mac_rx_irq(struct zd_mac *mac, const u8 *buffer, unsigned int length) +{ + struct sk_buff *skb; + + skb = dev_alloc_skb(sizeof(struct zd_rt_hdr) + length); + if (!skb) { + dev_warn(zd_mac_dev(mac), "Could not allocate skb.\n"); + return -ENOMEM; } + skb_reserve(skb, sizeof(struct zd_rt_hdr)); + memcpy(__skb_put(skb, length), buffer, length); + skb_queue_tail(&mac->rx_queue, skb); + tasklet_schedule(&mac->rx_tasklet); return 0; } diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h index b8ea3de..c1bea87 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/drivers/net/wireless/zd1211rw/zd_mac.h @@ -133,6 +133,10 @@ struct zd_mac { /* Unlocked reading possible */ struct iw_statistics iw_stats; struct housekeeping housekeeping; + + struct tasklet_struct rx_tasklet; + struct sk_buff_head rx_queue; + unsigned int stats_count; u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE]; u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE]; @@ -174,7 +178,7 @@ int zd_mac_open(struct net_device *netde int zd_mac_stop(struct net_device *netdev); int zd_mac_set_mac_address(struct net_device *dev, void *p); -int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length); +int zd_mac_rx_irq(struct zd_mac *mac, const u8 *buffer, unsigned int length); int zd_mac_set_regdomain(struct zd_mac *zd_mac, u8 regdomain); u8 zd_mac_get_regdomain(struct zd_mac *zd_mac); diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 3faaeb2..4a5f5d5 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -599,13 +599,13 @@ static void handle_rx_packet(struct zd_u n = l+k; if (n > length) return; - zd_mac_rx(mac, buffer+l, k); + zd_mac_rx_irq(mac, buffer+l, k); if (i >= 2) return; l = (n+3) & ~3; } } else { - zd_mac_rx(mac, buffer, length); + zd_mac_rx_irq(mac, buffer, length); } } -- 1.4.1 ^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2006-12-10 19:25 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-12-10 11:32 2.6.19 lot's of oops in mmx_copy_page/ mmx_clear_page functions matthieu castet 2006-12-10 19:02 ` Maxime Austruy 2006-12-10 19:25 ` Ulrich Kunitz
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox