2011-05-18 18:26:46

by Ivo Van Doorn

[permalink] [raw]
Subject: [PATCH 5/7] rt2x00: Move rt2800_txdone and rt2800_txdone_entry_check to rt2800usb.

From: Gertjan van Wingerde <[email protected]>

These two functions are only used by rt2800usb so they don't have to be
in rt2800lib.

Signed-off-by: Gertjan van Wingerde <[email protected]>
Signed-off-by: Ivo van Doorn <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 82 ------------------------------
drivers/net/wireless/rt2x00/rt2800lib.h | 1 -
drivers/net/wireless/rt2x00/rt2800usb.c | 83 ++++++++++++++++++++++++++++++-
3 files changed, 82 insertions(+), 84 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 445d681..562dc1d 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -601,49 +601,6 @@ void rt2800_process_rxwi(struct queue_entry *entry,
}
EXPORT_SYMBOL_GPL(rt2800_process_rxwi);

-static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg)
-{
- __le32 *txwi;
- u32 word;
- int wcid, ack, pid;
- int tx_wcid, tx_ack, tx_pid;
-
- wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
- ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
- pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
-
- /*
- * This frames has returned with an IO error,
- * so the status report is not intended for this
- * frame.
- */
- if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) {
- rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
- return false;
- }
-
- /*
- * Validate if this TX status report is intended for
- * this entry by comparing the WCID/ACK/PID fields.
- */
- txwi = rt2800_drv_get_txwi(entry);
-
- rt2x00_desc_read(txwi, 1, &word);
- tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
- tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK);
- tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID);
-
- if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) {
- WARNING(entry->queue->rt2x00dev,
- "TX status report missed for queue %d entry %d\n",
- entry->queue->qid, entry->entry_idx);
- rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN);
- return false;
- }
-
- return true;
-}
-
void rt2800_txdone_entry(struct queue_entry *entry, u32 status)
{
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
@@ -726,45 +683,6 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status)
}
EXPORT_SYMBOL_GPL(rt2800_txdone_entry);

-void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
-{
- struct data_queue *queue;
- struct queue_entry *entry;
- u32 reg;
- u8 qid;
-
- while (kfifo_get(&rt2x00dev->txstatus_fifo, &reg)) {
-
- /* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus
- * qid is guaranteed to be one of the TX QIDs
- */
- qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE);
- queue = rt2x00queue_get_tx_queue(rt2x00dev, qid);
- if (unlikely(!queue)) {
- WARNING(rt2x00dev, "Got TX status for an unavailable "
- "queue %u, dropping\n", qid);
- continue;
- }
-
- /*
- * Inside each queue, we process each entry in a chronological
- * order. We first check that the queue is not empty.
- */
- entry = NULL;
- while (!rt2x00queue_empty(queue)) {
- entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
- if (rt2800_txdone_entry_check(entry, reg))
- break;
- }
-
- if (!entry || rt2x00queue_empty(queue))
- break;
-
- rt2800_txdone_entry(entry, reg);
- }
-}
-EXPORT_SYMBOL_GPL(rt2800_txdone);
-
void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
{
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h
index f2d1594..69deb31 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/rt2x00/rt2800lib.h
@@ -152,7 +152,6 @@ void rt2800_write_tx_data(struct queue_entry *entry,
struct txentry_desc *txdesc);
void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc);

-void rt2800_txdone(struct rt2x00_dev *rt2x00dev);
void rt2800_txdone_entry(struct queue_entry *entry, u32 status);

void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc);
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index ba82c97..6e92298 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -457,6 +457,87 @@ static int rt2800usb_get_tx_data_len(struct queue_entry *entry)
/*
* TX control handlers
*/
+static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)
+{
+ __le32 *txwi;
+ u32 word;
+ int wcid, ack, pid;
+ int tx_wcid, tx_ack, tx_pid;
+
+ wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
+ ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
+ pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
+
+ /*
+ * This frames has returned with an IO error,
+ * so the status report is not intended for this
+ * frame.
+ */
+ if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) {
+ rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
+ return false;
+ }
+
+ /*
+ * Validate if this TX status report is intended for
+ * this entry by comparing the WCID/ACK/PID fields.
+ */
+ txwi = rt2800usb_get_txwi(entry);
+
+ rt2x00_desc_read(txwi, 1, &word);
+ tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
+ tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK);
+ tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID);
+
+ if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) {
+ WARNING(entry->queue->rt2x00dev,
+ "TX status report missed for queue %d entry %d\n",
+ entry->queue->qid, entry->entry_idx);
+ rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN);
+ return false;
+ }
+
+ return true;
+}
+
+static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev)
+{
+ struct data_queue *queue;
+ struct queue_entry *entry;
+ u32 reg;
+ u8 qid;
+
+ while (kfifo_get(&rt2x00dev->txstatus_fifo, &reg)) {
+
+ /* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus
+ * qid is guaranteed to be one of the TX QIDs
+ */
+ qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE);
+ queue = rt2x00queue_get_tx_queue(rt2x00dev, qid);
+ if (unlikely(!queue)) {
+ WARNING(rt2x00dev, "Got TX status for an unavailable "
+ "queue %u, dropping\n", qid);
+ continue;
+ }
+
+ /*
+ * Inside each queue, we process each entry in a chronological
+ * order. We first check that the queue is not empty.
+ */
+ entry = NULL;
+ while (!rt2x00queue_empty(queue)) {
+ entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
+ if (rt2800usb_txdone_entry_check(entry, reg))
+ break;
+ }
+
+ if (!entry || rt2x00queue_empty(queue))
+ break;
+
+ rt2800_txdone_entry(entry, reg);
+ }
+}
+
static void rt2800usb_work_txdone(struct work_struct *work)
{
struct rt2x00_dev *rt2x00dev =
@@ -464,7 +545,7 @@ static void rt2800usb_work_txdone(struct work_struct *work)
struct data_queue *queue;
struct queue_entry *entry;

- rt2800_txdone(rt2x00dev);
+ rt2800usb_txdone(rt2x00dev);

/*
* Process any trailing TX status reports for IO failures,
--
1.7.2.3



2011-05-18 20:38:56

by Marc Dietrich

[permalink] [raw]
Subject: Re: [rt2x00-users] [PATCH 5/7] rt2x00: Move rt2800_txdone andrt2800_txdone_entry_check to rt2800usb.


Hi,

I tested the patches and got this during boot on a rt3070 chip:

[ 14.173458] ------------[ cut here ]------------
[ 14.173482] WARNING: at /home/marc/ac100/marvin24s-kernel/kernel/softirq.c:159 local_bh_enable_ip+0x4c/0xcc()
[ 14.173490] Modules linked in: binfmt_misc snd_soc_tegra_paz00 snd_soc_alc5632 snd_soc_tegra_i2s snd_soc_tegra_pcm
snd_soc_tegra_das rt2800usb snd_soc_core snd_pcm_oss rt2800lib rt2x00usb snd_mixer_oss rt2x00lib snd_pcm mac80211
snd_seq_midi snd_rawmidi snd_seq_midi_event snd_seq cfg80211 snd_timer snd_seq_device uvcvideo rfkill cdc_acm snd
cdc_wdm videodev snd_soc_tegra_utils soundcore snd_page_alloc g_cdc btrfs
[ 14.173567] Backtrace:
[ 14.173607] [<c0043708>] (unwind_backtrace+0x0/0xe0) from [<c00753f8>] (warn_slowpath_common+0x4c/0x64)
[ 14.173628] [<c00753f8>] (warn_slowpath_common+0x4c/0x64) from [<c0075428>] (warn_slowpath_null+0x18/0x1c)
[ 14.173646] [<c0075428>] (warn_slowpath_null+0x18/0x1c) from [<c007bc80>] (local_bh_enable_ip+0x4c/0xcc)
[ 14.173676] [<c007bc80>] (local_bh_enable_ip+0x4c/0xcc) from [<bf40b9b4>] (rt2x00usb_interrupt_rxdone+0x30/0x70
[rt2x00usb])
[ 14.173723] [<bf40b9b4>] (rt2x00usb_interrupt_rxdone+0x30/0x70 [rt2x00usb]) from [<c02d9150>]
(usb_hcd_giveback_urb+0x74/0xbc)
[ 14.173752] [<c02d9150>] (usb_hcd_giveback_urb+0x74/0xbc) from [<c02e75f8>] (ehci_urb_done+0x90/0x9c)
[ 14.173775] [<c02e75f8>] (ehci_urb_done+0x90/0x9c) from [<c02eb284>] (qh_completions+0xb4/0x3ec)
[ 14.173795] [<c02eb284>] (qh_completions+0xb4/0x3ec) from [<c02ec4b8>] (ehci_work+0xb4/0x97c)
[ 14.173814] [<c02ec4b8>] (ehci_work+0xb4/0x97c) from [<c02ed3d0>] (ehci_irq+0x21c/0x24c)
[ 14.173830] [<c02ed3d0>] (ehci_irq+0x21c/0x24c) from [<c02d8b34>] (usb_hcd_irq+0x34/0x6c)
[ 14.173865] [<c02d8b34>] (usb_hcd_irq+0x34/0x6c) from [<c00bb840>] (handle_IRQ_event+0x9c/0x1b4)
[ 14.173884] [<c00bb840>] (handle_IRQ_event+0x9c/0x1b4) from [<c00bd4fc>] (handle_level_irq+0xd0/0x154)
[ 14.173910] [<c00bd4fc>] (handle_level_irq+0xd0/0x154) from [<c0037080>] (asm_do_IRQ+0x80/0xb4)
[ 14.173943] [<c0037080>] (asm_do_IRQ+0x80/0xb4) from [<c040d84c>] (__irq_svc+0x4c/0xe0)
[ 14.173954] Exception stack(0xdb84be10 to 0xdb84be58)
[ 14.173964] be00: db929800 db28dc60 00000000 dcc00000
[ 14.173979] be20: db28dc60 dcd20000 00000000 00000010 db929800 00000008 00000010 db28dc98
[ 14.173991] be40: 00000000 db84be58 c026c86c c026ef58 60000013 ffffffff
[ 14.174027] [<c040d84c>] (__irq_svc+0x4c/0xe0) from [<c026ef58>] (cfb_imageblit+0x54/0x43c)
[ 14.174047] [<c026ef58>] (cfb_imageblit+0x54/0x43c) from [<c026c86c>] (soft_cursor+0x1a0/0x1a8)
[ 14.174065] [<c026c86c>] (soft_cursor+0x1a0/0x1a8) from [<c026c254>] (bit_cursor+0x41c/0x42c)
[ 14.174083] [<c026c254>] (bit_cursor+0x41c/0x42c) from [<c0266d08>] (fb_flashcursor+0xfc/0x118)
[ 14.174114] [<c0266d08>] (fb_flashcursor+0xfc/0x118) from [<c008c9a0>] (process_one_work+0x274/0x43c)
[ 14.174136] [<c008c9a0>] (process_one_work+0x274/0x43c) from [<c008e698>] (worker_thread+0x1b8/0x2b4)
[ 14.174159] [<c008e698>] (worker_thread+0x1b8/0x2b4) from [<c0091d5c>] (kthread+0x7c/0x84)
[ 14.174190] [<c0091d5c>] (kthread+0x7c/0x84) from [<c003d470>] (kernel_thread_exit+0x0/0x8)
[ 14.174202] ---[ end trace 7b2804cb6c2b13fe ]---

Of course, this didn't happen before.

Thanks

Marc

Am Mittwoch 18 Mai 2011, 20:25:49 schrieb Ivo van Doorn:
> From: Gertjan van Wingerde <[email protected]>
>
> These two functions are only used by rt2800usb so they don't have to be
> in rt2800lib.
>
> Signed-off-by: Gertjan van Wingerde <[email protected]>
> Signed-off-by: Ivo van Doorn <[email protected]>
> ---
> drivers/net/wireless/rt2x00/rt2800lib.c | 82
> ------------------------------ drivers/net/wireless/rt2x00/rt2800lib.h |
> 1 -
> drivers/net/wireless/rt2x00/rt2800usb.c | 83
> ++++++++++++++++++++++++++++++- 3 files changed, 82 insertions(+), 84
> deletions(-)
>
> diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c
> b/drivers/net/wireless/rt2x00/rt2800lib.c index 445d681..562dc1d 100644
> --- a/drivers/net/wireless/rt2x00/rt2800lib.c
> +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
> @@ -601,49 +601,6 @@ void rt2800_process_rxwi(struct queue_entry *entry,
> }
> EXPORT_SYMBOL_GPL(rt2800_process_rxwi);
>
> -static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg)
> -{
> - __le32 *txwi;
> - u32 word;
> - int wcid, ack, pid;
> - int tx_wcid, tx_ack, tx_pid;
> -
> - wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
> - ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
> - pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
> -
> - /*
> - * This frames has returned with an IO error,
> - * so the status report is not intended for this
> - * frame.
> - */
> - if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) {
> - rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
> - return false;
> - }
> -
> - /*
> - * Validate if this TX status report is intended for
> - * this entry by comparing the WCID/ACK/PID fields.
> - */
> - txwi = rt2800_drv_get_txwi(entry);
> -
> - rt2x00_desc_read(txwi, 1, &word);
> - tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
> - tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK);
> - tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID);
> -
> - if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) {
> - WARNING(entry->queue->rt2x00dev,
> - "TX status report missed for queue %d entry %d\n",
> - entry->queue->qid, entry->entry_idx);
> - rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN);
> - return false;
> - }
> -
> - return true;
> -}
> -
> void rt2800_txdone_entry(struct queue_entry *entry, u32 status)
> {
> struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
> @@ -726,45 +683,6 @@ void rt2800_txdone_entry(struct queue_entry *entry,
> u32 status) }
> EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
>
> -void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
> -{
> - struct data_queue *queue;
> - struct queue_entry *entry;
> - u32 reg;
> - u8 qid;
> -
> - while (kfifo_get(&rt2x00dev->txstatus_fifo, &reg)) {
> -
> - /* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus
> - * qid is guaranteed to be one of the TX QIDs
> - */
> - qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE);
> - queue = rt2x00queue_get_tx_queue(rt2x00dev, qid);
> - if (unlikely(!queue)) {
> - WARNING(rt2x00dev, "Got TX status for an unavailable "
> - "queue %u, dropping\n", qid);
> - continue;
> - }
> -
> - /*
> - * Inside each queue, we process each entry in a chronological
> - * order. We first check that the queue is not empty.
> - */
> - entry = NULL;
> - while (!rt2x00queue_empty(queue)) {
> - entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
> - if (rt2800_txdone_entry_check(entry, reg))
> - break;
> - }
> -
> - if (!entry || rt2x00queue_empty(queue))
> - break;
> -
> - rt2800_txdone_entry(entry, reg);
> - }
> -}
> -EXPORT_SYMBOL_GPL(rt2800_txdone);
> -
> void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc
> *txdesc) {
> struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
> diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h
> b/drivers/net/wireless/rt2x00/rt2800lib.h index f2d1594..69deb31 100644
> --- a/drivers/net/wireless/rt2x00/rt2800lib.h
> +++ b/drivers/net/wireless/rt2x00/rt2800lib.h
> @@ -152,7 +152,6 @@ void rt2800_write_tx_data(struct queue_entry *entry,
> struct txentry_desc *txdesc);
> void rt2800_process_rxwi(struct queue_entry *entry, struct
> rxdone_entry_desc *txdesc);
>
> -void rt2800_txdone(struct rt2x00_dev *rt2x00dev);
> void rt2800_txdone_entry(struct queue_entry *entry, u32 status);
>
> void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc
> *txdesc); diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c
> b/drivers/net/wireless/rt2x00/rt2800usb.c index ba82c97..6e92298 100644
> --- a/drivers/net/wireless/rt2x00/rt2800usb.c
> +++ b/drivers/net/wireless/rt2x00/rt2800usb.c
> @@ -457,6 +457,87 @@ static int rt2800usb_get_tx_data_len(struct
> queue_entry *entry) /*
> * TX control handlers
> */
> +static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32
> reg) +{
> + __le32 *txwi;
> + u32 word;
> + int wcid, ack, pid;
> + int tx_wcid, tx_ack, tx_pid;
> +
> + wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
> + ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
> + pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
> +
> + /*
> + * This frames has returned with an IO error,
> + * so the status report is not intended for this
> + * frame.
> + */
> + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) {
> + rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
> + return false;
> + }
> +
> + /*
> + * Validate if this TX status report is intended for
> + * this entry by comparing the WCID/ACK/PID fields.
> + */
> + txwi = rt2800usb_get_txwi(entry);
> +
> + rt2x00_desc_read(txwi, 1, &word);
> + tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
> + tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK);
> + tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID);
> +
> + if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) {
> + WARNING(entry->queue->rt2x00dev,
> + "TX status report missed for queue %d entry %d\n",
> + entry->queue->qid, entry->entry_idx);
> + rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN);
> + return false;
> + }
> +
> + return true;
> +}
> +
> +static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev)
> +{
> + struct data_queue *queue;
> + struct queue_entry *entry;
> + u32 reg;
> + u8 qid;
> +
> + while (kfifo_get(&rt2x00dev->txstatus_fifo, &reg)) {
> +
> + /* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus
> + * qid is guaranteed to be one of the TX QIDs
> + */
> + qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE);
> + queue = rt2x00queue_get_tx_queue(rt2x00dev, qid);
> + if (unlikely(!queue)) {
> + WARNING(rt2x00dev, "Got TX status for an unavailable "
> + "queue %u, dropping\n", qid);
> + continue;
> + }
> +
> + /*
> + * Inside each queue, we process each entry in a chronological
> + * order. We first check that the queue is not empty.
> + */
> + entry = NULL;
> + while (!rt2x00queue_empty(queue)) {
> + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
> + if (rt2800usb_txdone_entry_check(entry, reg))
> + break;
> + }
> +
> + if (!entry || rt2x00queue_empty(queue))
> + break;
> +
> + rt2800_txdone_entry(entry, reg);
> + }
> +}
> +
> static void rt2800usb_work_txdone(struct work_struct *work)
> {
> struct rt2x00_dev *rt2x00dev =
> @@ -464,7 +545,7 @@ static void rt2800usb_work_txdone(struct work_struct
> *work) struct data_queue *queue;
> struct queue_entry *entry;
>
> - rt2800_txdone(rt2x00dev);
> + rt2800usb_txdone(rt2x00dev);
>
> /*
> * Process any trailing TX status reports for IO failures,


2011-05-18 20:53:20

by Gertjan van Wingerde

[permalink] [raw]
Subject: Re: [rt2x00-users] [PATCH 5/7] rt2x00: Move rt2800_txdone andrt2800_txdone_entry_check to rt2800usb.

On 05/18/11 22:38, Marc Dietrich wrote:
>
> Hi,
>
> I tested the patches and got this during boot on a rt3070 chip:
>
> [ 14.173458] ------------[ cut here ]------------
> [ 14.173482] WARNING: at /home/marc/ac100/marvin24s-kernel/kernel/softirq.c:159 local_bh_enable_ip+0x4c/0xcc()
> [ 14.173490] Modules linked in: binfmt_misc snd_soc_tegra_paz00 snd_soc_alc5632 snd_soc_tegra_i2s snd_soc_tegra_pcm
> snd_soc_tegra_das rt2800usb snd_soc_core snd_pcm_oss rt2800lib rt2x00usb snd_mixer_oss rt2x00lib snd_pcm mac80211
> snd_seq_midi snd_rawmidi snd_seq_midi_event snd_seq cfg80211 snd_timer snd_seq_device uvcvideo rfkill cdc_acm snd
> cdc_wdm videodev snd_soc_tegra_utils soundcore snd_page_alloc g_cdc btrfs
> [ 14.173567] Backtrace:
> [ 14.173607] [<c0043708>] (unwind_backtrace+0x0/0xe0) from [<c00753f8>] (warn_slowpath_common+0x4c/0x64)
> [ 14.173628] [<c00753f8>] (warn_slowpath_common+0x4c/0x64) from [<c0075428>] (warn_slowpath_null+0x18/0x1c)
> [ 14.173646] [<c0075428>] (warn_slowpath_null+0x18/0x1c) from [<c007bc80>] (local_bh_enable_ip+0x4c/0xcc)
> [ 14.173676] [<c007bc80>] (local_bh_enable_ip+0x4c/0xcc) from [<bf40b9b4>] (rt2x00usb_interrupt_rxdone+0x30/0x70
> [rt2x00usb])
> [ 14.173723] [<bf40b9b4>] (rt2x00usb_interrupt_rxdone+0x30/0x70 [rt2x00usb]) from [<c02d9150>]
> (usb_hcd_giveback_urb+0x74/0xbc)
> [ 14.173752] [<c02d9150>] (usb_hcd_giveback_urb+0x74/0xbc) from [<c02e75f8>] (ehci_urb_done+0x90/0x9c)
> [ 14.173775] [<c02e75f8>] (ehci_urb_done+0x90/0x9c) from [<c02eb284>] (qh_completions+0xb4/0x3ec)
> [ 14.173795] [<c02eb284>] (qh_completions+0xb4/0x3ec) from [<c02ec4b8>] (ehci_work+0xb4/0x97c)
> [ 14.173814] [<c02ec4b8>] (ehci_work+0xb4/0x97c) from [<c02ed3d0>] (ehci_irq+0x21c/0x24c)
> [ 14.173830] [<c02ed3d0>] (ehci_irq+0x21c/0x24c) from [<c02d8b34>] (usb_hcd_irq+0x34/0x6c)
> [ 14.173865] [<c02d8b34>] (usb_hcd_irq+0x34/0x6c) from [<c00bb840>] (handle_IRQ_event+0x9c/0x1b4)
> [ 14.173884] [<c00bb840>] (handle_IRQ_event+0x9c/0x1b4) from [<c00bd4fc>] (handle_level_irq+0xd0/0x154)
> [ 14.173910] [<c00bd4fc>] (handle_level_irq+0xd0/0x154) from [<c0037080>] (asm_do_IRQ+0x80/0xb4)
> [ 14.173943] [<c0037080>] (asm_do_IRQ+0x80/0xb4) from [<c040d84c>] (__irq_svc+0x4c/0xe0)
> [ 14.173954] Exception stack(0xdb84be10 to 0xdb84be58)
> [ 14.173964] be00: db929800 db28dc60 00000000 dcc00000
> [ 14.173979] be20: db28dc60 dcd20000 00000000 00000010 db929800 00000008 00000010 db28dc98
> [ 14.173991] be40: 00000000 db84be58 c026c86c c026ef58 60000013 ffffffff
> [ 14.174027] [<c040d84c>] (__irq_svc+0x4c/0xe0) from [<c026ef58>] (cfb_imageblit+0x54/0x43c)
> [ 14.174047] [<c026ef58>] (cfb_imageblit+0x54/0x43c) from [<c026c86c>] (soft_cursor+0x1a0/0x1a8)
> [ 14.174065] [<c026c86c>] (soft_cursor+0x1a0/0x1a8) from [<c026c254>] (bit_cursor+0x41c/0x42c)
> [ 14.174083] [<c026c254>] (bit_cursor+0x41c/0x42c) from [<c0266d08>] (fb_flashcursor+0xfc/0x118)
> [ 14.174114] [<c0266d08>] (fb_flashcursor+0xfc/0x118) from [<c008c9a0>] (process_one_work+0x274/0x43c)
> [ 14.174136] [<c008c9a0>] (process_one_work+0x274/0x43c) from [<c008e698>] (worker_thread+0x1b8/0x2b4)
> [ 14.174159] [<c008e698>] (worker_thread+0x1b8/0x2b4) from [<c0091d5c>] (kthread+0x7c/0x84)
> [ 14.174190] [<c0091d5c>] (kthread+0x7c/0x84) from [<c003d470>] (kernel_thread_exit+0x0/0x8)
> [ 14.174202] ---[ end trace 7b2804cb6c2b13fe ]---
>
> Of course, this didn't happen before.
>

Hmm, OK. This is not caused by the patch you responded to, but it is indeed introduced by an other patch.
I have no idea how this has escaped my testing, as I did test the patches on USB devices as well, but there
seems to be exactly 1 instance in which the queue index spin lock is still used in IRQ context, which escaped
my attention.
So, patch 6 of the series should not be applied right now.

---
Gertjan