netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PANIC] lro + iscsi or lro + skb text search causes panic
@ 2009-01-22 20:55 Brandeburg, Jesse
  2009-01-22 22:49 ` Mike Christie
  2009-01-22 23:21 ` Herbert Xu
  0 siblings, 2 replies; 19+ messages in thread
From: Brandeburg, Jesse @ 2009-01-22 20:55 UTC (permalink / raw)
  To: netdev; +Cc: olaf.kirch, tgraf, jesse.brandeburg, kkeil, michaelc, herbert

I've filed this bugzilla a while ago.
http://bugzilla.kernel.org/show_bug.cgi?id=11804
now other customers are becoming interested as well

what happens is that when a device driver (inet_lro) hands an skb that has 
possibly multiple skb->data pointers, chained together with skb->next and 
each one possibly having pages attached, skb_seq_read called by iSCSI 
doesn't follow the chain as it should.  result is a panic.

to reproduce you just get lro enabled igb or ixgbe and try to connect to 
an iSCSI target.

BUG: unable to handle kernel NULL pointer dereference at 000005a8
IP: [<f8de64b2>] :iscsi_tcp:iscsi_tcp_recv+0x161/0x473
*pdpt = 0000000036533001 *pde = 0000000000000000
Oops: 0000 [#1] SMP
Modules linked in: crc32c libcrc32c iscsi_tcp libiscsi 
scsi_transport_iscsi
ixgbe netconsole inet_lro ipv6 af_packet button battery ac loop usbhid
ff_memless ehci_hcd uhci_hcd usbcore dm_mod bnx2 ext3 jbd edd fan thermal
processor thermal_sys sg megaraid_sas ata_piix libata dock piix sd_mod 
scsi_mod
ide_disk ide_core [last unloaded: iscsi_tcp]

Pid: 0, comm: swapper Not tainted (2.6.26-bigsmp #1)
EIP: 0060:[<f8de64b2>] EFLAGS: 00010202 CPU: 3
EIP is at iscsi_tcp_recv+0x161/0x473 [iscsi_tcp]
EAX: 0000002b EBX: f747dd48 ECX: 00000038 EDX: 00000000
ESI: 000005a8 EDI: f593db20 EBP: f751ca10 ESP: f747dd20
 DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068
Process swapper (pid: 0, ti=f747c000 task=f745abe0 task.ti=f747c000)
Stack: f8de78e7 000000e0 f446c0c0 f6c35544 f751ca00 000005a8 00000000 
000000e0
       000005a8 08745958 00000000 00000a88 00000000 000005a8 f446c0c0 
f78ba0ac
       00000000 c0289617 00000000 00000000 05a80001 00007fff f78ba040 
000005a8
Call Trace:
 [<c0289617>] tcp_ack+0x15bd/0x1757
 [<c028391e>] tcp_read_sock+0x8c/0x1e0
 [<f8de6351>] iscsi_tcp_recv+0x0/0x473 [iscsi_tcp]
 [<f8de716a>] iscsi_tcp_data_ready+0x36/0x80 [iscsi_tcp]
 [<c028d1a2>] tcp_send_ack+0xab/0xaf
 [<c028c02e>] tcp_rcv_established+0x3b3/0x639
 [<c02909fb>] tcp_v4_do_rcv+0x22/0x16f
 [<c0292294>] tcp_v4_rcv+0x512/0x562
 [<c027b921>] ip_local_deliver_finish+0xb2/0x14a
 [<c027b852>] ip_rcv_finish+0x286/0x2a3
 [<f8ce9a93>] packet_rcv_spkt+0xb6/0xbd [af_packet]
 [<c0261889>] netif_receive_skb+0x2d0/0x33b
 [<f8afd5ca>] lro_flush+0x314/0x340 [inet_lro]
 [<f8afd636>] lro_flush_all+0x1b/0x28 [inet_lro]
 [<f8b410eb>] ixgbe_clean_rx_irq+0x73b/0x850 [ixgbe]
 [<f8b44183>] ixgbe_clean_rxonly+0x53/0xd0 [ixgbe]
 [<c0263521>] net_rx_action+0x8a/0x152
 [<c0124c6e>] __do_softirq+0x5d/0xc1
 [<c0124d04>] do_softirq+0x32/0x36
 [<c010663a>] do_IRQ+0x73/0x85
 [<c0109152>] mwait_idle+0x0/0x32
 [<c0105143>] common_interrupt+0x23/0x28
 [<c0109152>] mwait_idle+0x0/0x32
 [<c0109181>] mwait_idle+0x2f/0x32
 [<c0103535>] cpu_idle+0x88/0x9c
 =======================
Code: 24 14 0f 46 44 24 14 89 44 24 14 50 68 e7 78 de f8 e8 2e b3 33 c7 8b 
7d
08 03 7d 00 8b 4c 24 1c 8b 74 24 20 03 74 24 18 c1 e9 02 <f3> a5 8b 4c 24 
1c 83
e1 03 74 02 f3 a4 8b 4c 24 1c 01 4c 24 18
EIP: [<f8de64b2>] iscsi_tcp_recv+0x161/0x473 [iscsi_tcp] SS:ESP 
0068:f747dd20
Kernel panic - not syncing: Fatal exception in interrupt



skb_copy_bits is an example of the code flow that does work.

skb_seq_read appears to only be used by iSCSI and the skb text match 
support in tc/netfilter (aka skb_find_text)

skb_seq_read is so complex that it is not a simple job just to re-write it 
with a state machine switch statement, and I am unable to spend the time 
on it to fix it.  Can someone help?

I am also a little bit concerned that the recent effort to make GRO frames 
become more utilized in the stack may end up causing this issue to trigger 
as well.

We have test resources that can test patches with iSCSI.

^ permalink raw reply	[flat|nested] 19+ messages in thread
* RE: [PANIC] lro + iscsi or lro + skb text search causes panic
@ 2009-01-28 12:36 Shyam_Iyer
  2009-01-28 18:22 ` Mike Christie
  0 siblings, 1 reply; 19+ messages in thread
From: Shyam_Iyer @ 2009-01-28 12:36 UTC (permalink / raw)
  To: michaelc, herbert
  Cc: davem, jesse.brandeburg, netdev, olaf.kirch, tgraf, kkeil

[-- Attachment #1: Type: text/plain, Size: 3614 bytes --]



Mike Christie wrote:
> Herbert Xu wrote:
>> On Sun, Jan 25, 2009 at 09:32:22PM -0800, David Miller wrote:
>>> From: Mike Christie <michaelc@cs.wisc.edu>
>>> Date: Thu, 22 Jan 2009 18:04:11 -0600
>>>
>>>> With the patch running against linus's git tree, my box locks up. 
>>>> You cannot ping it. I do not get a oops or anything in the logs,
and 
>>>> the keyboard does not respond. I will try to get some oops output 
>>>> and more info.
>>> Herbert, any idea offhand?
>> 
>> Yeah, I missed an offset update in there :) Here's a better version.
>> 
>> net: Fix frag_list handling in skb_seq_read
>> 
>> The frag_list handling was broken in skb_seq_read:
>> 
>> 1) We didn't add the stepped offset when looking at the head are of 
>> fragments other than the first.
>> 
>> 2) We didn't take the stepped offset away when setting the data 
>> pointer in the head area.
>> 
>> 3) The frag index wasn't reset.
>> 
>> This patch fixes both issues.
>> 

>It oopsd for me in skb_seq_read. addr2line said it was
linux-2.6/net/core/skbuff.c:2228, which is this line:


>while (st->frag_idx < skb_shinfo(st->cur_skb)->nr_frags) {


>I added some printks in there and it looks like we hit this:

>         } else if (st->root_skb == st->cur_skb &&
>                   skb_shinfo(st->root_skb)->frag_list) {
>                 st->cur_skb = skb_shinfo(st->root_skb)->frag_list;
>                 st->frag_idx = 0;
>                 goto next_skb;
>        }



Actually I did some testing and added a few printks and found that the
st->cur_skb->data was 0 and hence the ptr used by iscsi_tcp was null.
This caused the kernel panic.

 	if (abs_offset < block_limit) {
-		*data = st->cur_skb->data + abs_offset;
+		*data = st->cur_skb->data + (abs_offset -
st->stepped_offset);

 I enabled the debug_tcp and with a few printks found that the code in
my scenario did not go to the next_skb label as described by Mike and
could find that the sequence being followed was this -

It hit this if condition -
 if (st->cur_skb->next) {
                st->cur_skb = st->cur_skb->next;
                st->frag_idx = 0;
                goto next_skb;

And so, now the st pointer is shifted to the next skb whereas actually
it should have hit the second else if first since the data is in the
frag_list.

else if (st->root_skb == st->cur_skb &&
                   skb_shinfo(st->root_skb)->frag_list) {
                st->cur_skb = skb_shinfo(st->root_skb)->frag_list;
                goto next_skb;
        }


Reversing the two conditions the attached patch fixes the issue for me
on top of Herbert's patches.  I have done the testing on the ixgbe
adapter itself and verified the fix using some amount of data transfer
as well.

Signed-off-by: Shyam Iyer <shyam_iyer@dell.com>

--- skbuff.c.orig	2009-01-29 01:12:03.000000000 +0530
+++ skbuff.c	2009-01-29 01:34:57.000000000 +0530
@@ -2039,15 +2039,15 @@
 		st->frag_data = NULL;
 	}
 
-	if (st->cur_skb->next) {
-		st->cur_skb = st->cur_skb->next;
-		st->frag_idx = 0;
-		goto next_skb;
-	} else if (st->root_skb == st->cur_skb &&
+	if (st->root_skb == st->cur_skb &&
 		   skb_shinfo(st->root_skb)->frag_list) {
 		st->cur_skb = skb_shinfo(st->root_skb)->frag_list;
 		st->frag_idx=0;
 		goto next_skb;
+	} else if (st->cur_skb->next) {
+		st->cur_skb = st->cur_skb->next;
+		st->frag_idx = 0;
+		goto next_skb;
 	}
 
 	return 0;


 
P.S: Currently sending through an email client that can't do proper
patch formatting so please excuse the patch in an attachement.


[-- Attachment #2: skbuff_patch --]
[-- Type: application/octet-stream, Size: 604 bytes --]

--- skbuff.c.orig	2009-01-29 01:12:03.000000000 +0530
+++ skbuff.c	2009-01-29 01:34:57.000000000 +0530
@@ -2039,15 +2039,15 @@
 		st->frag_data = NULL;
 	}
 
-	if (st->cur_skb->next) {
-		st->cur_skb = st->cur_skb->next;
-		st->frag_idx = 0;
-		goto next_skb;
-	} else if (st->root_skb == st->cur_skb &&
+	if (st->root_skb == st->cur_skb &&
 		   skb_shinfo(st->root_skb)->frag_list) {
 		st->cur_skb = skb_shinfo(st->root_skb)->frag_list;
 		st->frag_idx=0;
 		goto next_skb;
+	} else if (st->cur_skb->next) {
+		st->cur_skb = st->cur_skb->next;
+		st->frag_idx = 0;
+		goto next_skb;
 	}
 
 	return 0;

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2009-01-30  0:13 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-01-22 20:55 [PANIC] lro + iscsi or lro + skb text search causes panic Brandeburg, Jesse
2009-01-22 22:49 ` Mike Christie
2009-01-23  4:22   ` Mike Christie
2009-01-23  4:29     ` Mike Christie
2009-01-26  5:34     ` David Miller
2009-01-22 23:21 ` Herbert Xu
2009-01-22 23:45   ` Brandeburg, Jesse
2009-01-23  0:04   ` Mike Christie
2009-01-26  5:32     ` David Miller
2009-01-26 22:30       ` Herbert Xu
2009-01-27  1:40         ` Brandeburg, Jesse
2009-01-27  3:01           ` Herbert Xu
2009-01-27  5:52         ` David Miller
2009-01-27  6:12         ` Mike Christie
     [not found]           ` <46A00B48CC54E4468EF6911F877AC4CA01EF2BC9@blrx3m10.blr.amer.dell.com>
2009-01-28 21:25             ` Herbert Xu
2009-01-30  0:13               ` David Miller
2009-01-26 20:54     ` Mike Christie
  -- strict thread matches above, loose matches on Subject: below --
2009-01-28 12:36 Shyam_Iyer
2009-01-28 18:22 ` Mike Christie

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).