Almost there, almost there!!! :-) Using all of the attached three patches my problem seems gone: - I no longer see any "dropped TX filtered" messages in syslog - My app no longer times out p54_sta_flags_v2.diff alone does not change anything for me. Johannes' patch alone MAY reduce the frequency of my app-level timeouts, but I have only gut feeling to support that. All three together do it. Patches attached in original form for reference. However, after some time, the kernel oopses. Console output below. I watched this several times, and it always happens after seeing these last two lines in syslog:348 : Nov 26 14:16:32 alix kernel: STA 00:22:41:91:8e:96 aid 1: PS buffer (entries before 0) Nov 26 14:16:32 alix kernel: STA 00:22:41:91:8e:96 aid 1: PS buffer (entries before 1) Does this help? Anything you need me to try, I have this hardware only until tomorrow. It gets back to me after Dec 7. Thanks! Great work so far! Stefan. --- Console: console [netcon0] enabled netconsole: network logging started BUG: unable to handle kernel NULL pointer dereference at 00000038 IP: [<d08260fa>] p54_assign_address+0x67/0x14b [p54common] *pde = 00000000 Oops: 0000 [#1] last sysfs file: /sys/class/net/lo/operstate Modules linked in: netconsole ipv6 loop evdev ehci_hcd ohci_hcd rtc_cmos rtc_core pcspkr rtc_lib p54pci usbcore via_rhine p54common geode_aes mii [last unloaded: netconsole] Pid: 0, comm: swapper Not tainted (2.6.28-rc6-wl #16) EIP: 0060:[<d08260fa>] EFLAGS: 00010002 CPU: 0 EIP is at p54_assign_address+0x67/0x14b [p54common] EAX: cf98b178 EBX: cf86ee40 ECX: 00000000 EDX: 00000000 ESI: 000000f8 EDI: 00000000 EBP: 0002027c ESP: c03f9c4c DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068 Process swapper (pid: 0, ti=c03f8000 task=c03c4380 task.ti=c03f8000) Stack: 00000002 ce4d5880 ce4c48b4 cf86e1a0 00000000 00000038 00020200 00000286 cf86ee40 00000004 ce4d58b2 ce4d588c d0826fd7 00000090 014c48d4 ce4c48b4 cf86e1a0 0086ee40 00000004 02000282 ce4c48d4 cf86ef10 cf86ee40 ce4d5880 Call Trace: [<d0826fd7>] p54_tx+0x416/0x482 [p54common] [<c02fb7c2>] __ieee80211_tx+0x35/0xf8 [<c02fc235>] ieee80211_master_start_xmit+0x2ab/0x396 [<c01048d3>] common_interrupt+0x23/0x30 [<c0297368>] dev_hard_start_xmit+0x16e/0x1c9 [<c02a3518>] __qdisc_run+0xa2/0x15c [<c0297796>] dev_queue_xmit+0x2f5/0x3c5 [<c02f8608>] ieee80211_invoke_rx_handlers+0x488/0x1486 [<c02d9d14>] bictcp_cong_avoid+0x10/0x160 [<c02bd904>] tcp_ack+0x16f0/0x1850 [<c01170f0>] enqueue_task_fair+0x12a/0x16b [<c02c0c37>] tcp_current_mss+0x6b/0xe4 [<c02f9b50>] __ieee80211_rx_handle_packet+0x54a/0x56d [<c02fa1fe>] __ieee80211_rx+0x491/0x4e3 [<c02ec95d>] ieee80211_tasklet_handler+0x60/0xd6 [<c011cfae>] tasklet_action+0x3e/0x64 [<c011d305>] __do_softirq+0x4a/0xbc [<c011d399>] do_softirq+0x22/0x26 [<c011d44f>] irq_exit+0x25/0x55 [<c0105996>] do_IRQ+0x5a/0x6c [<c01048d3>] common_interrupt+0x23/0x30 [<c0108743>] default_idle+0x25/0x38 [<c0102926>] cpu_idle+0x41/0x5b Code: 0f 84 01 01 00 00 9c 8f 44 24 1c fa 8b 53 10 31 ff 89 6c 24 18 89 14 24 31 d2 eb 3f 8b 4c 24 10 83 c1 38 89 4c 24 14 8b 4c 24 10 <8b> 41 38 29 e8 85 d2 75 0d 39 f0 72 09 8b 51 04 29 f0 89 6c 24 EIP: [<d08260fa>] p54_assign_address+0x67/0x14b [p54common] SS:ESP 0068:c03f9c4c Kernel panic - not syncing: Fatal exception in interrupt 2008/11/24 Christian Lamparter <chunkeey@xxxxxx>: > On Monday 24 November 2008 17:51:45 Stefan Steuerwald wrote: >> Thanks again Christian and Johannes, >> >> from a first quick check >> - set-and-clear.diff doesn't seem to change anything >> - both patches together freeze my system >> >> I don't have a serial console on this embedded thing, so I don't know >> its death poem yet. Let me set up my debug environment properly and >> report back to you. > > This might not be necessary. > > Try this updated patch. And let us know if we no do the right thing. > > Regards, > Chr >
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 5a1a60f..077fdb7 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -657,7 +657,8 @@ static void ap_sta_ps_start(struct sta_info *sta) DECLARE_MAC_BUF(mac); atomic_inc(&sdata->bss->num_sta_ps); - set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL); + set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL | + WLAN_STA_CLEAR_PS_FILT); #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n", sdata->dev->name, print_mac(mac, sta->sta.addr), sta->sta.aid); @@ -674,7 +675,8 @@ static int ap_sta_ps_end(struct sta_info *sta) atomic_dec(&sdata->bss->num_sta_ps); - clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL); + set_and_clear_sta_flags(sta, WLAN_STA_CLEAR_PS_FILT, + WLAN_STA_PS | WLAN_STA_PSPOLL); if (!skb_queue_empty(&sta->ps_tx_buf)) sta_info_clear_tim_bit(sta);
diff -Nurp a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c --- a/drivers/net/wireless/p54/p54common.c 2008-11-24 13:07:09.053832187 +0100 +++ b/drivers/net/wireless/p54/p54common.c 2008-11-24 21:05:42.590287518 +0100 @@ -688,7 +688,8 @@ static void p54_rx_frame_sent(struct iee } } - priv->tx_stats[entry_data->hw_queue].len--; + if (priv->tx_stats[entry_data->hw_queue].len > 0) + priv->tx_stats[entry_data->hw_queue].len--; if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && (!payload->status)) info->flags |= IEEE80211_TX_STAT_ACK; @@ -1067,9 +1068,15 @@ static int p54_tx_fill(struct ieee80211_ *queue = 3; return 0; } - if (info->control.sta) + if (info->control.sta) { + if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) { + ret = p54_sta_unlock(dev, info->control.sta->addr); + if (ret) + return ret; + *flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL; + } *aid = info->control.sta->aid; - else + } else *flags = P54_HDR_FLAG_DATA_OUT_NOCANCEL; } return ret; @@ -1083,7 +1090,7 @@ static int p54_tx(struct ieee80211_hw *d struct p54_hdr *hdr; struct p54_tx_data *txhdr; size_t padding, len, tim_len = 0; - int i, j, ridx; + int i, j, ridx, ret; u16 hdr_flags = 0, aid = 0; u8 rate, queue; u8 cts_rate = 0x20; @@ -1093,7 +1100,10 @@ static int p54_tx(struct ieee80211_hw *d queue = skb_get_queue_mapping(skb); - if (p54_tx_fill(dev, skb, info, &queue, &tim_len, &hdr_flags, &aid)) { + ret = p54_tx_fill(dev, skb, info, &queue, &tim_len, &hdr_flags, &aid); + if (ret < 0) + return NETDEV_TX_BUSY; + if (ret) { current_queue = &priv->tx_stats[queue]; if (unlikely(current_queue->len > current_queue->limit)) return NETDEV_TX_BUSY; @@ -1106,17 +1116,6 @@ static int p54_tx(struct ieee80211_hw *d padding = (unsigned long)(skb->data - (sizeof(*hdr) + sizeof(*txhdr))) & 3; len = skb->len; - if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) { - if (info->control.sta) - if (p54_sta_unlock(dev, info->control.sta->addr)) { - if (current_queue) { - current_queue->len--; - current_queue->count--; - } - return NETDEV_TX_BUSY; - } - } - txhdr = (struct p54_tx_data *) skb_push(skb, sizeof(*txhdr) + padding); hdr = (struct p54_hdr *) skb_push(skb, sizeof(*hdr));
--- everything.orig/net/mac80211/rx.c 2008-11-23 14:58:21.000000000 +0100 +++ everything/net/mac80211/rx.c 2008-11-23 14:59:58.000000000 +0100 @@ -750,9 +750,11 @@ ieee80211_rx_h_sta_process(struct ieee80 /* Change STA power saving mode only in the end of a frame * exchange sequence */ if (test_sta_flags(sta, WLAN_STA_PS) && - !ieee80211_has_pm(hdr->frame_control)) - rx->sent_ps_buffered += ap_sta_ps_end(sta); - else if (!test_sta_flags(sta, WLAN_STA_PS) && + !ieee80211_has_pm(hdr->frame_control)) { + /* ignore PS bit on non-data frames */ + if (ieee80211_is_data(hdr->frame_control)) + rx->sent_ps_buffered += ap_sta_ps_end(sta); + } else if (!test_sta_flags(sta, WLAN_STA_PS) && ieee80211_has_pm(hdr->frame_control)) ap_sta_ps_start(sta); }
Attachment:
oops.syslog
Description: Binary data