public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [bug] block subsystem related crash with latest -git
@ 2007-10-17 15:46 Ingo Molnar
  2007-10-17 15:50 ` Ingo Molnar
  2007-10-17 16:50 ` Linus Torvalds
  0 siblings, 2 replies; 151+ messages in thread
From: Ingo Molnar @ 2007-10-17 15:46 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-kernel, Andrew Morton, Linus Torvalds

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


Jens, just got this crash on a testbox:

[   37.701628] warning: process `kmodule' used the removed sysctl system call with 1.23.
[   39.409390] BUG: unable to handle kernel paging request at virtual address 7ca76000
[   39.416892] printing eip: 78406669 *pde = 00dda027 *pte = 04a76000 
[   39.423132] Oops: 0000 [#1] DEBUG_PAGEALLOC
[   39.427292] 
[   39.428766] Pid: 431, comm: fsck.ext3 Not tainted (2.6.23 #45)
[   39.434571] EIP: 0060:[<78406669>] EFLAGS: 00010006 CPU: 0
[   39.440035] EIP is at blk_rq_map_sg+0xb9/0x170
[   39.444450] EAX: 04aed000 EBX: 7ca1f380 ECX: 04aee000 EDX: 00095da0
[   39.450689] ESI: 7ca75ff0 EDI: 79180da0 EBP: 00001000 ESP: 7caa1cac
[   39.456929]  DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 0068
[   39.462303] Process fsck.ext3 (pid: 431, ti=7caa0000 task=7ca80000 task.ti=7caa0000)
[   39.469841] Stack: 00000020 7b520000 00002000 04aef000 7ca75fe0 0000001f 00000001 00000000 
[   39.478161]        7ca1f300 01000002 7ca44980 7b522b94 7ca0de00 7b520000 784c89b5 7b520000 
[   39.486480]        784c843a 7ca0de00 7b520f20 7b522b94 7ca0de00 784e54a0 784f394b 00000000 
[   39.494799] Call Trace:
[   39.497400]  [<784c89b5>] scsi_init_io+0x55/0xe0
[   39.501992]  [<784c843a>] scsi_get_cmd_from_req+0x2a/0x40
[   39.507366]  [<784e54a0>] sd_prep_fn+0x80/0x940
[   39.511872]  [<784f394b>] ata_bmdma_start+0xb/0x20
[   39.516638]  [<784ef344>] ata_qc_issue_prot+0x164/0x1e0
[   39.521839]  [<78405c63>] elv_dispatch_sort+0x23/0xe0
[   39.526865]  [<784057d0>] elv_next_request+0xa0/0x130
[   39.531891]  [<787715b8>] _spin_lock_irq+0x38/0x50
[   39.536657]  [<784c9af4>] scsi_request_fn+0x1e4/0x370
[   39.541684]  [<78120e72>] del_timer+0x62/0x70
[   39.546016]  [<78408a45>] __generic_unplug_device+0x25/0x30
[   39.551563]  [<78408d15>] generic_unplug_device+0x15/0x30
[   39.556936]  [<78406430>] blk_backing_dev_unplug+0x0/0x10
[   39.562309]  [<7840643c>] blk_backing_dev_unplug+0xc/0x10
[   39.567682]  [<7818080d>] block_sync_page+0x2d/0x40
[   39.572535]  [<78144ee9>] sync_page+0x29/0x40
[   39.576868]  [<7876fdec>] __wait_on_bit_lock+0x3c/0x70
[   39.581981]  [<78144ec0>] sync_page+0x0/0x40
[   39.586227]  [<78144ea2>] __lock_page+0x52/0x60
[   39.590734]  [<7812ae90>] wake_bit_function+0x0/0x60
[   39.595674]  [<7814566c>] do_generic_mapping_read+0x21c/0x450
[   39.601393]  [<78144c30>] file_read_actor+0x0/0x130
[   39.606246]  [<78147227>] generic_file_aio_read+0x137/0x180
[   39.611793]  [<78144c30>] file_read_actor+0x0/0x130
[   39.616645]  [<78160d95>] do_sync_read+0xd5/0x120
[   39.621326]  [<78135cd8>] mark_held_locks+0x38/0x70
[   39.626179]  [<7812ae50>] autoremove_wake_function+0x0/0x40
[   39.631724]  [<787705b4>] mutex_lock_nested+0x1a4/0x200
[   39.636924]  [<78185611>] block_llseek+0x31/0xc0
[   39.641517]  [<787703a5>] __mutex_unlock_slowpath+0xb5/0x110
[   39.647150]  [<78135e1c>] trace_hardirqs_on+0x9c/0xb0
[   39.652177]  [<78160cc0>] do_sync_read+0x0/0x120
[   39.656770]  [<7816165b>] vfs_read+0xbb/0x120
[   39.661103]  [<78161a41>] sys_read+0x41/0x70
[   39.665349]  [<781028a2>] syscall_call+0x7/0xb
[   39.669769]  =======================
[   39.673322] Code: 05 c1 e1 0c 03 4a 08 8b 52 04 01 ca 89 54 24 0c 8b 3b 89 fa 29 c2 89 d0 c1 f8 05 c1 e0 0c 03 43 08 39 44 24 0c 0f 84 7e 00 00 00 <8b> 46 10 8d 56 10 a8 01 75 4c 89 3e 89 6e 0c 8b 43 08 89 46 04 

config and full bootlog attached.

i tried another bootup with the same kernel and the crash did not 
reoccur, so it seems to be spurious. This crash could be related to the 
scsi or block merges done in the past few days - never saw this before.

	Ingo

[-- Attachment #2: crash.log --]
[-- Type: text/plain, Size: 155929 bytes --]

[    0.000000] Linux version 2.6.23 (mingo@dione) (gcc version 4.2.2) #45 Wed Oct 17 17:24:44 CEST 2007
[    0.000000] BIOS-provided physical RAM map:
[    0.000000]  BIOS-e820: 0000000000000000 - 000000000009f800 (usable)
[    0.000000]  BIOS-e820: 000000000009f800 - 00000000000a0000 (reserved)
[    0.000000]  BIOS-e820: 00000000000f0000 - 0000000000100000 (reserved)
[    0.000000]  BIOS-e820: 0000000000100000 - 000000003fff0000 (usable)
[    0.000000]  BIOS-e820: 000000003fff0000 - 000000003fff3000 (ACPI NVS)
[    0.000000]  BIOS-e820: 000000003fff3000 - 0000000040000000 (ACPI data)
[    0.000000]  BIOS-e820: 00000000e0000000 - 00000000f0000000 (reserved)
[    0.000000]  BIOS-e820: 00000000fec00000 - 0000000100000000 (reserved)
[    0.000000] console [earlyser0] enabled
[    0.000000] using polling idle threads.
[    0.000000] using polling idle threads.
[    0.000000] ignoring highmem size on non-highmem kernel!
[    0.000000] 1023MB LOWMEM available.
[    0.000000] found SMP MP-table at 000f5680
[    0.000000] Entering add_active_range(0, 0, 262128) 0 entries of 256 used
[    0.000000] Zone PFN ranges:
[    0.000000]   DMA             0 ->     4096
[    0.000000]   Normal       4096 ->   262128
[    0.000000] Movable zone start PFN for each node
[    0.000000] early_node_map[1] active PFN ranges
[    0.000000]     0:        0 ->   262128
[    0.000000] On node 0 totalpages: 262128
[    0.000000]   DMA zone: 32 pages used for memmap
[    0.000000]   DMA zone: 0 pages reserved
[    0.000000]   DMA zone: 4064 pages, LIFO batch:0
[    0.000000]   Normal zone: 2015 pages used for memmap
[    0.000000]   Normal zone: 256017 pages, LIFO batch:31
[    0.000000]   Movable zone: 0 pages used for memmap
[    0.000000] DMI 2.3 present.
[    0.000000] Intel MultiProcessor Specification v1.4
[    0.000000]     Virtual Wire compatibility mode.
[    0.000000] OEM ID: OEM00000 Product ID: PROD00000000 APIC at: 0xFEE00000
[    0.000000] Processor #0 15:3 APIC version 17
[    0.000000] Processor #1 15:3 APIC version 17
[    0.000000] WARNING: NR_CPUS limit of 1 reached.  Processor ignored.
[    0.000000] I/O APIC #2 Version 17 at 0xFEC00000.
[    0.000000] Enabling APIC mode:  Flat.  Using 1 I/O APICs
[    0.000000] Processors: 1
[    0.000000] Allocating PCI resources starting at 50000000 (gap: 40000000:a0000000)
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 260081
[    0.000000] Kernel command line: root=/dev/sda1 console=tty 3 debug profile=0 initcall_debug selinux=0 enforcing=0 apic=verbose ignore_loglevel sysrq_always_enabled earlyprintk=serial,ttyS0,115200,keep idle=poll maxcpus=1 nosmp highres=0 lapic hpet=disable idle=poll highmem=512m
[    0.000000] kernel profiling enabled (shift: 0)
[    0.000000] debug: ignoring loglevel setting.
[    0.000000] debug: sysrq always enabled.
[    0.000000] mapped APIC to ffffb000 (fee00000)
[    0.000000] mapped IOAPIC to ffffa000 (fec00000)
[    0.000000] Enabling fast FPU save and restore... done.
[    0.000000] Enabling unmasked SIMD FPU exception support... done.
[    0.000000] Initializing CPU#0
[    0.000000] PID hash table entries: 4096 (order: 12, 16384 bytes)
[    0.000000] Detected 2160.216 MHz processor.
[   13.512953] spurious 8259A interrupt: IRQ7.
[   13.517829] Console: colour VGA+ 80x25
[   13.521401] console [tty0] enabled
[   13.821423] Lock dependency validator: Copyright (c) 2006 Red Hat, Inc., Ingo Molnar
[   13.829133] ... MAX_LOCKDEP_SUBCLASSES:    8
[   13.833380] ... MAX_LOCK_DEPTH:          30
[   13.837540] ... MAX_LOCKDEP_KEYS:        2048
[   13.841872] ... CLASSHASH_SIZE:           1024
[   13.846293] ... MAX_LOCKDEP_ENTRIES:     8192
[   13.850626] ... MAX_LOCKDEP_CHAINS:      16384
[   13.855046] ... CHAINHASH_SIZE:          8192
[   13.859379]  memory used by lock dependency info: 992 kB
[   13.864665]  per task-struct memory footprint: 1200 bytes
[   13.870323] Dentry cache hash table entries: 131072 (order: 7, 524288 bytes)
[   13.877560] Inode-cache hash table entries: 65536 (order: 6, 262144 bytes)
[   13.917852] Memory: 998396k/1048512k available (6601k kernel code, 49616k reserved, 2681k data, 372k init, 0k highmem)
[   13.928434] virtual kernel memory layout:
[   13.928435]     fixmap  : 0xfffb9000 - 0xfffff000   ( 280 kB)
[   13.928436]     vmalloc : 0xb8800000 - 0xfffb7000   (1143 MB)
[   13.928437]     lowmem  : 0x78000000 - 0xb7ff0000   (1023 MB)
[   13.928438]       .init : 0x78a14000 - 0x78a71000   ( 372 kB)
[   13.928439]       .data : 0x78772582 - 0x78a10a34   (2681 kB)
[   13.928440]       .text : 0x78100000 - 0x78772582   (6601 kB)
[   13.966734] Checking if this processor honours the WP bit even in supervisor mode... Ok.
[   14.058153] Calibrating delay using timer specific routine.. 4324.74 BogoMIPS (lpj=7204389)
[   14.066419] Security Framework v1.0.0 initialized
[   14.071033] Capability LSM initialized
[   14.074764] Mount-cache hash table entries: 512
[   14.079636] CPU: After generic identify, caps: 178bfbff e3d3fbff 00000000 00000000 00000001 00000000 00000003 00000000
[   14.090167] CPU: L1 I Cache: 64K (64 bytes/line), D cache 64K (64 bytes/line)
[   14.097279] CPU: L2 Cache: 512K (64 bytes/line)
[   14.101785] CPU: After all inits, caps: 178bfbf7 e3d3fbff 00000000 00000410 00000001 00000000 00000003 00000000
[   14.111835] Compat vDSO mapped to ffffe000.
[   14.115999] CPU: AMD Athlon(tm) 64 X2 Dual Core Processor 3800+ stepping 02
[   14.122925] Checking 'hlt' instruction... OK.
[   14.139083] Freeing SMP alternatives: 0k freed
[   14.143523] enabled ExtINT on CPU#0
[   14.146939] ExtINT not setup in hardware but reported by MP table
[   14.153036] ENABLING IO-APIC IRQs
[   14.156242] init IO_APIC IRQs
[   14.159189]  IO-APIC (apicid-pin) 2-0 not connected.
[   14.164181]  IO-APIC (apicid-pin) 2-16, 2-17, 2-18, 2-19, 2-20, 2-21, 2-22, 2-23 not connected.
[   14.172921] ..TIMER: vector=0x31 apic1=0 pin1=2 apic2=0 pin2=0
[   14.211647] ..MP-BIOS bug: 8254 timer not connected to IO-APIC
[   14.217341] ...trying to set up timer (IRQ0) through the 8259A ... 
[   14.223407] ..... (found pin 0) ...works.
[   14.260473] number of MP IRQ sources: 17.
[   14.264463] number of IO-APIC #2 registers: 24.
[   14.268969] testing the IO APIC.......................
[   14.274084] IO APIC #2......
[   14.276942] .... register #00: 00000000
[   14.280755] .......    : physical APIC id: 00
[   14.285087] .......    : Delivery Type: 0
[   14.289074] .......    : LTS          : 0
[   14.293060] .... register #01: 00170011
[   14.296874] .......     : max redirection entries: 0017
[   14.302073] .......     : PRQ implemented: 0
[   14.306320] .......     : IO APIC version: 0011
[   14.310826] .... register #02: 00000000
[   14.314639] .......     : arbitration: 00
[   14.318626] .... IRQ redirection table:
[   14.322439]  NR Log Phy Mask Trig IRR Pol Stat Dest Deli Vect:   
[   14.328507]  00 001 01  0    0    0   0   0    1    1    31
[   14.334054]  01 001 01  0    0    0   0   0    1    1    39
[   14.339600]  02 000 00  1    0    0   0   0    0    0    00
[   14.345146]  03 001 01  1    1    0   1   0    1    1    41
[   14.350692]  04 001 01  0    0    0   0   0    1    1    49
[   14.356239]  05 001 01  1    1    0   1   0    1    1    51
[   14.361785]  06 001 01  0    0    0   0   0    1    1    59
[   14.367331]  07 001 01  1    0    0   0   0    1    1    61
[   14.372878]  08 001 01  0    0    0   0   0    1    1    69
[   14.378424]  09 001 01  0    0    0   0   0    1    1    71
[   14.383971]  0a 001 01  0    0    0   0   0    1    1    79
[   14.389517]  0b 001 01  1    1    0   1   0    1    1    81
[   14.395062]  0c 001 01  0    0    0   0   0    1    1    89
[   14.400609]  0d 001 01  0    0    0   0   0    1    1    91
[   14.406155]  0e 001 01  0    0    0   0   0    1    1    99
[   14.411702]  0f 001 01  0    0    0   0   0    1    1    A1
[   14.417248]  10 000 00  1    0    0   0   0    0    0    00
[   14.422795]  11 000 00  1    0    0   0   0    0    0    00
[   14.428341]  12 000 00  1    0    0   0   0    0    0    00
[   14.433887]  13 000 00  1    0    0   0   0    0    0    00
[   14.439434]  14 000 00  1    0    0   0   0    0    0    00
[   14.444980]  15 000 00  1    0    0   0   0    0    0    00
[   14.450526]  16 000 00  1    0    0   0   0    0    0    00
[   14.456072]  17 000 00  1    0    0   0   0    0    0    00
[   14.461616] IRQ to pin mappings:
[   14.464823] IRQ0 -> 0:0
[   14.467246] IRQ1 -> 0:1
[   14.469672] IRQ3 -> 0:3
[   14.472099] IRQ4 -> 0:4
[   14.474526] IRQ5 -> 0:5
[   14.476952] IRQ6 -> 0:6
[   14.479378] IRQ7 -> 0:7
[   14.481805] IRQ8 -> 0:8
[   14.484231] IRQ9 -> 0:9
[   14.486658] IRQ10 -> 0:10
[   14.489258] IRQ11 -> 0:11
[   14.491858] IRQ12 -> 0:12
[   14.494457] IRQ13 -> 0:13
[   14.497057] IRQ14 -> 0:14
[   14.499657] IRQ15 -> 0:15
[   14.502257] .................................... done.
[   14.507375] Using local APIC timer interrupts.
[   14.507376] calibrating APIC timer ...
[   14.621409] ... lapic delta = 1350029
[   14.624935] ... PM timer delta = 0
[   14.628315] ..... delta 1350029
[   14.631435] ..... mult: 57987084
[   14.634640] ..... calibration result: 720015
[   14.638887] ..... CPU clock speed is 2160.0875 MHz.
[   14.643740] ..... host bus clock speed is 216.0087 MHz.
[   14.648939] ... verify APIC timer
[   14.758885] ... jiffies delta = 30
[   14.762157] ... jiffies result ok
[   14.765591] Calling initcall 0x78a4abe0: init_cpufreq_transition_notifier_list+0x0/0x10()
[   14.773604] initcall 0x78a4abe0: init_cpufreq_transition_notifier_list+0x0/0x10() returned 0.
[   14.782095] initcall 0x78a4abe0 ran for 0 msecs: init_cpufreq_transition_notifier_list+0x0/0x10()
[   14.790935] Calling initcall 0x78a4d1e0: net_ns_init+0x0/0x180()
[   14.796914] net_namespace: 64 bytes
[   14.800413] initcall 0x78a4d1e0: net_ns_init+0x0/0x180() returned 0.
[   14.806707] initcall 0x78a4d1e0 ran for 3 msecs: net_ns_init+0x0/0x180()
[   14.813381] Calling initcall 0x78a19b40: cpufreq_tsc+0x0/0x10()
[   14.819273] initcall 0x78a19b40: cpufreq_tsc+0x0/0x10() returned 0.
[   14.825514] initcall 0x78a19b40 ran for 0 msecs: cpufreq_tsc+0x0/0x10()
[   14.832620] Calling initcall 0x78a1d9c0: reboot_init+0x0/0x10()
[   14.838514] initcall 0x78a1d9c0: reboot_init+0x0/0x10() returned 0.
[   14.844751] initcall 0x78a1d9c0 ran for 0 msecs: reboot_init+0x0/0x10()
[   14.851337] Calling initcall 0x78a232f0: print_banner+0x0/0x10()
[   14.857317] Booting paravirtualized kernel on bare hardware
[   14.862865] initcall 0x78a232f0: print_banner+0x0/0x10() returned 0.
[   14.869191] initcall 0x78a232f0 ran for 3 msecs: print_banner+0x0/0x10()
[   14.875864] Calling initcall 0x78a24850: sysctl_init+0x0/0x10()
[   14.881760] initcall 0x78a24850: sysctl_init+0x0/0x10() returned 0.
[   14.887995] initcall 0x78a24850 ran for 0 msecs: sysctl_init+0x0/0x10()
[   14.894581] Calling initcall 0x78a254c0: init_jiffies_clocksource+0x0/0x10()
[   14.901606] initcall 0x78a254c0: init_jiffies_clocksource+0x0/0x10() returned 0.
[   14.908968] initcall 0x78a254c0 ran for 0 msecs: init_jiffies_clocksource+0x0/0x10()
[   14.916682] Calling initcall 0x78a25990: ksysfs_init+0x0/0x50()
[   14.922576] initcall 0x78a25990: ksysfs_init+0x0/0x50() returned 0.
[   14.928814] initcall 0x78a25990 ran for 0 msecs: ksysfs_init+0x0/0x50()
[   14.935399] Calling initcall 0x78a27a60: filelock_init+0x0/0x30()
[   14.941465] initcall 0x78a27a60: filelock_init+0x0/0x30() returned 0.
[   14.947878] initcall 0x78a27a60 ran for 0 msecs: filelock_init+0x0/0x30()
[   14.954637] Calling initcall 0x78a28440: init_misc_binfmt+0x0/0x40()
[   14.960971] initcall 0x78a28440: init_misc_binfmt+0x0/0x40() returned 0.
[   14.967637] initcall 0x78a28440 ran for 0 msecs: init_misc_binfmt+0x0/0x40()
[   14.974656] Calling initcall 0x78a28480: init_script_binfmt+0x0/0x10()
[   14.981156] initcall 0x78a28480: init_script_binfmt+0x0/0x10() returned 0.
[   14.988002] initcall 0x78a28480 ran for 0 msecs: init_script_binfmt+0x0/0x10()
[   14.995195] Calling initcall 0x78a28490: init_elf_binfmt+0x0/0x10()
[   15.001434] initcall 0x78a28490: init_elf_binfmt+0x0/0x10() returned 0.
[   15.008021] initcall 0x78a28490 ran for 0 msecs: init_elf_binfmt+0x0/0x10()
[   15.014953] Calling initcall 0x78a2a6f0: debugfs_init+0x0/0x40()
[   15.020937] initcall 0x78a2a6f0: debugfs_init+0x0/0x40() returned 0.
[   15.027259] initcall 0x78a2a6f0 ran for 0 msecs: debugfs_init+0x0/0x40()
[   15.033934] Calling initcall 0x78a2af40: securityfs_init+0x0/0x40()
[   15.040175] initcall 0x78a2af40: securityfs_init+0x0/0x40() returned 0.
[   15.046758] initcall 0x78a2af40 ran for 0 msecs: securityfs_init+0x0/0x40()
[   15.053693] Calling initcall 0x78a2b9a0: random32_init+0x0/0x20()
[   15.059758] initcall 0x78a2b9a0: random32_init+0x0/0x20() returned 0.
[   15.066171] initcall 0x78a2b9a0 ran for 0 msecs: random32_init+0x0/0x20()
[   15.072932] Calling initcall 0x78a4abf0: cpufreq_core_init+0x0/0x30()
[   15.079343] initcall 0x78a4abf0: cpufreq_core_init+0x0/0x30() returned 0.
[   15.086104] initcall 0x78a4abf0 ran for 0 msecs: cpufreq_core_init+0x0/0x30()
[   15.093210] Calling initcall 0x78a4d090: sock_init+0x0/0x60()
[   15.098962] initcall 0x78a4d090: sock_init+0x0/0x60() returned 0.
[   15.104995] initcall 0x78a4d090 ran for 0 msecs: sock_init+0x0/0x60()
[   15.111407] Calling initcall 0x78a4dbd0: netpoll_init+0x0/0x40()
[   15.117388] initcall 0x78a4dbd0: netpoll_init+0x0/0x40() returned 0.
[   15.123714] initcall 0x78a4dbd0 ran for 0 msecs: netpoll_init+0x0/0x40()
[   15.130388] Calling initcall 0x78a4e2e0: netlink_proto_init+0x0/0x140()
[   15.136997] NET: Registered protocol family 16
[   15.141411] initcall 0x78a4e2e0: netlink_proto_init+0x0/0x140() returned 0.
[   15.148325] initcall 0x78a4e2e0 ran for 3 msecs: netlink_proto_init+0x0/0x140()
[   15.155606] Calling initcall 0x78a2bac0: pcibus_class_init+0x0/0x10()
[   15.162032] initcall 0x78a2bac0: pcibus_class_init+0x0/0x10() returned 0.
[   15.168778] initcall 0x78a2bac0 ran for 0 msecs: pcibus_class_init+0x0/0x10()
[   15.175885] Calling initcall 0x78a2d020: pci_driver_init+0x0/0x10()
[   15.182145] initcall 0x78a2d020: pci_driver_init+0x0/0x10() returned 0.
[   15.188710] initcall 0x78a2d020 ran for 0 msecs: pci_driver_init+0x0/0x10()
[   15.195643] Calling initcall 0x78a2d160: lcd_class_init+0x0/0x50()
[   15.201804] initcall 0x78a2d160: lcd_class_init+0x0/0x50() returned 0.
[   15.208295] initcall 0x78a2d160 ran for 0 msecs: lcd_class_init+0x0/0x50()
[   15.215141] Calling initcall 0x78a2d1b0: backlight_class_init+0x0/0x50()
[   15.221822] initcall 0x78a2d1b0: backlight_class_init+0x0/0x50() returned 0.
[   15.228835] initcall 0x78a2d1b0 ran for 0 msecs: backlight_class_init+0x0/0x50()
[   15.236201] Calling initcall 0x78a2d370: tty_class_init+0x0/0x20()
[   15.242361] initcall 0x78a2d370: tty_class_init+0x0/0x20() returned 0.
[   15.248854] initcall 0x78a2d370 ran for 0 msecs: tty_class_init+0x0/0x20()
[   15.255700] Calling initcall 0x78a2ddb0: vtconsole_class_init+0x0/0xd0()
[   15.262397] initcall 0x78a2ddb0: vtconsole_class_init+0x0/0xd0() returned 0.
[   15.269393] initcall 0x78a2ddb0 ran for 0 msecs: vtconsole_class_init+0x0/0xd0()
[   15.276759] Calling initcall 0x78a199b0: init_pit_clocksource+0x0/0x70()
[   15.283442] initcall 0x78a199b0: init_pit_clocksource+0x0/0x70() returned 0.
[   15.290452] initcall 0x78a199b0 ran for 0 msecs: init_pit_clocksource+0x0/0x70()
[   15.297820] Calling initcall 0x78a4b8a0: pci_access_init+0x0/0x30()
[   15.308637] PCI: PCI BIOS revision 3.00 entry at 0xf21d0, last bus=5
[   15.314857] initcall 0x78a4b8a0: pci_access_init+0x0/0x30() returned 0.
[   15.321440] initcall 0x78a4b8a0 ran for 6 msecs: pci_access_init+0x0/0x30()
[   15.328375] Calling initcall 0x78a19010: request_standard_resources+0x0/0x3a0()
[   15.335652] Setting up standard PCI resources
[   15.342812] initcall 0x78a19010: request_standard_resources+0x0/0x3a0() returned 0.
[   15.350309] initcall 0x78a19010 ran for 6 msecs: request_standard_resources+0x0/0x3a0()
[   15.358283] Calling initcall 0x78a198e0: topology_init+0x0/0x10()
[   15.364355] initcall 0x78a198e0: topology_init+0x0/0x10() returned 0.
[   15.370761] initcall 0x78a198e0 ran for 0 msecs: topology_init+0x0/0x10()
[   15.377522] Calling initcall 0x78a1da00: mca_init+0x0/0x330()
[   15.383249] initcall 0x78a1da00: mca_init+0x0/0x330() returned -19.
[   15.389479] initcall 0x78a1da00 ran for 0 msecs: mca_init+0x0/0x330()
[   15.395892] Calling initcall 0x78a24e00: param_sysfs_init+0x0/0x180()
[   15.403702] initcall 0x78a24e00: param_sysfs_init+0x0/0x180() returned 0.
[   15.410330] initcall 0x78a24e00 ran for 0 msecs: param_sysfs_init+0x0/0x180()
[   15.417438] Calling initcall 0x78a28150: init_bio+0x0/0x100()
[   15.423185] initcall 0x78a28150: init_bio+0x0/0x100() returned 0.
[   15.429222] initcall 0x78a28150 ran for 0 msecs: init_bio+0x0/0x100()
[   15.435634] Calling initcall 0x78a2b6e0: genhd_device_init+0x0/0x60()
[   15.442077] initcall 0x78a2b6e0: genhd_device_init+0x0/0x60() returned 0.
[   15.448807] initcall 0x78a2b6e0 ran for 0 msecs: genhd_device_init+0x0/0x60()
[   15.455915] Calling initcall 0x78a2d850: misc_init+0x0/0x80()
[   15.461647] initcall 0x78a2d850: misc_init+0x0/0x80() returned 0.
[   15.467700] initcall 0x78a2d850 ran for 0 msecs: misc_init+0x0/0x80()
[   15.474112] Calling initcall 0x78a39230: init_dvbdev+0x0/0xd0()
[   15.480010] initcall 0x78a39230: init_dvbdev+0x0/0xd0() returned 0.
[   15.486245] initcall 0x78a39230 ran for 0 msecs: init_dvbdev+0x0/0xd0()
[   15.492831] Calling initcall 0x78a39300: init_scsi+0x0/0xa0()
[   15.498707] SCSI subsystem initialized
[   15.502333] initcall 0x78a39300: init_scsi+0x0/0xa0() returned 0.
[   15.508394] initcall 0x78a39300 ran for 6 msecs: init_scsi+0x0/0xa0()
[   15.514809] Calling initcall 0x78a39950: ata_init+0x0/0x70()
[   15.520481] libata version 3.00 loaded.
[   15.524257] initcall 0x78a39950: ata_init+0x0/0x70() returned 0.
[   15.530235] initcall 0x78a39950 ran for 3 msecs: ata_init+0x0/0x70()
[   15.536560] Calling initcall 0x78a3c8b0: spi_init+0x0/0x70()
[   15.542206] initcall 0x78a3c8b0: spi_init+0x0/0x70() returned 0.
[   15.548172] initcall 0x78a3c8b0 ran for 0 msecs: spi_init+0x0/0x70()
[   15.554500] Calling initcall 0x78a3d2e0: usb_init+0x0/0xd0()
[   15.560173] usbcore: registered new interface driver usbfs
[   15.565606] usbcore: registered new interface driver hub
[   15.570908] usbcore: registered new device driver usb
[   15.575908] initcall 0x78a3d2e0: usb_init+0x0/0xd0() returned 0.
[   15.581882] initcall 0x78a3d2e0 ran for 9 msecs: usb_init+0x0/0xd0()
[   15.588211] Calling initcall 0x78a3f350: serio_init+0x0/0xb0()
[   15.594050] initcall 0x78a3f350: serio_init+0x0/0xb0() returned 0.
[   15.600170] initcall 0x78a3f350 ran for 0 msecs: serio_init+0x0/0xb0()
[   15.606669] Calling initcall 0x78a3fe70: gameport_init+0x0/0xb0()
[   15.612786] initcall 0x78a3fe70: gameport_init+0x0/0xb0() returned 0.
[   15.619148] initcall 0x78a3fe70 ran for 0 msecs: gameport_init+0x0/0xb0()
[   15.625908] Calling initcall 0x78a406e0: input_init+0x0/0x100()
[   15.631811] initcall 0x78a406e0: input_init+0x0/0x100() returned 0.
[   15.638039] initcall 0x78a406e0 ran for 0 msecs: input_init+0x0/0x100()
[   15.644627] Calling initcall 0x78a40c10: i2c_init+0x0/0x20()
[   15.650274] initcall 0x78a40c10: i2c_init+0x0/0x20() returned 0.
[   15.656240] initcall 0x78a40c10 ran for 0 msecs: i2c_init+0x0/0x20()
[   15.662566] Calling initcall 0x78a42f50: hwmon_init+0x0/0x40()
[   15.668374] initcall 0x78a42f50: hwmon_init+0x0/0x40() returned 0.
[   15.674526] initcall 0x78a42f50 ran for 0 msecs: hwmon_init+0x0/0x40()
[   15.681025] Calling initcall 0x78a4acc0: leds_init+0x0/0x20()
[   15.686753] initcall 0x78a4acc0: leds_init+0x0/0x20() returned 0.
[   15.692810] initcall 0x78a4acc0 ran for 0 msecs: leds_init+0x0/0x20()
[   15.699223] Calling initcall 0x78a4b4e0: ssb_modinit+0x0/0x80()
[   15.705152] initcall 0x78a4b4e0: ssb_modinit+0x0/0x80() returned 0.
[   15.711354] initcall 0x78a4b4e0 ran for 0 msecs: ssb_modinit+0x0/0x80()
[   15.717943] Calling initcall 0x78a4c100: pci_legacy_init+0x0/0x100()
[   15.724267] PCI: Probing PCI hardware
[   15.727923] PCI: Probing PCI hardware (bus 00)
[   15.735245] PCI: Transparent bridge - 0000:00:09.0
[   15.742165] initcall 0x78a4c100: pci_legacy_init+0x0/0x100() returned 0.
[   15.748707] initcall 0x78a4c100 ran for 12 msecs: pci_legacy_init+0x0/0x100()
[   15.755816] Calling initcall 0x78a4c720: pcibios_irq_init+0x0/0x510()
[   15.762482] PCI: Using IRQ router default [10de/005e] at 0000:00:00.0
[   15.768823] PCI->APIC IRQ transform: 0000:00:04.0[A] -> IRQ 3
[   15.774520] PCI->APIC IRQ transform: 0000:00:0a.0[A] -> IRQ 11
[   15.780350] PCI->APIC IRQ transform: 0000:05:07.0[A] -> IRQ 11
[   15.786125] PCI->APIC IRQ transform: 0000:01:00.0[A] -> IRQ 5
[   15.791845] initcall 0x78a4c720: pcibios_irq_init+0x0/0x510() returned 0.
[   15.798597] initcall 0x78a4c720 ran for 15 msecs: pcibios_irq_init+0x0/0x510()
[   15.805793] Calling initcall 0x78a4cc90: pcibios_init+0x0/0xa0()
[   15.865364] initcall 0x78a4cc90: pcibios_init+0x0/0xa0() returned 0.
[   15.871556] initcall 0x78a4cc90 ran for 54 msecs: pcibios_init+0x0/0xa0()
[   15.878318] Calling initcall 0x78a4d150: proto_init+0x0/0x30()
[   15.884124] initcall 0x78a4d150: proto_init+0x0/0x30() returned 0.
[   15.890278] initcall 0x78a4d150 ran for 0 msecs: proto_init+0x0/0x30()
[   15.896779] Calling initcall 0x78a4d560: net_dev_init+0x0/0x110()
[   15.902872] initcall 0x78a4d560: net_dev_init+0x0/0x110() returned 0.
[   15.909256] initcall 0x78a4d560 ran for 0 msecs: net_dev_init+0x0/0x110()
[   15.916014] Calling initcall 0x78a4d6c0: neigh_init+0x0/0x80()
[   15.921820] initcall 0x78a4d6c0: neigh_init+0x0/0x80() returned 0.
[   15.927973] initcall 0x78a4d6c0 ran for 0 msecs: neigh_init+0x0/0x80()
[   15.934475] Calling initcall 0x78a4dfd0: pktsched_init+0x0/0xd0()
[   15.940547] initcall 0x78a4dfd0: pktsched_init+0x0/0xd0() returned 0.
[   15.946954] initcall 0x78a4dfd0 ran for 0 msecs: pktsched_init+0x0/0xd0()
[   15.953715] Calling initcall 0x78a4e0b0: tc_filter_init+0x0/0x60()
[   15.959864] initcall 0x78a4e0b0: tc_filter_init+0x0/0x60() returned 0.
[   15.966888] initcall 0x78a4e0b0 ran for 0 msecs: tc_filter_init+0x0/0x60()
[   15.973734] Calling initcall 0x78a4e110: tc_action_init+0x0/0x60()
[   15.979883] initcall 0x78a4e110: tc_action_init+0x0/0x60() returned 0.
[   15.986384] initcall 0x78a4e110 ran for 0 msecs: tc_action_init+0x0/0x60()
[   15.993230] Calling initcall 0x78a4e420: genl_init+0x0/0xd0()
[   16.008625] initcall 0x78a4e420: genl_init+0x0/0xd0() returned 0.
[   16.014559] initcall 0x78a4e420 ran for 9 msecs: genl_init+0x0/0xd0()
[   16.020972] Calling initcall 0x78a50ee0: cipso_v4_init+0x0/0x80()
[   16.027049] initcall 0x78a50ee0: cipso_v4_init+0x0/0x80() returned 0.
[   16.033450] initcall 0x78a50ee0 ran for 0 msecs: cipso_v4_init+0x0/0x80()
[   16.040212] Calling initcall 0x78a52400: wanrouter_init+0x0/0x60()
[   16.046361] Sangoma WANPIPE Router v1.1 (c) 1995-2000 Sangoma Technologies Inc.
[   16.053648] initcall 0x78a52400: wanrouter_init+0x0/0x60() returned 0.
[   16.060142] initcall 0x78a52400 ran for 3 msecs: wanrouter_init+0x0/0x60()
[   16.066990] Calling initcall 0x78a52960: irda_init+0x0/0x90()
[   16.072741] NET: Registered protocol family 23
[   16.077153] initcall 0x78a52960: irda_init+0x0/0x90() returned 0.
[   16.083191] initcall 0x78a52960 ran for 3 msecs: irda_init+0x0/0x90()
[   16.089606] Calling initcall 0x78a53880: wireless_nlevent_init+0x0/0x40()
[   16.096364] initcall 0x78a53880: wireless_nlevent_init+0x0/0x40() returned 0.
[   16.103472] initcall 0x78a53880 ran for 0 msecs: wireless_nlevent_init+0x0/0x40()
[   16.110927] Calling initcall 0x78730f10: cfg80211_init+0x0/0x50()
[   16.117093] initcall 0x78730f10: cfg80211_init+0x0/0x50() returned 0.
[   16.123405] initcall 0x78730f10 ran for 0 msecs: cfg80211_init+0x0/0x50()
[   16.130166] Calling initcall 0x78a538c0: ieee80211_init+0x0/0x40()
[   16.136317] initcall 0x78a538c0: ieee80211_init+0x0/0x40() returned 0.
[   16.142816] initcall 0x78a538c0 ran for 0 msecs: ieee80211_init+0x0/0x40()
[   16.149662] Calling initcall 0x78a53900: rate_control_simple_init+0x0/0x10()
[   16.156689] initcall 0x78a53900: rate_control_simple_init+0x0/0x10() returned 0.
[   16.164048] initcall 0x78a53900 ran for 0 msecs: rate_control_simple_init+0x0/0x10()
[   16.171763] Calling initcall 0x78a53ac0: netlbl_init+0x0/0x80()
[   16.177652] NetLabel: Initializing
[   16.181037] NetLabel:  domain hash size = 128
[   16.185370] NetLabel:  protocols = UNLABELED CIPSOv4
[   16.190360] NetLabel:  unlabeled traffic allowed by default
[   16.195856] initcall 0x78a53ac0: netlbl_init+0x0/0x80() returned 0.
[   16.202093] initcall 0x78a53ac0 ran for 12 msecs: netlbl_init+0x0/0x80()
[   16.208766] Calling initcall 0x78a253d0: clocksource_done_booting+0x0/0x10()
[   16.215783] initcall 0x78a253d0<6>Time: tsc clocksource has been installed.
[   16.222727] : clocksource_done_booting+0x0/0x10() returned 0.
[   16.228436] initcall 0x78a253d0 ran for 0 msecs: clocksource_done_booting+0x0/0x10()
[   16.236152] Calling initcall 0x78a279e0: init_pipe_fs+0x0/0x50()
[   16.242157] initcall 0x78a279e0: init_pipe_fs+0x0/0x50() returned 0.
[   16.248455] initcall 0x78a279e0 ran for 0 msecs: init_pipe_fs+0x0/0x50()
[   16.255130] Calling initcall 0x78a282c0: eventpoll_init+0x0/0x90()
[   16.261282] initcall 0x78a282c0: eventpoll_init+0x0/0x90() returned 0.
[   16.267782] initcall 0x78a282c0 ran for 0 msecs: eventpoll_init+0x0/0x90()
[   16.274628] Calling initcall 0x78a28350: anon_inode_init+0x0/0xf0()
[   16.280898] initcall 0x78a28350: anon_inode_init+0x0/0xf0() returned 0.
[   16.287454] initcall 0x78a28350 ran for 0 msecs: anon_inode_init+0x0/0xf0()
[   16.294387] Calling initcall 0x78a2d270: chr_dev_init+0x0/0xc0()
[   16.300464] initcall 0x78a2d270: chr_dev_init+0x0/0xc0() returned 0.
[   16.306693] initcall 0x78a2d270 ran for 0 msecs: chr_dev_init+0x0/0xc0()
[   16.313368] Calling initcall 0x78a31130: firmware_class_init+0x0/0x70()
[   16.319956] initcall 0x78a31130: firmware_class_init+0x0/0x70() returned 0.
[   16.326885] initcall 0x78a31130 ran for 0 msecs: firmware_class_init+0x0/0x70()
[   16.334167] Calling initcall 0x78a33a30: loopback_init+0x0/0x10()
[   16.340375] initcall 0x78a33a30: loopback_init+0x0/0x10() returned 0.
[   16.346661] initcall 0x78a33a30 ran for 0 msecs: loopback_init+0x0/0x10()
[   16.353422] Calling initcall 0x78a4aca0: cpufreq_gov_userspace_init+0x0/0x10()
[   16.360617] initcall 0x78a4aca0: cpufreq_gov_userspace_init+0x0/0x10() returned 0.
[   16.368150] initcall 0x78a4aca0 ran for 0 msecs: cpufreq_gov_userspace_init+0x0/0x10()
[   16.376041] Calling initcall 0x78a4b570: pcibios_assign_resources+0x0/0xa0()
[   16.383096] PCI: Bridge: 0000:00:09.0
[   16.386705]   IO window: c000-cfff
[   16.390096]   MEM window: da000000-da0fffff
[   16.394248]   PREFETCH window: disabled.
[   16.398152] PCI: Bridge: 0000:00:0b.0
[   16.401779]   IO window: disabled.
[   16.405170]   MEM window: disabled.
[   16.408632]   PREFETCH window: disabled.
[   16.412537] PCI: Bridge: 0000:00:0c.0
[   16.416165]   IO window: disabled.
[   16.419556]   MEM window: disabled.
[   16.423019]   PREFETCH window: disabled.
[   16.426923] PCI: Bridge: 0000:00:0d.0
[   16.430551]   IO window: disabled.
[   16.433942]   MEM window: disabled.
[   16.437404]   PREFETCH window: disabled.
[   16.441312] PCI: Bridge: 0000:00:0e.0
[   16.444941]   IO window: b000-bfff
[   16.448327]   MEM window: d8000000-d9ffffff
[   16.452484]   PREFETCH window: d0000000-d7ffffff
[   16.457103] PCI: Setting latency timer of device 0000:00:09.0 to 64
[   16.463354] PCI: Setting latency timer of device 0000:00:0b.0 to 64
[   16.469594] PCI: Setting latency timer of device 0000:00:0c.0 to 64
[   16.475833] PCI: Setting latency timer of device 0000:00:0d.0 to 64
[   16.482072] PCI: Setting latency timer of device 0000:00:0e.0 to 64
[   16.488273] initcall 0x78a4b570: pcibios_assign_resources+0x0/0xa0() returned 0.
[   16.495631] initcall 0x78a4b570 ran for 100 msecs: pcibios_assign_resources+0x0/0xa0()
[   16.503519] Calling initcall 0x78a4ee60: inet_init+0x0/0x300()
[   16.509327] NET: Registered protocol family 2
[   16.541898] IP route cache hash table entries: 32768 (order: 5, 131072 bytes)
[   16.549162] TCP established hash table entries: 131072 (order: 10, 4194304 bytes)
[   16.565249] TCP bind hash table entries: 65536 (order: 9, 2097152 bytes)
[   16.575949] TCP: Hash tables configured (established 131072 bind 65536)
[   16.582453] TCP reno registered
[   16.595222] initcall 0x78a4ee60: inet_init+0x0/0x300() returned 0.
[   16.601243] initcall 0x78a4ee60 ran for 81 msecs: inet_init+0x0/0x300()
[   16.607832] Calling initcall 0x78a17600: populate_rootfs+0x0/0xa0()
[   16.614366] initcall 0x78a17600: populate_rootfs+0x0/0xa0() returned 0.
[   16.620823] initcall 0x78a17600 ran for 0 msecs: populate_rootfs+0x0/0xa0()
[   16.627755] Calling initcall 0x78a186b0: i8259A_init_sysfs+0x0/0x20()
[   16.634182] initcall 0x78a186b0: i8259A_init_sysfs+0x0/0x20() returned 0.
[   16.640928] initcall 0x78a186b0 ran for 0 msecs: i8259A_init_sysfs+0x0/0x20()
[   16.648034] Calling initcall 0x78a18830: sbf_init+0x0/0xd0()
[   16.653665] initcall 0x78a18830: sbf_init+0x0/0xd0() returned 0.
[   16.659646] initcall 0x78a18830 ran for 0 msecs: sbf_init+0x0/0xd0()
[   16.665972] Calling initcall 0x78a198c0: i8237A_init_sysfs+0x0/0x20()
[   16.672394] initcall 0x78a198c0: i8237A_init_sysfs+0x0/0x20() returned 0.
[   16.679146] initcall 0x78a198c0 ran for 0 msecs: i8237A_init_sysfs+0x0/0x20()
[   16.686251] Calling initcall 0x78a1cbb0: cache_sysfs_init+0x0/0x200()
[   16.692749] initcall 0x78a1cbb0: cache_sysfs_init+0x0/0x200() returned 0.
[   16.699424] initcall 0x78a1cbb0 ran for 0 msecs: cache_sysfs_init+0x0/0x200()
[   16.706530] Calling initcall 0x78a1d460: longrun_init+0x0/0x30()
[   16.712508] initcall 0x78a1d460: longrun_init+0x0/0x30() returned -19.
[   16.719009] initcall 0x78a1d460 ran for 0 msecs: longrun_init+0x0/0x30()
[   16.725682] Calling initcall 0x78a1dd30: microcode_init+0x0/0xa0()
[   16.731924] microcode: CPU0 not a capable Intel processor
[   16.737212] IA-32 Microcode Update Driver: v1.14a <tigran@aivazian.fsnet.co.uk>
[   16.744490] initcall 0x78a1dd30: microcode_init+0x0/0xa0() returned 0.
[   16.750988] initcall 0x78a1dd30 ran for 12 msecs: microcode_init+0x0/0xa0()
[   16.757921] Calling initcall 0x78a202a0: ioapic_init_sysfs+0x0/0xe0()
[   16.764340] initcall 0x78a202a0: ioapic_init_sysfs+0x0/0xe0() returned 0.
[   16.771093] initcall 0x78a202a0 ran for 0 msecs: ioapic_init_sysfs+0x0/0xe0()
[   16.778199] Calling initcall 0x78a22ff0: init_vmi_clocksource+0x0/0x130()
[   16.784956] initcall 0x78a22ff0: init_vmi_clocksource+0x0/0x130() returned 0.
[   16.792065] initcall 0x78a22ff0 ran for 0 msecs: init_vmi_clocksource+0x0/0x130()
[   16.799520] Calling initcall 0x78a23320: add_pcspkr+0x0/0x60()
[   16.805338] initcall 0x78a23320: add_pcspkr+0x0/0x60() returned 0.
[   16.811475] initcall 0x78a23320 ran for 0 msecs: add_pcspkr+0x0/0x60()
[   16.817976] Calling initcall 0x78a23bd0: init+0x0/0x10()
[   16.823273] initcall 0x78a23bd0: init+0x0/0x10() returned 0.
[   16.828895] initcall 0x78a23bd0 ran for 0 msecs: init+0x0/0x10()
[   16.834874] Calling initcall 0x78a23c00: init_sched_debug_procfs+0x0/0x30()
[   16.841810] initcall 0x78a23c00: init_sched_debug_procfs+0x0/0x30() returned 0.
[   16.849088] initcall 0x78a23c00 ran for 0 msecs: init_sched_debug_procfs+0x0/0x30()
[   16.856716] Calling initcall 0x78a245a0: create_proc_profile+0x0/0x50()
[   16.863303] initcall 0x78a245a0: create_proc_profile+0x0/0x50() returned 0.
[   16.870234] initcall 0x78a245a0 ran for 0 msecs: create_proc_profile+0x0/0x50()
[   16.877515] Calling initcall 0x78a24730: ioresources_init+0x0/0x40()
[   16.883840] initcall 0x78a24730: ioresources_init+0x0/0x40() returned 0.
[   16.890512] initcall 0x78a24730 ran for 0 msecs: ioresources_init+0x0/0x40()
[   16.897534] Calling initcall 0x78a249f0: uid_cache_init+0x0/0x90()
[   16.903688] initcall 0x78a249f0: uid_cache_init+0x0/0x90() returned 0.
[   16.910184] initcall 0x78a249f0 ran for 0 msecs: uid_cache_init+0x0/0x90()
[   16.917033] Calling initcall 0x78a24f80: init_posix_timers+0x0/0x90()
[   16.923442] initcall 0x78a24f80: init_posix_timers+0x0/0x90() returned 0.
[   16.930203] initcall 0x78a24f80 ran for 0 msecs: init_posix_timers+0x0/0x90()
[   16.937311] Calling initcall 0x78a25010: init_posix_cpu_timers+0x0/0xa0()
[   16.944066] initcall 0x78a25010: init_posix_cpu_timers+0x0/0xa0() returned 0.
[   16.951173] initcall 0x78a25010 ran for 0 msecs: init_posix_cpu_timers+0x0/0xa0()
[   16.958630] Calling initcall 0x78a251d0: latency_init+0x0/0x20()
[   16.964611] initcall 0x78a251d0: latency_init+0x0/0x20() returned 0.
[   16.970933] initcall 0x78a251d0 ran for 0 msecs: latency_init+0x0/0x20()
[   16.977606] Calling initcall 0x78a251f0: nsproxy_cache_init+0x0/0x30()
[   16.984105] initcall 0x78a251f0: nsproxy_cache_init+0x0/0x30() returned 0.
[   16.990952] initcall 0x78a251f0 ran for 0 msecs: nsproxy_cache_init+0x0/0x30()
[   16.998146] Calling initcall 0x78a25220: timekeeping_init_device+0x0/0x20()
[   17.005089] initcall 0x78a25220: timekeeping_init_device+0x0/0x20() returned 0.
[   17.012894] initcall 0x78a25220 ran for 0 msecs: timekeeping_init_device+0x0/0x20()
[   17.020523] Calling initcall 0x78a253e0: init_clocksource_sysfs+0x0/0x40()
[   17.027380] initcall 0x78a253e0: init_clocksource_sysfs+0x0/0x40() returned 0.
[   17.034559] initcall 0x78a253e0 ran for 0 msecs: init_clocksource_sysfs+0x0/0x40()
[   17.042102] Calling initcall 0x78a254d0: init_timer_list_procfs+0x0/0x30()
[   17.048948] initcall 0x78a254d0: init_timer_list_procfs+0x0/0x30() returned 0.
[   17.056139] initcall 0x78a254d0 ran for 0 msecs: init_timer_list_procfs+0x0/0x30()
[   17.063680] Calling initcall 0x78a25510: init_tstats_procfs+0x0/0x30()
[   17.070178] initcall 0x78a25510: init_tstats_procfs+0x0/0x30() returned 0.
[   17.077025] initcall 0x78a25510 ran for 0 msecs: init_tstats_procfs+0x0/0x30()
[   17.084219] Calling initcall 0x78a25630: lockdep_proc_init+0x0/0x40()
[   17.090631] initcall 0x78a25630: lockdep_proc_init+0x0/0x40() returned 0.
[   17.097389] initcall 0x78a25630 ran for 0 msecs: lockdep_proc_init+0x0/0x40()
[   17.104496] Calling initcall 0x78a25670: init+0x0/0xf0()
[   17.109819] initcall 0x78a25670: init+0x0/0xf0() returned 0.
[   17.115415] initcall 0x78a25670 ran for 0 msecs: init+0x0/0xf0()
[   17.121393] Calling initcall 0x7813ae00: init_rttest+0x0/0x120()
[   17.127622] Initializing RT-Tester: OK
[   17.131243] initcall 0x7813ae00: init_rttest+0x0/0x120() returned 0.
[   17.137566] initcall 0x7813ae00 ran for 3 msecs: init_rttest+0x0/0x120()
[   17.144238] Calling initcall 0x78a25760: proc_dma_init+0x0/0x20()
[   17.150304] initcall 0x78a25760: proc_dma_init+0x0/0x20() returned 0.
[   17.156718] initcall 0x78a25760 ran for 0 msecs: proc_dma_init+0x0/0x20()
[   17.163480] Calling initcall 0x78a25780: kallsyms_init+0x0/0x20()
[   17.169542] initcall 0x78a25780: kallsyms_init+0x0/0x20() returned 0.
[   17.175956] initcall 0x78a25780 ran for 0 msecs: kallsyms_init+0x0/0x20()
[   17.182716] Calling initcall 0x78a25810: audit_init+0x0/0x100()
[   17.188607] audit: initializing netlink socket (disabled)
[   17.194013] audit(1192636448.851:1): initialized
[   17.198582] initcall 0x78a25810: audit_init+0x0/0x100() returned 0.
[   17.204812] initcall 0x78a25810 ran for 9 msecs: audit_init+0x0/0x100()
[   17.211401] Calling initcall 0x78a25a40: utsname_sysctl_init+0x0/0x10()
[   17.217987] initcall 0x78a25a40: utsname_sysctl_init+0x0/0x10() returned 0.
[   17.224918] initcall 0x78a25a40 ran for 0 msecs: utsname_sysctl_init+0x0/0x10()
[   17.232202] Calling initcall 0x78a27260: init_per_zone_pages_min+0x0/0x50()
[   17.239174] initcall 0x78a27260: init_per_zone_pages_min+0x0/0x50() returned 0.
[   17.246411] initcall 0x78a27260 ran for 0 msecs: init_per_zone_pages_min+0x0/0x50()
[   17.254041] Calling initcall 0x78a27800: pdflush_init+0x0/0x10()
[   17.260066] initcall 0x78a27800: pdflush_init+0x0/0x10() returned 0.
[   17.266343] initcall 0x78a27800 ran for 0 msecs: pdflush_init+0x0/0x10()
[   17.273017] Calling initcall 0x78a27830: kswapd_init+0x0/0x10()
[   17.278930] initcall 0x78a27830: kswapd_init+0x0/0x10() returned 0.
[   17.285150] initcall 0x78a27830 ran for 0 msecs: kswapd_init+0x0/0x10()
[   17.291738] Calling initcall 0x78a27880: procswaps_init+0x0/0x20()
[   17.297888] initcall 0x78a27880: procswaps_init+0x0/0x20() returned 0.
[   17.304389] initcall 0x78a27880 ran for 0 msecs: procswaps_init+0x0/0x20()
[   17.311235] Calling initcall 0x78a278a0: init_tmpfs+0x0/0xc0()
[   17.317075] initcall 0x78a278a0: init_tmpfs+0x0/0xc0() returned 0.
[   17.323194] initcall 0x78a278a0 ran for 0 msecs: init_tmpfs+0x0/0xc0()
[   17.329693] Calling initcall 0x78a27a30: fasync_init+0x0/0x30()
[   17.335585] initcall 0x78a27a30: fasync_init+0x0/0x30() returned 0.
[   17.341826] initcall 0x78a27a30 ran for 0 msecs: fasync_init+0x0/0x30()
[   17.348414] Calling initcall 0x78a28090: aio_setup+0x0/0x70()
[   17.354157] initcall 0x78a28090: aio_setup+0x0/0x70() returned 0.
[   17.360199] initcall 0x78a28090 ran for 0 msecs: aio_setup+0x0/0x70()
[   17.366613] Calling initcall 0x78a284a0: init_mbcache+0x0/0x10()
[   17.372590] initcall 0x78a284a0: init_mbcache+0x0/0x10() returned 0.
[   17.378916] initcall 0x78a284a0 ran for 0 msecs: init_mbcache+0x0/0x10()
[   17.385590] Calling initcall 0x78a284b0: dquot_init+0x0/0xf0()
[   17.391394] VFS: Disk quotas dquot_6.5.1
[   17.395305] Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
[   17.401800] initcall 0x78a284b0: dquot_init+0x0/0xf0() returned 0.
[   17.407947] initcall 0x78a284b0 ran for 9 msecs: dquot_init+0x0/0xf0()
[   17.414448] Calling initcall 0x78a285a0: dnotify_init+0x0/0x30()
[   17.420426] initcall 0x78a285a0: dnotify_init+0x0/0x30() returned 0.
[   17.426754] initcall 0x78a285a0 ran for 0 msecs: dnotify_init+0x0/0x30()
[   17.433429] Calling initcall 0x78a28a30: configfs_init+0x0/0x90()
[   17.439496] initcall 0x78a28a30: configfs_init+0x0/0x90() returned 0.
[   17.445906] initcall 0x78a28a30 ran for 0 msecs: configfs_init+0x0/0x90()
[   17.452666] Calling initcall 0x78a28ac0: init_devpts_fs+0x0/0x30()
[   17.458871] initcall 0x78a28ac0: init_devpts_fs+0x0/0x30() returned 0.
[   17.465318] initcall 0x78a28ac0 ran for 0 msecs: init_devpts_fs+0x0/0x30()
[   17.472165] Calling initcall 0x78a28af0: init_reiserfs_fs+0x0/0x90()
[   17.478504] initcall 0x78a28af0: init_reiserfs_fs+0x0/0x90() returned 0.
[   17.485163] initcall 0x78a28af0 ran for 0 msecs: init_reiserfs_fs+0x0/0x90()
[   17.492186] Calling initcall 0x78a28c60: init_ext3_fs+0x0/0x70()
[   17.498171] initcall 0x78a28c60: init_ext3_fs+0x0/0x70() returned 0.
[   17.504487] initcall 0x78a28c60 ran for 0 msecs: init_ext3_fs+0x0/0x70()
[   17.511163] Calling initcall 0x78a28d10: init_ext4_fs+0x0/0x60()
[   17.517141] initcall 0x78a28d10: init_ext4_fs+0x0/0x60() returned 0.
[   17.523469] initcall 0x78a28d10 ran for 0 msecs: init_ext4_fs+0x0/0x60()
[   17.530143] Calling initcall 0x78a28df0: journal_init+0x0/0x100()
[   17.536207] initcall 0x78a28df0: journal_init+0x0/0x100() returned 0.
[   17.542620] initcall 0x78a28df0 ran for 0 msecs: journal_init+0x0/0x100()
[   17.549379] Calling initcall 0x78a28f70: journal_init+0x0/0xd0()
[   17.555358] initcall 0x78a28f70: journal_init+0x0/0xd0() returned 0.
[   17.561684] initcall 0x78a28f70 ran for 0 msecs: journal_init+0x0/0xd0()
[   17.568360] Calling initcall 0x78a29040: init_cramfs_fs+0x0/0x30()
[   17.574552] initcall 0x78a29040: init_cramfs_fs+0x0/0x30() returned 0.
[   17.581011] initcall 0x78a29040 ran for 0 msecs: init_cramfs_fs+0x0/0x30()
[   17.587857] Calling initcall 0x78a29080: init_ramfs_fs+0x0/0x10()
[   17.593923] initcall 0x78a29080: init_ramfs_fs+0x0/0x10() returned 0.
[   17.600337] initcall 0x78a29080 ran for 0 msecs: init_ramfs_fs+0x0/0x10()
[   17.607098] Calling initcall 0x78a29090: init_coda+0x0/0x190()
[   17.612964] initcall 0x78a29090: init_coda+0x0/0x190() returned 0.
[   17.619055] initcall 0x78a29090 ran for 0 msecs: init_coda+0x0/0x190()
[   17.625554] Calling initcall 0x78a29220: init_minix_fs+0x0/0x60()
[   17.631620] initcall 0x78a29220: init_minix_fs+0x0/0x60() returned 0.
[   17.638033] initcall 0x78a29220 ran for 0 msecs: init_minix_fs+0x0/0x60()
[   17.644794] Calling initcall 0x78a292c0: init_fat_fs+0x0/0x50()
[   17.650686] initcall 0x78a292c0: init_fat_fs+0x0/0x50() returned 0.
[   17.656927] initcall 0x78a292c0 ran for 0 msecs: init_fat_fs+0x0/0x50()
[   17.663515] Calling initcall 0x78a29310: init_msdos_fs+0x0/0x10()
[   17.669578] initcall 0x78a29310: init_msdos_fs+0x0/0x10() returned 0.
[   17.675992] initcall 0x78a29310 ran for 0 msecs: init_msdos_fs+0x0/0x10()
[   17.682751] Calling initcall 0x78a29320: init_vfat_fs+0x0/0x10()
[   17.688730] initcall 0x78a29320: init_vfat_fs+0x0/0x10() returned 0.
[   17.695057] initcall 0x78a29320 ran for 0 msecs: init_vfat_fs+0x0/0x10()
[   17.701732] Calling initcall 0x78a29330: init_iso9660_fs+0x0/0x70()
[   17.707986] initcall 0x78a29330: init_iso9660_fs+0x0/0x70() returned 0.
[   17.714553] initcall 0x78a29330 ran for 0 msecs: init_iso9660_fs+0x0/0x70()
[   17.721489] Calling initcall 0x78a29410: init_hfsplus_fs+0x0/0x70()
[   17.727728] initcall 0x78a29410: init_hfsplus_fs+0x0/0x70() returned 0.
[   17.734315] initcall 0x78a29410 ran for 0 msecs: init_hfsplus_fs+0x0/0x70()
[   17.741247] Calling initcall 0x78a29480: init_hfs_fs+0x0/0x70()
[   17.747140] initcall 0x78a29480: init_hfs_fs+0x0/0x70() returned 0.
[   17.753381] initcall 0x78a29480 ran for 0 msecs: init_hfs_fs+0x0/0x70()
[   17.759968] Calling initcall 0x78a294f0: ecryptfs_init+0x0/0x1d0()
[   17.766187] initcall 0x78a294f0: ecryptfs_init+0x0/0x1d0() returned 0.
[   17.772619] initcall 0x78a294f0 ran for 0 msecs: ecryptfs_init+0x0/0x1d0()
[   17.779465] Calling initcall 0x78a296c0: vxfs_init+0x0/0x70()
[   17.785184] initcall 0x78a296c0: vxfs_init+0x0/0x70() returned 0.
[   17.791249] initcall 0x78a296c0 ran for 0 msecs: vxfs_init+0x0/0x70()
[   17.797665] Calling initcall 0x78a29730: init_nfsd+0x0/0xb0()
[   17.803382] Installing knfsd (copyright (C) 1996 okir@monad.swb.de).
[   17.810144] initcall 0x78a29730: init_nfsd+0x0/0xb0() returned 0.
[   17.816079] initcall 0x78a29730 ran for 6 msecs: init_nfsd+0x0/0xb0()
[   17.822492] Calling initcall 0x78a297e0: init_nlm+0x0/0x20()
[   17.828124] initcall 0x78a297e0: init_nlm+0x0/0x20() returned 0.
[   17.834105] initcall 0x78a297e0 ran for 0 msecs: init_nlm+0x0/0x20()
[   17.840432] Calling initcall 0x78a29800: init_nls_cp437+0x0/0x10()
[   17.846593] initcall 0x78a29800: init_nls_cp437+0x0/0x10() returned 0.
[   17.853082] initcall 0x78a29800 ran for 0 msecs: init_nls_cp437+0x0/0x10()
[   17.859933] Calling initcall 0x78a29810: init_nls_cp775+0x0/0x10()
[   17.866081] initcall 0x78a29810: init_nls_cp775+0x0/0x10() returned 0.
[   17.872582] initcall 0x78a29810 ran for 0 msecs: init_nls_cp775+0x0/0x10()
[   17.879429] Calling initcall 0x78a29820: init_nls_cp852+0x0/0x10()
[   17.885580] initcall 0x78a29820: init_nls_cp852+0x0/0x10() returned 0.
[   17.892081] initcall 0x78a29820 ran for 0 msecs: init_nls_cp852+0x0/0x10()
[   17.898928] Calling initcall 0x78a29830: init_nls_cp857+0x0/0x10()
[   17.905080] initcall 0x78a29830: init_nls_cp857+0x0/0x10() returned 0.
[   17.911578] initcall 0x78a29830 ran for 0 msecs: init_nls_cp857+0x0/0x10()
[   17.918428] Calling initcall 0x78a29840: init_nls_cp860+0x0/0x10()
[   17.924578] initcall 0x78a29840: init_nls_cp860+0x0/0x10() returned 0.
[   17.931076] initcall 0x78a29840 ran for 0 msecs: init_nls_cp860+0x0/0x10()
[   17.937925] Calling initcall 0x78a29850: init_nls_cp861+0x0/0x10()
[   17.944076] initcall 0x78a29850: init_nls_cp861+0x0/0x10() returned 0.
[   17.950578] initcall 0x78a29850 ran for 0 msecs: init_nls_cp861+0x0/0x10()
[   17.957424] Calling initcall 0x78a29860: init_nls_cp863+0x0/0x10()
[   17.963575] initcall 0x78a29860: init_nls_cp863+0x0/0x10() returned 0.
[   17.970077] initcall 0x78a29860 ran for 0 msecs: init_nls_cp863+0x0/0x10()
[   17.976925] Calling initcall 0x78a29870: init_nls_cp864+0x0/0x10()
[   17.983073] initcall 0x78a29870: init_nls_cp864+0x0/0x10() returned 0.
[   17.989573] initcall 0x78a29870 ran for 0 msecs: init_nls_cp864+0x0/0x10()
[   17.996424] Calling initcall 0x78a29880: init_nls_cp869+0x0/0x10()
[   18.002573] initcall 0x78a29880: init_nls_cp869+0x0/0x10() returned 0.
[   18.009074] initcall 0x78a29880 ran for 0 msecs: init_nls_cp869+0x0/0x10()
[   18.015920] Calling initcall 0x78a29890: init_nls_cp874+0x0/0x10()
[   18.022071] initcall 0x78a29890: init_nls_cp874+0x0/0x10() returned 0.
[   18.028573] initcall 0x78a29890 ran for 0 msecs: init_nls_cp874+0x0/0x10()
[   18.035419] Calling initcall 0x78a298a0: init_nls_cp932+0x0/0x10()
[   18.041570] initcall 0x78a298a0: init_nls_cp932+0x0/0x10() returned 0.
[   18.048069] initcall 0x78a298a0 ran for 0 msecs: init_nls_cp932+0x0/0x10()
[   18.054918] Calling initcall 0x78a298b0: init_nls_euc_jp+0x0/0x40()
[   18.061157] initcall 0x78a298b0: init_nls_euc_jp+0x0/0x40() returned 0.
[   18.067742] initcall 0x78a298b0 ran for 0 msecs: init_nls_euc_jp+0x0/0x40()
[   18.074677] Calling initcall 0x78a298f0: init_nls_cp936+0x0/0x10()
[   18.080828] initcall 0x78a298f0: init_nls_cp936+0x0/0x10() returned 0.
[   18.087330] initcall 0x78a298f0 ran for 0 msecs: init_nls_cp936+0x0/0x10()
[   18.094176] Calling initcall 0x78a29900: init_nls_cp1250+0x0/0x10()
[   18.100414] initcall 0x78a29900: init_nls_cp1250+0x0/0x10() returned 0.
[   18.107522] initcall 0x78a29900 ran for 0 msecs: init_nls_cp1250+0x0/0x10()
[   18.114454] Calling initcall 0x78a29910: init_nls_ascii+0x0/0x10()
[   18.120605] initcall 0x78a29910: init_nls_ascii+0x0/0x10() returned 0.
[   18.127107] initcall 0x78a29910 ran for 0 msecs: init_nls_ascii+0x0/0x10()
[   18.133952] Calling initcall 0x78a29920: init_nls_iso8859_3+0x0/0x10()
[   18.140451] initcall 0x78a29920: init_nls_iso8859_3+0x0/0x10() returned 0.
[   18.147299] initcall 0x78a29920 ran for 0 msecs: init_nls_iso8859_3+0x0/0x10()
[   18.154491] Calling initcall 0x78a29930: init_nls_iso8859_5+0x0/0x10()
[   18.160989] initcall 0x78a29930: init_nls_iso8859_5+0x0/0x10() returned 0.
[   18.167835] initcall 0x78a29930 ran for 0 msecs: init_nls_iso8859_5+0x0/0x10()
[   18.175032] Calling initcall 0x78a29940: init_nls_iso8859_6+0x0/0x10()
[   18.181528] initcall 0x78a29940: init_nls_iso8859_6+0x0/0x10() returned 0.
[   18.188376] initcall 0x78a29940 ran for 0 msecs: init_nls_iso8859_6+0x0/0x10()
[   18.195571] Calling initcall 0x78a29950: init_nls_iso8859_15+0x0/0x10()
[   18.202153] initcall 0x78a29950: init_nls_iso8859_15+0x0/0x10() returned 0.
[   18.209088] initcall 0x78a29950 ran for 0 msecs: init_nls_iso8859_15+0x0/0x10()
[   18.216367] Calling initcall 0x78a29960: init_nls_koi8_r+0x0/0x10()
[   18.222606] initcall 0x78a29960: init_nls_koi8_r+0x0/0x10() returned 0.
[   18.229193] initcall 0x78a29960 ran for 0 msecs: init_nls_koi8_r+0x0/0x10()
[   18.236126] Calling initcall 0x78a29970: init_nls_koi8_u+0x0/0x10()
[   18.242364] initcall 0x78a29970: init_nls_koi8_u+0x0/0x10() returned 0.
[   18.248951] initcall 0x78a29970 ran for 0 msecs: init_nls_koi8_u+0x0/0x10()
[   18.255885] Calling initcall 0x78a29980: init_nls_koi8_ru+0x0/0x40()
[   18.262210] initcall 0x78a29980: init_nls_koi8_ru+0x0/0x40() returned 0.
[   18.268884] initcall 0x78a29980 ran for 0 msecs: init_nls_koi8_ru+0x0/0x40()
[   18.275903] Calling initcall 0x78a299c0: init_nls_utf8+0x0/0x30()
[   18.281968] initcall 0x78a299c0: init_nls_utf8+0x0/0x30() returned 0.
[   18.288382] initcall 0x78a299c0 ran for 0 msecs: init_nls_utf8+0x0/0x30()
[   18.295145] Calling initcall 0x78a299f0: init_cifs+0x0/0x510()
[   18.301063] initcall 0x78a299f0: init_cifs+0x0/0x510() returned 0.
[   18.307103] initcall 0x78a299f0 ran for 0 msecs: init_cifs+0x0/0x510()
[   18.313602] Calling initcall 0x78a29f00: init_ncp_fs+0x0/0x60()
[   18.319494] initcall 0x78a29f00: init_ncp_fs+0x0/0x60() returned 0.
[   18.325734] initcall 0x78a29f00 ran for 0 msecs: init_ncp_fs+0x0/0x60()
[   18.332320] Calling initcall 0x78a29f60: init_hpfs_fs+0x0/0x60()
[   18.338301] initcall 0x78a29f60: init_hpfs_fs+0x0/0x60() returned 0.
[   18.344624] initcall 0x78a29f60 ran for 0 msecs: init_hpfs_fs+0x0/0x60()
[   18.351299] Calling initcall 0x78a29fc0: init_ntfs_fs+0x0/0x270()
[   18.357363] NTFS driver 2.1.29 [Flags: R/W DEBUG].
[   18.362138] initcall 0x78a29fc0: init_ntfs_fs+0x0/0x270() returned 0.
[   18.368544] initcall 0x78a29fc0 ran for 4 msecs: init_ntfs_fs+0x0/0x270()
[   18.375303] Calling initcall 0x78a2a230: init_romfs_fs+0x0/0x60()
[   18.381371] initcall 0x78a2a230: init_romfs_fs+0x0/0x60() returned 0.
[   18.387782] initcall 0x78a2a230 ran for 0 msecs: init_romfs_fs+0x0/0x60()
[   18.394543] Calling initcall 0x78a2a290: init_qnx4_fs+0x0/0x70()
[   18.400522] QNX4 filesystem 0.2.3 registered.
[   18.404857] initcall 0x78a2a290: init_qnx4_fs+0x0/0x70() returned 0.
[   18.411180] initcall 0x78a2a290 ran for 4 msecs: init_qnx4_fs+0x0/0x70()
[   18.417855] Calling initcall 0x78a2a300: init_autofs_fs+0x0/0x10()
[   18.424007] initcall 0x78a2a300: init_autofs_fs+0x0/0x10() returned 0.
[   18.430508] initcall 0x78a2a300 ran for 0 msecs: init_autofs_fs+0x0/0x10()
[   18.437354] Calling initcall 0x78a2a310: init_autofs4_fs+0x0/0x10()
[   18.443592] initcall 0x78a2a310: init_autofs4_fs+0x0/0x10() returned -16.
[   18.450353] initcall 0x78a2a310 ran for 0 msecs: init_autofs4_fs+0x0/0x10()
[   18.457288] initcall at 0x78a2a310: init_autofs4_fs+0x0/0x10(): returned with error code -16
[   18.465694] Calling initcall 0x78a2a320: init_adfs_fs+0x0/0x60()
[   18.471673] initcall 0x78a2a320: init_adfs_fs+0x0/0x60() returned 0.
[   18.477996] initcall 0x78a2a320 ran for 0 msecs: init_adfs_fs+0x0/0x60()
[   18.484671] Calling initcall 0x78a2a3f0: fuse_init+0x0/0x120()
[   18.490475] fuse init (API version 7.8)
[   18.494315] initcall 0x78a2a3f0: fuse_init+0x0/0x120() returned 0.
[   18.500444] initcall 0x78a2a3f0 ran for 3 msecs: fuse_init+0x0/0x120()
[   18.506944] Calling initcall 0x78a2a520: init_udf_fs+0x0/0x60()
[   18.512835] initcall 0x78a2a520: init_udf_fs+0x0/0x60() returned 0.
[   18.519075] initcall 0x78a2a520 ran for 0 msecs: init_udf_fs+0x0/0x60()
[   18.525660] Calling initcall 0x78a2a660: init_xfs_fs+0x0/0x70()
[   18.531554] SGI XFS with large block numbers, no debug enabled
[   18.537460] SGI XFS Quota Management subsystem
[   18.541789] initcall 0x78a2a660: init_xfs_fs+0x0/0x70() returned 0.
[   18.548018] initcall 0x78a2a660 ran for 9 msecs: init_xfs_fs+0x0/0x70()
[   18.554606] Calling initcall 0x78a2a6d0: init_v9fs+0x0/0x20()
[   18.560324] Installing v9fs 9p2000 file system support
[   18.565443] initcall 0x78a2a6d0: init_v9fs+0x0/0x20() returned 0.
[   18.571503] initcall 0x78a2a6d0 ran for 4 msecs: init_v9fs+0x0/0x20()
[   18.577918] Calling initcall 0x78a2a730: ocfs2_init+0x0/0x300()
[   18.583810] OCFS2 1.3.3
[   18.586275] initcall 0x78a2a730: ocfs2_init+0x0/0x300() returned 0.
[   18.592477] initcall 0x78a2a730 ran for 2 msecs: ocfs2_init+0x0/0x300()
[   18.599063] Calling initcall 0x78a2aad0: init_o2nm+0x0/0xd0()
[   18.604782] OCFS2 Node Manager 1.3.3
[   18.608580] initcall 0x78a2aad0: init_o2nm+0x0/0xd0() returned 0.
[   18.614513] initcall 0x78a2aad0 ran for 3 msecs: init_o2nm+0x0/0xd0()
[   18.620929] Calling initcall 0x78a2aba0: dlm_init+0x0/0x100()
[   18.626646] OCFS2 DLM 1.3.3
[   18.629431] initcall 0x78a2aba0<4>Clocksource tsc unstable (delta = 86616443 ns)
[   18.636797] : dlm_init+0x0/0x100()<6>Time: pit clocksource has been installed.
[   18.643987]  returned 0.
[   18.646498] initcall 0x78a2aba0 ran for 2 msecs: dlm_init+0x0/0x100()
[   18.652909] Calling initcall 0x78a2aca0: init_dlmfs_fs+0x0/0xb0()
[   18.658974] OCFS2 DLMFS 1.3.3
[   18.661961] OCFS2 User DLM kernel interface loaded
[   18.666696] initcall 0x78a2aca0: init_dlmfs_fs+0x0/0xb0() returned 0.
[   18.673098] initcall 0x78a2aca0 ran for 4 msecs: init_dlmfs_fs+0x0/0xb0()
[   18.679864] Calling initcall 0x78a2ae90: key_proc_init+0x0/0x60()
[   18.685932] initcall 0x78a2ae90: key_proc_init+0x0/0x60() returned 0.
[   18.692340] initcall 0x78a2ae90 ran for 0 msecs: key_proc_init+0x0/0x60()
[   18.699100] Calling initcall 0x78a2b010: crypto_algapi_init+0x0/0x10()
[   18.705603] initcall 0x78a2b010: crypto_algapi_init+0x0/0x10() returned 0.
[   18.712447] initcall 0x78a2b010 ran for 0 msecs: crypto_algapi_init+0x0/0x10()
[   18.719638] Calling initcall 0x78a2b040: cryptomgr_init+0x0/0x10()
[   18.725793] initcall 0x78a2b040: cryptomgr_init+0x0/0x10() returned 0.
[   18.732291] initcall 0x78a2b040 ran for 0 msecs: cryptomgr_init+0x0/0x10()
[   18.739137] Calling initcall 0x78a2b050: hmac_module_init+0x0/0x10()
[   18.745478] initcall 0x78a2b050: hmac_module_init+0x0/0x10() returned 0.
[   18.752136] initcall 0x78a2b050 ran for 0 msecs: hmac_module_init+0x0/0x10()
[   18.759156] Calling initcall 0x78a2b060: crypto_xcbc_module_init+0x0/0x10()
[   18.766091] initcall 0x78a2b060: crypto_xcbc_module_init+0x0/0x10() returned 0.
[   18.773365] initcall 0x78a2b060 ran for 0 msecs: crypto_xcbc_module_init+0x0/0x10()
[   18.780997] Calling initcall 0x78a2b070: init+0x0/0x50()
[   18.786286] initcall 0x78a2b070: init+0x0/0x50() returned 0.
[   18.791915] initcall 0x78a2b070 ran for 0 msecs: init+0x0/0x50()
[   18.797888] Calling initcall 0x78a2b0c0: init+0x0/0x10()
[   18.803182] initcall 0x78a2b0c0: init+0x0/0x10() returned 0.
[   18.808813] initcall 0x78a2b0c0 ran for 0 msecs: init+0x0/0x10()
[   18.814787] Calling initcall 0x78a2b0d0: init+0x0/0x10()
[   18.820081] initcall 0x78a2b0d0: init+0x0/0x10() returned 0.
[   18.825711] initcall 0x78a2b0d0 ran for 0 msecs: init+0x0/0x10()
[   18.831692] Calling initcall 0x78a2b0e0: init+0x0/0x10()
[   18.836980] initcall 0x78a2b0e0: init+0x0/0x10() returned 0.
[   18.842610] initcall 0x78a2b0e0 ran for 0 msecs: init+0x0/0x10()
[   18.848591] Calling initcall 0x78a2b0f0: init+0x0/0x10()
[   18.853879] initcall 0x78a2b0f0: init+0x0/0x10() returned 0.
[   18.859504] initcall 0x78a2b0f0 ran for 0 msecs: init+0x0/0x10()
[   18.865489] Calling initcall 0x78a2b100: crypto_ecb_module_init+0x0/0x10()
[   18.872338] initcall 0x78a2b100: crypto_ecb_module_init+0x0/0x10() returned 0.
[   18.879523] initcall 0x78a2b100 ran for 0 msecs: crypto_ecb_module_init+0x0/0x10()
[   18.887070] Calling initcall 0x78a2b110: crypto_cbc_module_init+0x0/0x10()
[   18.893917] initcall 0x78a2b110: crypto_cbc_module_init+0x0/0x10() returned 0.
[   18.901102] initcall 0x78a2b110 ran for 0 msecs: crypto_cbc_module_init+0x0/0x10()
[   18.908649] Calling initcall 0x78a2b120: crypto_pcbc_module_init+0x0/0x10()
[   18.915582] initcall 0x78a2b120: crypto_pcbc_module_init+0x0/0x10() returned 0.
[   18.922854] initcall 0x78a2b120 ran for 0 msecs: crypto_pcbc_module_init+0x0/0x10()
[   18.930487] Calling initcall 0x78a2b130: init+0x0/0x40()
[   18.935775] initcall 0x78a2b130: init+0x0/0x40() returned 0.
[   18.941399] initcall 0x78a2b130 ran for 0 msecs: init+0x0/0x40()
[   18.947381] Calling initcall 0x78a2b170: init+0x0/0x10()
[   18.952673] initcall 0x78a2b170: init+0x0/0x10() returned 0.
[   18.958303] initcall 0x78a2b170 ran for 0 msecs: init+0x0/0x10()
[   18.964280] Calling initcall 0x78a2b180: init+0x0/0x10()
[   18.969572] initcall 0x78a2b180: init+0x0/0x10() returned 0.
[   18.975203] initcall 0x78a2b180 ran for 0 msecs: init+0x0/0x10()
[   18.981176] Calling initcall 0x78a2b190: init+0x0/0x40()
[   18.986472] initcall 0x78a2b190: init+0x0/0x40() returned 0.
[   18.992101] initcall 0x78a2b190 ran for 0 msecs: init+0x0/0x40()
[   18.998075] Calling initcall 0x78a2b1d0: aes_init+0x0/0x330()
[   19.003820] initcall 0x78a2b1d0: aes_init+0x0/0x330() returned 0.
[   19.009864] initcall 0x78a2b1d0 ran for 0 msecs: aes_init+0x0/0x330()
[   19.016279] Calling initcall 0x78a2b500: camellia_init+0x0/0x10()
[   19.022348] initcall 0x78a2b500: camellia_init+0x0/0x10() returned 0.
[   19.028759] initcall 0x78a2b500 ran for 0 msecs: camellia_init+0x0/0x10()
[   19.035519] Calling initcall 0x78a2b510: init+0x0/0x10()
[   19.040808] initcall 0x78a2b510: init+0x0/0x10() returned 0.
[   19.046435] initcall 0x78a2b510 ran for 0 msecs: init+0x0/0x10()
[   19.052418] Calling initcall 0x78a2b520: init+0x0/0x10()
[   19.057707] initcall 0x78a2b520: init+0x0/0x10() returned 0.
[   19.063334] initcall 0x78a2b520 ran for 0 msecs: init+0x0/0x10()
[   19.069317] Calling initcall 0x78a2b530: arc4_init+0x0/0x10()
[   19.075039] initcall 0x78a2b530: arc4_init+0x0/0x10() returned 0.
[   19.081097] initcall 0x78a2b530 ran for 0 msecs: arc4_init+0x0/0x10()
[   19.087512] Calling initcall 0x78a2b540: init+0x0/0x60()
[   19.092806] initcall 0x78a2b540: init+0x0/0x60() returned 0.
[   19.098435] initcall 0x78a2b540 ran for 0 msecs: init+0x0/0x60()
[   19.104409] Calling initcall 0x78a2b5a0: init+0x0/0x10()
[   19.109706] initcall 0x78a2b5a0: init+0x0/0x10() returned 0.
[   19.115853] initcall 0x78a2b5a0 ran for 0 msecs: init+0x0/0x10()
[   19.121833] Calling initcall 0x78a2b5b0: init+0x0/0x10()
[   19.127123] initcall 0x78a2b5b0: init+0x0/0x10() returned 0.
[   19.132747] initcall 0x78a2b5b0 ran for 0 msecs: init+0x0/0x10()
[   19.138733] Calling initcall 0x78a2b8c0: noop_init+0x0/0x10()
[   19.144460] io scheduler noop registered (default)
[   19.149224] initcall 0x78a2b8c0: noop_init+0x0/0x10() returned 0.
[   19.155285] initcall 0x78a2b8c0 ran for 3 msecs: noop_init+0x0/0x10()
[   19.161697] Calling initcall 0x78a2b8d0: deadline_init+0x0/0x10()
[   19.167762] io scheduler deadline registered
[   19.172016] initcall 0x78a2b8d0: deadline_init+0x0/0x10() returned 0.
[   19.178422] initcall 0x78a2b8d0 ran for 3 msecs: deadline_init+0x0/0x10()
[   19.185182] Calling initcall 0x78a2b9f0: audit_classes_init+0x0/0x50()
[   19.191688] initcall 0x78a2b9f0: audit_classes_init+0x0/0x50() returned 0.
[   19.198528] initcall 0x78a2b9f0 ran for 0 msecs: audit_classes_init+0x0/0x50()
[   19.205721] Calling initcall 0x78a2be10: pci_init+0x0/0x30()
[   19.231480] Boot video device is 0000:01:00.0
[   19.235715] initcall 0x78a2be10: pci_init+0x0/0x30() returned 0.
[   19.241685] initcall 0x78a2be10 ran for 15 msecs: pci_init+0x0/0x30()
[   19.248093] Calling initcall 0x78a2d070: pci_proc_init+0x0/0x70()
[   19.254203] initcall 0x78a2d070: pci_proc_init+0x0/0x70() returned 0.
[   19.260575] initcall 0x78a2d070 ran for 0 msecs: pci_proc_init+0x0/0x70()
[   19.267334] Calling initcall 0x78a2d200: corgibl_init+0x0/0x10()
[   19.273333] initcall 0x78a2d200: corgibl_init+0x0/0x10() returned 0.
[   19.279640] initcall 0x78a2d200 ran for 0 msecs: corgibl_init+0x0/0x10()
[   19.286319] Calling initcall 0x78a2d210: progearbl_init+0x0/0x60()
[   19.292497] ALI M7101 PMU not found.
[   19.296049] initcall 0x78a2d210: progearbl_init+0x0/0x60() returned 0.
[   19.302522] initcall 0x78a2d210 ran for 3 msecs: progearbl_init+0x0/0x60()
[   19.309368] Calling initcall 0x78a2d330: rand_initialize+0x0/0x30()
[   19.315636] initcall 0x78a2d330: rand_initialize+0x0/0x30() returned 0.
[   19.322194] initcall 0x78a2d330 ran for 0 msecs: rand_initialize+0x0/0x30()
[   19.329127] Calling initcall 0x78a2d390: tty_init+0x0/0x1f0()
[   19.335791] initcall 0x78a2d390: tty_init+0x0/0x1f0() returned 0.
[   19.341727] initcall 0x78a2d390 ran for 0 msecs: tty_init+0x0/0x1f0()
[   19.348143] Calling initcall 0x78a2d5b0: pty_init+0x0/0x2a0()
[   19.353868] initcall 0x78a2d5b0: pty_init+0x0/0x2a0() returned 0.
[   19.359923] initcall 0x78a2d5b0 ran for 0 msecs: pty_init+0x0/0x2a0()
[   19.366341] Calling initcall 0x78a2deb0: raw_init+0x0/0xd0()
[   19.372000] initcall 0x78a2deb0: raw_init+0x0/0xd0() returned 0.
[   19.377946] initcall 0x78a2deb0 ran for 0 msecs: raw_init+0x0/0xd0()
[   19.384275] Calling initcall 0x78a2df80: applicom_init+0x0/0x4c0()
[   19.390429] Applicom driver: $Id: ac.c,v 1.30 2000/03/22 16:03:57 dwmw2 Exp $
[   19.397542] ac.o: No PCI boards found.
[   19.401268] ac.o: For an ISA board you must supply memory and irq parameters.
[   19.408376] initcall 0x78a2df80: applicom_init+0x0/0x4c0() returned -6.
[   19.414956] initcall 0x78a2df80 ran for 10 msecs: applicom_init+0x0/0x4c0()
[   19.421891] initcall at 0x78a2df80: applicom_init+0x0/0x4c0(): returned with error code -6
[   19.430124] Calling initcall 0x78a2e440: rtc_init+0x0/0x1b0()
[   19.435871] Real Time Clock Driver v1.12ac
[   19.439921] initcall 0x78a2e440: rtc_init+0x0/0x1b0() returned 0.
[   19.445975] initcall 0x78a2e440 ran for 0 msecs: rtc_init+0x0/0x1b0()
[   19.452393] Calling initcall 0x78a2e5f0: nvram_init+0x0/0x80()
[   19.458216] Non-volatile memory driver v1.2
[   19.462366] initcall 0x78a2e5f0: nvram_init+0x0/0x80() returned 0.
[   19.468513] initcall 0x78a2e5f0 ran for 3 msecs: nvram_init+0x0/0x80()
[   19.475012] Calling initcall 0x78a2e670: i8k_init+0x0/0x250()
[   19.480736] initcall 0x78a2e670: i8k_init+0x0/0x250() returned -19.
[   19.486968] initcall 0x78a2e670 ran for 0 msecs: i8k_init+0x0/0x250()
[   19.493382] Calling initcall 0x78a2e8c0: mod_init+0x0/0x210()
[   19.499115] initcall 0x78a2e8c0: mod_init+0x0/0x210() returned -19.
[   19.505344] initcall 0x78a2e8c0 ran for 0 msecs: mod_init+0x0/0x210()
[   19.511756] Calling initcall 0x78a2ebc0: mod_init+0x0/0xb0()
[   19.517396] initcall 0x78a2ebc0: mod_init+0x0/0xb0() returned -19.
[   19.523540] initcall 0x78a2ebc0 ran for 0 msecs: mod_init+0x0/0xb0()
[   19.529871] Calling initcall 0x78a2ec70: cs5535_gpio_init+0x0/0x1d0()
[   19.536283] cs5535_gpio: DIVIL not found
[   19.540187] initcall 0x78a2ec70: cs5535_gpio_init+0x0/0x1d0() returned -19.
[   19.547111] initcall 0x78a2ec70 ran for 0 msecs: cs5535_gpio_init+0x0/0x1d0()
[   19.554218] Calling initcall 0x78a2ee40: mwave_init+0x0/0x340()
[   19.560119] smapi::smapi_init, ERROR invalid usSmapiID
[   19.565230] mwave: tp3780i::tp3780I_InitializeBoardData: Error: SMAPI is not available on this machine
[   19.574502] mwave: mwavedd::mwave_init: Error: Failed to initialize board data
[   19.581694] mwave: mwavedd::mwave_init: Error: Failed to initialize
[   19.587939] initcall 0x78a2ee40: mwave_init+0x0/0x340() returned -5.
[   19.594252] initcall 0x78a2ee40 ran for 13 msecs: mwave_init+0x0/0x340()
[   19.600928] initcall at 0x78a2ee40: mwave_init+0x0/0x340(): returned with error code -5
[   19.608905] Calling initcall 0x78a2f1c0: agp_init+0x0/0x30()
[   19.614536] Linux agpgart interface v0.102
[   19.618616] initcall 0x78a2f1c0: agp_init+0x0/0x30() returned 0.
[   19.624584] initcall 0x78a2f1c0 ran for 2 msecs: agp_init+0x0/0x30()
[   19.630912] Calling initcall 0x78a2f360: agp_ali_init+0x0/0x30()
[   19.636916] initcall 0x78a2f360: agp_ali_init+0x0/0x30() returned 0.
[   19.643218] initcall 0x78a2f360 ran for 0 msecs: agp_ali_init+0x0/0x30()
[   19.649896] Calling initcall 0x78a2f470: agp_ati_init+0x0/0x30()
[   19.655892] initcall 0x78a2f470: agp_ati_init+0x0/0x30() returned 0.
[   19.662201] initcall 0x78a2f470 ran for 0 msecs: agp_ati_init+0x0/0x30()
[   19.668873] Calling initcall 0x78a2fc10: agp_amd64_init+0x0/0xd0()
[   19.675045] initcall 0x78a2fc10: agp_amd64_init+0x0/0xd0() returned 0.
[   19.681526] initcall 0x78a2fc10 ran for 0 msecs: agp_amd64_init+0x0/0xd0()
[   19.688375] Calling initcall 0x78a2fe40: agp_nvidia_init+0x0/0x30()
[   19.694634] initcall 0x78a2fe40: agp_nvidia_init+0x0/0x30() returned 0.
[   19.701192] initcall 0x78a2fe40 ran for 0 msecs: agp_nvidia_init+0x0/0x30()
[   19.708134] Calling initcall 0x78a2ffc0: agp_sis_init+0x0/0x30()
[   19.714134] initcall 0x78a2ffc0: agp_sis_init+0x0/0x30() returned 0.
[   19.720434] initcall 0x78a2ffc0 ran for 0 msecs: agp_sis_init+0x0/0x30()
[   19.727107] Calling initcall 0x78a2fff0: drm_core_init+0x0/0x140()
[   19.733287] [drm] Initialized drm 1.1.0 20060810
[   19.737863] initcall 0x78a2fff0: drm_core_init+0x0/0x140() returned 0.
[   19.744350] initcall 0x78a2fff0 ran for 4 msecs: drm_core_init+0x0/0x140()
[   19.751199] Calling initcall 0x78a30130: tdfx_init+0x0/0x10()
[   19.756927] initcall 0x78a30130: tdfx_init+0x0/0x10() returned 0.
[   19.762985] initcall 0x78a30130 ran for 0 msecs: tdfx_init+0x0/0x10()
[   19.769400] Calling initcall 0x78a30140: radeon_init+0x0/0x20()
[   19.775505] [drm] Initialized radeon 1.28.0 20060524 on minor 0
[   19.781313] initcall 0x78a30140: radeon_init+0x0/0x20() returned 0.
[   19.787533] initcall 0x78a30140 ran for 2 msecs: radeon_init+0x0/0x20()
[   19.794122] Calling initcall 0x78a30160: mga_init+0x0/0x20()
[   19.799761] initcall 0x78a30160: mga_init+0x0/0x20() returned 0.
[   19.805737] initcall 0x78a30160 ran for 0 msecs: mga_init+0x0/0x20()
[   19.812064] Calling initcall 0x78a30180: sis_init+0x0/0x20()
[   19.817701] initcall 0x78a30180: sis_init+0x0/0x20() returned 0.
[   19.823673] initcall 0x78a30180 ran for 0 msecs: sis_init+0x0/0x20()
[   19.830000] Calling initcall 0x78a301a0: via_init+0x0/0x20()
[   19.835643] initcall 0x78a301a0: via_init+0x0/0x20() returned 0.
[   19.841616] initcall 0x78a301a0 ran for 0 msecs: via_init+0x0/0x20()
[   19.847938] Calling initcall 0x78a30280: hangcheck_init+0x0/0xb0()
[   19.854093] Hangcheck: starting hangcheck timer 0.9.0 (tick is 180 seconds, margin is 60 seconds).
[   19.863023] Hangcheck: Using get_cycles().
[   19.867101] initcall 0x78a30280: hangcheck_init+0x0/0xb0() returned 0.
[   19.873590] initcall 0x78a30280 ran for 5 msecs: hangcheck_init+0x0/0xb0()
[   19.880437] Calling initcall 0x78a307c0: serial8250_init+0x0/0x140()
[   19.886764] Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing disabled
[   19.894722] serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
[   19.900777] initcall 0x78a307c0: serial8250_init+0x0/0x140() returned 0.
[   19.907319] initcall 0x78a307c0 ran for 10 msecs: serial8250_init+0x0/0x140()
[   19.914425] Calling initcall 0x78a30ef0: mca_init+0x0/0x20()
[   19.920063] initcall 0x78a30ef0: mca_init+0x0/0x20() returned -19.
[   19.926211] initcall 0x78a30ef0 ran for 0 msecs: mca_init+0x0/0x20()
[   19.932540] Calling initcall 0x78a30f10: jsm_init_module+0x0/0x40()
[   19.938812] initcall 0x78a30f10: jsm_init_module+0x0/0x40() returned 0.
[   19.945366] initcall 0x78a30f10 ran for 0 msecs: jsm_init_module+0x0/0x40()
[   19.952299] Calling initcall 0x78a311a0: e1000_init_module+0x0/0x90()
[   19.958710] Intel(R) PRO/1000 Network Driver - version 7.3.20-k2
[   19.964694] Copyright (c) 1999-2006 Intel Corporation.
[   19.969829] initcall 0x78a311a0: e1000_init_module+0x0/0x90() returned 0.
[   19.976561] initcall 0x78a311a0 ran for 4 msecs: e1000_init_module+0x0/0x90()
[   19.983673] Calling initcall 0x78a33190: e100_init_module+0x0/0x60()
[   19.989995] e100: Intel(R) PRO/100 Network Driver, 3.5.23-k4-NAPI
[   19.996065] e100: Copyright(c) 1999-2006 Intel Corporation
[   20.001546] initcall 0x78a33190: e100_init_module+0x0/0x60() returned 0.
[   20.008195] initcall 0x78a33190 ran for 7 msecs: e100_init_module+0x0/0x60()
[   20.015218] Calling initcall 0x78a339a0: net_olddevs_init+0x0/0x90()
[   20.021547] initcall 0x78a339a0: net_olddevs_init+0x0/0x90() returned 0.
[   20.028214] initcall 0x78a339a0 ran for 0 msecs: net_olddevs_init+0x0/0x90()
[   20.035236] Calling initcall 0x78a33ad0: init_nic+0x0/0x20()
[   20.040881] forcedeth: Reverse Engineered nForce ethernet driver. Version 0.61.
[   20.048197] PCI: Setting latency timer of device 0000:00:0a.0 to 64
[   20.571522] forcedeth 0000:00:0a.0: ifname eth0, PHY OUI 0x5043 @ 1, addr 00:13:d4:dc:41:12
[   20.579774] forcedeth 0000:00:0a.0: highdma csum timirq gbit lnktim desc-v3
[   20.586718] initcall 0x78a33ad0: init_nic+0x0/0x20() returned 0.
[   20.592677] initcall 0x78a33ad0 ran for 506 msecs: init_nic+0x0/0x20()
[   20.599180] Calling initcall 0x78a352f0: rtl8139_init_module+0x0/0x20()
[   20.605785] 8139too Fast Ethernet driver 0.9.28
[   20.610640] eth1: RealTek RTL8139 at 0xb8820000, 00:c0:df:03:68:5d, IRQ 11
[   20.617385] eth1:  Identified 8139 chip type 'RTL-8139B'
[   20.622678] initcall 0x78a352f0: rtl8139_init_module+0x0/0x20() returned 0.
[   20.629596] initcall 0x78a352f0 ran for 9 msecs: rtl8139_init_module+0x0/0x20()
[   20.636881] Calling initcall 0x78a35d20: ipddp_init_module+0x0/0x110()
[   20.643378] ipddp.c:v0.01 8/28/97 Bradford W. Johnson <johns393@maroon.tc.umn.edu>
[   20.651020] ipddp0: Appletalk-IP Decap. mode by Jay Schulist <jschlst@samba.org>
[   20.658317] initcall 0x78a35d20: ipddp_init_module+0x0/0x110() returned 0.
[   20.665156] initcall 0x78a35d20 ran for 7 msecs: ipddp_init_module+0x0/0x110()
[   20.672349] Calling initcall 0x78a35e30: usb_irda_init+0x0/0x50()
[   20.678422] usbcore: registered new interface driver irda-usb
[   20.684145] USB IrDA support registered
[   20.687955] initcall 0x78a35e30: usb_irda_init+0x0/0x50() returned 0.
[   20.694881] initcall 0x78a35e30 ran for 5 msecs: usb_irda_init+0x0/0x50()
[   20.701643] Calling initcall 0x78a35e80: w83977af_init+0x0/0x520()
[   20.707843] initcall 0x78a35e80: w83977af_init+0x0/0x520() returned -19.
[   20.714461] initcall 0x78a35e80 ran for 0 msecs: w83977af_init+0x0/0x520()
[   20.721315] Calling initcall 0x78a363a0: donauboe_init+0x0/0x20()
[   20.727402] initcall 0x78a363a0: donauboe_init+0x0/0x20() returned 0.
[   20.733789] initcall 0x78a363a0 ran for 0 msecs: donauboe_init+0x0/0x20()
[   20.740548] Calling initcall 0x78a372d0: smsc_ircc_init+0x0/0x5c0()
[   20.746922] initcall 0x78a372d0: smsc_ircc_init+0x0/0x5c0() returned -19.
[   20.753548] initcall 0x78a372d0 ran for 0 msecs: smsc_ircc_init+0x0/0x5c0()
[   20.760481] Calling initcall 0x78a37b50: ali_ircc_init+0x0/0x6a0()
[   20.766693] initcall 0x78a37b50: ali_ircc_init+0x0/0x6a0() returned -19.
[   20.773306] initcall 0x78a37b50 ran for 0 msecs: ali_ircc_init+0x0/0x6a0()
[   20.780158] Calling initcall 0x78a381f0: vlsi_mod_init+0x0/0x130()
[   20.786333] initcall 0x78a381f0: vlsi_mod_init+0x0/0x130() returned 0.
[   20.792805] initcall 0x78a381f0 ran for 0 msecs: vlsi_mod_init+0x0/0x130()
[   20.799657] Calling initcall 0x78a38c10: via_ircc_init+0x0/0x20()
[   20.805742] initcall 0x78a38c10: via_ircc_init+0x0/0x20() returned 0.
[   20.812134] initcall 0x78a38c10 ran for 0 msecs: via_ircc_init+0x0/0x20()
[   20.818893] Calling initcall 0x78a38ff0: irtty_sir_init+0x0/0x40()
[   20.825048] initcall 0x78a38ff0: irtty_sir_init+0x0/0x40() returned 0.
[   20.831546] initcall 0x78a38ff0 ran for 0 msecs: irtty_sir_init+0x0/0x40()
[   20.838392] Calling initcall 0x78a39030: sir_wq_init+0x0/0x20()
[   20.844320] initcall 0x78a39030: sir_wq_init+0x0/0x20() returned 0.
[   20.850521] initcall 0x78a39030 ran for 0 msecs: sir_wq_init+0x0/0x20()
[   20.857107] Calling initcall 0x78a39050: ksdazzle_init+0x0/0x20()
[   20.863183] usbcore: registered new interface driver ksdazzle-sir
[   20.869250] initcall 0x78a39050: ksdazzle_init+0x0/0x20() returned 0.
[   20.875656] initcall 0x78a39050 ran for 5 msecs: ksdazzle_init+0x0/0x20()
[   20.882416] Calling initcall 0x78a39090: init_netconsole+0x0/0x1a0()
[   20.888743] console [netcon0] enabled
[   27.186511] netconsole: network logging started
[   27.191020] initcall 0x78a39090: init_netconsole+0x0/0x1a0() returned 0.
[   27.197685] initcall 0x78a39090 ran for 9 msecs: init_netconsole+0x0/0x1a0()
[   27.204706] Calling initcall 0x78a39590: raid_init+0x0/0x10()
[   27.210433] initcall 0x78a39590: raid_init+0x0/0x10() returned 0.
[   27.216486] initcall 0x78a39590 ran for 0 msecs: raid_init+0x0/0x10()
[   27.222902] Calling initcall 0x78a395a0: spi_transport_init+0x0/0x30()
[   27.229426] initcall 0x78a395a0: spi_transport_init+0x0/0x30() returned 0.
[   27.236247] initcall 0x78a395a0 ran for 0 msecs: spi_transport_init+0x0/0x30()
[   27.243440] Calling initcall 0x78a395d0: fc_transport_init+0x0/0x50()
[   27.249875] initcall 0x78a395d0: fc_transport_init+0x0/0x50() returned 0.
[   27.256610] initcall 0x78a395d0 ran for 0 msecs: fc_transport_init+0x0/0x50()
[   27.263724] Calling initcall 0x78a39620: iscsi_transport_init+0x0/0xe0()
[   27.270393] Loading iSCSI transport class v2.0-724.
[   27.275282] initcall 0x78a39620: iscsi_transport_init+0x0/0xe0() returned 0.
[   27.282264] initcall 0x78a39620 ran for 1 msecs: iscsi_transport_init+0x0/0xe0()
[   27.289636] Calling initcall 0x78a39700: sas_transport_init+0x0/0xa0()
[   27.296185] initcall 0x78a39700: sas_transport_init+0x0/0xa0() returned 0.
[   27.302976] initcall 0x78a39700 ran for 0 msecs: sas_transport_init+0x0/0xa0()
[   27.310169] Calling initcall 0x78a397a0: sas_class_init+0x0/0x40()
[   27.316328] initcall 0x78a397a0: sas_class_init+0x0/0x40() returned 0.
[   27.322822] initcall 0x78a397a0 ran for 0 msecs: sas_class_init+0x0/0x40()
[   27.329668] Calling initcall 0x78a397e0: init_sd+0x0/0xd0()
[   27.335269] initcall 0x78a397e0: init_sd+0x0/0xd0() returned 0.
[   27.341110] initcall 0x78a397e0 ran for 0 msecs: init_sd+0x0/0xd0()
[   27.347350] Calling initcall 0x78a398b0: init_ch_module+0x0/0xa0()
[   27.353500] SCSI Media Changer driver v0.25 
[   27.357781] initcall 0x78a398b0: init_ch_module+0x0/0xa0() returned 0.
[   27.364249] initcall 0x78a398b0 ran for 3 msecs: init_ch_module+0x0/0xa0()
[   27.371095] Calling initcall 0x78a399c0: ahci_init+0x0/0x20()
[   27.376852] initcall 0x78a399c0: ahci_init+0x0/0x20() returned 0.
[   27.382878] initcall 0x78a399c0 ran for 2 msecs: ahci_init+0x0/0x20()
[   27.389291] Calling initcall 0x78a399e0: piix_init+0x0/0x20()
[   27.395037] initcall 0x78a399e0: piix_init+0x0/0x20() returned 0.
[   27.401080] initcall 0x78a399e0 ran for 0 msecs: piix_init+0x0/0x20()
[   27.407492] Calling initcall 0x78a39a00: pdc_ata_init+0x0/0x20()
[   27.413496] initcall 0x78a39a00: pdc_ata_init+0x0/0x20() returned 0.
[   27.419793] initcall 0x78a39a00 ran for 0 msecs: pdc_ata_init+0x0/0x20()
[   27.426468] Calling initcall 0x78a39a20: qs_ata_init+0x0/0x20()
[   27.432386] initcall 0x78a39a20: qs_ata_init+0x0/0x20() returned 0.
[   27.438601] initcall 0x78a39a20 ran for 0 msecs: qs_ata_init+0x0/0x20()
[   27.445193] Calling initcall 0x78a39d00: vsc_sata_init+0x0/0x20()
[   27.451279] initcall 0x78a39d00: vsc_sata_init+0x0/0x20() returned 0.
[   27.457670] initcall 0x78a39d00 ran for 0 msecs: vsc_sata_init+0x0/0x20()
[   27.464429] Calling initcall 0x78a39d20: nv_init+0x0/0x20()
[   27.469998] initcall 0x78a39d20: nv_init+0x0/0x20() returned 0.
[   27.475866] initcall 0x78a39d20 ran for 0 msecs: nv_init+0x0/0x20()
[   27.482105] Calling initcall 0x78a39d40: mv_init+0x0/0x20()
[   27.487677] initcall 0x78a39d40: mv_init+0x0/0x20() returned 0.
[   27.493547] initcall 0x78a39d40 ran for 0 msecs: mv_init+0x0/0x20()
[   27.499784] Calling initcall 0x78a39d60: inic_init+0x0/0x20()
[   27.505530] initcall 0x78a39d60: inic_init+0x0/0x20() returned 0.
[   27.511567] initcall 0x78a39d60 ran for 0 msecs: inic_init+0x0/0x20()
[   27.517985] Calling initcall 0x78a39d80: amd_init+0x0/0x20()
[   27.523647] pata_amd 0000:00:06.0: version 0.3.9
[   27.528329] PCI: Setting latency timer of device 0000:00:06.0 to 64
[   27.534566] scsi0 : pata_amd
[   27.537401] scsi1 : pata_amd
[   27.540228] ata1: PATA max UDMA/133 cmd 0x1f0 ctl 0x3f6 bmdma 0xf000 irq 14
[   27.547125] ata2: PATA max UDMA/133 cmd 0x170 ctl 0x376 bmdma 0xf008 irq 15
[   27.880496] ata1.00: ATA-5: MAXTOR 6L040J2, AR1.0500, max UDMA/133
[   27.886551] ata1.00: 78177792 sectors, multi 1: LBA 
[   27.891771] ata1.01: ATA-6: ST380011A, 3.06, max UDMA/100
[   27.897046] ata1.01: 156301488 sectors, multi 1: LBA48 
[   27.913730] ata1.00: configured for UDMA/133
[   27.930394] ata1.01: configured for UDMA/100
[   28.097846] scsi 0:0:0:0: Direct-Access     ATA      MAXTOR 6L040J2   AR1. PQ: 0 ANSI: 5
[   28.106020] sd 0:0:0:0: [sda] 78177792 512-byte hardware sectors (40027 MB)
[   28.112875] sd 0:0:0:0: [sda] Write Protect is off
[   28.117624] sd 0:0:0:0: [sda] Mode Sense: 00 3a 00 00
[   28.122679] sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[   28.131925] sd 0:0:0:0: [sda] 78177792 512-byte hardware sectors (40027 MB)
[   28.138776] sd 0:0:0:0: [sda] Write Protect is off
[   28.143527] sd 0:0:0:0: [sda] Mode Sense: 00 3a 00 00
[   28.148582] sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[   28.157590]  sda: sda1 sda2 sda3 sda4 < sda5 >
[   28.198720] sd 0:0:0:0: [sda] Attached SCSI disk
[   28.203319] scsi 0:0:1:0: Direct-Access     ATA      ST380011A        3.06 PQ: 0 ANSI: 5
[   28.211420] sd 0:0:1:0: [sdb] 156301488 512-byte hardware sectors (80026 MB)
[   28.218361] sd 0:0:1:0: [sdb] Write Protect is off
[   28.223108] sd 0:0:1:0: [sdb] Mode Sense: 00 3a 00 00
[   28.228167] sd 0:0:1:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[   28.237253] sd 0:0:1:0: [sdb] 156301488 512-byte hardware sectors (80026 MB)
[   28.244203] sd 0:0:1:0: [sdb] Write Protect is off
[   28.248942] sd 0:0:1:0: [sdb] Mode Sense: 00 3a 00 00
[   28.254021] sd 0:0:1:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[   28.262984]  sdb: sdb1 sdb2 sdb3 < sdb5 >
[   28.285871] sd 0:0:1:0: [sdb] Attached SCSI disk
[   28.290406] initcall 0x78a39d80: amd_init+0x0/0x20() returned 0.
[   28.296336] initcall 0x78a39d80 ran for 648 msecs: amd_init+0x0/0x20()
[   28.302839] Calling initcall 0x78a39da0: artop_init+0x0/0x20()
[   28.308674] initcall 0x78a39da0: artop_init+0x0/0x20() returned 0.
[   28.314796] initcall 0x78a39da0 ran for 0 msecs: artop_init+0x0/0x20()
[   28.321301] Calling initcall 0x78a39dc0: atiixp_init+0x0/0x20()
[   28.327217] initcall 0x78a39dc0: atiixp_init+0x0/0x20() returned 0.
[   28.333953] initcall 0x78a39dc0 ran for 0 msecs: atiixp_init+0x0/0x20()
[   28.340539] Calling initcall 0x78a39de0: cmd640_init+0x0/0x20()
[   28.346454] initcall 0x78a39de0: cmd640_init+0x0/0x20() returned 0.
[   28.352669] initcall 0x78a39de0 ran for 0 msecs: cmd640_init+0x0/0x20()
[   28.359254] Calling initcall 0x78a39e00: cmd64x_init+0x0/0x20()
[   28.365176] initcall 0x78a39e00: cmd64x_init+0x0/0x20() returned 0.
[   28.371385] initcall 0x78a39e00 ran for 0 msecs: cmd64x_init+0x0/0x20()
[   28.377977] Calling initcall 0x78a39e20: cs5535_init+0x0/0x20()
[   28.383893] initcall 0x78a39e20: cs5535_init+0x0/0x20() returned 0.
[   28.390109] initcall 0x78a39e20 ran for 0 msecs: cs5535_init+0x0/0x20()
[   28.396698] Calling initcall 0x78a39e40: cy82c693_init+0x0/0x20()
[   28.402785] initcall 0x78a39e40: cy82c693_init+0x0/0x20() returned 0.
[   28.409171] initcall 0x78a39e40 ran for 0 msecs: cy82c693_init+0x0/0x20()
[   28.415931] Calling initcall 0x78a39e60: hpt37x_init+0x0/0x20()
[   28.421853] initcall 0x78a39e60: hpt37x_init+0x0/0x20() returned 0.
[   28.428061] initcall 0x78a39e60 ran for 0 msecs: hpt37x_init+0x0/0x20()
[   28.434653] Calling initcall 0x78a39e80: hpt3x2n_init+0x0/0x20()
[   28.440657] initcall 0x78a39e80: hpt3x2n_init+0x0/0x20() returned 0.
[   28.446959] initcall 0x78a39e80 ran for 0 msecs: hpt3x2n_init+0x0/0x20()
[   28.453634] Calling initcall 0x78a39ea0: hpt3x3_init+0x0/0x20()
[   28.459547] initcall 0x78a39ea0: hpt3x3_init+0x0/0x20() returned 0.
[   28.465762] initcall 0x78a39ea0 ran for 0 msecs: hpt3x3_init+0x0/0x20()
[   28.472347] Calling initcall 0x78a39ec0: it8213_init+0x0/0x20()
[   28.478266] initcall 0x78a39ec0: it8213_init+0x0/0x20() returned 0.
[   28.484483] initcall 0x78a39ec0 ran for 0 msecs: it8213_init+0x0/0x20()
[   28.491069] Calling initcall 0x78a39ee0: netcell_init+0x0/0x20()
[   28.497070] initcall 0x78a39ee0: netcell_init+0x0/0x20() returned 0.
[   28.503375] initcall 0x78a39ee0 ran for 0 msecs: netcell_init+0x0/0x20()
[   28.510051] Calling initcall 0x78a39f00: ns87410_init+0x0/0x20()
[   28.516051] initcall 0x78a39f00: ns87410_init+0x0/0x20() returned 0.
[   28.522351] initcall 0x78a39f00 ran for 0 msecs: ns87410_init+0x0/0x20()
[   28.529024] Calling initcall 0x78a39f20: ns87415_init+0x0/0x20()
[   28.535029] initcall 0x78a39f20: ns87415_init+0x0/0x20() returned 0.
[   28.541328] initcall 0x78a39f20 ran for 0 msecs: ns87415_init+0x0/0x20()
[   28.548006] Calling initcall 0x78a39f40: opti_init+0x0/0x20()
[   28.553753] initcall 0x78a39f40: opti_init+0x0/0x20() returned 0.
[   28.559787] initcall 0x78a39f40 ran for 0 msecs: opti_init+0x0/0x20()
[   28.566202] Calling initcall 0x78a39f60: marvell_init+0x0/0x20()
[   28.572210] initcall 0x78a39f60: marvell_init+0x0/0x20() returned 0.
[   28.578508] initcall 0x78a39f60 ran for 0 msecs: marvell_init+0x0/0x20()
[   28.585186] Calling initcall 0x78a39f80: mpiix_init+0x0/0x20()
[   28.591012] initcall 0x78a39f80: mpiix_init+0x0/0x20() returned 0.
[   28.597143] initcall 0x78a39f80 ran for 0 msecs: mpiix_init+0x0/0x20()
[   28.603644] Calling initcall 0x78a39fa0: oldpiix_init+0x0/0x20()
[   28.609645] initcall 0x78a39fa0: oldpiix_init+0x0/0x20() returned 0.
[   28.615945] initcall 0x78a39fa0 ran for 0 msecs: oldpiix_init+0x0/0x20()
[   28.622618] Calling initcall 0x78a39fc0: pdc202xx_init+0x0/0x20()
[   28.628710] initcall 0x78a39fc0: pdc202xx_init+0x0/0x20() returned 0.
[   28.635098] initcall 0x78a39fc0 ran for 0 msecs: pdc202xx_init+0x0/0x20()
[   28.641862] Calling initcall 0x78a39fe0: serverworks_init+0x0/0x20()
[   28.648210] initcall 0x78a39fe0: serverworks_init+0x0/0x20() returned 0.
[   28.654854] initcall 0x78a39fe0 ran for 0 msecs: serverworks_init+0x0/0x20()
[   28.661881] Calling initcall 0x78a3a440: sil680_init+0x0/0x20()
[   28.667793] initcall 0x78a3a440: sil680_init+0x0/0x20() returned 0.
[   28.674011] initcall 0x78a3a440 ran for 0 msecs: sil680_init+0x0/0x20()
[   28.680598] Calling initcall 0x78a3a460: via_init+0x0/0x20()
[   28.686263] initcall 0x78a3a460: via_init+0x0/0x20() returned 0.
[   28.692207] initcall 0x78a3a460 ran for 0 msecs: via_init+0x0/0x20()
[   28.698533] Calling initcall 0x78a3a480: triflex_init+0x0/0x20()
[   28.704539] initcall 0x78a3a480: triflex_init+0x0/0x20() returned 0.
[   28.710842] initcall 0x78a3a480 ran for 0 msecs: triflex_init+0x0/0x20()
[   28.717515] Calling initcall 0x78a3a4a0: pata_platform_init+0x0/0x10()
[   28.724030] initcall 0x78a3a4a0: pata_platform_init+0x0/0x10() returned 0.
[   28.730861] initcall 0x78a3a4a0 ran for 0 msecs: pata_platform_init+0x0/0x10()
[   28.738054] Calling initcall 0x78a3a810: ata_generic_init+0x0/0x20()
[   28.744426] initcall 0x78a3a810: ata_generic_init+0x0/0x20() returned 0.
[   28.751053] initcall 0x78a3a810 ran for 0 msecs: ata_generic_init+0x0/0x20()
[   28.758073] Calling initcall 0x78a3a830: i2o_iop_init+0x0/0x50()
[   28.764051] I2O subsystem v1.325
[   28.767262] i2o: max drivers = 8
[   28.770544] initcall 0x78a3a830: i2o_iop_init+0x0/0x50() returned 0.
[   28.776796] initcall 0x78a3a830 ran for 6 msecs: i2o_iop_init+0x0/0x50()
[   28.783467] Calling initcall 0x78a3b1a0: i2o_config_init+0x0/0xa0()
[   28.789703] I2O Configuration OSM v1.323
[   28.793629] initcall 0x78a3b1a0: i2o_config_init+0x0/0xa0() returned 0.
[   28.800191] initcall 0x78a3b1a0 ran for 3 msecs: i2o_config_init+0x0/0xa0()
[   28.807125] Calling initcall 0x78a3b240: i2o_bus_init+0x0/0x40()
[   28.813101] I2O Bus Adapter OSM v1.317
[   28.816841] initcall 0x78a3b240: i2o_bus_init+0x0/0x40() returned 0.
[   28.823150] initcall 0x78a3b240 ran for 2 msecs: i2o_bus_init+0x0/0x40()
[   28.829825] Calling initcall 0x78a3b280: i2o_block_init+0x0/0x120()
[   28.836066] I2O Block Device OSM v1.325
[   28.840017] initcall 0x78a3b280: i2o_block_init+0x0/0x120() returned 0.
[   28.846470] initcall 0x78a3b280 ran for 6 msecs: i2o_block_init+0x0/0x120()
[   28.853411] Calling initcall 0x78a3b3a0: i2o_proc_init+0x0/0x190()
[   28.859560] I2O ProcFS OSM v1.316
[   28.862870] initcall 0x78a3b3a0: i2o_proc_init+0x0/0x190() returned 0.
[   28.869351] initcall 0x78a3b3a0 ran for 2 msecs: i2o_proc_init+0x0/0x190()
[   28.876197] Calling initcall 0x78a3b530: fusion_init+0x0/0x110()
[   28.882179] Fusion MPT base driver 3.04.06
[   28.886256] Copyright (c) 1999-2007 LSI Corporation
[   28.891118] initcall 0x78a3b530: fusion_init+0x0/0x110() returned 0.
[   28.897432] initcall 0x78a3b530 ran for 8 msecs: fusion_init+0x0/0x110()
[   28.904105] Calling initcall 0x78a3b640: mptspi_init+0x0/0xd0()
[   28.910002] Fusion MPT SPI Host driver 3.04.06
[   28.914443] initcall 0x78a3b640: mptspi_init+0x0/0xd0() returned 0.
[   28.920658] initcall 0x78a3b640 ran for 4 msecs: mptspi_init+0x0/0xd0()
[   28.927244] Calling initcall 0x78a3b710: mptfc_init+0x0/0xf0()
[   28.933048] Fusion MPT FC Host driver 3.04.06
[   28.937411] initcall 0x78a3b710: mptfc_init+0x0/0xf0() returned 0.
[   28.943536] initcall 0x78a3b710 ran for 3 msecs: mptfc_init+0x0/0xf0()
[   28.950038] Calling initcall 0x78a3b800: mptsas_init+0x0/0xf0()
[   28.955928] Fusion MPT SAS Host driver 3.04.06
[   28.960376] initcall 0x78a3b800: mptsas_init+0x0/0xf0() returned 0.
[   28.966583] initcall 0x78a3b800 ran for 3 msecs: mptsas_init+0x0/0xf0()
[   28.973172] Calling initcall 0x78a3b8f0: mptctl_init+0x0/0x100()
[   28.979153] Fusion MPT misc device (ioctl) driver 3.04.06
[   28.984540] mptctl: Registered with Fusion MPT base driver
[   28.989990] mptctl: /dev/mptctl @ (major,minor=10,220)
[   28.995107] initcall 0x78a3b8f0: mptctl_init+0x0/0x100() returned 0.
[   29.001420] initcall 0x78a3b8f0 ran for 7 msecs: mptctl_init+0x0/0x100()
[   29.008099] Calling initcall 0x78a3b9f0: ieee1394_init+0x0/0x250()
[   29.014345] initcall 0x78a3b9f0: ieee1394_init+0x0/0x250() returned 0.
[   29.020751] initcall 0x78a3b9f0 ran for 0 msecs: ieee1394_init+0x0/0x250()
[   29.027599] Calling initcall 0x78a3bc40: ohci1394_init+0x0/0x20()
[   29.033681] initcall 0x78a3bc40: ohci1394_init+0x0/0x20() returned 0.
[   29.040077] initcall 0x78a3bc40 ran for 0 msecs: ohci1394_init+0x0/0x20()
[   29.046839] Calling initcall 0x78a3c6b0: video1394_init_module+0x0/0xc0()
[   29.053607] video1394: Installed video1394 module
[   29.058282] initcall 0x78a3c6b0: video1394_init_module+0x0/0xc0() returned 0.
[   29.065379] initcall 0x78a3c6b0 ran for 4 msecs: video1394_init_module+0x0/0xc0()
[   29.072837] Calling initcall 0x78538420: sbp2_module_init+0x0/0xa0()
[   29.079173] initcall 0x78538420: sbp2_module_init+0x0/0xa0() returned 0.
[   29.085831] initcall 0x78538420 ran for 0 msecs: sbp2_module_init+0x0/0xa0()
[   29.092850] Calling initcall 0x78a3c770: dv1394_init_module+0x0/0xc0()
[   29.099351] NOTE: The dv1394 driver is unsupported and may be removed in a future Linux release. Use raw1394 instead.
[   29.109942] initcall 0x78a3c770: dv1394_init_module+0x0/0xc0() returned 0.
[   29.116772] initcall 0x78a3c770 ran for 3 msecs: dv1394_init_module+0x0/0xc0()
[   29.123967] Calling initcall 0x78a3c830: ether1394_init_module+0x0/0x70()
[   29.130736] initcall 0x78a3c830: ether1394_init_module+0x0/0x70() returned 0.
[   29.137825] initcall 0x78a3c830 ran for 0 msecs: ether1394_init_module+0x0/0x70()
[   29.145286] Calling initcall 0x78a3c8a0: uio_init+0x0/0x10()
[   29.150918] initcall 0x78a3c8a0: uio_init+0x0/0x10() returned 0.
[   29.156896] initcall 0x78a3c8a0 ran for 0 msecs: uio_init+0x0/0x10()
[   29.163219] Calling initcall 0x78a3c9c0: at25_init+0x0/0x10()
[   29.168950] initcall 0x78a3c9c0: at25_init+0x0/0x10() returned 0.
[   29.175005] initcall 0x78a3c9c0 ran for 0 msecs: at25_init+0x0/0x10()
[   29.181421] Calling initcall 0x78a3c9d0: tle62x0_init+0x0/0x10()
[   29.187409] initcall 0x78a3c9d0: tle62x0_init+0x0/0x10() returned 0.
[   29.193728] initcall 0x78a3c9d0 ran for 0 msecs: tle62x0_init+0x0/0x10()
[   29.200403] Calling initcall 0x78a3cb90: kvm_init+0x0/0x120()
[   29.206195] initcall 0x78a3cb90: kvm_init+0x0/0x120() returned 0.
[   29.212183] initcall 0x78a3cb90 ran for 0 msecs: kvm_init+0x0/0x120()
[   29.218596] Calling initcall 0x78a3d000: vmx_init+0x0/0x110()
[   29.224329] kvm: no hardware support
[   29.227883] initcall 0x78a3d000: vmx_init+0x0/0x110() returned -95.
[   29.234111] initcall 0x78a3d000 ran for 3 msecs: vmx_init+0x0/0x110()
[   29.240524] initcall at 0x78a3d000: vmx_init+0x0/0x110(): returned with error code -95
[   29.248413] Calling initcall 0x78a3d110: svm_init+0x0/0x20()
[   29.254042] has_svm: svm not available
[   29.257772] kvm: no hardware support
[   29.261330] initcall 0x78a3d110: svm_init+0x0/0x20() returned -95.
[   29.267476] initcall 0x78a3d110 ran for 6 msecs: svm_init+0x0/0x20()
[   29.273803] initcall at 0x78a3d110: svm_init+0x0/0x20(): returned with error code -95
[   29.281604] Calling initcall 0x78a3d450: mon_init+0x0/0x120()
[   29.287367] initcall 0x78a3d450: mon_init+0x0/0x120() returned 0.
[   29.293388] initcall 0x78a3d450 ran for 0 msecs: mon_init+0x0/0x120()
[   29.299797] Calling initcall 0x78a3dad0: ehci_hcd_init+0x0/0x20()
[   29.305928] PCI: No IRQ known for interrupt pin B of device 0000:00:02.1. Probably buggy MP table.
[   29.314797] ehci_hcd 0000:00:02.1: Found HC with no IRQ.  Check BIOS/PCI 0000:00:02.1 setup!
[   29.323217] ehci_hcd 0000:00:02.1: init 0000:00:02.1 fail, -19
[   29.329025] initcall 0x78a3dad0: ehci_hcd_init+0x0/0x20() returned 0.
[   29.335415] initcall 0x78a3dad0 ran for 11 msecs: ehci_hcd_init+0x0/0x20()
[   29.342261] Calling initcall 0x78a3daf0: isp116x_init+0x0/0x40()
[   29.348242] 116x: driver isp116x-hcd, 03 Nov 2005
[   29.352946] initcall 0x78a3daf0: isp116x_init+0x0/0x40() returned 0.
[   29.359247] initcall 0x78a3daf0 ran for 1 msecs: isp116x_init+0x0/0x40()
[   29.365920] Calling initcall 0x78a3de10: ohci_hcd_mod_init+0x0/0x70()
[   29.372335] ohci_hcd: 2006 August 04 USB 1.1 'Open' Host Controller (OHCI) Driver
[   29.379867] PCI: No IRQ known for interrupt pin A of device 0000:00:02.0. Probably buggy MP table.
[   29.389341] ohci_hcd 0000:00:02.0: Found HC with no IRQ.  Check BIOS/PCI 0000:00:02.0 setup!
[   29.397757] ohci_hcd 0000:00:02.0: init 0000:00:02.0 fail, -19
[   29.403587] initcall 0x78a3de10: ohci_hcd_mod_init+0x0/0x70() returned 0.
[   29.410312] initcall 0x78a3de10 ran for 17 msecs: ohci_hcd_mod_init+0x0/0x70()
[   29.417507] Calling initcall 0x78a3dee0: uhci_hcd_init+0x0/0xb0()
[   29.423569] USB Universal Host Controller Interface driver v3.0
[   29.429492] initcall 0x78a3dee0: uhci_hcd_init+0x0/0xb0() returned 0.
[   29.435873] initcall 0x78a3dee0 ran for 2 msecs: uhci_hcd_init+0x0/0xb0()
[   29.442633] Calling initcall 0x78a3df90: r8a66597_init+0x0/0x50()
[   29.448700] drivers/usb/host/r8a66597-hcd.c: driver r8a66597_hcd, 29 May 2007
[   29.455830] initcall 0x78a3df90: r8a66597_init+0x0/0x50() returned 0.
[   29.462218] initcall 0x78a3df90 ran for 3 msecs: r8a66597_init+0x0/0x50()
[   29.468978] Calling initcall 0x78a3e270: usblp_init+0x0/0x20()
[   29.474800] usbcore: registered new interface driver usblp
[   29.480254] initcall 0x78a3e270: usblp_init+0x0/0x20() returned 0.
[   29.486393] initcall 0x78a3e270 ran for 2 msecs: usblp_init+0x0/0x20()
[   29.492896] Calling initcall 0x78a3e290: usb_stor_init+0x0/0x50()
[   29.498964] Initializing USB Mass Storage driver...
[   29.503835] usbcore: registered new interface driver usb-storage
[   29.509802] USB Mass Storage support registered.
[   29.514405] initcall 0x78a3e290: usb_stor_init+0x0/0x50() returned 0.
[   29.520804] initcall 0x78a3e290 ran for 10 msecs: usb_stor_init+0x0/0x50()
[   29.527651] Calling initcall 0x78a3e2e0: usb_usual_init+0x0/0x30()
[   29.533817] usbcore: registered new interface driver libusual
[   29.539529] initcall 0x78a3e2e0: usb_usual_init+0x0/0x30() returned 0.
[   29.546019] initcall 0x78a3e2e0 ran for 2 msecs: usb_usual_init+0x0/0x30()
[   29.552865] Calling initcall 0x78a3e310: usb_mdc800_init+0x0/0x230()
[   29.559209] usbcore: registered new interface driver mdc800
[   29.564745] drivers/usb/image/mdc800.c: v0.7.5 (30/10/2000):USB Driver for Mustek MDC800 Digital Camera
[   29.574107] initcall 0x78a3e310: usb_mdc800_init+0x0/0x230() returned 0.
[   29.580774] initcall 0x78a3e310 ran for 7 msecs: usb_mdc800_init+0x0/0x230()
[   29.587794] Calling initcall 0x78a3e540: microtek_drv_init+0x0/0x20()
[   29.594218] usbcore: registered new interface driver microtekX6
[   29.600106] initcall 0x78a3e540: microtek_drv_init+0x0/0x20() returned 0.
[   29.606858] initcall 0x78a3e540 ran for 2 msecs: microtek_drv_init+0x0/0x20()
[   29.613966] Calling initcall 0x78a3e560: usb_serial_init+0x0/0x260()
[   29.620342] usbcore: registered new interface driver usbserial
[   29.626114] drivers/usb/serial/usb-serial.c: USB Serial support registered for generic
[   29.634000] usbcore: registered new interface driver usbserial_generic
[   29.640487] drivers/usb/serial/usb-serial.c: USB Serial Driver core
[   29.646729] initcall 0x78a3e560: usb_serial_init+0x0/0x260() returned 0.
[   29.653396] initcall 0x78a3e560 ran for 12 msecs: usb_serial_init+0x0/0x260()
[   29.660504] Calling initcall 0x78a3e7c0: aircable_init+0x0/0x40()
[   29.666585] drivers/usb/serial/usb-serial.c: USB Serial support registered for aircable
[   29.674557] usbcore: registered new interface driver aircable
[   29.680268] initcall 0x78a3e7c0: aircable_init+0x0/0x40() returned 0.
[   29.686674] initcall 0x78a3e7c0 ran for 6 msecs: aircable_init+0x0/0x40()
[   29.693436] Calling initcall 0x78a3e800: airprime_init+0x0/0x60()
[   29.699511] drivers/usb/serial/usb-serial.c: USB Serial support registered for airprime
[   29.707488] usbcore: registered new interface driver airprime
[   29.713199] initcall 0x78a3e800: airprime_init+0x0/0x60() returned 0.
[   29.719599] initcall 0x78a3e800 ran for 5 msecs: airprime_init+0x0/0x60()
[   29.726361] Calling initcall 0x78a3e860: ark3116_init+0x0/0x40()
[   29.732355] drivers/usb/serial/usb-serial.c: USB Serial support registered for ark3116
[   29.740246] usbcore: registered new interface driver ark3116
[   29.745870] initcall 0x78a3e860: ark3116_init+0x0/0x40() returned 0.
[   29.752186] initcall 0x78a3e860 ran for 5 msecs: ark3116_init+0x0/0x40()
[   29.758859] Calling initcall 0x78a3e8a0: cypress_init+0x0/0xd0()
[   29.764841] drivers/usb/serial/cypress_m8.c: cypress_init
[   29.770231] drivers/usb/serial/usb-serial.c: USB Serial support registered for DeLorme Earthmate USB
[   29.779330] drivers/usb/serial/usb-serial.c: USB Serial support registered for HID->COM RS232 Adapter
[   29.788517] drivers/usb/serial/usb-serial.c: USB Serial support registered for Nokia CA-42 V2 Adapter
[   29.797703] usbcore: registered new interface driver cypress
[   29.803323] drivers/usb/serial/cypress_m8.c: Cypress USB to Serial Driver v1.09
[   29.810605] initcall 0x78a3e8a0: cypress_init+0x0/0xd0() returned 0.
[   29.816925] initcall 0x78a3e8a0 ran for 18 msecs: cypress_init+0x0/0xd0()
[   29.823687] Calling initcall 0x78a3e970: debug_init+0x0/0x40()
[   29.829502] drivers/usb/serial/usb-serial.c: USB Serial support registered for debug
[   29.837220] usbcore: registered new interface driver debug
[   29.842670] initcall 0x78a3e970: debug_init+0x0/0x40() returned 0.
[   29.848814] initcall 0x78a3e970 ran for 5 msecs: debug_init+0x0/0x40()
[   29.855312] Calling initcall 0x78a3e9b0: empeg_init+0x0/0x120()
[   29.861251] drivers/usb/serial/usb-serial.c: USB Serial support registered for empeg
[   29.868939] usbcore: registered new interface driver empeg
[   29.874385] drivers/usb/serial/empeg.c: v1.2:USB Empeg Mark I/II Driver
[   29.880975] initcall 0x78a3e9b0: empeg_init+0x0/0x120() returned 0.
[   29.887207] initcall 0x78a3e9b0 ran for 9 msecs: empeg_init+0x0/0x120()
[   29.893794] Calling initcall 0x78a3ead0: ftdi_init+0x0/0xf0()
[   29.899525] drivers/usb/serial/usb-serial.c: USB Serial support registered for FTDI USB Serial Device
[   29.908716] usbcore: registered new interface driver ftdi_sio
[   29.914423] drivers/usb/serial/ftdi_sio.c: v1.4.3:USB FTDI Serial Converters Driver
[   29.922052] initcall 0x78a3ead0: ftdi_init+0x0/0xf0() returned 0.
[   29.928106] initcall 0x78a3ead0 ran for 7 msecs: ftdi_init+0x0/0xf0()
[   29.934524] Calling initcall 0x78a3ebc0: funsoft_init+0x0/0x40()
[   29.940516] drivers/usb/serial/usb-serial.c: USB Serial support registered for funsoft
[   29.948408] usbcore: registered new interface driver funsoft
[   29.954031] initcall 0x78a3ebc0: funsoft_init+0x0/0x40() returned 0.
[   29.960349] initcall 0x78a3ebc0 ran for 6 msecs: funsoft_init+0x0/0x40()
[   29.967022] Calling initcall 0x78a3ec00: hp49gp_init+0x0/0x70()
[   29.972927] drivers/usb/serial/usb-serial.c: USB Serial support registered for hp4X
[   29.980559] usbcore: registered new interface driver hp4X
[   29.985918] drivers/usb/serial/hp4x.c: HP4x (48/49) Generic Serial driver v1.00
[   29.993200] initcall 0x78a3ec00: hp49gp_init+0x0/0x70() returned 0.
[   29.999428] initcall 0x78a3ec00 ran for 8 msecs: hp49gp_init+0x0/0x70()
[   30.006017] Calling initcall 0x7858be70: usb_ipw_init+0x0/0x70()
[   30.012012] drivers/usb/serial/usb-serial.c: USB Serial support registered for IPWireless converter
[   30.021030] usbcore: registered new interface driver ipwtty
[   30.026562] drivers/usb/serial/ipw.c: IPWireless tty driver v0.3
[   30.032546] initcall 0x7858be70: usb_ipw_init+0x0/0x70() returned 0.
[   30.038861] initcall 0x7858be70 ran for 10 msecs: usb_ipw_init+0x0/0x70()
[   30.045621] Calling initcall 0x78a3ec70: keyspan_pda_init+0x0/0xa0()
[   30.051963] drivers/usb/serial/usb-serial.c: USB Serial support registered for Keyspan PDA
[   30.060200] drivers/usb/serial/usb-serial.c: USB Serial support registered for Keyspan PDA - (prerenumeration)
[   30.070165] drivers/usb/serial/usb-serial.c: USB Serial support registered for Xircom / Entregra PGS - (prerenumeration)
[   30.080998] usbcore: registered new interface driver keyspan_pda
[   30.086965] drivers/usb/serial/keyspan_pda.c: USB Keyspan PDA Converter driver v1.1
[   30.094594] initcall 0x78a3ec70: keyspan_pda_init+0x0/0xa0() returned 0.
[   30.101255] initcall 0x78a3ec70 ran for 18 msecs: keyspan_pda_init+0x0/0xa0()
[   30.108370] Calling initcall 0x78a3ed10: klsi_105_init+0x0/0x70()
[   30.114444] drivers/usb/serial/usb-serial.c: USB Serial support registered for KL5KUSB105D / PalmConnect
[   30.123897] usbcore: registered new interface driver kl5kusb105d
[   30.129862] drivers/usb/serial/kl5kusb105.c: KLSI KL5KUSB105 chipset USB->Serial Converter driver v0.3a
[   30.139224] initcall 0x78a3ed10: klsi_105_init+0x0/0x70() returned 0.
[   30.145628] initcall 0x78a3ed10 ran for 7 msecs: klsi_105_init+0x0/0x70()
[   30.152388] Calling initcall 0x78a3ed80: moschip7720_init+0x0/0x90()
[   30.158729] drivers/usb/serial/usb-serial.c: USB Serial support registered for Moschip 2 port adapter
[   30.167906] drivers/usb/serial/mos7720.c: Moschip USB Serial Driver 1.0.0.4F
[   30.174938] usbcore: registered new interface driver moschip7720
[   30.180909] initcall 0x78a3ed80: moschip7720_init+0x0/0x90() returned 0.
[   30.187575] initcall 0x78a3ed80 ran for 11 msecs: moschip7720_init+0x0/0x90()
[   30.194680] Calling initcall 0x78a3ee10: moschip7840_init+0x0/0xf0()
[   30.201019] drivers/usb/serial/usb-serial.c: USB Serial support registered for Moschip 7840/7820 USB Serial Driver
[   30.211324] drivers/usb/serial/mos7840.c: Moschip 7840/7820 USB Serial Driver 1.3.1
[   30.218962] usbcore: registered new interface driver mos7840
[   30.224587] initcall 0x78a3ee10: moschip7840_init+0x0/0xf0() returned 0.
[   30.231246] initcall 0x78a3ee10 ran for 9 msecs: moschip7840_init+0x0/0xf0()
[   30.238274] Calling initcall 0x78a3ef00: omninet_init+0x0/0x70()
[   30.244263] drivers/usb/serial/usb-serial.c: USB Serial support registered for ZyXEL - omni.net lcd plus usb
[   30.254061] usbcore: registered new interface driver omninet
[   30.259682] drivers/usb/serial/omninet.c: v1.1:USB ZyXEL omni.net LCD PLUS Driver
[   30.267137] initcall 0x78a3ef00: omninet_init+0x0/0x70() returned 0.
[   30.273457] initcall 0x78a3ef00 ran for 9 msecs: omninet_init+0x0/0x70()
[   30.280131] Calling initcall 0x78a3ef70: sierra_init+0x0/0x80()
[   30.286033] drivers/usb/serial/usb-serial.c: USB Serial support registered for Sierra USB modem (1 port)
[   30.295485] drivers/usb/serial/usb-serial.c: USB Serial support registered for Sierra USB modem (3 port)
[   30.304930] usbcore: registered new interface driver sierra
[   30.310464] drivers/usb/serial/sierra.c: USB Driver for Sierra Wireless USB modems: v.1.2.5b
[   30.318873] initcall 0x78a3ef70: sierra_init+0x0/0x80() returned 0.
[   30.325103] initcall 0x78a3ef70 ran for 11 msecs: sierra_init+0x0/0x80()
[   30.331782] Calling initcall 0x78a3eff0: whiteheat_init+0x0/0x80()
[   30.337943] drivers/usb/serial/usb-serial.c: USB Serial support registered for Connect Tech - WhiteHEAT - (prerenumeration)
[   30.349040] drivers/usb/serial/usb-serial.c: USB Serial support registered for Connect Tech - WhiteHEAT
[   30.358401] usbcore: registered new interface driver whiteheat
[   30.364195] drivers/usb/serial/whiteheat.c: USB ConnectTech WhiteHEAT driver v2.0
[   30.372204] initcall 0x78a3eff0: whiteheat_init+0x0/0x80() returned 0.
[   30.378694] initcall 0x78a3eff0 ran for 10 msecs: whiteheat_init+0x0/0x80()
[   30.385628] Calling initcall 0x78a3f070: appledisplay_init+0x0/0x50()
[   30.392089] usbcore: registered new interface driver appledisplay
[   30.398117] initcall 0x78a3f070: appledisplay_init+0x0/0x50() returned 0.
[   30.404866] initcall 0x78a3f070 ran for 5 msecs: appledisplay_init+0x0/0x50()
[   30.411978] Calling initcall 0x78a3f0c0: auerswald_init+0x0/0x40()
[   30.418136] usbcore: registered new interface driver auerswald
[   30.423941] initcall 0x78a3f0c0: auerswald_init+0x0/0x40() returned 0.
[   30.430435] initcall 0x78a3f0c0 ran for 2 msecs: auerswald_init+0x0/0x40()
[   30.437280] Calling initcall 0x78a3f100: berry_init+0x0/0x20()
[   30.443096] usbcore: registered new interface driver berry_charge
[   30.449159] initcall 0x78a3f100: berry_init+0x0/0x20() returned 0.
[   30.455303] initcall 0x78a3f100 ran for 2 msecs: berry_init+0x0/0x20()
[   30.461803] Calling initcall 0x78a3f120: emi26_init+0x0/0x20()
[   30.467618] usbcore: registered new interface driver emi26 - firmware loader
[   30.474638] initcall 0x78a3f120: emi26_init+0x0/0x20() returned 0.
[   30.480785] initcall 0x78a3f120 ran for 3 msecs: emi26_init+0x0/0x20()
[   30.487285] Calling initcall 0x78a3f140: usb_idmouse_init+0x0/0x50()
[   30.493609] drivers/usb/misc/idmouse.c: Siemens ID Mouse FingerTIP Sensor Driver 0.6
[   30.501333] usbcore: registered new interface driver idmouse
[   30.506963] initcall 0x78a3f140: usb_idmouse_init+0x0/0x50() returned 0.
[   30.513629] initcall 0x78a3f140 ran for 6 msecs: usb_idmouse_init+0x0/0x50()
[   30.520649] Calling initcall 0x78a3f190: ld_usb_init+0x0/0x40()
[   30.526546] usbcore: registered new interface driver ldusb
[   30.532008] initcall 0x78a3f190: ld_usb_init+0x0/0x40() returned 0.
[   30.538237] initcall 0x78a3f190 ran for 2 msecs: ld_usb_init+0x0/0x40()
[   30.544829] Calling initcall 0x78a3f1d0: usb_led_init+0x0/0x40()
[   30.550811] usbcore: registered new interface driver usbled
[   30.556359] initcall 0x78a3f1d0: usb_led_init+0x0/0x40() returned 0.
[   30.562674] initcall 0x78a3f1d0 ran for 2 msecs: usb_led_init+0x0/0x40()
[   30.569349] Calling initcall 0x78a3f210: lego_usb_tower_init+0x0/0xa0()
[   30.575944] usbcore: registered new interface driver legousbtower
[   30.582007] drivers/usb/misc/legousbtower.c: LEGO USB Tower Driver v0.96
[   30.588685] initcall 0x78a3f210: lego_usb_tower_init+0x0/0xa0() returned 0.
[   30.595608] initcall 0x78a3f210 ran for 5 msecs: lego_usb_tower_init+0x0/0xa0()
[   30.602887] Calling initcall 0x78a3f2b0: init_phidget+0x0/0x20()
[   30.608877] initcall 0x78a3f2b0: init_phidget+0x0/0x20() returned 0.
[   30.615193] initcall 0x78a3f2b0 ran for 0 msecs: init_phidget+0x0/0x20()
[   30.621866] Calling initcall 0x78a3f2d0: tv_init+0x0/0x60()
[   30.627428] usbcore: registered new interface driver trancevibrator
[   30.633659] drivers/usb/misc/trancevibrator.c: v1.1:PlayStation 2 Trance Vibrator driver
[   30.641720] initcall 0x78a3f2d0: tv_init+0x0/0x60() returned 0.
[   30.647602] initcall 0x78a3f2d0 ran for 4 msecs: tv_init+0x0/0x60()
[   30.653846] Calling initcall 0x78a3f330: usb_sisusb_init+0x0/0x20()
[   30.660097] usbcore: registered new interface driver sisusb
[   30.665640] initcall 0x78a3f330: usb_sisusb_init+0x0/0x20() returned 0.
[   30.672216] initcall 0x78a3f330 ran for 2 msecs: usb_sisusb_init+0x0/0x20()
[   30.679149] Calling initcall 0x78a3fc30: i8042_init+0x0/0xe0()
[   30.687754] serio: i8042 KBD port at 0x60,0x64 irq 1
[   30.692614] serio: i8042 AUX port at 0x60,0x64 irq 12
[   30.697630] initcall 0x78a3fc30: i8042_init+0x0/0xe0() returned 0.
[   30.703773] initcall 0x78a3fc30 ran for 12 msecs: i8042_init+0x0/0xe0()
[   30.710359] Calling initcall 0x78a3fd10: pcips2_init+0x0/0x20()
[   30.716278] initcall 0x78a3fd10: pcips2_init+0x0/0x20() returned 0.
[   30.722488] initcall 0x78a3fd10 ran for 0 msecs: pcips2_init+0x0/0x20()
[   30.729074] Calling initcall 0x78a3fe50: serio_raw_init+0x0/0x20()
[   30.735248] initcall 0x78a3fe50: serio_raw_init+0x0/0x20() returned 0.
[   30.741727] initcall 0x78a3fe50 ran for 0 msecs: serio_raw_init+0x0/0x20()
[   30.748579] Calling initcall 0x78a40080: fm801_gp_init+0x0/0x20()
[   30.754666] initcall 0x78a40080: fm801_gp_init+0x0/0x20() returned 0.
[   30.761050] initcall 0x78a40080 ran for 0 msecs: fm801_gp_init+0x0/0x20()
[   30.767815] Calling initcall 0x78a400a0: l4_init+0x0/0x2b0()
[   30.773460] initcall 0x78a400a0: l4_init+0x0/0x2b0() returned -19.
[   30.779595] initcall 0x78a400a0 ran for 0 msecs: l4_init+0x0/0x2b0()
[   30.785925] Calling initcall 0x78a40350: ns558_init+0x0/0x390()
[   30.800567] initcall 0x78a40350: ns558_init+0x0/0x390() returned -19.
[   30.806848] initcall 0x78a40350 ran for 11 msecs: ns558_init+0x0/0x390()
[   30.813520] Calling initcall 0x78a407e0: mousedev_init+0x0/0x90()
[   30.819648] mice: PS/2 mouse device common for all mice
[   30.824793] initcall 0x78a407e0: mousedev_init+0x0/0x90() returned 0.
[   30.831193] initcall 0x78a407e0 ran for 4 msecs: mousedev_init+0x0/0x90()
[   30.837959] Calling initcall 0x78a40870: evdev_init+0x0/0x10()
[   30.843767] initcall 0x78a40870: evdev_init+0x0/0x10() returned 0.
[   30.849918] initcall 0x78a40870 ran for 0 msecs: evdev_init+0x0/0x10()
[   30.856420] Calling initcall 0x78a40880: evbug_init+0x0/0x10()
[   30.862226] initcall 0x78a40880: evbug_init+0x0/0x10() returned 0.
[   30.868374] initcall 0x78a40880 ran for 0 msecs: evbug_init+0x0/0x10()
[   30.874879] Calling initcall 0x78a40890: atkbd_init+0x0/0x20()
[   30.880702] initcall 0x78a40890: atkbd_init+0x0/0x20() returned 0.
[   30.886836] initcall 0x78a40890 ran for 0 msecs: atkbd_init+0x0/0x20()
[   30.893338] Calling initcall 0x78a408b0: sunkbd_init+0x0/0x20()
[   30.899247] initcall 0x78a408b0: sunkbd_init+0x0/0x20() returned 0.
[   30.905465] initcall 0x78a408b0 ran for 0 msecs: sunkbd_init+0x0/0x20()
[   30.912051] Calling initcall 0x78a408d0: xtkbd_init+0x0/0x20()
[   30.917878] initcall 0x78a408d0: xtkbd_init+0x0/0x20() returned 0.
[   30.924014] initcall 0x78a408d0 ran for 0 msecs: xtkbd_init+0x0/0x20()
[   30.930514] Calling initcall 0x78a408f0: a3d_init+0x0/0x10()
[   30.936160] initcall 0x78a408f0: a3d_init+0x0/0x10() returned 0.
[   30.942123] initcall 0x78a408f0 ran for 0 msecs: a3d_init+0x0/0x10()
[   30.948449] Calling initcall 0x78a40900: adi_init+0x0/0x10()
[   30.954088] initcall 0x78a40900: adi_init+0x0/0x10() returned 0.
[   30.960064] initcall 0x78a40900 ran for 0 msecs: adi_init+0x0/0x10()
[   30.966393] Calling initcall 0x78a40910: analog_init+0x0/0x100()
[   30.972374] initcall 0x78a40910: analog_init+0x0/0x100() returned 0.
[   30.978694] initcall 0x78a40910 ran for 0 msecs: analog_init+0x0/0x100()
[   30.985366] Calling initcall 0x78a40a10: cobra_init+0x0/0x10()
[   30.991179] initcall 0x78a40a10: cobra_init+0x0/0x10() returned 0.
[   30.997329] initcall 0x78a40a10 ran for 0 msecs: cobra_init+0x0/0x10()
[   31.003828] Calling initcall 0x78a40a20: grip_init+0x0/0x10()
[   31.009551] initcall 0x78a40a20: grip_init+0x0/0x10() returned 0.
[   31.015611] initcall 0x78a40a20 ran for 0 msecs: grip_init+0x0/0x10()
[   31.022024] Calling initcall 0x78a40a30: grip_init+0x0/0x10()
[   31.027750] initcall 0x78a40a30: grip_init+0x0/0x10() returned 0.
[   31.033813] initcall 0x78a40a30 ran for 0 msecs: grip_init+0x0/0x10()
[   31.040226] Calling initcall 0x78a40a40: guillemot_init+0x0/0x10()
[   31.046387] initcall 0x78a40a40: guillemot_init+0x0/0x10() returned 0.
[   31.052873] initcall 0x78a40a40 ran for 0 msecs: guillemot_init+0x0/0x10()
[   31.059727] Calling initcall 0x78a40a50: interact_init+0x0/0x10()
[   31.065794] initcall 0x78a40a50: interact_init+0x0/0x10() returned 0.
[   31.072201] initcall 0x78a40a50 ran for 0 msecs: interact_init+0x0/0x10()
[   31.078960] Calling initcall 0x78a40a60: joydump_init+0x0/0x10()
[   31.084947] initcall 0x78a40a60: joydump_init+0x0/0x10() returned 0.
[   31.091263] initcall 0x78a40a60 ran for 0 msecs: joydump_init+0x0/0x10()
[   31.097943] Calling initcall 0x78a40a70: magellan_init+0x0/0x20()
[   31.104026] initcall 0x78a40a70: magellan_init+0x0/0x20() returned 0.
[   31.110422] initcall 0x78a40a70 ran for 0 msecs: magellan_init+0x0/0x20()
[   31.117181] Calling initcall 0x78a40a90: sw_init+0x0/0x10()
[   31.122731] initcall 0x78a40a90: sw_init+0x0/0x10() returned 0.
[   31.128618] initcall 0x78a40a90 ran for 0 msecs: sw_init+0x0/0x10()
[   31.134856] Calling initcall 0x78a40aa0: stinger_init+0x0/0x20()
[   31.140857] initcall 0x78a40aa0: stinger_init+0x0/0x20() returned 0.
[   31.147166] initcall 0x78a40aa0 ran for 0 msecs: stinger_init+0x0/0x20()
[   31.153838] Calling initcall 0x78a40ac0: tmdc_init+0x0/0x10()
[   31.159562] initcall 0x78a40ac0: tmdc_init+0x0/0x10() returned 0.
[   31.165621] initcall 0x78a40ac0 ran for 0 msecs: tmdc_init+0x0/0x10()
[   31.172034] Calling initcall 0x78a40ad0: usb_xpad_init+0x0/0x40()
[   31.178117] usbcore: registered new interface driver xpad
[   31.183481] drivers/input/joystick/xpad.c: X-Box pad driver:v0.0.6
[   31.189636] initcall 0x78a40ad0: usb_xpad_init+0x0/0x40() returned 0.
[   31.196037] initcall 0x78a40ad0 ran for 4 msecs: usb_xpad_init+0x0/0x40()
[   31.202799] Calling initcall 0x78a40b10: iforce_init+0x0/0x20()
[   31.208714] initcall 0x78a40b10: iforce_init+0x0/0x20() returned 0.
[   31.214932] initcall 0x78a40b10 ran for 0 msecs: iforce_init+0x0/0x20()
[   31.221524] Calling initcall 0x78a40c30: i2c_dev_init+0x0/0x90()
[   31.227499] i2c /dev entries driver
[   31.231016] initcall 0x78a40c30: i2c_dev_init+0x0/0x90() returned 0.
[   31.237294] initcall 0x78a40c30 ran for 3 msecs: i2c_dev_init+0x0/0x90()
[   31.243966] Calling initcall 0x78a40ee0: ali1563_init+0x0/0x20()
[   31.249971] initcall 0x78a40ee0: ali1563_init+0x0/0x20() returned 0.
[   31.256272] initcall 0x78a40ee0 ran for 0 msecs: ali1563_init+0x0/0x20()
[   31.262948] Calling initcall 0x78a410b0: i2c_amd8111_init+0x0/0x20()
[   31.269295] initcall 0x78a410b0: i2c_amd8111_init+0x0/0x20() returned 0.
[   31.275939] initcall 0x78a410b0 ran for 0 msecs: i2c_amd8111_init+0x0/0x20()
[   31.282966] Calling initcall 0x78a411a0: i2c_i810_init+0x0/0x20()
[   31.289054] initcall 0x78a411a0: i2c_i810_init+0x0/0x20() returned 0.
[   31.295440] initcall 0x78a411a0 ran for 0 msecs: i2c_i810_init+0x0/0x20()
[   31.302200] Calling initcall 0x78a411c0: i2c_parport_init+0x0/0x190()
[   31.308614] i2c-parport-light: adapter type unspecified
[   31.313822] initcall 0x78a411c0: i2c_parport_init+0x0/0x190() returned -19.
[   31.320748] initcall 0x78a411c0 ran for 4 msecs: i2c_parport_init+0x0/0x190()
[   31.327854] Calling initcall 0x78a418c0: i2c_piix4_init+0x0/0x20()
[   31.334032] initcall 0x78a418c0: i2c_piix4_init+0x0/0x20() returned 0.
[   31.340507] initcall 0x78a418c0 ran for 0 msecs: i2c_piix4_init+0x0/0x20()
[   31.347353] Calling initcall 0x78a41a90: i2c_prosavage_init+0x0/0x20()
[   31.353876] initcall 0x78a41a90: i2c_prosavage_init+0x0/0x20() returned 0.
[   31.360699] initcall 0x78a41a90 ran for 0 msecs: i2c_prosavage_init+0x0/0x20()
[   31.367892] Calling initcall 0x78a41b50: i2c_savage4_init+0x0/0x20()
[   31.374242] initcall 0x78a41b50: i2c_savage4_init+0x0/0x20() returned 0.
[   31.380885] initcall 0x78a41b50 ran for 0 msecs: i2c_savage4_init+0x0/0x20()
[   31.387910] Calling initcall 0x78a41f30: i2c_sis5595_init+0x0/0x20()
[   31.394260] initcall 0x78a41f30: i2c_sis5595_init+0x0/0x20() returned 0.
[   31.400904] initcall 0x78a41f30 ran for 0 msecs: i2c_sis5595_init+0x0/0x20()
[   31.407929] Calling initcall 0x78a42190: i2c_sis630_init+0x0/0x20()
[   31.414193] initcall 0x78a42190: i2c_sis630_init+0x0/0x20() returned 0.
[   31.420755] initcall 0x78a42190 ran for 0 msecs: i2c_sis630_init+0x0/0x20()
[   31.427689] Calling initcall 0x78a421b0: usb_i2c_tiny_usb_init+0x0/0x20()
[   31.434460] usbcore: registered new interface driver i2c-tiny-usb
[   31.440521] initcall 0x78a421b0: usb_i2c_tiny_usb_init+0x0/0x20() returned 0.
[   31.447615] initcall 0x78a421b0 ran for 2 msecs: usb_i2c_tiny_usb_init+0x0/0x20()
[   31.455075] Calling initcall 0x78a421d0: i2c_vt596_init+0x0/0x20()
[   31.461251] initcall 0x78a421d0: i2c_vt596_init+0x0/0x20() returned 0.
[   31.467720] initcall 0x78a421d0 ran for 0 msecs: i2c_vt596_init+0x0/0x20()
[   31.474572] Calling initcall 0x78a426a0: i2c_voodoo3_init+0x0/0x20()
[   31.481444] initcall 0x78a426a0: i2c_voodoo3_init+0x0/0x20() returned 0.
[   31.488088] initcall 0x78a426a0 ran for 0 msecs: i2c_voodoo3_init+0x0/0x20()
[   31.495113] Calling initcall 0x78a42870: scx200_acb_init+0x0/0x220()
[   31.501437] scx200_acb: NatSemi SCx200 ACCESS.bus Driver
[   31.506732] initcall 0x78a42870: scx200_acb_init+0x0/0x220() returned -19.
[   31.513570] initcall 0x78a42870 ran for 2 msecs: scx200_acb_init+0x0/0x220()
[   31.520589] Calling initcall 0x78a42a90: ds1682_init+0x0/0x10()
[   31.526499] initcall 0x78a42a90: ds1682_init+0x0/0x10() returned 0.
[   31.532716] initcall 0x78a42a90 ran for 0 msecs: ds1682_init+0x0/0x10()
[   31.539305] Calling initcall 0x78a42aa0: pcf8591_init+0x0/0x40()
[   31.545303] initcall 0x78a42aa0: pcf8591_init+0x0/0x40() returned 0.
[   31.551611] initcall 0x78a42aa0 ran for 0 msecs: pcf8591_init+0x0/0x40()
[   31.558288] Calling initcall 0x78a42cc0: tsl2550_init+0x0/0x10()
[   31.564282] initcall 0x78a42cc0: tsl2550_init+0x0/0x10() returned 0.
[   31.570592] initcall 0x78a42cc0 ran for 0 msecs: tsl2550_init+0x0/0x10()
[   31.577265] Calling initcall 0x785c7880: w1_init+0x0/0x120()
[   31.582902] Driver for 1-wire Dallas network protocol.
[   31.588428] initcall 0x785c7880: w1_init+0x0/0x120() returned 0.
[   31.594272] initcall 0x785c7880 ran for 2 msecs: w1_init+0x0/0x120()
[   31.600603] Calling initcall 0x78a42f00: matrox_w1_init+0x0/0x20()
[   31.606775] initcall 0x78a42f00: matrox_w1_init+0x0/0x20() returned 0.
[   31.613256] initcall 0x78a42f00 ran for 0 msecs: matrox_w1_init+0x0/0x20()
[   31.620105] Calling initcall 0x785c8ef0: ds_init+0x0/0x40()
[   31.625654] usbcore: registered new interface driver DS9490R
[   31.631287] initcall 0x785c8ef0: ds_init+0x0/0x40() returned 0.
[   31.637174] initcall 0x785c8ef0 ran for 4 msecs: ds_init+0x0/0x40()
[   31.643413] Calling initcall 0x78a42f20: w1_ds2760_init+0x0/0x30()
[   31.649571] 1-Wire driver for the DS2760 battery monitor  chip  - (c) 2004-2005, Szabolcs Gyurko
[   31.658343] initcall 0x78a42f20: w1_ds2760_init+0x0/0x30() returned 0.
[   31.664816] initcall 0x78a42f20 ran for 2 msecs: w1_ds2760_init+0x0/0x30()
[   31.671667] Calling initcall 0x78a42f90: asb100_init+0x0/0x10()
[   31.677568] initcall 0x78a42f90: asb100_init+0x0/0x10() returned 0.
[   31.683798] initcall 0x78a42f90 ran for 0 msecs: asb100_init+0x0/0x10()
[   31.690384] Calling initcall 0x78a42fa0: sensors_w83792d_init+0x0/0x10()
[   31.697065] initcall 0x78a42fa0: sensors_w83792d_init+0x0/0x10() returned 0.
[   31.704071] initcall 0x78a42fa0 ran for 0 msecs: sensors_w83792d_init+0x0/0x10()
[   31.711446] Calling initcall 0x78a43170: sensors_w83781d_init+0x0/0x420()
[   31.718221] w83781d: Detection failed at step 3
[   31.722716] initcall 0x78a43170: sensors_w83781d_init+0x0/0x420() returned 0.
[   31.729815] initcall 0x78a43170 ran for 4 msecs: sensors_w83781d_init+0x0/0x420()
[   31.737270] Calling initcall 0x78a43590: ad7418_init+0x0/0x10()
[   31.743168] initcall 0x78a43590: ad7418_init+0x0/0x10() returned 0.
[   31.749395] initcall 0x78a43590 ran for 0 msecs: ad7418_init+0x0/0x10()
[   31.755984] Calling initcall 0x78a435a0: sensors_adm1021_init+0x0/0x10()
[   31.762668] initcall 0x78a435a0: sensors_adm1021_init+0x0/0x10() returned 0.
[   31.769680] initcall 0x78a435a0 ran for 0 msecs: sensors_adm1021_init+0x0/0x10()
[   31.777048] Calling initcall 0x78a435b0: sensors_adm1031_init+0x0/0x10()
[   31.783727] initcall 0x78a435b0: sensors_adm1031_init+0x0/0x10() returned 0.
[   31.790732] initcall 0x78a435b0 ran for 0 msecs: sensors_adm1031_init+0x0/0x10()
[   31.798106] Calling initcall 0x78a435c0: applesmc_init+0x0/0x520()
[   31.804256] applesmc: supported laptop not found!
[   31.808940] applesmc: driver init failed (ret=-19)!
[   31.813796] initcall 0x78a435c0: applesmc_init+0x0/0x520() returned -19.
[   31.820463] initcall 0x78a435c0 ran for 5 msecs: applesmc_init+0x0/0x520()
[   31.827308] Calling initcall 0x78a43c30: f71805f_init+0x0/0x170()
[   31.833402] initcall 0x78a43c30: f71805f_init+0x0/0x170() returned -19.
[   31.839961] initcall 0x78a43c30 ran for 0 msecs: f71805f_init+0x0/0x170()
[   31.846724] Calling initcall 0x78a441c0: sensors_f75375_init+0x0/0x10()
[   31.853317] initcall 0x78a441c0: sensors_f75375_init+0x0/0x10() returned 0.
[   31.860240] initcall 0x78a441c0 ran for 0 msecs: sensors_f75375_init+0x0/0x10()
[   31.867519] Calling initcall 0x78a441d0: sensors_fscher_init+0x0/0x10()
[   31.874114] initcall 0x78a441d0: sensors_fscher_init+0x0/0x10() returned 0.
[   31.881033] initcall 0x78a441d0 ran for 0 msecs: sensors_fscher_init+0x0/0x10()
[   31.888321] Calling initcall 0x78a441e0: sensors_gl518sm_init+0x0/0x10()
[   31.895000] initcall 0x78a441e0: sensors_gl518sm_init+0x0/0x10() returned 0.
[   31.902008] initcall 0x78a441e0 ran for 0 msecs: sensors_gl518sm_init+0x0/0x10()
[   31.909373] Calling initcall 0x78a441f0: sensors_gl520sm_init+0x0/0x10()
[   31.916058] initcall 0x78a441f0: sensors_gl520sm_init+0x0/0x10() returned 0.
[   31.923069] initcall 0x78a441f0 ran for 0 msecs: sensors_gl520sm_init+0x0/0x10()
[   31.930438] Calling initcall 0x78a44250: hdaps_init+0x0/0x1f0()
[   31.936331] hdaps: supported laptop not found!
[   31.940751] hdaps: driver init failed (ret=-19)!
[   31.945348] initcall 0x78a44250: hdaps_init+0x0/0x1f0() returned -19.
[   31.951752] initcall 0x78a44250 ran for 5 msecs: hdaps_init+0x0/0x1f0()
[   31.958338] Calling initcall 0x78a44440: init_lm70+0x0/0x10()
[   31.964077] initcall 0x78a44440: init_lm70+0x0/0x10() returned 0.
[   31.970126] initcall 0x78a44440 ran for 0 msecs: init_lm70+0x0/0x10()
[   31.976540] Calling initcall 0x78a44570: sensors_lm77_init+0x0/0x10()
[   31.982972] initcall 0x78a44570: sensors_lm77_init+0x0/0x10() returned 0.
[   31.989711] initcall 0x78a44570 ran for 0 msecs: sensors_lm77_init+0x0/0x10()
[   31.996820] Calling initcall 0x78a44580: sensors_lm80_init+0x0/0x10()
[   32.003246] initcall 0x78a44580: sensors_lm80_init+0x0/0x10() returned 0.
[   32.009991] initcall 0x78a44580 ran for 0 msecs: sensors_lm80_init+0x0/0x10()
[   32.017100] Calling initcall 0x78a44590: sm_lm85_init+0x0/0x10()
[   32.023091] initcall 0x78a44590: sm_lm85_init+0x0/0x10() returned 0.
[   32.029397] initcall 0x78a44590 ran for 0 msecs: sm_lm85_init+0x0/0x10()
[   32.036072] Calling initcall 0x78a445a0: sensors_lm87_init+0x0/0x10()
[   32.042503] initcall 0x78a445a0: sensors_lm87_init+0x0/0x10() returned 0.
[   32.049243] initcall 0x78a445a0 ran for 0 msecs: sensors_lm87_init+0x0/0x10()
[   32.056356] Calling initcall 0x78a445b0: lm93_init+0x0/0x10()
[   32.062090] initcall 0x78a445b0: lm93_init+0x0/0x10() returned 0.
[   32.068138] initcall 0x78a445b0 ran for 0 msecs: lm93_init+0x0/0x10()
[   32.074554] Calling initcall 0x78a445c0: sensors_max1619_init+0x0/0x10()
[   32.081244] initcall 0x78a445c0: sensors_max1619_init+0x0/0x10() returned 0.
[   32.088242] initcall 0x78a445c0 ran for 0 msecs: sensors_max1619_init+0x0/0x10()
[   32.095614] Calling initcall 0x78a445d0: sensors_max6650_init+0x0/0x10()
[   32.102300] initcall 0x78a445d0: sensors_max6650_init+0x0/0x10() returned 0.
[   32.109298] initcall 0x78a445d0 ran for 0 msecs: sensors_max6650_init+0x0/0x10()
[   32.116673] Calling initcall 0x78a454b0: pc87360_init+0x0/0x1a0()
[   32.122748] pc87360: PC8736x not detected, module not inserted.
[   32.128639] initcall 0x78a454b0: pc87360_init+0x0/0x1a0() returned -19.
[   32.135213] initcall 0x78a454b0 ran for 1 msecs: pc87360_init+0x0/0x1a0()
[   32.141973] Calling initcall 0x78a45770: pc87427_init+0x0/0x140()
[   32.148060] initcall 0x78a45770: pc87427_init+0x0/0x140() returned -19.
[   32.154625] initcall 0x78a45770 ran for 0 msecs: pc87427_init+0x0/0x140()
[   32.161390] Calling initcall 0x78a45ba0: sm_sis5595_init+0x0/0x20()
[   32.167652] initcall 0x78a45ba0: sm_sis5595_init+0x0/0x20() returned 0.
[   32.174208] initcall 0x78a45ba0 ran for 0 msecs: sm_sis5595_init+0x0/0x20()
[   32.181147] Calling initcall 0x78a462c0: vt1211_init+0x0/0x180()
[   32.187146] initcall 0x78a462c0: vt1211_init+0x0/0x180() returned -19.
[   32.193626] initcall 0x78a462c0 ran for 0 msecs: vt1211_init+0x0/0x180()
[   32.200298] Calling initcall 0x78a46800: sm_vt8231_init+0x0/0x20()
[   32.206476] initcall 0x78a46800: sm_vt8231_init+0x0/0x20() returned 0.
[   32.212952] initcall 0x78a46800 ran for 0 msecs: sm_vt8231_init+0x0/0x20()
[   32.219800] Calling initcall 0x78a46c00: sensors_w83627ehf_init+0x0/0x180()
[   32.226761] initcall 0x78a46c00: sensors_w83627ehf_init+0x0/0x180() returned -19.
[   32.234178] initcall 0x78a46c00 ran for 0 msecs: sensors_w83627ehf_init+0x0/0x180()
[   32.241812] Calling initcall 0x78a47720: wdtpci_init+0x0/0x20()
[   32.247727] initcall 0x78a47720: wdtpci_init+0x0/0x20() returned 0.
[   32.253942] initcall 0x78a47720 ran for 0 msecs: wdtpci_init+0x0/0x20()
[   32.260528] Calling initcall 0x78a47890: acq_init+0x0/0x70()
[   32.266165] WDT driver for Acquire single board computer initialising.
[   32.272703] acquirewdt: I/O address 0x0043 already in use
[   32.278042] acquirewdt: probe of acquirewdt failed with error -5
[   32.284021] initcall 0x78a47890: acq_init+0x0/0x70() returned 0.
[   32.289993] initcall 0x78a47890 ran for 10 msecs: acq_init+0x0/0x70()
[   32.296407] Calling initcall 0x78a47a90: advwdt_init+0x0/0x70()
[   32.302297] WDT driver for Advantech single board computer initialising.
[   32.309031] advantechwdt: initialized. timeout=60 sec (nowayout=0)
[   32.315134] initcall 0x78a47a90: advwdt_init+0x0/0x70() returned 0.
[   32.321362] initcall 0x78a47a90 ran for 4 msecs: advwdt_init+0x0/0x70()
[   32.327952] Calling initcall 0x78a47b00: watchdog_init+0x0/0x1a0()
[   32.334107] initcall 0x78a47b00: watchdog_init+0x0/0x1a0() returned -19.
[   32.340776] initcall 0x78a47b00 ran for 0 msecs: watchdog_init+0x0/0x1a0()
[   32.347622] Calling initcall 0x78a47ca0: alim7101_wdt_init+0x0/0x200()
[   32.354121] alim7101_wdt: Steve Hill <steve@navaho.co.uk>.
[   32.359586] alim7101_wdt: ALi M7101 PMU not present - WDT not set
[   32.365654] initcall 0x78a47ca0: alim7101_wdt_init+0x0/0x200() returned -16.
[   32.372662] initcall 0x78a47ca0 ran for 4 msecs: alim7101_wdt_init+0x0/0x200()
[   32.379864] initcall at 0x78a47ca0: alim7101_wdt_init+0x0/0x200(): returned with error code -16
[   32.388529] Calling initcall 0x78a47ea0: sc520_wdt_init+0x0/0x110()
[   32.394769] sc520_wdt: cannot register miscdev on minor=130 (err=-16)
[   32.401191] initcall 0x78a47ea0: sc520_wdt_init+0x0/0x110() returned -16.
[   32.407936] initcall 0x78a47ea0 ran for 6 msecs: sc520_wdt_init+0x0/0x110()
[   32.414874] initcall at 0x78a47ea0: sc520_wdt_init+0x0/0x110(): returned with error code -16
[   32.423279] Calling initcall 0x78a47fb0: watchdog_init+0x0/0x2e0()
[   32.429444] initcall 0x78a47fb0: watchdog_init+0x0/0x2e0() returned -19.
[   32.436104] initcall 0x78a47fb0 ran for 0 msecs: watchdog_init+0x0/0x2e0()
[   32.442953] Calling initcall 0x78a48290: iTCO_wdt_init_module+0x0/0x80()
[   32.449622] iTCO_wdt: Intel TCO WatchDog Timer Driver v1.02 (26-Jul-2007)
[   32.456429] iTCO_wdt: No card detected
[   32.460122] initcall 0x78a48290: iTCO_wdt_init_module+0x0/0x80() returned 0.
[   32.467129] initcall 0x78a48290 ran for 6 msecs: iTCO_wdt_init_module+0x0/0x80()
[   32.474495] Calling initcall 0x78a48310: iTCO_vendor_init_module+0x0/0x20()
[   32.481426] iTCO_vendor_support: vendor-support=0
[   32.486114] initcall 0x78a48310: iTCO_vendor_init_module+0x0/0x20() returned 0.
[   32.493387] initcall 0x78a48310 ran for 4 msecs: iTCO_vendor_init_module+0x0/0x20()
[   32.501013] Calling initcall 0x78a48330: cpu5wdt_init_module+0x0/0x150()
[   32.507685] cpu5wdt: misc_register failed
[   32.511679] initcall 0x78a48330: cpu5wdt_init_module+0x0/0x150() returned -16.
[   32.519413] initcall 0x78a48330 ran for 0 msecs: cpu5wdt_init_module+0x0/0x150()
[   32.526780] initcall at 0x78a48330: cpu5wdt_init_module+0x0/0x150(): returned with error code -16
[   32.535614] Calling initcall 0x78a48480: wb_smsc_wdt_init+0x0/0x200()
[   32.542028] SMsC 37B787 watchdog component driver 1.1 initialising...
[   32.549482] smsc37b787_wdt: Unable to register miscdev on minor 130
[   32.555625] initcall 0x78a48480: wb_smsc_wdt_init+0x0/0x200() returned -16.
[   32.562548] initcall 0x78a48480 ran for 9 msecs: wb_smsc_wdt_init+0x0/0x200()
[   32.569661] initcall at 0x78a48480: wb_smsc_wdt_init+0x0/0x200(): returned with error code -16
[   32.578239] Calling initcall 0x78a48680: w83977f_wdt_init+0x0/0x160()
[   32.584651] W83977F WDT: W83977F WDT driver, v1.00
[   32.589420] W83977F WDT: cannot register miscdev on minor=130 (err=-16)
[   32.596009] initcall 0x78a48680: w83977f_wdt_init+0x0/0x160() returned -16.
[   32.602936] initcall 0x78a48680 ran for 4 msecs: w83977f_wdt_init+0x0/0x160()
[   32.610045] initcall at 0x78a48680: w83977f_wdt_init+0x0/0x160(): returned with error code -16
[   32.618624] Calling initcall 0x78a487e0: zf_init+0x0/0x1c0()
[   32.624252] machzwd: MachZ ZF-Logic Watchdog driver initializing.
[   32.630324] machzwd: no ZF-Logic found
[   32.634053] initcall 0x78a487e0: zf_init+0x0/0x1c0() returned -19.
[   32.640200] initcall 0x78a487e0 ran for 6 msecs: zf_init+0x0/0x1c0()
[   32.646526] Calling initcall 0x78a489a0: watchdog_init+0x0/0xd0()
[   32.652592] epx_c3: cannot register miscdev on minor=130 (err=-16)
[   32.658751] initcall 0x78a489a0: watchdog_init+0x0/0xd0() returned -16.
[   32.665328] initcall 0x78a489a0 ran for 1 msecs: watchdog_init+0x0/0xd0()
[   32.672088] initcall at 0x78a489a0: watchdog_init+0x0/0xd0(): returned with error code -16
[   32.680325] Calling initcall 0x78a48a70: watchdog_init+0x0/0xe0()
[   32.686389] SoftDog: cannot register miscdev on minor=130 (err=-16)
[   32.692636] initcall 0x78a48a70: watchdog_init+0x0/0xe0() returned -16.
[   32.699210] initcall 0x78a48a70 ran for 2 msecs: watchdog_init+0x0/0xe0()
[   32.705973] initcall at 0x78a48a70: watchdog_init+0x0/0xe0(): returned with error code -16
[   32.714208] Calling initcall 0x78a48b50: telephony_init+0x0/0x50()
[   32.720360] Linux telephony interface: v1.00
[   32.724625] initcall 0x78a48b50: telephony_init+0x0/0x50() returned 0.
[   32.731102] initcall 0x78a48b50 ran for 0 msecs: telephony_init+0x0/0x50()
[   32.737955] Calling initcall 0x78a48ba0: dm_init+0x0/0x70()
[   32.743531] device-mapper: ioctl: 4.11.0-ioctl (2006-10-12) initialised: dm-devel@redhat.com
[   32.751913] initcall 0x78a48ba0: dm_init+0x0/0x70() returned 0.
[   32.757794] initcall 0x78a48ba0 ran for 1 msecs: dm_init+0x0/0x70()
[   32.764039] Calling initcall 0x78a48dd0: dm_crypt_init+0x0/0xa0()
[   32.770152] initcall 0x78a48dd0: dm_crypt_init+0x0/0xa0() returned 0.
[   32.776518] initcall 0x78a48dd0 ran for 0 msecs: dm_crypt_init+0x0/0xa0()
[   32.783279] Calling initcall 0x78a48e70: dm_delay_init+0x0/0xc0()
[   32.789384] initcall 0x78a48e70: dm_delay_init+0x0/0xc0() returned 0.
[   32.795751] initcall 0x78a48e70 ran for 0 msecs: dm_delay_init+0x0/0xc0()
[   32.802513] Calling initcall 0x78a48f30: dm_snapshot_init+0x0/0x1e0()
[   32.809013] initcall 0x78a48f30: dm_snapshot_init+0x0/0x1e0() returned 0.
[   32.815683] initcall 0x78a48f30 ran for 0 msecs: dm_snapshot_init+0x0/0x1e0()
[   32.822797] Calling initcall 0x78a49160: dm_mirror_init+0x0/0x40()
[   32.828962] initcall 0x78a49160: dm_mirror_init+0x0/0x40() returned 0.
[   32.835444] initcall 0x78a49160 ran for 0 msecs: dm_mirror_init+0x0/0x40()
[   32.842291] Calling initcall 0x78a491a0: kcapi_init+0x0/0xb0()
[   32.848109] CAPI Subsystem Rev 1.1.2.8
[   32.851832] initcall 0x78a491a0: kcapi_init+0x0/0xb0() returned 0.
[   32.857976] initcall 0x78a491a0 ran for 3 msecs: kcapi_init+0x0/0xb0()
[   32.864482] Calling initcall 0x78a49a10: b1pci_init+0x0/0xd0()
[   32.870307] b1pci: revision 1.1.2.2
[   32.873758] initcall 0x78a49a10: b1pci_init+0x0/0xd0() returned 0.
[   32.879904] initcall 0x78a49a10 ran for 3 msecs: b1pci_init+0x0/0xd0()
[   32.886406] Calling initcall 0x78a49ae0: b1_init+0x0/0x80()
[   32.891949] b1: revision 1.1.2.2
[   32.895163] initcall 0x78a49ae0: b1_init+0x0/0x80() returned 0.
[   32.901044] initcall 0x78a49ae0 ran for 1 msecs: b1_init+0x0/0x80()
[   32.907289] Calling initcall 0x78a49b60: b1dma_init+0x0/0x80()
[   32.913094] b1dma: revision 1.1.2.3
[   32.916568] initcall 0x78a49b60: b1dma_init+0x0/0x80() returned 0.
[   32.922715] initcall 0x78a49b60 ran for 3 msecs: b1dma_init+0x0/0x80()
[   32.929211] Calling initcall 0x78a49be0: b1pcmcia_init+0x0/0xa0()
[   32.935280] b1pci: revision 1.1.2.2
[   32.938754] initcall 0x78a49be0: b1pcmcia_init+0x0/0xa0() returned 0.
[   32.945157] initcall 0x78a49be0 ran for 2 msecs: b1pcmcia_init+0x0/0xa0()
[   32.951917] Calling initcall 0x78a49fc0: t1pci_init+0x0/0xb0()
[   32.957739] t1pci: revision 1.1.2.2
[   32.961199] initcall 0x78a49fc0: t1pci_init+0x0/0xb0() returned 0.
[   32.967340] initcall 0x78a49fc0 ran for 0 msecs: t1pci_init+0x0/0xb0()
[   32.973845] Calling initcall 0x78a4a970: c4_init+0x0/0xd0()
[   32.979413] c4: revision 1.1.2.2
[   32.982598] initcall 0x78a4a970: c4_init+0x0/0xd0() returned 0.
[   32.988487] initcall 0x78a4a970 ran for 0 msecs: c4_init+0x0/0xd0()
[   32.994728] Calling initcall 0x78a4ac20: cpufreq_stats_init+0x0/0x70()
[   33.001243] initcall 0x78a4ac20: cpufreq_stats_init+0x0/0x70() returned 0.
[   33.008073] initcall 0x78a4ac20 ran for 0 msecs: cpufreq_stats_init+0x0/0x70()
[   33.015272] Calling initcall 0x78a4ac90: cpufreq_gov_powersave_init+0x0/0x10()
[   33.022466] initcall 0x78a4ac90: cpufreq_gov_powersave_init+0x0/0x10() returned 0.
[   33.030001] initcall 0x78a4ac90 ran for 0 msecs: cpufreq_gov_powersave_init+0x0/0x10()
[   33.037890] Calling initcall 0x78a4acb0: cpufreq_gov_dbs_init+0x0/0x10()
[   33.044566] initcall 0x78a4acb0: cpufreq_gov_dbs_init+0x0/0x10() returned 0.
[   33.051577] initcall 0x78a4acb0 ran for 0 msecs: cpufreq_gov_dbs_init+0x0/0x10()
[   33.058944] Calling initcall 0x78a4b430: hid_init+0x0/0x10()
[   33.064585] initcall 0x78a4b430: hid_init+0x0/0x10() returned 0.
[   33.070553] initcall 0x78a4b430 ran for 0 msecs: hid_init+0x0/0x10()
[   33.076886] Calling initcall 0x78a4b440: hid_init+0x0/0x60()
[   33.082531] usbcore: registered new interface driver usbhid
[   33.088069] drivers/hid/usbhid/hid-core.c: v2.6:USB HID core driver
[   33.094310] initcall 0x78a4b440: hid_init+0x0/0x60() returned 0.
[   33.100285] initcall 0x78a4b440 ran for 6 msecs: hid_init+0x0/0x60()
[   33.106610] Calling initcall 0x78a4b4a0: usb_mouse_init+0x0/0x40()
[   33.112778] usbcore: registered new interface driver usbmouse
[   33.118487] drivers/hid/usbhid/usbmouse.c: v1.6:USB HID Boot Protocol mouse driver
[   33.126028] initcall 0x78a4b4a0: usb_mouse_init+0x0/0x40() returned 0.
[   33.132516] initcall 0x78a4b4a0 ran for 6 msecs: usb_mouse_init+0x0/0x40()
[   33.139371] Calling initcall 0x78a4d880: flow_cache_init+0x0/0x100()
[   33.145701] initcall 0x78a4d880: flow_cache_init+0x0/0x100() returned 0.
[   33.152362] initcall 0x78a4d880 ran for 0 msecs: flow_cache_init+0x0/0x100()
[   33.159389] Calling initcall 0x78a4d980: pg_init+0x0/0x250()
[   33.165018] pktgen v2.69: Packet Generator for packet performance testing.
[   33.171914] initcall 0x78a4d980: pg_init+0x0/0x250() returned 0.
[   33.177842] initcall 0x78a4d980 ran for 2 msecs: pg_init+0x0/0x250()
[   33.184172] Calling initcall 0x78a4dc10: llc_init+0x0/0x70()
[   33.189808] initcall 0x78a4dc10: llc_init+0x0/0x70() returned 0.
[   33.195779] initcall 0x78a4dc10 ran for 0 msecs: llc_init+0x0/0x70()
[   33.202108] Calling initcall 0x78a4dd00: llc2_init+0x0/0xd0()
[   33.207844] NET: Registered protocol family 26
[   33.212257] initcall 0x78a4dd00: llc2_init+0x0/0xd0() returned 0.
[   33.218313] initcall 0x78a4dd00 ran for 1 msecs: llc2_init+0x0/0xd0()
[   33.224726] Calling initcall 0x78a4df90: snap_init+0x0/0x40()
[   33.230465] initcall 0x78a4df90: snap_init+0x0/0x40() returned 0.
[   33.236515] initcall 0x78a4df90 ran for 0 msecs: snap_init+0x0/0x40()
[   33.242930] Calling initcall 0x78a4e0a0: blackhole_module_init+0x0/0x10()
[   33.249690] initcall 0x78a4e0a0: blackhole_module_init+0x0/0x10() returned 0.
[   33.256794] initcall 0x78a4e0a0 ran for 0 msecs: blackhole_module_init+0x0/0x10()
[   33.264247] Calling initcall 0x78a4e170: gact_init_module+0x0/0x20()
[   33.270572] GACT probability on
[   33.273706] initcall 0x78a4e170: gact_init_module+0x0/0x20() returned 0.
[   33.280366] initcall 0x78a4e170 ran for 2 msecs: gact_init_module+0x0/0x20()
[   33.287385] Calling initcall 0x78a4e190: simp_init_module+0x0/0x30()
[   33.293710] Simple TC action Loaded
[   33.297184] initcall 0x78a4e190: simp_init_module+0x0/0x30() returned 0.
[   33.303846] initcall 0x78a4e190 ran for 3 msecs: simp_init_module+0x0/0x30()
[   33.310870] Calling initcall 0x78a4e1c0: hfsc_init+0x0/0x10()
[   33.316593] initcall 0x78a4e1c0: hfsc_init+0x0/0x10() returned 0.
[   33.322656] initcall 0x78a4e1c0 ran for 0 msecs: hfsc_init+0x0/0x10()
[   33.329066] Calling initcall 0x78a4e1d0: gred_module_init+0x0/0x10()
[   33.335398] initcall 0x78a4e1d0: gred_module_init+0x0/0x10() returned 0.
[   33.342065] initcall 0x78a4e1d0 ran for 0 msecs: gred_module_init+0x0/0x10()
[   33.349085] Calling initcall 0x78a4e1e0: sfq_module_init+0x0/0x10()
[   33.355331] initcall 0x78a4e1e0: sfq_module_init+0x0/0x10() returned 0.
[   33.361911] initcall 0x78a4e1e0 ran for 0 msecs: sfq_module_init+0x0/0x10()
[   33.368844] Calling initcall 0x78a4e1f0: prio_module_init+0x0/0x40()
[   33.375176] initcall 0x78a4e1f0: prio_module_init+0x0/0x40() returned 0.
[   33.381843] initcall 0x78a4e1f0 ran for 0 msecs: prio_module_init+0x0/0x40()
[   33.388862] Calling initcall 0x78a4e230: netem_module_init+0x0/0x20()
[   33.395277] netem: version 1.2
[   33.398317] initcall 0x78a4e230: netem_module_init+0x0/0x20() returned 0.
[   33.405068] initcall 0x78a4e230 ran for 2 msecs: netem_module_init+0x0/0x20()
[   33.412175] Calling initcall 0x78a4e250: init_u32+0x0/0x30()
[   33.417811] u32 classifier
[   33.420497]     Actions configured 
[   33.423978] initcall 0x78a4e250: init_u32+0x0/0x30() returned 0.
[   33.429943] initcall 0x78a4e250 ran for 6 msecs: init_u32+0x0/0x30()
[   33.436269] Calling initcall 0x78a4e280: init_route4+0x0/0x10()
[   33.442165] initcall 0x78a4e280: init_route4+0x0/0x10() returned 0.
[   33.448399] initcall 0x78a4e280 ran for 0 msecs: init_route4+0x0/0x10()
[   33.454985] Calling initcall 0x78a4e290: init_rsvp+0x0/0x10()
[   33.460710] initcall 0x78a4e290: init_rsvp+0x0/0x10() returned 0.
[   33.466774] initcall 0x78a4e290 ran for 0 msecs: init_rsvp+0x0/0x10()
[   33.473187] Calling initcall 0x78a4e2a0: init_rsvp+0x0/0x10()
[   33.478910] initcall 0x78a4e2a0: init_rsvp+0x0/0x10() returned 0.
[   33.484970] initcall 0x78a4e2a0 ran for 0 msecs: init_rsvp+0x0/0x10()
[   33.491382] Calling initcall 0x78a4f450: ipip_init+0x0/0xa0()
[   33.497104] IPv4 over IPv4 tunneling driver
[   33.501390] initcall 0x78a4f450: ipip_init+0x0/0xa0() returned 0.
[   33.507326] initcall 0x78a4f450 ran for 0 msecs: ipip_init+0x0/0xa0()
[   33.513744] Calling initcall 0x78a4f540: ipgre_init+0x0/0xa0()
[   33.519549] GRE over IPv4 tunneling driver
[   33.523715] initcall 0x78a4f540: ipgre_init+0x0/0xa0() returned 0.
[   33.529776] initcall 0x78a4f540 ran for 3 msecs: ipgre_init+0x0/0xa0()
[   33.536279] Calling initcall 0x78a4f630: ah4_init+0x0/0x70()
[   33.542432] initcall 0x78a4f630: ah4_init+0x0/0x70() returned 0.
[   33.548406] initcall 0x78a4f630 ran for 0 msecs: ah4_init+0x0/0x70()
[   33.554732] Calling initcall 0x78a4f6a0: ipcomp4_init+0x0/0x70()
[   33.560718] initcall 0x78a4f6a0: ipcomp4_init+0x0/0x70() returned 0.
[   33.567042] initcall 0x78a4f6a0 ran for 0 msecs: ipcomp4_init+0x0/0x70()
[   33.573714] Calling initcall 0x78a4f710: ipip_init+0x0/0xb0()
[   33.579436] initcall 0x78a4f710: ipip_init+0x0/0xb0() returned 0.
[   33.585497] initcall 0x78a4f710 ran for 0 msecs: ipip_init+0x0/0xb0()
[   33.591909] Calling initcall 0x78a4f7c0: xfrm4_beet_init+0x0/0x10()
[   33.598155] initcall 0x78a4f7c0: xfrm4_beet_init+0x0/0x10() returned 0.
[   33.604736] initcall 0x78a4f7c0 ran for 0 msecs: xfrm4_beet_init+0x0/0x10()
[   33.611669] Calling initcall 0x78a4f7d0: tunnel4_init+0x0/0x70()
[   33.617653] initcall 0x78a4f7d0: tunnel4_init+0x0/0x70() returned 0.
[   33.623972] initcall 0x78a4f7d0 ran for 0 msecs: tunnel4_init+0x0/0x70()
[   33.630650] Calling initcall 0x78a4f840: xfrm4_transport_init+0x0/0x10()
[   33.637326] initcall 0x78a4f840: xfrm4_transport_init+0x0/0x10() returned 0.
[   33.644337] initcall 0x78a4f840 ran for 0 msecs: xfrm4_transport_init+0x0/0x10()
[   33.651711] Calling initcall 0x78a4f850: xfrm4_tunnel_init+0x0/0x10()
[   33.658124] initcall 0x78a4f850: xfrm4_tunnel_init+0x0/0x10() returned 0.
[   33.664878] initcall 0x78a4f850 ran for 0 msecs: xfrm4_tunnel_init+0x0/0x10()
[   33.671985] Calling initcall 0x78a50e40: cubictcp_register+0x0/0xa0()
[   33.678400] TCP cubic registered
[   33.681614] initcall 0x78a50e40: cubictcp_register+0x0/0xa0() returned 0.
[   33.688364] initcall 0x78a50e40 ran for 3 msecs: cubictcp_register+0x0/0xa0()
[   33.695470] Calling initcall 0x78a51120: af_unix_init+0x0/0x70()
[   33.701452] NET: Registered protocol family 1
[   33.705796] initcall 0x78a51120: af_unix_init+0x0/0x70() returned 0.
[   33.712108] initcall 0x78a51120 ran for 4 msecs: af_unix_init+0x0/0x70()
[   33.718781] Calling initcall 0x78a51190: inet6_init+0x0/0x2e0()
[   33.724690] NET: Registered protocol family 10
[   33.729219] lo: Disabled Privacy Extensions
[   33.733444] tunl0: Disabled Privacy Extensions
[   33.737843] initcall 0x78a51190: inet6_init+0x0/0x2e0() returned 0.
[   33.743998] initcall 0x78a51190 ran for 12 msecs: inet6_init+0x0/0x2e0()
[   33.750676] Calling initcall 0x78a51d10: xfrm6_tunnel_init+0x0/0x10()
[   33.757091] initcall 0x78a51d10: xfrm6_tunnel_init+0x0/0x10() returned 0.
[   33.763843] initcall 0x78a51d10 ran for 0 msecs: xfrm6_tunnel_init+0x0/0x10()
[   33.770955] Calling initcall 0x78a51d20: xfrm6_beet_init+0x0/0x10()
[   33.777196] initcall 0x78a51d20: xfrm6_beet_init+0x0/0x10() returned 0.
[   33.783775] initcall 0x78a51d20 ran for 0 msecs: xfrm6_beet_init+0x0/0x10()
[   33.790713] Calling initcall 0x78a51d30: sit_init+0x0/0xa0()
[   33.796345] IPv6 over IPv4 tunneling driver
[   33.800618] sit0: Disabled Privacy Extensions
[   33.804862] initcall 0x78a51d30: sit_init+0x0/0xa0() returned 0.
[   33.810822] initcall 0x78a51d30 ran for 4 msecs: sit_init+0x0/0xa0()
[   33.817154] Calling initcall 0x78a51e20: packet_init+0x0/0x50()
[   33.823046] NET: Registered protocol family 17
[   33.827488] initcall 0x78a51e20: packet_init+0x0/0x50() returned 0.
[   33.833707] initcall 0x78a51e20 ran for 4 msecs: packet_init+0x0/0x50()
[   33.840292] Calling initcall 0x78a51e70: br_init+0x0/0xb0()
[   33.845869] initcall 0x78a51e70: br_init+0x0/0xb0() returned 0.
[   33.851729] initcall 0x78a51e70 ran for 0 msecs: br_init+0x0/0xb0()
[   33.857968] Calling initcall 0x78a51fc0: ipx_init+0x0/0xf0()
[   33.863604] NET: Registered protocol family 4
[   33.871365] input: AT Translated Set 2 keyboard as /class/input/input0
[   33.879184] initcall 0x78a51fc0: ipx_init+0x0/0xf0() returned 0.
[   33.885032] initcall 0x78a51fc0 ran for 11 msecs: ipx_init+0x0/0xf0()
[   33.891446] Calling initcall 0x78a521e0: atalk_init+0x0/0x90()
[   33.897254] NET: Registered protocol family 5
[   33.919166] evbug.c: Connected device: "AT Translated Set 2 keyboard", isa0060/serio0/input0
[   33.927623] initcall 0x78a521e0: atalk_init+0x0/0x90() returned 0.
[   33.933653] initcall 0x78a521e0 ran for 25 msecs: atalk_init+0x0/0x90()
[   33.940239] Calling initcall 0x78a52460: x25_init+0x0/0x60()
[   33.945877] NET: Registered protocol family 9
[   33.950209] X.25 for Linux. Version 0.2 for Linux 2.1.15
[   33.955502] initcall 0x78a52460: x25_init+0x0/0x60() returned 0.
[   33.961468] initcall 0x78a52460 ran for 6 msecs: x25_init+0x0/0x60()
[   33.967794] Calling initcall 0x78a52a70: irlan_init+0x0/0x220()
[   33.973835] initcall 0x78a52a70: irlan_init+0x0/0x220() returned 0.
[   33.979949] initcall 0x78a52a70 ran for 0 msecs: irlan_init+0x0/0x220()
[   33.986534] Calling initcall 0x78a52c90: ircomm_init+0x0/0x80()
[   33.992426] IrCOMM protocol (Dag Brattli)
[   33.996420] initcall 0x78a52c90: ircomm_init+0x0/0x80() returned 0.
[   34.002653] initcall 0x78a52c90 ran for 2 msecs: ircomm_init+0x0/0x80()
[   34.009240] Calling initcall 0x78a52d10: ircomm_tty_init+0x0/0x170()
[   34.016031] initcall 0x78a52d10: ircomm_tty_init+0x0/0x170() returned 0.
[   34.022575] initcall 0x78a52d10 ran for 3 msecs: ircomm_tty_init+0x0/0x170()
[   34.029597] Calling initcall 0x78a52eb0: init_sunrpc+0x0/0x60()
[   34.035684] RPC: Registered udp transport module.
[   34.040273] RPC: Registered tcp transport module.
[   34.044955] initcall 0x78a52eb0: init_sunrpc+0x0/0x60() returned 0.
[   34.051179] initcall 0x78a52eb0 ran for 4 msecs: init_sunrpc+0x0/0x60()
[   34.057771] Calling initcall 0x78a52f10: init_rpcsec_gss+0x0/0x30()
[   34.064034] initcall 0x78a52f10: init_rpcsec_gss+0x0/0x30() returned 0.
[   34.070589] initcall 0x78a52f10 ran for 0 msecs: init_rpcsec_gss+0x0/0x30()
[   34.077528] Calling initcall 0x78a52f40: init_kerberos_module+0x0/0x30()
[   34.084225] initcall 0x78a52f40: init_kerberos_module+0x0/0x30() returned 0.
[   34.091217] initcall 0x78a52f40 ran for 0 msecs: init_kerberos_module+0x0/0x30()
[   34.098589] Calling initcall 0x78a52f70: decnet_init+0x0/0x80()
[   34.104478] NET4: DECnet for Linux: V.2.5.68s (C) 1995-2003 Linux DECnet Project Team
[   34.112308] DECnet: Routing cache hash table of 1024 buckets, 32Kbytes
[   34.118851] NET: Registered protocol family 12
[   34.123209] initcall 0x78a52f70: decnet_init+0x0/0x80() returned 0.
[   34.129438] initcall 0x78a52f70 ran for 11 msecs: decnet_init+0x0/0x80()
[   34.136112] Calling initcall 0x78a532d0: econet_proto_init+0x0/0x40()
[   34.142528] NET: Registered protocol family 19
[   34.146952] initcall 0x78a532d0: econet_proto_init+0x0/0x40() returned 0.
[   34.153697] initcall 0x78a532d0 ran for 4 msecs: econet_proto_init+0x0/0x40()
[   34.160809] Calling initcall 0x78a53310: vlan_proto_init+0x0/0xd0()
[   34.167047] 802.1Q VLAN Support v1.8 Ben Greear <greearb@candelatech.com>
[   34.173811] All bugs added by David S. Miller <davem@redhat.com>
[   34.179810] initcall 0x78a53310: vlan_proto_init+0x0/0xd0() returned 0.
[   34.186373] initcall 0x78a53310 ran for 5 msecs: vlan_proto_init+0x0/0xd0()
[   34.193309] Calling initcall 0x78a53440: dccp_init+0x0/0x2c0()
[   34.207686] initcall 0x78a53440: dccp_init+0x0/0x2c0() returned 0.
[   34.213710] initcall 0x78a53440 ran for 8 msecs: dccp_init+0x0/0x2c0()
[   34.220215] Calling initcall 0x78a53740: dccp_v4_init+0x0/0xa0()
[   34.235804] initcall 0x78a53740: dccp_v4_init+0x0/0xa0() returned 0.
[   34.241998] initcall 0x78a53740 ran for 9 msecs: dccp_v4_init+0x0/0xa0()
[   34.248672] Calling initcall 0x78a537e0: dccp_v6_init+0x0/0xa0()
[   34.254678] initcall 0x78a537e0: dccp_v6_init+0x0/0xa0() returned 0.
[   34.260977] initcall 0x78a537e0 ran for 0 msecs: dccp_v6_init+0x0/0xa0()
[   34.267656] Calling initcall 0x78a53910: ieee80211_init+0x0/0xb0()
[   34.273809] ieee80211: 802.11 data/management/control stack, git-1.1.13
[   34.280396] ieee80211: Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>
[   34.288719] initcall 0x78a53910: ieee80211_init+0x0/0xb0() returned 0.
[   34.295208] initcall 0x78a53910 ran for 4 msecs: ieee80211_init+0x0/0xb0()
[   34.302055] Calling initcall 0x78a539c0: ieee80211_crypto_init+0x0/0x10()
[   34.308843] ieee80211_crypt: registered algorithm 'NULL'
[   34.314110] initcall 0x78a539c0: ieee80211_crypto_init+0x0/0x10() returned 0.
[   34.321207] initcall 0x78a539c0 ran for 5 msecs: ieee80211_crypto_init+0x0/0x10()
[   34.328665] Calling initcall 0x78a539d0: tipc_init+0x0/0xf0()
[   34.334393] TIPC: Activated (version 1.6.2 compiled Oct 17 2007 17:24:06)
[   34.342666] NET: Registered protocol family 30
[   34.346991] TIPC: Started in single node mode
[   34.351324] initcall 0x78a539d0: tipc_init+0x0/0xf0() returned 0.
[   34.357377] initcall 0x78a539d0 ran for 9 msecs: tipc_init+0x0/0xf0()
[   34.363796] Calling initcall 0x78a53b40: init_p9+0x0/0x60()
[   34.369354] Installing 9P2000 support
[   34.373041] initcall 0x78a53b40: init_p9+0x0/0x60() returned 0.
[   34.378869] initcall 0x78a53b40 ran for 3 msecs: init_p9+0x0/0x60()
[   34.385111] Calling initcall 0x78a1d920: centrino_init+0x0/0x20()
[   34.391182] initcall 0x78a1d920: centrino_init+0x0/0x20() returned -19.
[   34.397764] initcall 0x78a1d920 ran for 0 msecs: centrino_init+0x0/0x20()
[   34.404529] Calling initcall 0x78a1fb30: check_nmi_watchdog+0x0/0x140()
[   34.411116] initcall 0x78a1fb30: check_nmi_watchdog+0x0/0x140() returned 0.
[   34.418042] initcall 0x78a1fb30 ran for 0 msecs: check_nmi_watchdog+0x0/0x140()
[   34.425322] Calling initcall 0x78a1fda0: io_apic_bug_finalize+0x0/0x20()
[   34.432000] initcall 0x78a1fda0: io_apic_bug_finalize+0x0/0x20() returned 0.
[   34.439012] initcall 0x78a1fda0 ran for 0 msecs: io_apic_bug_finalize+0x0/0x20()
[   34.446386] Calling initcall 0x78a23a40: print_ipi_mode+0x0/0x30()
[   34.452540] Using IPI Shortcut mode
[   34.456009] initcall 0x78a23a40: print_ipi_mode+0x0/0x30() returned 0.
[   34.462502] initcall 0x78a23a40 ran for 3 msecs: print_ipi_mode+0x0/0x30()
[   34.469352] Calling initcall 0x78a24180: disable_boot_consoles+0x0/0x50()
[   34.476111] initcall 0x78a24180: disable_boot_consoles+0x0/0x50() returned 0.
[   34.483215] initcall 0x78a24180 ran for 0 msecs: disable_boot_consoles+0x0/0x50()
[   34.490667] Calling initcall 0x78a25a60: taskstats_init+0x0/0x70()
[   34.496834] initcall 0x78a25a60: taskstats_init+0x0/0x70() returned 0.
[   34.503320] initcall 0x78a25a60 ran for 0 msecs: taskstats_init+0x0/0x70()
[   34.510166] Calling initcall 0x78a2b9c0: random32_reseed+0x0/0x30()
[   34.516414] initcall 0x78a2b9c0: random32_reseed+0x0/0x30() returned 0.
[   34.522992] initcall 0x78a2b9c0 ran for 0 msecs: random32_reseed+0x0/0x30()
[   34.529927] Calling initcall 0x78a2d030: pci_sysfs_init+0x0/0x40()
[   34.536194] initcall 0x78a2d030: pci_sysfs_init+0x0/0x40() returned 0.
[   34.542577] initcall 0x78a2d030 ran for 0 msecs: pci_sysfs_init+0x0/0x40()
[   34.549427] Calling initcall 0x78a2d360: seqgen_init+0x0/0x10()
[   34.555334] initcall 0x78a2d360: seqgen_init+0x0/0x10() returned 0.
[   34.561553] initcall 0x78a2d360 ran for 0 msecs: seqgen_init+0x0/0x10()
[   34.568140] Calling initcall 0x784ca5a0: scsi_complete_async_scans+0x0/0xe0()
[   34.575251] initcall 0x784ca5a0: scsi_complete_async_scans+0x0/0xe0() returned 0.
[   34.582702] initcall 0x784ca5a0 ran for 0 msecs: scsi_complete_async_scans+0x0/0xe0()
[   34.590503] Calling initcall 0x78a4ebf0: tcp_congestion_default+0x0/0x10()
[   34.597350] initcall 0x78a4ebf0: tcp_congestion_default+0x0/0x10() returned 0.
[   34.604538] initcall 0x78a4ebf0 ran for 0 msecs: tcp_congestion_default+0x0/0x10()
[   34.612082] Calling initcall 0x78a4fc40: ip_auto_config+0x0/0xdc0()
[   34.618324] initcall 0x78a4fc40: ip_auto_config+0x0/0xdc0() returned 0.
[   34.625422] initcall 0x78a4fc40 ran for 0 msecs: ip_auto_config+0x0/0xdc0()
[   34.665133] kjournald starting.  Commit interval 5 seconds
[   34.670612] EXT3-fs: mounted filesystem with ordered data mode.
[   34.676419] VFS: Mounted root (ext3 filesystem) readonly.
[   34.682140] Freeing unused kernel memory: 372k freed
[   37.701628] warning: process `kmodule' used the removed sysctl system call with 1.23.
[   39.409390] BUG: unable to handle kernel paging request at virtual address 7ca76000
[   39.416892] printing eip: 78406669 *pde = 00dda027 *pte = 04a76000 
[   39.423132] Oops: 0000 [#1] DEBUG_PAGEALLOC
[   39.427292] 
[   39.428766] Pid: 431, comm: fsck.ext3 Not tainted (2.6.23 #45)
[   39.434571] EIP: 0060:[<78406669>] EFLAGS: 00010006 CPU: 0
[   39.440035] EIP is at blk_rq_map_sg+0xb9/0x170
[   39.444450] EAX: 04aed000 EBX: 7ca1f380 ECX: 04aee000 EDX: 00095da0
[   39.450689] ESI: 7ca75ff0 EDI: 79180da0 EBP: 00001000 ESP: 7caa1cac
[   39.456929]  DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 0068
[   39.462303] Process fsck.ext3 (pid: 431, ti=7caa0000 task=7ca80000 task.ti=7caa0000)
[   39.469841] Stack: 00000020 7b520000 00002000 04aef000 7ca75fe0 0000001f 00000001 00000000 
[   39.478161]        7ca1f300 01000002 7ca44980 7b522b94 7ca0de00 7b520000 784c89b5 7b520000 
[   39.486480]        784c843a 7ca0de00 7b520f20 7b522b94 7ca0de00 784e54a0 784f394b 00000000 
[   39.494799] Call Trace:
[   39.497400]  [<784c89b5>] scsi_init_io+0x55/0xe0
[   39.501992]  [<784c843a>] scsi_get_cmd_from_req+0x2a/0x40
[   39.507366]  [<784e54a0>] sd_prep_fn+0x80/0x940
[   39.511872]  [<784f394b>] ata_bmdma_start+0xb/0x20
[   39.516638]  [<784ef344>] ata_qc_issue_prot+0x164/0x1e0
[   39.521839]  [<78405c63>] elv_dispatch_sort+0x23/0xe0
[   39.526865]  [<784057d0>] elv_next_request+0xa0/0x130
[   39.531891]  [<787715b8>] _spin_lock_irq+0x38/0x50
[   39.536657]  [<784c9af4>] scsi_request_fn+0x1e4/0x370
[   39.541684]  [<78120e72>] del_timer+0x62/0x70
[   39.546016]  [<78408a45>] __generic_unplug_device+0x25/0x30
[   39.551563]  [<78408d15>] generic_unplug_device+0x15/0x30
[   39.556936]  [<78406430>] blk_backing_dev_unplug+0x0/0x10
[   39.562309]  [<7840643c>] blk_backing_dev_unplug+0xc/0x10
[   39.567682]  [<7818080d>] block_sync_page+0x2d/0x40
[   39.572535]  [<78144ee9>] sync_page+0x29/0x40
[   39.576868]  [<7876fdec>] __wait_on_bit_lock+0x3c/0x70
[   39.581981]  [<78144ec0>] sync_page+0x0/0x40
[   39.586227]  [<78144ea2>] __lock_page+0x52/0x60
[   39.590734]  [<7812ae90>] wake_bit_function+0x0/0x60
[   39.595674]  [<7814566c>] do_generic_mapping_read+0x21c/0x450
[   39.601393]  [<78144c30>] file_read_actor+0x0/0x130
[   39.606246]  [<78147227>] generic_file_aio_read+0x137/0x180
[   39.611793]  [<78144c30>] file_read_actor+0x0/0x130
[   39.616645]  [<78160d95>] do_sync_read+0xd5/0x120
[   39.621326]  [<78135cd8>] mark_held_locks+0x38/0x70
[   39.626179]  [<7812ae50>] autoremove_wake_function+0x0/0x40
[   39.631724]  [<787705b4>] mutex_lock_nested+0x1a4/0x200
[   39.636924]  [<78185611>] block_llseek+0x31/0xc0
[   39.641517]  [<787703a5>] __mutex_unlock_slowpath+0xb5/0x110
[   39.647150]  [<78135e1c>] trace_hardirqs_on+0x9c/0xb0
[   39.652177]  [<78160cc0>] do_sync_read+0x0/0x120
[   39.656770]  [<7816165b>] vfs_read+0xbb/0x120
[   39.661103]  [<78161a41>] sys_read+0x41/0x70
[   39.665349]  [<781028a2>] syscall_call+0x7/0xb
[   39.669769]  =======================
[   39.673322] Code: 05 c1 e1 0c 03 4a 08 8b 52 04 01 ca 89 54 24 0c 8b 3b 89 fa 29 c2 89 d0 c1 f8 05 c1 e0 0c 03 43 08 39 44 24 0c 0f 84 7e 00 00 00 <8b> 46 10 8d 56 10 a8 01 75 4c 89 3e 89 6e 0c 8b 43 08 89 46 04 
[   39.692128] EIP: [<78406669>] blk_rq_map_sg+0xb9/0x170 SS:ESP 0068:7caa1cac
[   73.714486] BUG: spinlock lockup on CPU#0, fsck.ext3/431, 7b52010c
[   73.720530]  [<78415bfb>] _raw_spin_lock+0x13b/0x140
[   73.725469]  [<784c8c66>] scsi_device_unbusy+0x66/0xa0
[   73.730582]  [<784c31ec>] scsi_finish_command+0x1c/0xd0
[   73.735782]  [<7811d4b8>] do_softirq+0x68/0x70
[   73.740202]  [<784068f3>] blk_done_softirq+0x73/0x80
[   73.745141]  [<7811d3f3>] __do_softirq+0x53/0xb0
[   73.749734]  [<7811d4b8>] do_softirq+0x68/0x70
[   73.754154]  [<7810c1ce>] smp_apic_timer_interrupt+0x3e/0x80
[   73.759787]  [<781038c9>] apic_timer_interrupt+0x29/0x40
[   73.765073]  [<781038d3>] apic_timer_interrupt+0x33/0x40
[   73.770360]  [<7811b6ee>] do_exit+0x6e/0x760
[   73.774606]  [<78771645>] _spin_unlock_irq+0x25/0x30
[   73.779546]  [<7811b6ee>] do_exit+0x6e/0x760
[   73.783792]  [<78104031>] show_registers+0x71/0x1a0
[   73.788645]  [<78439153>] do_unblank_screen+0x23/0x130
[   73.793759]  [<7810437f>] die+0x21f/0x220
[   73.797745]  [<7810fcb7>] do_page_fault+0x177/0x670
[   73.802597]  [<7810fb40>] do_page_fault+0x0/0x670
[   73.807277]  [<787718fa>] error_code+0x6a/0x70
[   73.811697]  [<78406669>] blk_rq_map_sg+0xb9/0x170
[   73.816464]  [<784c89b5>] scsi_init_io+0x55/0xe0
[   73.821057]  [<784c843a>] scsi_get_cmd_from_req+0x2a/0x40
[   73.826429]  [<784e54a0>] sd_prep_fn+0x80/0x940
[   73.830936]  [<784f394b>] ata_bmdma_start+0xb/0x20
[   73.835702]  [<784ef344>] ata_qc_issue_prot+0x164/0x1e0
[   73.840902]  [<78405c63>] elv_dispatch_sort+0x23/0xe0
[   73.845928]  [<784057d0>] elv_next_request+0xa0/0x130
[   73.850955]  [<787715b8>] _spin_lock_irq+0x38/0x50
[   73.855721]  [<784c9af4>] scsi_request_fn+0x1e4/0x370
[   73.860747]  [<78120e72>] del_timer+0x62/0x70
[   73.865081]  [<78408a45>] __generic_unplug_device+0x25/0x30
[   73.870627]  [<78408d15>] generic_unplug_device+0x15/0x30
[   73.876000]  [<78406430>] blk_backing_dev_unplug+0x0/0x10
[   73.881372]  [<7840643c>] blk_backing_dev_unplug+0xc/0x10
[   73.886746]  [<7818080d>] block_sync_page+0x2d/0x40
[   73.891599]  [<78144ee9>] sync_page+0x29/0x40
[   73.895932]  [<7876fdec>] __wait_on_bit_lock+0x3c/0x70
[   73.901044]  [<78144ec0>] sync_page+0x0/0x40
[   73.905291]  [<78144ea2>] __lock_page+0x52/0x60
[   73.909797]  [<7812ae90>] wake_bit_function+0x0/0x60
[   73.914737]  [<7814566c>] do_generic_mapping_read+0x21c/0x450
[   73.920456]  [<78144c30>] file_read_actor+0x0/0x130
[   73.925310]  [<78147227>] generic_file_aio_read+0x137/0x180
[   73.930857]  [<78144c30>] file_read_actor+0x0/0x130
[   73.935709]  [<78160d95>] do_sync_read+0xd5/0x120
[   73.940389]  [<78135cd8>] mark_held_locks+0x38/0x70
[   73.945242]  [<7812ae50>] autoremove_wake_function+0x0/0x40
[   73.950788]  [<787705b4>] mutex_lock_nested+0x1a4/0x200
[   73.955988]  [<78185611>] block_llseek+0x31/0xc0
[   73.960581]  [<787703a5>] __mutex_unlock_slowpath+0xb5/0x110
[   73.966214]  [<78135e1c>] trace_hardirqs_on+0x9c/0xb0
[   73.971241]  [<78160cc0>] do_sync_read+0x0/0x120
[   73.975833]  [<7816165b>] vfs_read+0xbb/0x120
[   73.980166]  [<78161a41>] sys_read+0x41/0x70
[   73.984413]  [<781028a2>] syscall_call+0x7/0xb
[   73.988832]  =======================

[-- Attachment #3: config --]
[-- Type: text/plain, Size: 40001 bytes --]

#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.23
# Wed Oct 17 17:23:34 2007
#
CONFIG_X86_32=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_CLOCKSOURCE_WATCHDOG=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_SEMAPHORE_SLEEPERS=y
CONFIG_X86=y
CONFIG_MMU=y
CONFIG_ZONE_DMA=y
CONFIG_QUICKLIST=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_IOMAP=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_DMI=y
CONFIG_BOOTPARAM_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"

#
# General setup
#
CONFIG_EXPERIMENTAL=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
# CONFIG_SYSVIPC is not set
# CONFIG_POSIX_MQUEUE is not set
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
# CONFIG_USER_NS is not set
CONFIG_AUDIT=y
# CONFIG_AUDITSYSCALL is not set
CONFIG_IKCONFIG=y
# CONFIG_IKCONFIG_PROC is not set
CONFIG_LOG_BUF_SHIFT=20
CONFIG_BOOTPARAM_MAXCPUS_1=y
CONFIG_BOOTPARAM_NOSMP=y
# CONFIG_FAIR_GROUP_SCHED is not set
CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
CONFIG_KALLSYMS_EXTRA_PASS=y
# CONFIG_HOTPLUG is not set
CONFIG_PRINTK=y
# CONFIG_BUG is not set
CONFIG_ELF_CORE=y
# CONFIG_BASE_FULL is not set
CONFIG_FUTEX=y
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
# CONFIG_SIGNALFD is not set
# CONFIG_EVENTFD is not set
CONFIG_SHMEM=y
# CONFIG_VM_EVENT_COUNTERS is not set
# CONFIG_SLAB is not set
# CONFIG_SLUB is not set
CONFIG_SLOB=y
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=1
# CONFIG_MODULES is not set
CONFIG_BLOCK=y
CONFIG_LBD=y
# CONFIG_BLK_DEV_IO_TRACE is not set
CONFIG_LSF=y
# CONFIG_BLK_DEV_BSG is not set

#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
# CONFIG_IOSCHED_AS is not set
CONFIG_IOSCHED_DEADLINE=y
# CONFIG_IOSCHED_CFQ is not set
# CONFIG_DEFAULT_AS is not set
# CONFIG_DEFAULT_DEADLINE is not set
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"

#
# Processor type and features
#
CONFIG_TICK_ONESHOT=y
# CONFIG_NO_HZ is not set
# CONFIG_BOOTPARAM_NO_HZ_OFF is not set
CONFIG_HIGH_RES_TIMERS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_BOOTPARAM_HIGHRES_OFF=y
# CONFIG_SMP is not set
CONFIG_X86_PC=y
# CONFIG_X86_ELAN is not set
# CONFIG_X86_VOYAGER is not set
# CONFIG_X86_NUMAQ is not set
# CONFIG_X86_SUMMIT is not set
# CONFIG_X86_BIGSMP is not set
# CONFIG_X86_VISWS is not set
# CONFIG_X86_GENERICARCH is not set
# CONFIG_X86_ES7000 is not set
# CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER is not set
CONFIG_PARAVIRT=y
# CONFIG_XEN is not set
CONFIG_VMI=y
# CONFIG_M386 is not set
# CONFIG_M486 is not set
# CONFIG_M586 is not set
# CONFIG_M586TSC is not set
# CONFIG_M586MMX is not set
# CONFIG_M686 is not set
# CONFIG_MPENTIUMII is not set
# CONFIG_MPENTIUMIII is not set
# CONFIG_MPENTIUMM is not set
# CONFIG_MCORE2 is not set
# CONFIG_MPENTIUM4 is not set
# CONFIG_MK6 is not set
# CONFIG_MK7 is not set
# CONFIG_MK8 is not set
# CONFIG_MCRUSOE is not set
# CONFIG_MEFFICEON is not set
# CONFIG_MWINCHIPC6 is not set
# CONFIG_MWINCHIP2 is not set
# CONFIG_MWINCHIP3D is not set
CONFIG_MGEODEGX1=y
# CONFIG_MGEODE_LX is not set
# CONFIG_MCYRIXIII is not set
# CONFIG_MVIAC3_2 is not set
# CONFIG_MVIAC7 is not set
CONFIG_X86_GENERIC=y
CONFIG_X86_CMPXCHG=y
CONFIG_X86_L1_CACHE_SHIFT=7
CONFIG_X86_XADD=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_X86_PPRO_FENCE=y
CONFIG_X86_WP_WORKS_OK=y
CONFIG_X86_INVLPG=y
CONFIG_X86_BSWAP=y
CONFIG_X86_POPAD_OK=y
CONFIG_X86_ALIGNMENT_16=y
CONFIG_X86_INTEL_USERCOPY=y
CONFIG_X86_TSC=y
CONFIG_X86_MINIMUM_CPU_FAMILY=4
# CONFIG_HPET_TIMER is not set
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
CONFIG_PREEMPT_NOTIFIERS=y
CONFIG_X86_UP_APIC=y
CONFIG_X86_UP_IOAPIC=y
CONFIG_X86_LOCAL_APIC=y
CONFIG_X86_IO_APIC=y
# CONFIG_X86_MCE is not set
# CONFIG_VM86 is not set
# CONFIG_TOSHIBA is not set
CONFIG_I8K=y
# CONFIG_X86_REBOOTFIXUPS is not set
CONFIG_MICROCODE=y
CONFIG_MICROCODE_OLD_INTERFACE=y
# CONFIG_X86_MSR is not set
# CONFIG_X86_CPUID is not set

#
# Firmware Drivers
#
# CONFIG_EDD is not set
# CONFIG_DELL_RBU is not set
# CONFIG_DCDBAS is not set
# CONFIG_DMIID is not set
CONFIG_NOHIGHMEM=y
# CONFIG_HIGHMEM4G is not set
# CONFIG_HIGHMEM64G is not set
# CONFIG_VMSPLIT_3G is not set
# CONFIG_VMSPLIT_3G_OPT is not set
# CONFIG_VMSPLIT_2G is not set
CONFIG_VMSPLIT_2G_OPT=y
# CONFIG_VMSPLIT_1G is not set
CONFIG_PAGE_OFFSET=0x78000000
# CONFIG_X86_PAE is not set
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_SPARSEMEM_STATIC=y
# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_RESOURCES_64BIT=y
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
CONFIG_NR_QUICK=1
CONFIG_VIRT_TO_BUS=y
CONFIG_MATH_EMULATION=y
# CONFIG_MTRR is not set
CONFIG_SECCOMP=y
# CONFIG_HZ_100 is not set
# CONFIG_HZ_250 is not set
CONFIG_HZ_300=y
# CONFIG_HZ_1000 is not set
CONFIG_HZ=300
# CONFIG_KEXEC is not set
CONFIG_PHYSICAL_START=0x100000
# CONFIG_RELOCATABLE is not set
CONFIG_PHYSICAL_ALIGN=0x100000
# CONFIG_COMPAT_VDSO is not set
# CONFIG_BOOTPARAM_NMI_WATCHDOG_BIT_0 is not set
# CONFIG_BOOTPARAM_NMI_WATCHDOG_BIT_1 is not set
# CONFIG_BOOTPARAM_NOAPIC is not set
# CONFIG_BOOTPARAM_NOLAPIC is not set
CONFIG_BOOTPARAM_LAPIC=y
CONFIG_BOOTPARAM_HPET_DISABLE=y
# CONFIG_BOOTPARAM_IDLE_MWAIT is not set
CONFIG_BOOTPARAM_IDLE_POLL=y
CONFIG_BOOTPARAM_HIGHMEM_512M=y

#
# Power management options (ACPI, APM)
#
# CONFIG_PM is not set
CONFIG_SUSPEND_UP_POSSIBLE=y
CONFIG_HIBERNATION_UP_POSSIBLE=y

#
# CPU Frequency scaling
#
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_TABLE=y
CONFIG_CPU_FREQ_DEBUG=y
CONFIG_CPU_FREQ_STAT=y
# CONFIG_CPU_FREQ_STAT_DETAILS is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y

#
# CPUFreq processor drivers
#
# CONFIG_X86_POWERNOW_K6 is not set
# CONFIG_X86_POWERNOW_K7 is not set
# CONFIG_X86_POWERNOW_K8 is not set
# CONFIG_X86_GX_SUSPMOD is not set
CONFIG_X86_SPEEDSTEP_CENTRINO=y
CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y
# CONFIG_X86_SPEEDSTEP_ICH is not set
# CONFIG_X86_SPEEDSTEP_SMI is not set
# CONFIG_X86_P4_CLOCKMOD is not set
# CONFIG_X86_CPUFREQ_NFORCE2 is not set
CONFIG_X86_LONGRUN=y
# CONFIG_X86_E_POWERSAVER is not set

#
# shared options
#
# CONFIG_X86_SPEEDSTEP_LIB is not set

#
# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
#
CONFIG_PCI=y
CONFIG_PCI_GOBIOS=y
# CONFIG_PCI_GOMMCONFIG is not set
# CONFIG_PCI_GODIRECT is not set
# CONFIG_PCI_GOANY is not set
CONFIG_PCI_BIOS=y
CONFIG_PCI_DOMAINS=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_HT_IRQ is not set
CONFIG_ISA_DMA_API=y
# CONFIG_ISA is not set
CONFIG_MCA=y
# CONFIG_MCA_LEGACY is not set
# CONFIG_SCx200 is not set
CONFIG_K8_NB=y

#
# Executable file formats
#
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_AOUT is not set
CONFIG_BINFMT_MISC=y

#
# Networking
#
CONFIG_NET=y

#
# Networking options
#
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
CONFIG_XFRM_SUB_POLICY=y
CONFIG_XFRM_MIGRATE=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_FIB_HASH=y
CONFIG_IP_PNP=y
# CONFIG_IP_PNP_DHCP is not set
CONFIG_IP_PNP_BOOTP=y
# CONFIG_IP_PNP_RARP is not set
CONFIG_NET_IPIP=y
CONFIG_NET_IPGRE=y
CONFIG_NET_IPGRE_BROADCAST=y
# CONFIG_IP_MROUTE is not set
# CONFIG_ARPD is not set
# CONFIG_SYN_COOKIES is not set
CONFIG_INET_AH=y
# CONFIG_INET_ESP is not set
CONFIG_INET_IPCOMP=y
CONFIG_INET_XFRM_TUNNEL=y
CONFIG_INET_TUNNEL=y
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_XFRM_MODE_BEET=y
CONFIG_INET_LRO=y
# CONFIG_INET_DIAG is not set
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
CONFIG_TCP_MD5SIG=y
CONFIG_IPV6=y
CONFIG_IPV6_PRIVACY=y
# CONFIG_IPV6_ROUTER_PREF is not set
CONFIG_IPV6_OPTIMISTIC_DAD=y
# CONFIG_INET6_AH is not set
# CONFIG_INET6_ESP is not set
# CONFIG_INET6_IPCOMP is not set
# CONFIG_IPV6_MIP6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
CONFIG_INET6_XFRM_MODE_TUNNEL=y
CONFIG_INET6_XFRM_MODE_BEET=y
# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
CONFIG_IPV6_SIT=y
# CONFIG_IPV6_TUNNEL is not set
# CONFIG_IPV6_MULTIPLE_TABLES is not set
CONFIG_NETLABEL=y
CONFIG_NETWORK_SECMARK=y
# CONFIG_NETFILTER is not set
CONFIG_IP_DCCP=y

#
# DCCP CCIDs Configuration (EXPERIMENTAL)
#
# CONFIG_IP_DCCP_CCID2 is not set
# CONFIG_IP_DCCP_CCID3 is not set

#
# DCCP Kernel Hacking
#
# CONFIG_IP_DCCP_DEBUG is not set
# CONFIG_IP_SCTP is not set
CONFIG_TIPC=y
# CONFIG_TIPC_ADVANCED is not set
CONFIG_TIPC_DEBUG=y
# CONFIG_ATM is not set
CONFIG_BRIDGE=y
CONFIG_VLAN_8021Q=y
CONFIG_DECNET=y
# CONFIG_DECNET_ROUTER is not set
CONFIG_LLC=y
CONFIG_LLC2=y
CONFIG_IPX=y
CONFIG_IPX_INTERN=y
CONFIG_ATALK=y
CONFIG_DEV_APPLETALK=y
CONFIG_IPDDP=y
# CONFIG_IPDDP_ENCAP is not set
# CONFIG_IPDDP_DECAP is not set
CONFIG_X25=y
# CONFIG_LAPB is not set
CONFIG_ECONET=y
# CONFIG_ECONET_AUNUDP is not set
CONFIG_ECONET_NATIVE=y
CONFIG_WAN_ROUTER=y

#
# QoS and/or fair queueing
#
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_FIFO=y

#
# Queueing/Scheduling
#
# CONFIG_NET_SCH_CBQ is not set
# CONFIG_NET_SCH_HTB is not set
CONFIG_NET_SCH_HFSC=y
CONFIG_NET_SCH_PRIO=y
CONFIG_NET_SCH_RR=y
# CONFIG_NET_SCH_RED is not set
CONFIG_NET_SCH_SFQ=y
# CONFIG_NET_SCH_TEQL is not set
# CONFIG_NET_SCH_TBF is not set
CONFIG_NET_SCH_GRED=y
# CONFIG_NET_SCH_DSMARK is not set
CONFIG_NET_SCH_NETEM=y
# CONFIG_NET_SCH_INGRESS is not set

#
# Classification
#
CONFIG_NET_CLS=y
# CONFIG_NET_CLS_BASIC is not set
# CONFIG_NET_CLS_TCINDEX is not set
CONFIG_NET_CLS_ROUTE4=y
CONFIG_NET_CLS_ROUTE=y
# CONFIG_NET_CLS_FW is not set
CONFIG_NET_CLS_U32=y
# CONFIG_CLS_U32_PERF is not set
# CONFIG_CLS_U32_MARK is not set
CONFIG_NET_CLS_RSVP=y
CONFIG_NET_CLS_RSVP6=y
# CONFIG_NET_EMATCH is not set
CONFIG_NET_CLS_ACT=y
# CONFIG_NET_ACT_POLICE is not set
CONFIG_NET_ACT_GACT=y
CONFIG_GACT_PROB=y
# CONFIG_NET_ACT_MIRRED is not set
# CONFIG_NET_ACT_NAT is not set
# CONFIG_NET_ACT_PEDIT is not set
CONFIG_NET_ACT_SIMP=y
# CONFIG_NET_CLS_POLICE is not set
# CONFIG_NET_CLS_IND is not set

#
# Network testing
#
CONFIG_NET_PKTGEN=y
CONFIG_HAMRADIO=y

#
# Packet Radio protocols
#
# CONFIG_AX25 is not set
CONFIG_IRDA=y

#
# IrDA protocols
#
CONFIG_IRLAN=y
CONFIG_IRCOMM=y
CONFIG_IRDA_ULTRA=y

#
# IrDA options
#
# CONFIG_IRDA_CACHE_LAST_LSAP is not set
CONFIG_IRDA_FAST_RR=y
# CONFIG_IRDA_DEBUG is not set

#
# Infrared-port device drivers
#

#
# SIR device drivers
#
CONFIG_IRTTY_SIR=y

#
# Dongle support
#
# CONFIG_DONGLE is not set
# CONFIG_KINGSUN_DONGLE is not set
CONFIG_KSDAZZLE_DONGLE=y
# CONFIG_KS959_DONGLE is not set

#
# Old SIR device drivers
#
# CONFIG_IRPORT_SIR is not set

#
# Old Serial dongle support
#

#
# FIR device drivers
#
CONFIG_USB_IRDA=y
# CONFIG_SIGMATEL_FIR is not set
# CONFIG_NSC_FIR is not set
CONFIG_WINBOND_FIR=y
CONFIG_TOSHIBA_FIR=y
CONFIG_SMC_IRCC_FIR=y
CONFIG_ALI_FIR=y
CONFIG_VLSI_FIR=y
CONFIG_VIA_FIR=y
# CONFIG_MCS_FIR is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set

#
# Wireless
#
CONFIG_CFG80211=y
# CONFIG_NL80211 is not set
CONFIG_WIRELESS_EXT=y
CONFIG_MAC80211=y
CONFIG_MAC80211_DEBUGFS=y
CONFIG_MAC80211_DEBUG=y
# CONFIG_MAC80211_VERBOSE_DEBUG is not set
CONFIG_MAC80211_LOWTX_FRAME_DUMP=y
# CONFIG_TKIP_DEBUG is not set
CONFIG_MAC80211_DEBUG_COUNTERS=y
# CONFIG_MAC80211_IBSS_DEBUG is not set
CONFIG_MAC80211_VERBOSE_PS_DEBUG=y
CONFIG_IEEE80211=y
CONFIG_IEEE80211_DEBUG=y
# CONFIG_IEEE80211_CRYPT_WEP is not set
# CONFIG_IEEE80211_CRYPT_CCMP is not set
# CONFIG_IEEE80211_CRYPT_TKIP is not set
# CONFIG_IEEE80211_SOFTMAC is not set
# CONFIG_RFKILL is not set
CONFIG_NET_9P=y
# CONFIG_NET_9P_DEBUG is not set

#
# Device Drivers
#

#
# Generic Driver Options
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
# CONFIG_DEBUG_DRIVER is not set
CONFIG_DEBUG_DEVRES=y
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
# CONFIG_PARPORT is not set
# CONFIG_BLK_DEV is not set
# CONFIG_MISC_DEVICES is not set

#
# SCSI device support
#
CONFIG_RAID_ATTRS=y
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
# CONFIG_SCSI_TGT is not set
CONFIG_SCSI_NETLINK=y
CONFIG_SCSI_PROC_FS=y

#
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=y
# CONFIG_CHR_DEV_ST is not set
# CONFIG_CHR_DEV_OSST is not set
# CONFIG_BLK_DEV_SR is not set
# CONFIG_CHR_DEV_SG is not set
CONFIG_CHR_DEV_SCH=y

#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
CONFIG_SCSI_MULTI_LUN=y
# CONFIG_SCSI_CONSTANTS is not set
CONFIG_SCSI_LOGGING=y
# CONFIG_SCSI_SCAN_ASYNC is not set

#
# SCSI Transports
#
CONFIG_SCSI_SPI_ATTRS=y
CONFIG_SCSI_FC_ATTRS=y
CONFIG_SCSI_ISCSI_ATTRS=y
CONFIG_SCSI_SAS_ATTRS=y
CONFIG_SCSI_SAS_LIBSAS=y
CONFIG_SCSI_SAS_ATA=y
# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
# CONFIG_SCSI_SRP_ATTRS is not set
# CONFIG_SCSI_LOWLEVEL is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_AHCI=y
# CONFIG_SATA_SVW is not set
CONFIG_ATA_PIIX=y
CONFIG_SATA_MV=y
CONFIG_SATA_NV=y
# CONFIG_PDC_ADMA is not set
CONFIG_SATA_QSTOR=y
CONFIG_SATA_PROMISE=y
# CONFIG_SATA_SX4 is not set
# CONFIG_SATA_SIL is not set
# CONFIG_SATA_SIL24 is not set
# CONFIG_SATA_SIS is not set
# CONFIG_SATA_ULI is not set
# CONFIG_SATA_VIA is not set
CONFIG_SATA_VITESSE=y
CONFIG_SATA_INIC162X=y
# CONFIG_PATA_ALI is not set
CONFIG_PATA_AMD=y
CONFIG_PATA_ARTOP=y
CONFIG_PATA_ATIIXP=y
CONFIG_PATA_CMD640_PCI=y
CONFIG_PATA_CMD64X=y
# CONFIG_PATA_CS5520 is not set
# CONFIG_PATA_CS5530 is not set
CONFIG_PATA_CS5535=y
# CONFIG_PATA_CS5536 is not set
CONFIG_PATA_CYPRESS=y
# CONFIG_PATA_EFAR is not set
CONFIG_ATA_GENERIC=y
# CONFIG_PATA_HPT366 is not set
CONFIG_PATA_HPT37X=y
CONFIG_PATA_HPT3X2N=y
CONFIG_PATA_HPT3X3=y
CONFIG_PATA_HPT3X3_DMA=y
# CONFIG_PATA_IT821X is not set
CONFIG_PATA_IT8213=y
# CONFIG_PATA_JMICRON is not set
CONFIG_PATA_TRIFLEX=y
CONFIG_PATA_MARVELL=y
CONFIG_PATA_MPIIX=y
CONFIG_PATA_OLDPIIX=y
CONFIG_PATA_NETCELL=y
CONFIG_PATA_NS87410=y
CONFIG_PATA_NS87415=y
CONFIG_PATA_OPTI=y
# CONFIG_PATA_OPTIDMA is not set
CONFIG_PATA_PDC_OLD=y
# CONFIG_PATA_RADISYS is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
CONFIG_PATA_SERVERWORKS=y
# CONFIG_PATA_PDC2027X is not set
CONFIG_PATA_SIL680=y
# CONFIG_PATA_SIS is not set
CONFIG_PATA_VIA=y
# CONFIG_PATA_WINBOND is not set
CONFIG_PATA_PLATFORM=y
CONFIG_MD=y
# CONFIG_BLK_DEV_MD is not set
CONFIG_BLK_DEV_DM=y
# CONFIG_DM_DEBUG is not set
CONFIG_DM_CRYPT=y
CONFIG_DM_SNAPSHOT=y
CONFIG_DM_MIRROR=y
# CONFIG_DM_ZERO is not set
# CONFIG_DM_MULTIPATH is not set
CONFIG_DM_DELAY=y
CONFIG_FUSION=y
CONFIG_FUSION_SPI=y
CONFIG_FUSION_FC=y
CONFIG_FUSION_SAS=y
CONFIG_FUSION_MAX_SGE=128
CONFIG_FUSION_CTL=y
# CONFIG_FUSION_LOGGING is not set

#
# IEEE 1394 (FireWire) support
#
# CONFIG_FIREWIRE is not set
CONFIG_IEEE1394=y

#
# Subsystem Options
#
# CONFIG_IEEE1394_VERBOSEDEBUG is not set

#
# Controllers
#
# CONFIG_IEEE1394_PCILYNX is not set
CONFIG_IEEE1394_OHCI1394=y

#
# Protocols
#
CONFIG_IEEE1394_VIDEO1394=y
CONFIG_IEEE1394_SBP2=y
# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y
CONFIG_IEEE1394_ETH1394=y
CONFIG_IEEE1394_DV1394=y
# CONFIG_IEEE1394_RAWIO is not set
CONFIG_I2O=y
# CONFIG_I2O_LCT_NOTIFY_ON_CHANGES is not set
# CONFIG_I2O_EXT_ADAPTEC is not set
CONFIG_I2O_CONFIG=y
CONFIG_I2O_CONFIG_OLD_IOCTL=y
CONFIG_I2O_BUS=y
CONFIG_I2O_BLOCK=y
# CONFIG_I2O_SCSI is not set
CONFIG_I2O_PROC=y
# CONFIG_MACINTOSH_DRIVERS is not set
# CONFIG_NETDEVICES is not set
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
CONFIG_NET_PCI=y
CONFIG_FORCEDETH=y
CONFIG_E100=y
CONFIG_8139TOO=y
CONFIG_E1000=y
CONFIG_NETCONSOLE=y
CONFIG_NETPOLL=y
CONFIG_NET_POLL_CONTROLLER=y
CONFIG_ISDN=y
# CONFIG_ISDN_I4L is not set
CONFIG_ISDN_CAPI=y
# CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON is not set
# CONFIG_CAPI_TRACE is not set
# CONFIG_ISDN_CAPI_MIDDLEWARE is not set
# CONFIG_ISDN_CAPI_CAPI20 is not set

#
# CAPI hardware drivers
#
CONFIG_CAPI_AVM=y
CONFIG_ISDN_DRV_AVMB1_B1PCI=y
CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=y
CONFIG_ISDN_DRV_AVMB1_T1PCI=y
CONFIG_ISDN_DRV_AVMB1_C4=y
CONFIG_CAPI_EICON=y
# CONFIG_ISDN_DIVAS is not set
CONFIG_PHONE=y
# CONFIG_PHONE_IXJ is not set

#
# Input device support
#
CONFIG_INPUT=y
# CONFIG_INPUT_FF_MEMLESS is not set
CONFIG_INPUT_POLLDEV=y

#
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_EVBUG=y

#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYBOARD_ATKBD=y
CONFIG_KEYBOARD_SUNKBD=y
# CONFIG_KEYBOARD_LKKBD is not set
CONFIG_KEYBOARD_XTKBD=y
# CONFIG_KEYBOARD_NEWTON is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_JOYSTICK=y
CONFIG_JOYSTICK_ANALOG=y
CONFIG_JOYSTICK_A3D=y
CONFIG_JOYSTICK_ADI=y
CONFIG_JOYSTICK_COBRA=y
# CONFIG_JOYSTICK_GF2K is not set
CONFIG_JOYSTICK_GRIP=y
CONFIG_JOYSTICK_GRIP_MP=y
CONFIG_JOYSTICK_GUILLEMOT=y
CONFIG_JOYSTICK_INTERACT=y
CONFIG_JOYSTICK_SIDEWINDER=y
CONFIG_JOYSTICK_TMDC=y
CONFIG_JOYSTICK_IFORCE=y
# CONFIG_JOYSTICK_IFORCE_USB is not set
CONFIG_JOYSTICK_IFORCE_232=y
# CONFIG_JOYSTICK_WARRIOR is not set
CONFIG_JOYSTICK_MAGELLAN=y
# CONFIG_JOYSTICK_SPACEORB is not set
# CONFIG_JOYSTICK_SPACEBALL is not set
CONFIG_JOYSTICK_STINGER=y
# CONFIG_JOYSTICK_TWIDJOY is not set
CONFIG_JOYSTICK_JOYDUMP=y
CONFIG_JOYSTICK_XPAD=y
# CONFIG_JOYSTICK_XPAD_FF is not set
CONFIG_JOYSTICK_XPAD_LEDS=y
# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set

#
# Hardware I/O ports
#
CONFIG_SERIO=y
CONFIG_SERIO_I8042=y
# CONFIG_SERIO_SERPORT is not set
# CONFIG_SERIO_CT82C710 is not set
CONFIG_SERIO_PCIPS2=y
CONFIG_SERIO_LIBPS2=y
CONFIG_SERIO_RAW=y
CONFIG_GAMEPORT=y
CONFIG_GAMEPORT_NS558=y
CONFIG_GAMEPORT_L4=y
# CONFIG_GAMEPORT_EMU10K1 is not set
CONFIG_GAMEPORT_FM801=y

#
# Character devices
#
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
CONFIG_VT_HW_CONSOLE_BINDING=y
# CONFIG_SERIAL_NONSTANDARD is not set

#
# Serial drivers
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_FIX_EARLYCON_MEM=y
# CONFIG_SERIAL_8250_PCI is not set
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
# CONFIG_SERIAL_8250_EXTENDED is not set
CONFIG_SERIAL_8250_MCA=y

#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_JSM=y
CONFIG_UNIX98_PTYS=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_IPMI_HANDLER is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set

#
# Watchdog Device Drivers
#
CONFIG_SOFT_WATCHDOG=y
CONFIG_ACQUIRE_WDT=y
CONFIG_ADVANTECH_WDT=y
CONFIG_ALIM1535_WDT=y
CONFIG_ALIM7101_WDT=y
CONFIG_SC520_WDT=y
# CONFIG_IB700_WDT is not set
# CONFIG_IBMASR is not set
# CONFIG_WAFER_WDT is not set
CONFIG_I6300ESB_WDT=y
CONFIG_ITCO_WDT=y
CONFIG_ITCO_VENDOR_SUPPORT=y
# CONFIG_SC1200_WDT is not set
# CONFIG_PC87413_WDT is not set
# CONFIG_60XX_WDT is not set
# CONFIG_SBC8360_WDT is not set
CONFIG_CPU5_WDT=y
CONFIG_SMSC37B787_WDT=y
# CONFIG_W83627HF_WDT is not set
# CONFIG_W83697HF_WDT is not set
# CONFIG_W83877F_WDT is not set
CONFIG_W83977F_WDT=y
CONFIG_MACHZ_WDT=y
CONFIG_SBC_EPX_C3_WATCHDOG=y

#
# PCI-based Watchdog Cards
#
# CONFIG_PCIPCWATCHDOG is not set
CONFIG_WDTPCI=y
CONFIG_WDT_501_PCI=y

#
# USB-based Watchdog Cards
#
# CONFIG_USBPCWATCHDOG is not set
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_INTEL=y
CONFIG_HW_RANDOM_AMD=y
# CONFIG_HW_RANDOM_GEODE is not set
# CONFIG_HW_RANDOM_VIA is not set
CONFIG_NVRAM=y
CONFIG_RTC=y
# CONFIG_R3964 is not set
CONFIG_APPLICOM=y
# CONFIG_SONYPI is not set
CONFIG_MWAVE=y
# CONFIG_PC8736x_GPIO is not set
# CONFIG_NSC_GPIO is not set
CONFIG_CS5535_GPIO=y
CONFIG_RAW_DRIVER=y
CONFIG_MAX_RAW_DEVS=256
CONFIG_HANGCHECK_TIMER=y
# CONFIG_TCG_TPM is not set
# CONFIG_TELCLOCK is not set
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=y

#
# I2C Algorithms
#
CONFIG_I2C_ALGOBIT=y
# CONFIG_I2C_ALGOPCF is not set
CONFIG_I2C_ALGOPCA=y

#
# I2C Hardware Bus support
#
# CONFIG_I2C_ALI1535 is not set
CONFIG_I2C_ALI1563=y
# CONFIG_I2C_ALI15X3 is not set
# CONFIG_I2C_AMD756 is not set
CONFIG_I2C_AMD8111=y
# CONFIG_I2C_I801 is not set
CONFIG_I2C_I810=y
CONFIG_I2C_PIIX4=y
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_OCORES is not set
CONFIG_I2C_PARPORT_LIGHT=y
CONFIG_I2C_PROSAVAGE=y
CONFIG_I2C_SAVAGE4=y
# CONFIG_I2C_SIMTEC is not set
CONFIG_SCx200_ACB=y
CONFIG_I2C_SIS5595=y
CONFIG_I2C_SIS630=y
# CONFIG_I2C_SIS96X is not set
# CONFIG_I2C_TAOS_EVM is not set
CONFIG_I2C_TINY_USB=y
# CONFIG_I2C_VIA is not set
CONFIG_I2C_VIAPRO=y
CONFIG_I2C_VOODOO3=y

#
# Miscellaneous I2C Chip support
#
# CONFIG_SENSORS_DS1337 is not set
# CONFIG_SENSORS_DS1374 is not set
CONFIG_DS1682=y
# CONFIG_SENSORS_EEPROM is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_SENSORS_PCA9539 is not set
CONFIG_SENSORS_PCF8591=y
# CONFIG_SENSORS_MAX6875 is not set
CONFIG_SENSORS_TSL2550=y
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
CONFIG_I2C_DEBUG_BUS=y
# CONFIG_I2C_DEBUG_CHIP is not set

#
# SPI support
#
CONFIG_SPI=y
# CONFIG_SPI_DEBUG is not set
CONFIG_SPI_MASTER=y

#
# SPI Master Controller Drivers
#
# CONFIG_SPI_BITBANG is not set

#
# SPI Protocol Masters
#
CONFIG_SPI_AT25=y
# CONFIG_SPI_SPIDEV is not set
CONFIG_SPI_TLE62X0=y
CONFIG_W1=y

#
# 1-wire Bus Masters
#
CONFIG_W1_MASTER_MATROX=y
CONFIG_W1_MASTER_DS2490=y
# CONFIG_W1_MASTER_DS2482 is not set

#
# 1-wire Slaves
#
# CONFIG_W1_SLAVE_THERM is not set
# CONFIG_W1_SLAVE_SMEM is not set
# CONFIG_W1_SLAVE_DS2433 is not set
CONFIG_W1_SLAVE_DS2760=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
CONFIG_HWMON_VID=y
# CONFIG_SENSORS_ABITUGURU is not set
# CONFIG_SENSORS_ABITUGURU3 is not set
CONFIG_SENSORS_AD7418=y
CONFIG_SENSORS_ADM1021=y
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
# CONFIG_SENSORS_ADM1029 is not set
CONFIG_SENSORS_ADM1031=y
# CONFIG_SENSORS_ADM9240 is not set
# CONFIG_SENSORS_ADT7470 is not set
# CONFIG_SENSORS_K8TEMP is not set
CONFIG_SENSORS_ASB100=y
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
CONFIG_SENSORS_F71805F=y
# CONFIG_SENSORS_F71882FG is not set
CONFIG_SENSORS_F75375S=y
CONFIG_SENSORS_FSCHER=y
# CONFIG_SENSORS_FSCPOS is not set
# CONFIG_SENSORS_FSCHMD is not set
CONFIG_SENSORS_GL518SM=y
CONFIG_SENSORS_GL520SM=y
# CONFIG_SENSORS_CORETEMP is not set
# CONFIG_SENSORS_IT87 is not set
# CONFIG_SENSORS_LM63 is not set
CONFIG_SENSORS_LM70=y
# CONFIG_SENSORS_LM75 is not set
CONFIG_SENSORS_LM77=y
# CONFIG_SENSORS_LM78 is not set
CONFIG_SENSORS_LM80=y
# CONFIG_SENSORS_LM83 is not set
CONFIG_SENSORS_LM85=y
CONFIG_SENSORS_LM87=y
# CONFIG_SENSORS_LM90 is not set
# CONFIG_SENSORS_LM92 is not set
CONFIG_SENSORS_LM93=y
CONFIG_SENSORS_MAX1619=y
CONFIG_SENSORS_MAX6650=y
CONFIG_SENSORS_PC87360=y
CONFIG_SENSORS_PC87427=y
CONFIG_SENSORS_SIS5595=y
# CONFIG_SENSORS_DME1737 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_VIA686A is not set
CONFIG_SENSORS_VT1211=y
CONFIG_SENSORS_VT8231=y
CONFIG_SENSORS_W83781D=y
# CONFIG_SENSORS_W83791D is not set
CONFIG_SENSORS_W83792D=y
# CONFIG_SENSORS_W83793 is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83627HF is not set
CONFIG_SENSORS_W83627EHF=y
CONFIG_SENSORS_HDAPS=y
CONFIG_SENSORS_APPLESMC=y
CONFIG_HWMON_DEBUG_CHIP=y

#
# Sonics Silicon Backplane
#
CONFIG_SSB_POSSIBLE=y
CONFIG_SSB=y
CONFIG_SSB_PCIHOST_POSSIBLE=y
CONFIG_SSB_PCIHOST=y
# CONFIG_SSB_SILENT is not set
# CONFIG_SSB_DEBUG is not set
CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
# CONFIG_SSB_DRIVER_PCICORE is not set

#
# Multifunction device drivers
#
# CONFIG_MFD_SM501 is not set

#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
CONFIG_DVB_CORE=y
CONFIG_DVB_CAPTURE_DRIVERS=y

#
# Supported SAA7146 based PCI Adapters
#

#
# Supported USB Adapters
#
# CONFIG_DVB_USB is not set
# CONFIG_DVB_TTUSB_BUDGET is not set
# CONFIG_DVB_TTUSB_DEC is not set
# CONFIG_DVB_CINERGYT2 is not set

#
# Supported FlexCopII (B2C2) Adapters
#
# CONFIG_DVB_B2C2_FLEXCOP is not set

#
# Supported BT878 Adapters
#

#
# Supported Pluto2 Adapters
#
# CONFIG_DVB_PLUTO2 is not set

#
# Supported DVB Frontends
#

#
# Customise DVB Frontends
#
CONFIG_DVB_FE_CUSTOMISE=y

#
# DVB-S (satellite) frontends
#
# CONFIG_DVB_STV0299 is not set
CONFIG_DVB_CX24110=y
CONFIG_DVB_CX24123=y
# CONFIG_DVB_TDA8083 is not set
CONFIG_DVB_MT312=y
# CONFIG_DVB_VES1X93 is not set
CONFIG_DVB_S5H1420=y
# CONFIG_DVB_TDA10086 is not set

#
# DVB-T (terrestrial) frontends
#
# CONFIG_DVB_SP8870 is not set
# CONFIG_DVB_SP887X is not set
# CONFIG_DVB_CX22700 is not set
CONFIG_DVB_CX22702=y
# CONFIG_DVB_L64781 is not set
# CONFIG_DVB_TDA1004X is not set
# CONFIG_DVB_NXT6000 is not set
CONFIG_DVB_MT352=y
# CONFIG_DVB_ZL10353 is not set
# CONFIG_DVB_DIB3000MB is not set
CONFIG_DVB_DIB3000MC=y
# CONFIG_DVB_DIB7000M is not set
# CONFIG_DVB_DIB7000P is not set

#
# DVB-C (cable) frontends
#
CONFIG_DVB_VES1820=y
# CONFIG_DVB_TDA10021 is not set
# CONFIG_DVB_TDA10023 is not set
CONFIG_DVB_STV0297=y

#
# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
#
CONFIG_DVB_NXT200X=y
CONFIG_DVB_OR51211=y
# CONFIG_DVB_OR51132 is not set
CONFIG_DVB_BCM3510=y
# CONFIG_DVB_LGDT330X is not set
CONFIG_DVB_S5H1409=y

#
# Tuners/PLL support
#
# CONFIG_DVB_PLL is not set
CONFIG_DVB_TDA826X=y
# CONFIG_DVB_TDA827X is not set
# CONFIG_DVB_TUNER_QT1010 is not set
CONFIG_DVB_TUNER_MT2060=y
# CONFIG_DVB_TUNER_MT2266 is not set
# CONFIG_DVB_TUNER_MT2131 is not set
# CONFIG_DVB_TUNER_DIB0070 is not set

#
# Miscellaneous devices
#
# CONFIG_DVB_LNBP21 is not set
CONFIG_DVB_ISL6421=y
CONFIG_DVB_TUA6100=y
# CONFIG_DAB is not set

#
# Graphics support
#
CONFIG_AGP=y
CONFIG_AGP_ALI=y
CONFIG_AGP_ATI=y
# CONFIG_AGP_AMD is not set
CONFIG_AGP_AMD64=y
# CONFIG_AGP_INTEL is not set
CONFIG_AGP_NVIDIA=y
CONFIG_AGP_SIS=y
# CONFIG_AGP_SWORKS is not set
# CONFIG_AGP_VIA is not set
# CONFIG_AGP_EFFICEON is not set
CONFIG_DRM=y
CONFIG_DRM_TDFX=y
# CONFIG_DRM_R128 is not set
CONFIG_DRM_RADEON=y
CONFIG_DRM_MGA=y
CONFIG_DRM_SIS=y
CONFIG_DRM_VIA=y
# CONFIG_DRM_SAVAGE is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
# CONFIG_FB is not set
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_LCD_CLASS_DEVICE=y
# CONFIG_LCD_LTV350QV is not set
CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_BACKLIGHT_CORGI=y
CONFIG_BACKLIGHT_PROGEAR=y

#
# Display device support
#
# CONFIG_DISPLAY_SUPPORT is not set

#
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
CONFIG_VGACON_SOFT_SCROLLBACK=y
CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
# CONFIG_VIDEO_SELECT is not set
CONFIG_DUMMY_CONSOLE=y

#
# Sound
#
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
CONFIG_HID_DEBUG=y
# CONFIG_HIDRAW is not set

#
# USB Input Devices
#
CONFIG_USB_HID=y
CONFIG_USB_HIDINPUT_POWERBOOK=y
# CONFIG_HID_FF is not set
# CONFIG_USB_HIDDEV is not set
CONFIG_USB_MOUSE=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB_ARCH_HAS_EHCI=y
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set

#
# Miscellaneous USB options
#
# CONFIG_USB_DEVICEFS is not set
# CONFIG_USB_DEVICE_CLASS is not set
CONFIG_USB_DYNAMIC_MINORS=y
# CONFIG_USB_OTG is not set

#
# USB Host Controller Drivers
#
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_SPLIT_ISO=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_EHCI_TT_NEWSCHED=y
CONFIG_USB_ISP116X_HCD=y
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_SSB=y
# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB_UHCI_HCD=y
# CONFIG_USB_SL811_HCD is not set
CONFIG_USB_R8A66597_HCD=y

#
# USB Device Class drivers
#
# CONFIG_USB_ACM is not set
CONFIG_USB_PRINTER=y

#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
#

#
# may also be needed; see USB_STORAGE Help for more information
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
CONFIG_USB_STORAGE_FREECOM=y
CONFIG_USB_STORAGE_DPCM=y
CONFIG_USB_STORAGE_USBAT=y
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
# CONFIG_USB_STORAGE_JUMPSHOT is not set
CONFIG_USB_STORAGE_ALAUDA=y
CONFIG_USB_STORAGE_ONETOUCH=y
CONFIG_USB_STORAGE_KARMA=y
CONFIG_USB_LIBUSUAL=y

#
# USB Imaging devices
#
CONFIG_USB_MDC800=y
CONFIG_USB_MICROTEK=y
CONFIG_USB_MON=y

#
# USB port drivers
#

#
# USB Serial Converter support
#
CONFIG_USB_SERIAL=y
CONFIG_USB_SERIAL_CONSOLE=y
CONFIG_USB_SERIAL_GENERIC=y
CONFIG_USB_SERIAL_AIRCABLE=y
CONFIG_USB_SERIAL_AIRPRIME=y
CONFIG_USB_SERIAL_ARK3116=y
# CONFIG_USB_SERIAL_BELKIN is not set
# CONFIG_USB_SERIAL_CH341 is not set
CONFIG_USB_SERIAL_WHITEHEAT=y
# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
# CONFIG_USB_SERIAL_CP2101 is not set
CONFIG_USB_SERIAL_CYPRESS_M8=y
CONFIG_USB_SERIAL_EMPEG=y
CONFIG_USB_SERIAL_FTDI_SIO=y
CONFIG_USB_SERIAL_FUNSOFT=y
# CONFIG_USB_SERIAL_VISOR is not set
# CONFIG_USB_SERIAL_IPAQ is not set
# CONFIG_USB_SERIAL_IR is not set
# CONFIG_USB_SERIAL_EDGEPORT is not set
# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
# CONFIG_USB_SERIAL_GARMIN is not set
CONFIG_USB_SERIAL_IPW=y
CONFIG_USB_SERIAL_KEYSPAN_PDA=y
# CONFIG_USB_SERIAL_KEYSPAN is not set
CONFIG_USB_SERIAL_KLSI=y
# CONFIG_USB_SERIAL_KOBIL_SCT is not set
# CONFIG_USB_SERIAL_MCT_U232 is not set
CONFIG_USB_SERIAL_MOS7720=y
CONFIG_USB_SERIAL_MOS7840=y
# CONFIG_USB_SERIAL_NAVMAN is not set
# CONFIG_USB_SERIAL_PL2303 is not set
# CONFIG_USB_SERIAL_OTI6858 is not set
CONFIG_USB_SERIAL_HP4X=y
# CONFIG_USB_SERIAL_SAFE is not set
CONFIG_USB_SERIAL_SIERRAWIRELESS=y
# CONFIG_USB_SERIAL_TI is not set
# CONFIG_USB_SERIAL_CYBERJACK is not set
CONFIG_USB_SERIAL_XIRCOM=y
# CONFIG_USB_SERIAL_OPTION is not set
CONFIG_USB_SERIAL_OMNINET=y
CONFIG_USB_SERIAL_DEBUG=y
CONFIG_USB_EZUSB=y

#
# USB Miscellaneous drivers
#
# CONFIG_USB_EMI62 is not set
CONFIG_USB_EMI26=y
# CONFIG_USB_ADUTUX is not set
CONFIG_USB_AUERSWALD=y
# CONFIG_USB_RIO500 is not set
CONFIG_USB_LEGOTOWER=y
# CONFIG_USB_LCD is not set
CONFIG_USB_BERRY_CHARGE=y
CONFIG_USB_LED=y
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
CONFIG_USB_PHIDGET=y
# CONFIG_USB_PHIDGETKIT is not set
# CONFIG_USB_PHIDGETMOTORCONTROL is not set
# CONFIG_USB_PHIDGETSERVO is not set
CONFIG_USB_IDMOUSE=y
# CONFIG_USB_FTDI_ELAN is not set
CONFIG_USB_APPLEDISPLAY=y
CONFIG_USB_SISUSBVGA=y
# CONFIG_USB_SISUSBVGA_CON is not set
CONFIG_USB_LD=y
CONFIG_USB_TRANCEVIBRATOR=y
# CONFIG_USB_IOWARRIOR is not set

#
# USB DSL modem support
#

#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
# CONFIG_MMC is not set
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y

#
# LED drivers
#

#
# LED Triggers
#
# CONFIG_LEDS_TRIGGERS is not set
# CONFIG_INFINIBAND is not set
CONFIG_EDAC=y

#
# Reporting subsystems
#
CONFIG_EDAC_DEBUG=y
# CONFIG_EDAC_MM_EDAC is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
CONFIG_VIRTUALIZATION=y
CONFIG_KVM=y
CONFIG_KVM_INTEL=y
CONFIG_KVM_AMD=y

#
# Userspace I/O
#
CONFIG_UIO=y
# CONFIG_UIO_CIF is not set
# CONFIG_LGUEST is not set

#
# File systems
#
# CONFIG_EXT2_FS is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_EXT3_FS_SECURITY=y
CONFIG_EXT4DEV_FS=y
# CONFIG_EXT4DEV_FS_XATTR is not set
CONFIG_JBD=y
CONFIG_JBD_DEBUG=y
CONFIG_JBD2=y
# CONFIG_JBD2_DEBUG is not set
CONFIG_FS_MBCACHE=y
CONFIG_REISERFS_FS=y
CONFIG_REISERFS_CHECK=y
CONFIG_REISERFS_PROC_INFO=y
CONFIG_REISERFS_FS_XATTR=y
CONFIG_REISERFS_FS_POSIX_ACL=y
# CONFIG_REISERFS_FS_SECURITY is not set
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_FS=y
CONFIG_XFS_QUOTA=y
# CONFIG_XFS_SECURITY is not set
# CONFIG_XFS_POSIX_ACL is not set
# CONFIG_XFS_RT is not set
# CONFIG_GFS2_FS is not set
CONFIG_OCFS2_FS=y
CONFIG_OCFS2_DEBUG_MASKLOG=y
CONFIG_MINIX_FS=y
CONFIG_ROMFS_FS=y
# CONFIG_INOTIFY is not set
CONFIG_QUOTA=y
# CONFIG_QFMT_V1 is not set
# CONFIG_QFMT_V2 is not set
CONFIG_QUOTACTL=y
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
CONFIG_AUTOFS4_FS=y
CONFIG_FUSE_FS=y

#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=y
CONFIG_JOLIET=y
CONFIG_ZISOFS=y
CONFIG_UDF_FS=y
CONFIG_UDF_NLS=y

#
# DOS/FAT/NT Filesystems
#
CONFIG_FAT_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_NTFS_FS=y
CONFIG_NTFS_DEBUG=y
CONFIG_NTFS_RW=y

#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
CONFIG_CONFIGFS_FS=y

#
# Miscellaneous filesystems
#
CONFIG_ADFS_FS=y
CONFIG_ADFS_FS_RW=y
# CONFIG_AFFS_FS is not set
CONFIG_ECRYPT_FS=y
CONFIG_HFS_FS=y
CONFIG_HFSPLUS_FS=y
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
CONFIG_CRAMFS=y
CONFIG_VXFS_FS=y
CONFIG_HPFS_FS=y
CONFIG_QNX4FS_FS=y
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set

#
# Network File Systems
#
# CONFIG_NFS_FS is not set
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
# CONFIG_NFSD_V3_ACL is not set
CONFIG_NFSD_V4=y
CONFIG_NFSD_TCP=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
# CONFIG_SUNRPC_BIND34 is not set
CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
CONFIG_CIFS=y
CONFIG_CIFS_STATS=y
CONFIG_CIFS_STATS2=y
CONFIG_CIFS_WEAK_PW_HASH=y
CONFIG_CIFS_XATTR=y
CONFIG_CIFS_POSIX=y
# CONFIG_CIFS_DEBUG2 is not set
# CONFIG_CIFS_EXPERIMENTAL is not set
CONFIG_NCP_FS=y
# CONFIG_NCPFS_PACKET_SIGNING is not set
# CONFIG_NCPFS_IOCTL_LOCKING is not set
CONFIG_NCPFS_STRONG=y
CONFIG_NCPFS_NFS_NS=y
# CONFIG_NCPFS_OS2_NS is not set
# CONFIG_NCPFS_SMALLDOS is not set
# CONFIG_NCPFS_NLS is not set
# CONFIG_NCPFS_EXTRAS is not set
CONFIG_CODA_FS=y
CONFIG_CODA_FS_OLD_API=y
# CONFIG_AFS_FS is not set
CONFIG_9P_FS=y

#
# Partition Types
#
CONFIG_PARTITION_ADVANCED=y
# CONFIG_ACORN_PARTITION is not set
# CONFIG_OSF_PARTITION is not set
CONFIG_AMIGA_PARTITION=y
# CONFIG_ATARI_PARTITION is not set
CONFIG_MAC_PARTITION=y
CONFIG_MSDOS_PARTITION=y
CONFIG_BSD_DISKLABEL=y
CONFIG_MINIX_SUBPARTITION=y
# CONFIG_SOLARIS_X86_PARTITION is not set
CONFIG_UNIXWARE_DISKLABEL=y
CONFIG_LDM_PARTITION=y
# CONFIG_LDM_DEBUG is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_KARMA_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
CONFIG_SYSV68_PARTITION=y

#
# Native Language Support
#
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=y
# CONFIG_NLS_CODEPAGE_737 is not set
CONFIG_NLS_CODEPAGE_775=y
# CONFIG_NLS_CODEPAGE_850 is not set
CONFIG_NLS_CODEPAGE_852=y
# CONFIG_NLS_CODEPAGE_855 is not set
CONFIG_NLS_CODEPAGE_857=y
CONFIG_NLS_CODEPAGE_860=y
CONFIG_NLS_CODEPAGE_861=y
# CONFIG_NLS_CODEPAGE_862 is not set
CONFIG_NLS_CODEPAGE_863=y
CONFIG_NLS_CODEPAGE_864=y
# CONFIG_NLS_CODEPAGE_865 is not set
# CONFIG_NLS_CODEPAGE_866 is not set
CONFIG_NLS_CODEPAGE_869=y
CONFIG_NLS_CODEPAGE_936=y
# CONFIG_NLS_CODEPAGE_950 is not set
CONFIG_NLS_CODEPAGE_932=y
# CONFIG_NLS_CODEPAGE_949 is not set
CONFIG_NLS_CODEPAGE_874=y
# CONFIG_NLS_ISO8859_8 is not set
CONFIG_NLS_CODEPAGE_1250=y
# CONFIG_NLS_CODEPAGE_1251 is not set
CONFIG_NLS_ASCII=y
# CONFIG_NLS_ISO8859_1 is not set
# CONFIG_NLS_ISO8859_2 is not set
CONFIG_NLS_ISO8859_3=y
# CONFIG_NLS_ISO8859_4 is not set
CONFIG_NLS_ISO8859_5=y
CONFIG_NLS_ISO8859_6=y
# CONFIG_NLS_ISO8859_7 is not set
# CONFIG_NLS_ISO8859_9 is not set
# CONFIG_NLS_ISO8859_13 is not set
# CONFIG_NLS_ISO8859_14 is not set
CONFIG_NLS_ISO8859_15=y
CONFIG_NLS_KOI8_R=y
CONFIG_NLS_KOI8_U=y
CONFIG_NLS_UTF8=y

#
# Distributed Lock Manager
#
# CONFIG_DLM is not set
# CONFIG_INSTRUMENTATION is not set

#
# Kernel hacking
#
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_PRINTK_TIME=y
# CONFIG_ENABLE_MUST_CHECK is not set
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
# CONFIG_DETECT_SOFTLOCKUP is not set
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
CONFIG_TIMER_STATS=y
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_DEBUG_PI_LIST=y
CONFIG_RT_MUTEX_TESTER=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_LOCK_ALLOC=y
CONFIG_PROVE_LOCKING=y
CONFIG_LOCKDEP=y
# CONFIG_LOCK_STAT is not set
# CONFIG_DEBUG_LOCKDEP is not set
CONFIG_TRACE_IRQFLAGS=y
CONFIG_DEBUG_SPINLOCK_SLEEP=y
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
CONFIG_STACKTRACE=y
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_VM=y
CONFIG_DEBUG_LIST=y
# CONFIG_FRAME_POINTER is not set
# CONFIG_FORCED_INLINING is not set
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_FAULT_INJECTION is not set
CONFIG_EARLY_PRINTK=y
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set
CONFIG_DEBUG_PAGEALLOC=y
# CONFIG_DEBUG_RODATA is not set
# CONFIG_4KSTACKS is not set
CONFIG_X86_FIND_SMP_CONFIG=y
CONFIG_X86_MPPARSE=y
# CONFIG_DOUBLEFAULT is not set

#
# Security options
#
CONFIG_KEYS=y
CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_SECURITY=y
# CONFIG_SECURITY_NETWORK is not set
CONFIG_SECURITY_CAPABILITIES=y
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_BLKCIPHER=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_NULL=y
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA256=y
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_WP512 is not set
# CONFIG_CRYPTO_TGR192 is not set
CONFIG_CRYPTO_GF128MUL=y
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_PCBC=y
# CONFIG_CRYPTO_LRW is not set
# CONFIG_CRYPTO_XTS is not set
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_FCRYPT is not set
CONFIG_CRYPTO_BLOWFISH=y
CONFIG_CRYPTO_TWOFISH=y
CONFIG_CRYPTO_TWOFISH_COMMON=y
CONFIG_CRYPTO_TWOFISH_586=y
CONFIG_CRYPTO_SERPENT=y
CONFIG_CRYPTO_AES=y
# CONFIG_CRYPTO_AES_586 is not set
CONFIG_CRYPTO_CAST5=y
CONFIG_CRYPTO_CAST6=y
CONFIG_CRYPTO_TEA=y
CONFIG_CRYPTO_ARC4=y
# CONFIG_CRYPTO_KHAZAD is not set
CONFIG_CRYPTO_ANUBIS=y
# CONFIG_CRYPTO_SEED is not set
CONFIG_CRYPTO_DEFLATE=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_CRC32C is not set
CONFIG_CRYPTO_CAMELLIA=y
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_HW is not set

#
# Library routines
#
CONFIG_BITREVERSE=y
CONFIG_CRC_CCITT=y
# CONFIG_CRC16 is not set
# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_AUDIT_GENERIC=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_X86_BIOS_REBOOT=y
CONFIG_KTIME_SCALAR=y
CONFIG_FORCE_MINIMAL_CONFIG=y

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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 15:46 [bug] block subsystem related crash with latest -git Ingo Molnar
@ 2007-10-17 15:50 ` Ingo Molnar
  2007-10-17 16:32   ` Jens Axboe
  2007-10-17 16:50 ` Linus Torvalds
  1 sibling, 1 reply; 151+ messages in thread
From: Ingo Molnar @ 2007-10-17 15:50 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-kernel, Andrew Morton, Linus Torvalds


* Ingo Molnar <mingo@elte.hu> wrote:

> i tried another bootup with the same kernel and the crash did not 
> reoccur, so it seems to be spurious. This crash could be related to 
> the scsi or block merges done in the past few days - never saw this 
> before.

managed to trigger it a second time, so it seems rather reproducible:

[  328.771333] kjournald starting.  Commit interval 5 seconds
[  328.776963] EXT3 FS on sda5, internal journal
[  328.781172] EXT3-fs: mounted filesystem with ordered data mode.
[  329.689493] BUG: unable to handle kernel paging request at virtual address 7d516000
[  329.696990] printing eip: 78406669 *pde = 00ddd027 *pte = 05516000 
[  329.703230] Oops: 0000 [#1] DEBUG_PAGEALLOC
[  329.707390] 
[  329.708863] Pid: 0, comm: swapper Not tainted (2.6.23 #45)
[  329.714321] EIP: 0060:[<78406669>] EFLAGS: 00010006 CPU: 0
[  329.719787] EIP is at blk_rq_map_sg+0xb9/0x170
[  329.724202] EAX: 2f6df000 EBX: 7d6af880 ECX: 34d55000 EDX: 005edbe0
[  329.730441] ESI: 7d515ff0 EDI: 796d8be0 EBP: 00001000 ESP: 78a13db0
[  329.736680]  DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068
[  329.742054] Process swapper (pid: 0, ti=78a12000 task=7893c400 task.ti=78a12000)
[  329.749246] Stack: 00000020 7b520000 00002000 34d56000 7d515fe0 00000007 00000001 00000000 
[  329.757565]        7d6af800 01000000 7d515e00 7b522b94 7d84f58c 7b520000 784c89b5 7b520000 
[  329.765885]        784c843a 7d84f58c 7b520f20 7b522b94 7d84f58c 784e54a0 784f394b 00000000 
[  329.774204] Call Trace:
[  329.776804]  [<784c89b5>] scsi_init_io+0x55/0xe0
[  329.781398]  [<784c843a>] scsi_get_cmd_from_req+0x2a/0x40
[  329.786770]  [<784e54a0>] sd_prep_fn+0x80/0x940
[  329.791277]  [<784f394b>] ata_bmdma_start+0xb/0x20
[  329.796043]  [<784ef344>] ata_qc_issue_prot+0x164/0x1e0
[  329.801243]  [<78405c63>] elv_dispatch_sort+0x23/0xe0
[  329.806268]  [<784057d0>] elv_next_request+0xa0/0x130
[  329.811295]  [<787715b8>] _spin_lock_irq+0x38/0x50
[  329.816062]  [<784c9af4>] scsi_request_fn+0x1e4/0x370
[  329.821088]  [<784097f6>] blk_run_queue+0x36/0x80
[  329.825768]  [<784c8370>] scsi_next_command+0x30/0x50
[  329.830794]  [<784c84fb>] scsi_end_request+0xab/0xe0
[  329.835733]  [<784c9249>] scsi_io_completion+0xa9/0x3d0
[  329.840933]  [<78135de7>] trace_hardirqs_on+0x67/0xb0
[  329.845960]  [<784068c5>] blk_done_softirq+0x45/0x80
[  329.850900]  [<784068f3>] blk_done_softirq+0x73/0x80
[  329.855839]  [<7811d3f3>] __do_softirq+0x53/0xb0
[  329.860432]  [<7811d4b8>] do_softirq+0x68/0x70
[  329.864852]  [<78105351>] do_IRQ+0x51/0x90
[  329.868925]  [<78135e1c>] trace_hardirqs_on+0x9c/0xb0
[  329.873951]  [<7810388e>] common_interrupt+0x2e/0x40
[  329.878891]  [<78100c55>] cpu_idle+0x35/0x60
[  329.883138]  [<78a14b35>] start_kernel+0x265/0x300
[  329.887904]  [<78a14380>] unknown_bootoption+0x0/0x1e0
[  329.893016]  =======================
[  329.896570] Code: 05 c1 e1 0c 03 4a 08 8b 52 04 01 ca 89 54 24 0c 8b 3b 89 fa 29 c2 89 d0 c1 f8 05 c1 e0 0c 03 43 08 39 44 24 0c 0f 84 7e 00 00 00 <8b> 46 10 8d 56 10 a8 01 75 4c 89 3e 89 6e 0c 8b 43 08 89 46 04 
[  329.915375] EIP: [<78406669>] blk_rq_map_sg+0xb9/0x170 SS:ESP 0068:78a13db0
[  329.922309] Kernel panic - not syncing: Fatal exception in interrupt

	Ingo

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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 15:50 ` Ingo Molnar
@ 2007-10-17 16:32   ` Jens Axboe
  0 siblings, 0 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-17 16:32 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: linux-kernel, Andrew Morton, Linus Torvalds

On Wed, Oct 17 2007, Ingo Molnar wrote:
> 
> * Ingo Molnar <mingo@elte.hu> wrote:
> 
> > i tried another bootup with the same kernel and the crash did not 
> > reoccur, so it seems to be spurious. This crash could be related to 
> > the scsi or block merges done in the past few days - never saw this 
> > before.
> 
> managed to trigger it a second time, so it seems rather reproducible:

Can you pull

git://git.kernel.dk/linux-2.6-block.git for-linus

and see if it still reproduces?

-- 
Jens Axboe


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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 15:46 [bug] block subsystem related crash with latest -git Ingo Molnar
  2007-10-17 15:50 ` Ingo Molnar
@ 2007-10-17 16:50 ` Linus Torvalds
  2007-10-17 16:59   ` Jens Axboe
  1 sibling, 1 reply; 151+ messages in thread
From: Linus Torvalds @ 2007-10-17 16:50 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Jens Axboe, linux-kernel, Andrew Morton



On Wed, 17 Oct 2007, Ingo Molnar wrote:
> 
> Jens, just got this crash on a testbox:

The code in question is:

     mov    %edx,0xc(%esp)
     mov    (%ebx),%edi
     mov    %edi,%edx
     sub    %eax,%edx
     mov    %edx,%eax
     sar    $0x5,%eax
     shl    $0xc,%eax
     add    0x8(%ebx),%eax
     cmp    %eax,0xc(%esp)
     je     +126
     mov    0x10(%esi),%eax	<----- Oops
     lea    0x10(%esi),%edx
     test   $0x1,%al
     jne    +76
     mov    %edi,(%esi)
     mov    %ebp,0xc(%esi)
     mov    0x8(%ebx),%eax
     mov    %eax,0x4(%esi)


and it looks like %esi is overflowing from one page to the next one, ie:

	BUG: unable to handle kernel paging request at virtual address 7ca76000
	ESI: 7ca75ff0

and you caught this thanks to page-alloc debugging again.

I think I can match that up with the source code: that's "sg_next()". It's 
doing:

        sg++;

        if (unlikely(sg_is_chain(sg)))
                sg = sg_chain_ptr(sg);

        return sg;

and the oopsing instruction is that load of "sg->page" in the assembly 
code:

	mov    0x10(%esi),%eax		# %eax = sg->page
	lea    0x10(%esi),%edx		# %edx = sg+1;
	test   $0x1,%al			# if (unlikely(sg_is_chain()))
	jne    +76

Jens?

		Linus

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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 16:50 ` Linus Torvalds
@ 2007-10-17 16:59   ` Jens Axboe
  2007-10-17 17:08     ` Jens Axboe
  2007-10-17 17:11     ` Ingo Molnar
  0 siblings, 2 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-17 16:59 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Ingo Molnar, linux-kernel, Andrew Morton

On Wed, Oct 17 2007, Linus Torvalds wrote:
> 
> 
> On Wed, 17 Oct 2007, Ingo Molnar wrote:
> > 
> > Jens, just got this crash on a testbox:
> 
> The code in question is:
> 
>      mov    %edx,0xc(%esp)
>      mov    (%ebx),%edi
>      mov    %edi,%edx
>      sub    %eax,%edx
>      mov    %edx,%eax
>      sar    $0x5,%eax
>      shl    $0xc,%eax
>      add    0x8(%ebx),%eax
>      cmp    %eax,0xc(%esp)
>      je     +126
>      mov    0x10(%esi),%eax	<----- Oops
>      lea    0x10(%esi),%edx
>      test   $0x1,%al
>      jne    +76
>      mov    %edi,(%esi)
>      mov    %ebp,0xc(%esi)
>      mov    0x8(%ebx),%eax
>      mov    %eax,0x4(%esi)
> 
> 
> and it looks like %esi is overflowing from one page to the next one, ie:
> 
> 	BUG: unable to handle kernel paging request at virtual address 7ca76000
> 	ESI: 7ca75ff0
> 
> and you caught this thanks to page-alloc debugging again.
> 
> I think I can match that up with the source code: that's "sg_next()". It's 
> doing:
> 
>         sg++;
> 
>         if (unlikely(sg_is_chain(sg)))
>                 sg = sg_chain_ptr(sg);
> 
>         return sg;
> 
> and the oopsing instruction is that load of "sg->page" in the assembly 
> code:
> 
> 	mov    0x10(%esi),%eax		# %eax = sg->page
> 	lea    0x10(%esi),%edx		# %edx = sg+1;
> 	test   $0x1,%al			# if (unlikely(sg_is_chain()))
> 	jne    +76
> 
> Jens?

Yep, that's what I came up with as well - I asked Ingo for a dump in
private, but ended up just using ksymoops to decode the line.

The way blk_rq_map_sg() operates is that it ends up doing a

        next_sg = sg_next(sg);

even though sg may be the last entry. Perhaps this is crapping out,
although if sg is a valid address, then sg + 1 should be as well.
next_sg may end up being crap, in fact it will, but we'll never use that
unless there are more entries to fill. And if there is, then both sg and
next_sg were valid.

So nothing in for-linus should fix it, I'll try and come up with an
alternate way to assign next_sg so it's always valid.

-- 
Jens Axboe


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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 16:59   ` Jens Axboe
@ 2007-10-17 17:08     ` Jens Axboe
  2007-10-17 17:21       ` Jens Axboe
                         ` (2 more replies)
  2007-10-17 17:11     ` Ingo Molnar
  1 sibling, 3 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-17 17:08 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Ingo Molnar, linux-kernel, Andrew Morton

On Wed, Oct 17 2007, Jens Axboe wrote:
> On Wed, Oct 17 2007, Linus Torvalds wrote:
> > 
> > 
> > On Wed, 17 Oct 2007, Ingo Molnar wrote:
> > > 
> > > Jens, just got this crash on a testbox:
> > 
> > The code in question is:
> > 
> >      mov    %edx,0xc(%esp)
> >      mov    (%ebx),%edi
> >      mov    %edi,%edx
> >      sub    %eax,%edx
> >      mov    %edx,%eax
> >      sar    $0x5,%eax
> >      shl    $0xc,%eax
> >      add    0x8(%ebx),%eax
> >      cmp    %eax,0xc(%esp)
> >      je     +126
> >      mov    0x10(%esi),%eax	<----- Oops
> >      lea    0x10(%esi),%edx
> >      test   $0x1,%al
> >      jne    +76
> >      mov    %edi,(%esi)
> >      mov    %ebp,0xc(%esi)
> >      mov    0x8(%ebx),%eax
> >      mov    %eax,0x4(%esi)
> > 
> > 
> > and it looks like %esi is overflowing from one page to the next one, ie:
> > 
> > 	BUG: unable to handle kernel paging request at virtual address 7ca76000
> > 	ESI: 7ca75ff0
> > 
> > and you caught this thanks to page-alloc debugging again.
> > 
> > I think I can match that up with the source code: that's "sg_next()". It's 
> > doing:
> > 
> >         sg++;
> > 
> >         if (unlikely(sg_is_chain(sg)))
> >                 sg = sg_chain_ptr(sg);
> > 
> >         return sg;
> > 
> > and the oopsing instruction is that load of "sg->page" in the assembly 
> > code:
> > 
> > 	mov    0x10(%esi),%eax		# %eax = sg->page
> > 	lea    0x10(%esi),%edx		# %edx = sg+1;
> > 	test   $0x1,%al			# if (unlikely(sg_is_chain()))
> > 	jne    +76
> > 
> > Jens?
> 
> Yep, that's what I came up with as well - I asked Ingo for a dump in
> private, but ended up just using ksymoops to decode the line.
> 
> The way blk_rq_map_sg() operates is that it ends up doing a
> 
>         next_sg = sg_next(sg);
> 
> even though sg may be the last entry. Perhaps this is crapping out,
> although if sg is a valid address, then sg + 1 should be as well.
> next_sg may end up being crap, in fact it will, but we'll never use that
> unless there are more entries to fill. And if there is, then both sg and
> next_sg were valid.
> 
> So nothing in for-linus should fix it, I'll try and come up with an
> alternate way to assign next_sg so it's always valid.

OK, the below should actually be safe, I don't know why I talked myself
into the next_sg stuff in the beginning. It's always safe to zero sg,
since it's a valid entry - nothing to save in ->page. Ingo, does this
work for you?

diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 9e3f3cc..3935469 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -1322,8 +1322,8 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
 		  struct scatterlist *sglist)
 {
 	struct bio_vec *bvec, *bvprv;
-	struct scatterlist *next_sg, *sg;
 	struct req_iterator iter;
+	struct scatterlist *sg;
 	int nsegs, cluster;
 
 	nsegs = 0;
@@ -1333,7 +1333,7 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
 	 * for each bio in rq
 	 */
 	bvprv = NULL;
-	sg = next_sg = &sglist[0];
+	sg = NULL;
 	rq_for_each_segment(bvec, rq, iter) {
 		int nbytes = bvec->bv_len;
 
@@ -1349,8 +1349,10 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
 			sg->length += nbytes;
 		} else {
 new_segment:
-			sg = next_sg;
-			next_sg = sg_next(sg);
+			if (!sg)
+				sg = sglist;
+			else
+				sg = sg_next(sg);
 
 			memset(sg, 0, sizeof(*sg));
 			sg->page = bvec->bv_page;

-- 
Jens Axboe


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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 16:59   ` Jens Axboe
  2007-10-17 17:08     ` Jens Axboe
@ 2007-10-17 17:11     ` Ingo Molnar
  1 sibling, 0 replies; 151+ messages in thread
From: Ingo Molnar @ 2007-10-17 17:11 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Linus Torvalds, linux-kernel, Andrew Morton


* Jens Axboe <jens.axboe@oracle.com> wrote:

> > and the oopsing instruction is that load of "sg->page" in the assembly 
> > code:
> > 
> > 	mov    0x10(%esi),%eax		# %eax = sg->page
> > 	lea    0x10(%esi),%edx		# %edx = sg+1;
> > 	test   $0x1,%al			# if (unlikely(sg_is_chain()))
> > 	jne    +76
> > 
> > Jens?
> 
> Yep, that's what I came up with as well - I asked Ingo for a dump in 
> private, but ended up just using ksymoops to decode the line.
> 
> The way blk_rq_map_sg() operates is that it ends up doing a
> 
>         next_sg = sg_next(sg);
> 
> even though sg may be the last entry. Perhaps this is crapping out, 
> although if sg is a valid address, then sg + 1 should be as well. 
> next_sg may end up being crap, in fact it will, but we'll never use 
> that unless there are more entries to fill. And if there is, then both 
> sg and next_sg were valid.

find below the disassembled code. Here's the faulting source line 
according to gdb:

(gdb) list *0x78406669
0x78406669 is in blk_rq_map_sg (include/linux/scatterlist.h:48).
43       */
44      static inline struct scatterlist *sg_next(struct scatterlist *sg)
45      {
46              sg++;
47
48              if (unlikely(sg_is_chain(sg)))
49                      sg = sg_chain_ptr(sg);
50
51              return sg;
52      }

(gdb) list *0x78406673
0x78406673 is in blk_rq_map_sg (block/ll_rw_blk.c:1355).
1350                    } else {
1351    new_segment:
1352                            sg = next_sg;
1353                            next_sg = sg_next(sg);
1354
1355                            sg->page = bvec->bv_page;
1356                            sg->length = nbytes;
1357                            sg->offset = bvec->bv_offset;
1358                            nsegs++;
1359                    }
(gdb)

the compiler is gcc-4.2.2. (vanilla, built from sources)

	Ingo

784065b0 <blk_rq_map_sg>:
784065b0:	55                   	push   %ebp
784065b1:	57                   	push   %edi
784065b2:	56                   	push   %esi
784065b3:	53                   	push   %ebx
784065b4:	83 ec 28             	sub    $0x28,%esp
784065b7:	89 44 24 04          	mov    %eax,0x4(%esp)
784065bb:	8b 98 08 01 00 00    	mov    0x108(%eax),%ebx
784065c1:	83 e3 01             	and    $0x1,%ebx
784065c4:	89 5c 24 18          	mov    %ebx,0x18(%esp)
784065c8:	8b 52 3c             	mov    0x3c(%edx),%edx
784065cb:	c7 44 24 14 00 00 00 	movl   $0x0,0x14(%esp)
784065d2:	00 
784065d3:	85 d2                	test   %edx,%edx
784065d5:	89 54 24 20          	mov    %edx,0x20(%esp)
784065d9:	0f 84 fc 00 00 00    	je     784066db <blk_rq_map_sg+0x12b>
784065df:	89 ce                	mov    %ecx,%esi
784065e1:	31 d2                	xor    %edx,%edx
784065e3:	89 4c 24 10          	mov    %ecx,0x10(%esp)
784065e7:	8b 44 24 20          	mov    0x20(%esp),%eax
784065eb:	0f b7 58 1a          	movzwl 0x1a(%eax),%ebx
784065ef:	8b 48 30             	mov    0x30(%eax),%ecx
784065f2:	89 5c 24 1c          	mov    %ebx,0x1c(%esp)
784065f6:	0f b7 40 18          	movzwl 0x18(%eax),%eax
784065fa:	39 d8                	cmp    %ebx,%eax
784065fc:	0f 8e c6 00 00 00    	jle    784066c8 <blk_rq_map_sg+0x118>
78406602:	8d 04 5b             	lea    (%ebx,%ebx,2),%eax
78406605:	8d 1c 81             	lea    (%ecx,%eax,4),%ebx
78406608:	0f b6 44 24 18       	movzbl 0x18(%esp),%eax
7840660d:	88 44 24 27          	mov    %al,0x27(%esp)
78406611:	e9 8b 00 00 00       	jmp    784066a1 <blk_rq_map_sg+0xf1>
78406616:	8b 4c 24 10          	mov    0x10(%esp),%ecx
7840661a:	8b 41 0c             	mov    0xc(%ecx),%eax
7840661d:	8b 4c 24 04          	mov    0x4(%esp),%ecx
78406621:	01 e8                	add    %ebp,%eax
78406623:	89 44 24 08          	mov    %eax,0x8(%esp)
78406627:	3b 81 6c 01 00 00    	cmp    0x16c(%ecx),%eax
7840662d:	0f 87 80 00 00 00    	ja     784066b3 <blk_rq_map_sg+0x103>
78406633:	a1 18 ec d7 78       	mov    0x78d7ec18,%eax
78406638:	8b 0a                	mov    (%edx),%ecx
7840663a:	29 c1                	sub    %eax,%ecx
7840663c:	c1 f9 05             	sar    $0x5,%ecx
7840663f:	c1 e1 0c             	shl    $0xc,%ecx
78406642:	03 4a 08             	add    0x8(%edx),%ecx
78406645:	8b 52 04             	mov    0x4(%edx),%edx
78406648:	01 ca                	add    %ecx,%edx
7840664a:	89 54 24 0c          	mov    %edx,0xc(%esp)
7840664e:	8b 3b                	mov    (%ebx),%edi
78406650:	89 fa                	mov    %edi,%edx
78406652:	29 c2                	sub    %eax,%edx
78406654:	89 d0                	mov    %edx,%eax
78406656:	c1 f8 05             	sar    $0x5,%eax
78406659:	c1 e0 0c             	shl    $0xc,%eax
7840665c:	03 43 08             	add    0x8(%ebx),%eax
7840665f:	39 44 24 0c          	cmp    %eax,0xc(%esp)
78406663:	0f 84 7e 00 00 00    	je     784066e7 <blk_rq_map_sg+0x137>
78406669:	8b 46 10             	mov    0x10(%esi),%eax
7840666c:	8d 56 10             	lea    0x10(%esi),%edx
7840666f:	a8 01                	test   $0x1,%al
78406671:	75 4c                	jne    784066bf <blk_rq_map_sg+0x10f>
78406673:	89 3e                	mov    %edi,(%esi)
78406675:	89 6e 0c             	mov    %ebp,0xc(%esi)
78406678:	8b 43 08             	mov    0x8(%ebx),%eax
7840667b:	89 46 04             	mov    %eax,0x4(%esi)
7840667e:	83 44 24 14 01       	addl   $0x1,0x14(%esp)
78406683:	89 74 24 10          	mov    %esi,0x10(%esp)
78406687:	89 d6                	mov    %edx,%esi
78406689:	8b 54 24 20          	mov    0x20(%esp),%edx
7840668d:	83 44 24 1c 01       	addl   $0x1,0x1c(%esp)
78406692:	0f b7 42 18          	movzwl 0x18(%edx),%eax
78406696:	3b 44 24 1c          	cmp    0x1c(%esp),%eax
7840669a:	7e 2a                	jle    784066c6 <blk_rq_map_sg+0x116>
7840669c:	89 da                	mov    %ebx,%edx
7840669e:	83 c3 0c             	add    $0xc,%ebx
784066a1:	85 d2                	test   %edx,%edx
784066a3:	8b 6b 04             	mov    0x4(%ebx),%ebp
784066a6:	74 0b                	je     784066b3 <blk_rq_map_sg+0x103>
784066a8:	80 7c 24 27 00       	cmpb   $0x0,0x27(%esp)
784066ad:	0f 85 63 ff ff ff    	jne    78406616 <blk_rq_map_sg+0x66>
784066b3:	8b 46 10             	mov    0x10(%esi),%eax
784066b6:	8d 56 10             	lea    0x10(%esi),%edx
784066b9:	8b 3b                	mov    (%ebx),%edi
784066bb:	a8 01                	test   $0x1,%al
784066bd:	74 b4                	je     78406673 <blk_rq_map_sg+0xc3>
784066bf:	89 c2                	mov    %eax,%edx
784066c1:	83 e2 fe             	and    $0xfffffffe,%edx
784066c4:	eb ad                	jmp    78406673 <blk_rq_map_sg+0xc3>
784066c6:	89 da                	mov    %ebx,%edx
784066c8:	8b 4c 24 20          	mov    0x20(%esp),%ecx
784066cc:	8b 49 08             	mov    0x8(%ecx),%ecx
784066cf:	85 c9                	test   %ecx,%ecx
784066d1:	89 4c 24 20          	mov    %ecx,0x20(%esp)
784066d5:	0f 85 0c ff ff ff    	jne    784065e7 <blk_rq_map_sg+0x37>
784066db:	8b 44 24 14          	mov    0x14(%esp),%eax
784066df:	83 c4 28             	add    $0x28,%esp
784066e2:	5b                   	pop    %ebx
784066e3:	5e                   	pop    %esi
784066e4:	5f                   	pop    %edi
784066e5:	5d                   	pop    %ebp
784066e6:	c3                   	ret    
784066e7:	8b 44 24 04          	mov    0x4(%esp),%eax
784066eb:	8b 54 24 0c          	mov    0xc(%esp),%edx
784066ef:	8b 80 70 01 00 00    	mov    0x170(%eax),%eax
784066f5:	89 04 24             	mov    %eax,(%esp)
784066f8:	09 c1                	or     %eax,%ecx
784066fa:	8d 44 2a ff          	lea    0xffffffff(%edx,%ebp,1),%eax
784066fe:	0b 04 24             	or     (%esp),%eax
78406701:	39 c1                	cmp    %eax,%ecx
78406703:	0f 85 60 ff ff ff    	jne    78406669 <blk_rq_map_sg+0xb9>
78406709:	8b 44 24 08          	mov    0x8(%esp),%eax
7840670d:	8b 4c 24 10          	mov    0x10(%esp),%ecx
78406711:	89 41 0c             	mov    %eax,0xc(%ecx)
78406714:	e9 70 ff ff ff       	jmp    78406689 <blk_rq_map_sg+0xd9>
78406719:	8d b4 26 00 00 00 00 	lea    0x0(%esi),%esi


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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 17:08     ` Jens Axboe
@ 2007-10-17 17:21       ` Jens Axboe
  2007-10-17 17:29         ` Jens Axboe
  2007-10-17 17:30         ` Ingo Molnar
  2007-10-17 17:28       ` Ingo Molnar
  2007-10-17 17:52       ` Linus Torvalds
  2 siblings, 2 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-17 17:21 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Ingo Molnar, linux-kernel, Andrew Morton

On Wed, Oct 17 2007, Jens Axboe wrote:
> On Wed, Oct 17 2007, Jens Axboe wrote:
> > On Wed, Oct 17 2007, Linus Torvalds wrote:
> > > 
> > > 
> > > On Wed, 17 Oct 2007, Ingo Molnar wrote:
> > > > 
> > > > Jens, just got this crash on a testbox:
> > > 
> > > The code in question is:
> > > 
> > >      mov    %edx,0xc(%esp)
> > >      mov    (%ebx),%edi
> > >      mov    %edi,%edx
> > >      sub    %eax,%edx
> > >      mov    %edx,%eax
> > >      sar    $0x5,%eax
> > >      shl    $0xc,%eax
> > >      add    0x8(%ebx),%eax
> > >      cmp    %eax,0xc(%esp)
> > >      je     +126
> > >      mov    0x10(%esi),%eax	<----- Oops
> > >      lea    0x10(%esi),%edx
> > >      test   $0x1,%al
> > >      jne    +76
> > >      mov    %edi,(%esi)
> > >      mov    %ebp,0xc(%esi)
> > >      mov    0x8(%ebx),%eax
> > >      mov    %eax,0x4(%esi)
> > > 
> > > 
> > > and it looks like %esi is overflowing from one page to the next one, ie:
> > > 
> > > 	BUG: unable to handle kernel paging request at virtual address 7ca76000
> > > 	ESI: 7ca75ff0
> > > 
> > > and you caught this thanks to page-alloc debugging again.
> > > 
> > > I think I can match that up with the source code: that's "sg_next()". It's 
> > > doing:
> > > 
> > >         sg++;
> > > 
> > >         if (unlikely(sg_is_chain(sg)))
> > >                 sg = sg_chain_ptr(sg);
> > > 
> > >         return sg;
> > > 
> > > and the oopsing instruction is that load of "sg->page" in the assembly 
> > > code:
> > > 
> > > 	mov    0x10(%esi),%eax		# %eax = sg->page
> > > 	lea    0x10(%esi),%edx		# %edx = sg+1;
> > > 	test   $0x1,%al			# if (unlikely(sg_is_chain()))
> > > 	jne    +76
> > > 
> > > Jens?
> > 
> > Yep, that's what I came up with as well - I asked Ingo for a dump in
> > private, but ended up just using ksymoops to decode the line.
> > 
> > The way blk_rq_map_sg() operates is that it ends up doing a
> > 
> >         next_sg = sg_next(sg);
> > 
> > even though sg may be the last entry. Perhaps this is crapping out,
> > although if sg is a valid address, then sg + 1 should be as well.
> > next_sg may end up being crap, in fact it will, but we'll never use that
> > unless there are more entries to fill. And if there is, then both sg and
> > next_sg were valid.
> > 
> > So nothing in for-linus should fix it, I'll try and come up with an
> > alternate way to assign next_sg so it's always valid.
> 
> OK, the below should actually be safe, I don't know why I talked myself
> into the next_sg stuff in the beginning. It's always safe to zero sg,
> since it's a valid entry - nothing to save in ->page. Ingo, does this
> work for you?
> 
> diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
> index 9e3f3cc..3935469 100644
> --- a/block/ll_rw_blk.c
> +++ b/block/ll_rw_blk.c
> @@ -1322,8 +1322,8 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
>  		  struct scatterlist *sglist)
>  {
>  	struct bio_vec *bvec, *bvprv;
> -	struct scatterlist *next_sg, *sg;
>  	struct req_iterator iter;
> +	struct scatterlist *sg;
>  	int nsegs, cluster;
>  
>  	nsegs = 0;
> @@ -1333,7 +1333,7 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
>  	 * for each bio in rq
>  	 */
>  	bvprv = NULL;
> -	sg = next_sg = &sglist[0];
> +	sg = NULL;
>  	rq_for_each_segment(bvec, rq, iter) {
>  		int nbytes = bvec->bv_len;
>  
> @@ -1349,8 +1349,10 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
>  			sg->length += nbytes;
>  		} else {
>  new_segment:
> -			sg = next_sg;
> -			next_sg = sg_next(sg);
> +			if (!sg)
> +				sg = sglist;
> +			else
> +				sg = sg_next(sg);
>  
>  			memset(sg, 0, sizeof(*sg));
>  			sg->page = bvec->bv_page;
> 

Scratch that, it cannot work... I'll think up a different approach.

-- 
Jens Axboe


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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 17:08     ` Jens Axboe
  2007-10-17 17:21       ` Jens Axboe
@ 2007-10-17 17:28       ` Ingo Molnar
  2007-10-17 17:52       ` Linus Torvalds
  2 siblings, 0 replies; 151+ messages in thread
From: Ingo Molnar @ 2007-10-17 17:28 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Linus Torvalds, linux-kernel


* Jens Axboe <jens.axboe@oracle.com> wrote:

> [...] It's always safe to zero sg, since it's a valid entry - nothing 
> to save in ->page. Ingo, does this work for you?

with that patch it not crashes on NULL dereference - see crashlog below. 
Compiler bug perhaps?

	Ingo

---------------->
[   34.605614] EXT3-fs: INFO: recovery required on readonly filesystem.
[   34.611842] EXT3-fs: write access will be enabled during recovery.
[   34.635861] BUG: unable to handle kernel NULL pointer dereference at virtual address 00000008
[   34.644227] printing eip: 7840840e *pde = 00000000 
[   34.649081] Oops: 0002 [#1] DEBUG_PAGEALLOC
[   34.653239] 
[   34.654713] Pid: 1, comm: swapper Not tainted (2.6.23 #3)
[   34.660086] EIP: 0060:[<7840840e>] EFLAGS: 00010046 CPU: 0
[   34.665548] EIP is at blk_rq_map_sg+0x8e/0x190
[   34.669965] EAX: 00000000 EBX: 7c885180 ECX: 00000004 EDX: 033b6000
[   34.676205] ESI: 00001000 EDI: 00000008 EBP: 00000000 ESP: 7b4219b8
[   34.682444]  DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068
[   34.687818] Process swapper (pid: 1, ti=7b420000 task=7b416000 task.ti=7b420000)
[   34.695010] Stack: 7b521d38 00000008 7c884000 7b520000 00002000 033b6000 7c885080 00000001 
[   34.703329]        00000001 7c885880 01000002 7c886e00 7b521d1c 7c8857c4 7b520000 784c7ae5 
[   34.711649]        7b520000 784c75ea 7c8857c4 7b524ce4 7b521d1c 7c8857c4 784e4590 7b416000 
[   34.719968] Call Trace:
[   34.722568]  [<784c7ae5>] scsi_init_io+0x55/0xe0
[   34.727161]  [<784c75ea>] scsi_get_cmd_from_req+0x2a/0x40
[   34.732534]  [<784e4590>] sd_prep_fn+0x80/0x940
[   34.737041]  [<7813661b>] __lock_acquire+0x4ab/0xe20
[   34.741981]  [<78135c9c>] trace_hardirqs_on+0x9c/0xb0
[   34.747007]  [<78770e30>] _spin_unlock_irq+0x20/0x30
[   34.751946]  [<78404633>] elv_dispatch_sort+0x23/0xe0
[   34.756973]  [<784041a0>] elv_next_request+0xa0/0x130
[   34.761999]  [<784c8c24>] scsi_request_fn+0x1e4/0x370
[   34.767025]  [<78120f02>] del_timer+0x62/0x70
[   34.771358]  [<784072d5>] __generic_unplug_device+0x25/0x30
[   34.776905]  [<784075a5>] generic_unplug_device+0x15/0x30
[   34.782278]  [<78404e0c>] blk_backing_dev_unplug+0xc/0x10
[   34.787650]  [<78181e76>] sync_buffer+0x26/0x40
[   34.792157]  [<7876f6c2>] __wait_on_bit+0x42/0x70
[   34.796836]  [<78181e50>] sync_buffer+0x0/0x40
[   34.801256]  [<78181e50>] sync_buffer+0x0/0x40
[   34.805676]  [<7876f74a>] out_of_line_wait_on_bit+0x5a/0x70
[   34.811223]  [<7812adb0>] wake_bit_function+0x0/0x60
[   34.816163]  [<78181db4>] __wait_on_buffer+0x24/0x30
[   34.821102]  [<78207a27>] jread+0x1b7/0x250
[   34.825262]  [<78207bcd>] do_one_pass+0x10d/0x600
[   34.829942]  [<78135c9c>] trace_hardirqs_on+0x9c/0xb0
[   34.834968]  [<7820823b>] journal_recover+0x9b/0x1a0
[   34.839908]  [<7820b811>] journal_load+0x51/0xf0
[   34.844501]  [<781e6914>] ext3_fill_super+0xdd4/0x1850
[   34.849613]  [<78411cef>] snprintf+0x1f/0x30
[   34.853860]  [<7819ce70>] disk_name+0xb0/0xc0
[   34.858193]  [<78163809>] get_sb_bdev+0x109/0x130
[   34.862873]  [<7815f300>] __kmalloc_node+0x80/0x90
[   34.867639]  [<781e3a80>] ext3_get_sb+0x20/0x30
[   34.872146]  [<781e5b40>] ext3_fill_super+0x0/0x1850
[   34.877085]  [<78163315>] vfs_kern_mount+0xb5/0x130
[   34.881938]  [<781633ed>] do_kern_mount+0x3d/0xe0
[   34.886618]  [<78177c57>] do_mount+0x5e7/0x710
[   34.891038]  [<78770fe5>] _spin_unlock_irqrestore+0x55/0x70
[   34.896584]  [<78135c9c>] trace_hardirqs_on+0x9c/0xb0
[   34.901610]  [<78110935>] change_page_attr+0x3d5/0x400
[   34.906724]  [<7811099a>] kernel_map_pages+0x3a/0x90
[   34.911663]  [<7814972f>] get_page_from_freelist+0x1ff/0x3e0
[   34.917296]  [<7814a2cf>] __alloc_pages+0x5f/0x380
[   34.922063]  [<7814a61e>] __get_free_pages+0x2e/0x50
[   34.927002]  [<78176660>] copy_mount_options+0x40/0x140
[   34.932202]  [<78177df2>] sys_mount+0x72/0xb0
[   34.936535]  [<78a14d39>] mount_block_root+0x89/0x260
[   34.941561]  [<7816b4c7>] sys_mknod+0x27/0x30
[   34.945894]  [<78a14f56>] mount_root+0x46/0x60
[   34.950314]  [<78a1501c>] prepare_namespace+0xac/0x170
[   34.955427]  [<7816000f>] sys_access+0x1f/0x30
[   34.959846]  [<78a147ae>] kernel_init+0x15e/0x280
[   34.964526]  [<78a14650>] kernel_init+0x0/0x280
[   34.969033]  [<78103a97>] kernel_thread_helper+0x7/0x10
[   34.974233]  =======================
[   34.977785] Code: 44 24 20 88 44 24 2b eb 54 8d 74 26 00 83 44 24 04 10 8b 7c 24 04 8b 07 a8 01 0f 85 fb 00 00 00 31 c0 b9 04 00 00 00 8b 7c 24 04 <f3> ab 8b 03 8b 54 24 04 89 02 89 72 0c 8b 43 08 89 42 04 83 44 
[   34.996590] EIP: [<7840840e>] blk_rq_map_sg+0x8e/0x190 SS:ESP 0068:7b4219b8
[   35.003525] Kernel panic - not syncing: Attempted to kill init!

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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 17:21       ` Jens Axboe
@ 2007-10-17 17:29         ` Jens Axboe
  2007-10-17 17:34           ` Ingo Molnar
                             ` (2 more replies)
  2007-10-17 17:30         ` Ingo Molnar
  1 sibling, 3 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-17 17:29 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Ingo Molnar, linux-kernel, Andrew Morton

On Wed, Oct 17 2007, Jens Axboe wrote:
> On Wed, Oct 17 2007, Jens Axboe wrote:
> > On Wed, Oct 17 2007, Jens Axboe wrote:
> > > On Wed, Oct 17 2007, Linus Torvalds wrote:
> > > > 
> > > > 
> > > > On Wed, 17 Oct 2007, Ingo Molnar wrote:
> > > > > 
> > > > > Jens, just got this crash on a testbox:
> > > > 
> > > > The code in question is:
> > > > 
> > > >      mov    %edx,0xc(%esp)
> > > >      mov    (%ebx),%edi
> > > >      mov    %edi,%edx
> > > >      sub    %eax,%edx
> > > >      mov    %edx,%eax
> > > >      sar    $0x5,%eax
> > > >      shl    $0xc,%eax
> > > >      add    0x8(%ebx),%eax
> > > >      cmp    %eax,0xc(%esp)
> > > >      je     +126
> > > >      mov    0x10(%esi),%eax	<----- Oops
> > > >      lea    0x10(%esi),%edx
> > > >      test   $0x1,%al
> > > >      jne    +76
> > > >      mov    %edi,(%esi)
> > > >      mov    %ebp,0xc(%esi)
> > > >      mov    0x8(%ebx),%eax
> > > >      mov    %eax,0x4(%esi)
> > > > 
> > > > 
> > > > and it looks like %esi is overflowing from one page to the next one, ie:
> > > > 
> > > > 	BUG: unable to handle kernel paging request at virtual address 7ca76000
> > > > 	ESI: 7ca75ff0
> > > > 
> > > > and you caught this thanks to page-alloc debugging again.
> > > > 
> > > > I think I can match that up with the source code: that's "sg_next()". It's 
> > > > doing:
> > > > 
> > > >         sg++;
> > > > 
> > > >         if (unlikely(sg_is_chain(sg)))
> > > >                 sg = sg_chain_ptr(sg);
> > > > 
> > > >         return sg;
> > > > 
> > > > and the oopsing instruction is that load of "sg->page" in the assembly 
> > > > code:
> > > > 
> > > > 	mov    0x10(%esi),%eax		# %eax = sg->page
> > > > 	lea    0x10(%esi),%edx		# %edx = sg+1;
> > > > 	test   $0x1,%al			# if (unlikely(sg_is_chain()))
> > > > 	jne    +76
> > > > 
> > > > Jens?
> > > 
> > > Yep, that's what I came up with as well - I asked Ingo for a dump in
> > > private, but ended up just using ksymoops to decode the line.
> > > 
> > > The way blk_rq_map_sg() operates is that it ends up doing a
> > > 
> > >         next_sg = sg_next(sg);
> > > 
> > > even though sg may be the last entry. Perhaps this is crapping out,
> > > although if sg is a valid address, then sg + 1 should be as well.
> > > next_sg may end up being crap, in fact it will, but we'll never use that
> > > unless there are more entries to fill. And if there is, then both sg and
> > > next_sg were valid.
> > > 
> > > So nothing in for-linus should fix it, I'll try and come up with an
> > > alternate way to assign next_sg so it's always valid.
> > 
> > OK, the below should actually be safe, I don't know why I talked myself
> > into the next_sg stuff in the beginning. It's always safe to zero sg,
> > since it's a valid entry - nothing to save in ->page. Ingo, does this
> > work for you?
> > 
> > diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
> > index 9e3f3cc..3935469 100644
> > --- a/block/ll_rw_blk.c
> > +++ b/block/ll_rw_blk.c
> > @@ -1322,8 +1322,8 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
> >  		  struct scatterlist *sglist)
> >  {
> >  	struct bio_vec *bvec, *bvprv;
> > -	struct scatterlist *next_sg, *sg;
> >  	struct req_iterator iter;
> > +	struct scatterlist *sg;
> >  	int nsegs, cluster;
> >  
> >  	nsegs = 0;
> > @@ -1333,7 +1333,7 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
> >  	 * for each bio in rq
> >  	 */
> >  	bvprv = NULL;
> > -	sg = next_sg = &sglist[0];
> > +	sg = NULL;
> >  	rq_for_each_segment(bvec, rq, iter) {
> >  		int nbytes = bvec->bv_len;
> >  
> > @@ -1349,8 +1349,10 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
> >  			sg->length += nbytes;
> >  		} else {
> >  new_segment:
> > -			sg = next_sg;
> > -			next_sg = sg_next(sg);
> > +			if (!sg)
> > +				sg = sglist;
> > +			else
> > +				sg = sg_next(sg);
> >  
> >  			memset(sg, 0, sizeof(*sg));
> >  			sg->page = bvec->bv_page;
> > 
> 
> Scratch that, it cannot work... I'll think up a different approach.

OK, it is fine, as long as the sglist is cleared initially. And I don't
think there's anyway around that, clearly I didn't think long enough
before including the memset() removal from Tomo.

Ingo, please try this rolled up version.

Linus, this should work. It would probably be best if you first did a
git revert on f5c0dde4c66421a3a2d7d6fa604a712c9b0744e5 and then applied
the ll_rw_blk.c bit alone. Do you want me to stuff that (revert + patch)
into a branch for you to pull?

diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 9e3f3cc..3935469 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -1322,8 +1322,8 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
 		  struct scatterlist *sglist)
 {
 	struct bio_vec *bvec, *bvprv;
-	struct scatterlist *next_sg, *sg;
 	struct req_iterator iter;
+	struct scatterlist *sg;
 	int nsegs, cluster;
 
 	nsegs = 0;
@@ -1333,7 +1333,7 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
 	 * for each bio in rq
 	 */
 	bvprv = NULL;
-	sg = next_sg = &sglist[0];
+	sg = NULL;
 	rq_for_each_segment(bvec, rq, iter) {
 		int nbytes = bvec->bv_len;
 
@@ -1349,8 +1349,10 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
 			sg->length += nbytes;
 		} else {
 new_segment:
-			sg = next_sg;
-			next_sg = sg_next(sg);
+			if (!sg)
+				sg = sglist;
+			else
+				sg = sg_next(sg);
 
 			memset(sg, 0, sizeof(*sg));
 			sg->page = bvec->bv_page;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 0c86be7..aac8a02 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -764,6 +764,8 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
 		if (unlikely(!sgl))
 			goto enomem;
 
+		memset(sgl, 0, sizeof(*sgl) * sgp->size);
+
 		/*
 		 * first loop through, set initial index and return value
 		 */

-- 
Jens Axboe


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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 17:21       ` Jens Axboe
  2007-10-17 17:29         ` Jens Axboe
@ 2007-10-17 17:30         ` Ingo Molnar
  2007-10-17 17:31           ` Jens Axboe
  1 sibling, 1 reply; 151+ messages in thread
From: Ingo Molnar @ 2007-10-17 17:30 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Linus Torvalds, linux-kernel, Andrew Morton


* Jens Axboe <jens.axboe@oracle.com> wrote:

> > -			sg = next_sg;
> > -			next_sg = sg_next(sg);
> > +			if (!sg)
> > +				sg = sglist;
> > +			else
> > +				sg = sg_next(sg);
> >  
> >  			memset(sg, 0, sizeof(*sg));
> >  			sg->page = bvec->bv_page;
> > 
> 
> Scratch that, it cannot work... I'll think up a different approach.

too late, crashed my box with it already :-)

	Ingo

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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 17:30         ` Ingo Molnar
@ 2007-10-17 17:31           ` Jens Axboe
  0 siblings, 0 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-17 17:31 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Linus Torvalds, linux-kernel, Andrew Morton

On Wed, Oct 17 2007, Ingo Molnar wrote:
> 
> * Jens Axboe <jens.axboe@oracle.com> wrote:
> 
> > > -			sg = next_sg;
> > > -			next_sg = sg_next(sg);
> > > +			if (!sg)
> > > +				sg = sglist;
> > > +			else
> > > +				sg = sg_next(sg);
> > >  
> > >  			memset(sg, 0, sizeof(*sg));
> > >  			sg->page = bvec->bv_page;
> > > 
> > 
> > Scratch that, it cannot work... I'll think up a different approach.
> 
> too late, crashed my box with it already :-)

Sorry about that, please try the next one that includes the scsi_lib.c
one liner to clear the sg table on alloc :-)

-- 
Jens Axboe


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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 17:29         ` Jens Axboe
@ 2007-10-17 17:34           ` Ingo Molnar
  2007-10-17 17:36             ` Jens Axboe
  2007-10-17 17:45             ` [bug] ata " Ingo Molnar
  2007-10-17 17:56           ` [bug] block " Linus Torvalds
  2007-10-17 20:15           ` Luca Tettamanti
  2 siblings, 2 replies; 151+ messages in thread
From: Ingo Molnar @ 2007-10-17 17:34 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Linus Torvalds, linux-kernel


* Jens Axboe <jens.axboe@oracle.com> wrote:

> OK, it is fine, as long as the sglist is cleared initially. And I 
> don't think there's anyway around that, clearly I didn't think long 
> enough before including the memset() removal from Tomo.
> 
> Ingo, please try this rolled up version.
> 
> Linus, this should work. It would probably be best if you first did a 
> git revert on f5c0dde4c66421a3a2d7d6fa604a712c9b0744e5 and then 
> applied the ll_rw_blk.c bit alone. Do you want me to stuff that 
> (revert + patch) into a branch for you to pull?

yep, this one did the trick, it booted up fine twice in a row already!

 Tested-by: Ingo Molnar <mingo@elte.hu>

thanks!

	Ingo

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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 17:34           ` Ingo Molnar
@ 2007-10-17 17:36             ` Jens Axboe
  2007-10-17 17:45             ` [bug] ata " Ingo Molnar
  1 sibling, 0 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-17 17:36 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Linus Torvalds, linux-kernel

On Wed, Oct 17 2007, Ingo Molnar wrote:
> 
> * Jens Axboe <jens.axboe@oracle.com> wrote:
> 
> > OK, it is fine, as long as the sglist is cleared initially. And I 
> > don't think there's anyway around that, clearly I didn't think long 
> > enough before including the memset() removal from Tomo.
> > 
> > Ingo, please try this rolled up version.
> > 
> > Linus, this should work. It would probably be best if you first did a 
> > git revert on f5c0dde4c66421a3a2d7d6fa604a712c9b0744e5 and then 
> > applied the ll_rw_blk.c bit alone. Do you want me to stuff that 
> > (revert + patch) into a branch for you to pull?
> 
> yep, this one did the trick, it booted up fine twice in a row already!
> 
>  Tested-by: Ingo Molnar <mingo@elte.hu>
> 
> thanks!

Great! Thanks a lot for reporting and testing... Linus, care to pull

  git://git.kernel.dk/data/git/linux-2.6-block.git for-linus

Jens Axboe (2):
      Revert "[SCSI] Remove full sg table memset()"
      [BLOCK] blk_rq_map_sg() next_sg fixup

 block/ll_rw_blk.c       |   10 ++++++----
 drivers/scsi/scsi_lib.c |    2 ++
 2 files changed, 8 insertions(+), 4 deletions(-)

-- 
Jens Axboe


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

* [bug] ata subsystem related crash with latest -git
  2007-10-17 17:34           ` Ingo Molnar
  2007-10-17 17:36             ` Jens Axboe
@ 2007-10-17 17:45             ` Ingo Molnar
  2007-10-17 17:53               ` Jens Axboe
  2007-10-17 18:08               ` Linus Torvalds
  1 sibling, 2 replies; 151+ messages in thread
From: Ingo Molnar @ 2007-10-17 17:45 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Linus Torvalds, linux-kernel, Jeff Garzik, Alan Cox


ok, here's a different but similar crash that triggers on the testbox:

[  233.438890] BUG: unable to handle kernel paging request at virtual address 7d93e000
[  233.446390] printing eip: 784e9480 *pde = 01000067 *pte = 0593e000 
[  233.452630] Oops: 0000 [#1] DEBUG_PAGEALLOC
[  233.456790] 
[  233.458264] Pid: 0, comm: swapper Not tainted (2.6.23 #5)
[  233.463637] EIP: 0060:[<784e9480>] EFLAGS: 00010087 CPU: 0
[  233.469101] EIP is at ata_qc_issue+0x90/0x380
[  233.473429] EAX: 7d93dff0 EBX: 0000001f ECX: 7d93dff0 EDX: 798daf80
[  233.479668] ESI: 00000020 EDI: 7d93de00 EBP: 7b54007c ESP: 78a13e14
[  233.485908]  DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068
[  233.491282] Process swapper (pid: 0, ti=78a12000 task=789753e0 task.ti=78a12000)
[  233.498473] Stack: 7d93de00 7b540000 7b540000 00000000 7d93dfe0 7b54007c 7d93db00 7b5417a4 
[  233.506793]        784c2490 784ef69e 784f21f3 7b52de98 7d93db00 7b540000 7b5417a4 7d93db00 
[  233.515112]        7b540000 7b524004 784f22e0 784ef380 784c2490 7d93db00 00000202 7b524004 
[  233.523432] Call Trace:
[  233.526033]  [<784c2490>] scsi_done+0x0/0x20
[  233.530279]  [<784ef69e>] ata_scsi_translate+0xbe/0x140
[  233.535478]  [<784f21f3>] ata_scsi_queuecmd+0x33/0x200
[  233.540591]  [<784f22e0>] ata_scsi_queuecmd+0x120/0x200
[  233.545791]  [<784ef380>] ata_scsi_rw_xlat+0x0/0x220
[  233.550730]  [<784c2490>] scsi_done+0x0/0x20
[  233.554976]  [<784c2d12>] scsi_dispatch_cmd+0x152/0x290
[  233.560177]  [<78135c67>] trace_hardirqs_on+0x67/0xb0
[  233.565202]  [<784c8c7e>] scsi_request_fn+0x1be/0x370
[  233.570229]  [<78408086>] blk_run_queue+0x36/0x80
[  233.574909]  [<784c7520>] scsi_next_command+0x30/0x50
[  233.579935]  [<784c76ab>] scsi_end_request+0xab/0xe0
[  233.584875]  [<784c83f9>] scsi_io_completion+0xa9/0x3d0
[  233.590075]  [<78135c67>] trace_hardirqs_on+0x67/0xb0
[  233.595100]  [<78405125>] blk_done_softirq+0x45/0x80
[  233.600040]  [<78405153>] blk_done_softirq+0x73/0x80
[  233.604981]  [<7811d4c3>] __do_softirq+0x53/0xb0
[  233.609573]  [<7811d588>] do_softirq+0x68/0x70
[  233.613993]  [<78105351>] do_IRQ+0x51/0x90
[  233.618066]  [<78135c9c>] trace_hardirqs_on+0x9c/0xb0
[  233.623092]  [<7810f2d0>] pgd_dtor+0x0/0x50
[  233.627252]  [<7810388e>] common_interrupt+0x2e/0x40
[  233.632192]  [<7810f2d0>] pgd_dtor+0x0/0x50
[  233.636352]  [<7815f3be>] quicklist_trim+0x5e/0x90
[  233.641118]  [<7810f2cb>] check_pgt_cache+0x1b/0x20
[  233.645971]  [<78100c52>] cpu_idle+0x32/0x60
[  233.650217]  [<78a14b35>] start_kernel+0x265/0x300
[  233.654983]  [<78a14380>] unknown_bootoption+0x0/0x1e0
[  233.660097]  =======================
[  233.663649] Code: 00 00 00 8b 45 34 a8 02 0f 84 ed 00 00 00 8b bd 88 00 00 00 31 db 89 3c 24 8b 75 3c 89 f8 c7 44 24 10 00 00 00 00 eb 1b 8d 76 00 <8b> 50 10 8d 48 10 f6 c2 01 0f 85 be 02 00 00 89 44 24 10 83 c3 
[  233.682455] EIP: [<784e9480>] ata_qc_issue+0x90/0x380 SS:ESP 0068:78a13e14
[  233.689302] Kernel panic - not syncing: Fatal exception in interrupt

(gdb) list *0x784e9480
0x784e9480 is in ata_qc_issue (include/linux/scatterlist.h:48).
43       */
44      static inline struct scatterlist *sg_next(struct scatterlist *sg)
45      {
46              sg++;
47
48              if (unlikely(sg_is_chain(sg)))
49                      sg = sg_chain_ptr(sg);
50
51              return sg;
52      }
(gdb)

so there's sg_next() involvement too. Below is the disassembly.

	Ingo

------------------------->
784e93f0 <ata_qc_issue>:
784e93f0:	55                   	push   %ebp
784e93f1:	89 c5                	mov    %eax,%ebp
784e93f3:	57                   	push   %edi
784e93f4:	56                   	push   %esi
784e93f5:	53                   	push   %ebx
784e93f6:	83 ec 14             	sub    $0x14,%esp
784e93f9:	8b 00                	mov    (%eax),%eax
784e93fb:	89 44 24 04          	mov    %eax,0x4(%esp)
784e93ff:	8b 45 04             	mov    0x4(%ebp),%eax
784e9402:	80 7d 14 04          	cmpb   $0x4,0x14(%ebp)
784e9406:	8b 10                	mov    (%eax),%edx
784e9408:	0f 84 d2 01 00 00    	je     784e95e0 <ata_qc_issue+0x1f0>
784e940e:	8b 5c 24 04          	mov    0x4(%esp),%ebx
784e9412:	83 83 84 16 00 00 01 	addl   $0x1,0x1684(%ebx)
784e9419:	8b 45 38             	mov    0x38(%ebp),%eax
784e941c:	89 42 08             	mov    %eax,0x8(%edx)
784e941f:	83 4d 34 01          	orl    $0x1,0x34(%ebp)
784e9423:	b8 01 00 00 00       	mov    $0x1,%eax
784e9428:	8b 4d 38             	mov    0x38(%ebp),%ecx
784e942b:	89 c7                	mov    %eax,%edi
784e942d:	8b 54 24 04          	mov    0x4(%esp),%edx
784e9431:	d3 e7                	shl    %cl,%edi
784e9433:	09 ba 80 16 00 00    	or     %edi,0x1680(%edx)
784e9439:	8b 4d 00             	mov    0x0(%ebp),%ecx
784e943c:	89 4c 24 08          	mov    %ecx,0x8(%esp)
784e9440:	80 7d 14 07          	cmpb   $0x7,0x14(%ebp)
784e9444:	0f 87 c6 00 00 00    	ja     784e9510 <ata_qc_issue+0x120>
784e944a:	0f be 4d 14          	movsbl 0x14(%ebp),%ecx
784e944e:	d3 e0                	shl    %cl,%eax
784e9450:	a8 98                	test   $0x98,%al
784e9452:	0f 84 ab 00 00 00    	je     784e9503 <ata_qc_issue+0x113>
784e9458:	8b 45 34             	mov    0x34(%ebp),%eax
784e945b:	a8 02                	test   $0x2,%al
784e945d:	0f 84 ed 00 00 00    	je     784e9550 <ata_qc_issue+0x160>
784e9463:	8b bd 88 00 00 00    	mov    0x88(%ebp),%edi
784e9469:	31 db                	xor    %ebx,%ebx
784e946b:	89 3c 24             	mov    %edi,(%esp)
784e946e:	8b 75 3c             	mov    0x3c(%ebp),%esi
784e9471:	89 f8                	mov    %edi,%eax
784e9473:	c7 44 24 10 00 00 00 	movl   $0x0,0x10(%esp)
784e947a:	00 
784e947b:	eb 1b                	jmp    784e9498 <ata_qc_issue+0xa8>
784e947d:	8d 76 00             	lea    0x0(%esi),%esi
784e9480:	8b 50 10             	mov    0x10(%eax),%edx
784e9483:	8d 48 10             	lea    0x10(%eax),%ecx
784e9486:	f6 c2 01             	test   $0x1,%dl
784e9489:	0f 85 be 02 00 00    	jne    784e974d <ata_qc_issue+0x35d>
784e948f:	89 44 24 10          	mov    %eax,0x10(%esp)
784e9493:	83 c3 01             	add    $0x1,%ebx
784e9496:	89 c8                	mov    %ecx,%eax
784e9498:	39 f3                	cmp    %esi,%ebx
784e949a:	75 e4                	jne    784e9480 <ata_qc_issue+0x90>
784e949c:	8b 54 24 10          	mov    0x10(%esp),%edx
784e94a0:	8b 42 0c             	mov    0xc(%edx),%eax
784e94a3:	83 e0 03             	and    $0x3,%eax
784e94a6:	85 c0                	test   %eax,%eax
784e94a8:	89 45 4c             	mov    %eax,0x4c(%ebp)
784e94ab:	0f 85 53 01 00 00    	jne    784e9604 <ata_qc_issue+0x214>
784e94b1:	89 f1                	mov    %esi,%ecx
784e94b3:	83 f9 00             	cmp    $0x0,%ecx
784e94b6:	0f 84 df 01 00 00    	je     784e969b <ata_qc_issue+0x2ab>
784e94bc:	7e 30                	jle    784e94ee <ata_qc_issue+0xfe>
784e94be:	31 d2                	xor    %edx,%edx
784e94c0:	8b 1c 24             	mov    (%esp),%ebx
784e94c3:	83 c2 01             	add    $0x1,%edx
784e94c6:	8b 03                	mov    (%ebx),%eax
784e94c8:	2b 05 f8 ec d7 78    	sub    0x78d7ecf8,%eax
784e94ce:	c1 f8 05             	sar    $0x5,%eax
784e94d1:	c1 e0 0c             	shl    $0xc,%eax
784e94d4:	03 43 04             	add    0x4(%ebx),%eax
784e94d7:	89 43 08             	mov    %eax,0x8(%ebx)
784e94da:	83 c3 10             	add    $0x10,%ebx
784e94dd:	89 1c 24             	mov    %ebx,(%esp)
784e94e0:	8b 03                	mov    (%ebx),%eax
784e94e2:	a8 01                	test   $0x1,%al
784e94e4:	0f 85 6d 02 00 00    	jne    784e9757 <ata_qc_issue+0x367>
784e94ea:	39 ca                	cmp    %ecx,%edx
784e94ec:	75 d2                	jne    784e94c0 <ata_qc_issue+0xd0>
784e94ee:	f0 83 44 24 00 00    	lock addl $0x0,0x0(%esp)
784e94f4:	85 c9                	test   %ecx,%ecx
784e94f6:	89 c8                	mov    %ecx,%eax
784e94f8:	0f 8e 2c 02 00 00    	jle    784e972a <ata_qc_issue+0x33a>
784e94fe:	89 45 3c             	mov    %eax,0x3c(%ebp)
784e9501:	eb 11                	jmp    784e9514 <ata_qc_issue+0x124>
784e9503:	a8 24                	test   $0x24,%al
784e9505:	0f 85 b5 00 00 00    	jne    784e95c0 <ata_qc_issue+0x1d0>
784e950b:	90                   	nop    
784e950c:	8d 74 26 00          	lea    0x0(%esi),%esi
784e9510:	83 65 34 f9          	andl   $0xfffffff9,0x34(%ebp)
784e9514:	8b 5c 24 04          	mov    0x4(%esp),%ebx
784e9518:	89 e8                	mov    %ebp,%eax
784e951a:	8b 53 04             	mov    0x4(%ebx),%edx
784e951d:	ff 52 48             	call   *0x48(%edx)
784e9520:	8b 9d 8c 00 00 00    	mov    0x8c(%ebp),%ebx
784e9526:	89 e8                	mov    %ebp,%eax
784e9528:	8b 7c 24 04          	mov    0x4(%esp),%edi
784e952c:	8b 57 04             	mov    0x4(%edi),%edx
784e952f:	ff 52 4c             	call   *0x4c(%edx)
784e9532:	09 d8                	or     %ebx,%eax
784e9534:	85 c0                	test   %eax,%eax
784e9536:	89 85 8c 00 00 00    	mov    %eax,0x8c(%ebp)
784e953c:	0f 85 fd 01 00 00    	jne    784e973f <ata_qc_issue+0x34f>
784e9542:	83 c4 14             	add    $0x14,%esp
784e9545:	5b                   	pop    %ebx
784e9546:	5e                   	pop    %esi
784e9547:	5f                   	pop    %edi
784e9548:	5d                   	pop    %ebp
784e9549:	c3                   	ret    
784e954a:	8d b6 00 00 00 00    	lea    0x0(%esi),%esi
784e9550:	a8 04                	test   $0x4,%al
784e9552:	74 c0                	je     784e9514 <ata_qc_issue+0x124>
784e9554:	8b 95 88 00 00 00    	mov    0x88(%ebp),%edx
784e955a:	8b 42 0c             	mov    0xc(%edx),%eax
784e955d:	83 e0 03             	and    $0x3,%eax
784e9560:	85 c0                	test   %eax,%eax
784e9562:	89 45 4c             	mov    %eax,0x4c(%ebp)
784e9565:	0f 84 3a 01 00 00    	je     784e96a5 <ata_qc_issue+0x2b5>
784e956b:	8b 45 38             	mov    0x38(%ebp),%eax
784e956e:	8d 3c 85 00 00 00 00 	lea    0x0(,%eax,4),%edi
784e9575:	8b 44 24 08          	mov    0x8(%esp),%eax
784e9579:	03 78 24             	add    0x24(%eax),%edi
784e957c:	c7 07 00 00 00 00    	movl   $0x0,(%edi)
784e9582:	f6 45 10 08          	testb  $0x8,0x10(%ebp)
784e9586:	0f 85 3a 01 00 00    	jne    784e96c6 <ata_qc_issue+0x2d6>
784e958c:	8b 4c 24 08          	mov    0x8(%esp),%ecx
784e9590:	8b 45 38             	mov    0x38(%ebp),%eax
784e9593:	c1 e0 02             	shl    $0x2,%eax
784e9596:	03 41 28             	add    0x28(%ecx),%eax
784e9599:	c7 85 80 00 00 00 04 	movl   $0x4,0x80(%ebp)
784e95a0:	00 00 00 
784e95a3:	89 45 7c             	mov    %eax,0x7c(%ebp)
784e95a6:	8b 42 0c             	mov    0xc(%edx),%eax
784e95a9:	2b 45 4c             	sub    0x4c(%ebp),%eax
784e95ac:	85 c0                	test   %eax,%eax
784e95ae:	89 42 0c             	mov    %eax,0xc(%edx)
784e95b1:	0f 85 ee 00 00 00    	jne    784e96a5 <ata_qc_issue+0x2b5>
784e95b7:	83 6d 3c 01          	subl   $0x1,0x3c(%ebp)
784e95bb:	e9 54 ff ff ff       	jmp    784e9514 <ata_qc_issue+0x124>
784e95c0:	8b 5c 24 08          	mov    0x8(%esp),%ebx
784e95c4:	80 7b 0c 00          	cmpb   $0x0,0xc(%ebx)
784e95c8:	0f 89 42 ff ff ff    	jns    784e9510 <ata_qc_issue+0x120>
784e95ce:	8b 45 34             	mov    0x34(%ebp),%eax
784e95d1:	a8 02                	test   $0x2,%al
784e95d3:	0f 84 77 ff ff ff    	je     784e9550 <ata_qc_issue+0x160>
784e95d9:	e9 85 fe ff ff       	jmp    784e9463 <ata_qc_issue+0x73>
784e95de:	89 f6                	mov    %esi,%esi
784e95e0:	8b 42 0c             	mov    0xc(%edx),%eax
784e95e3:	85 c0                	test   %eax,%eax
784e95e5:	75 0b                	jne    784e95f2 <ata_qc_issue+0x202>
784e95e7:	8b 4c 24 04          	mov    0x4(%esp),%ecx
784e95eb:	83 81 84 16 00 00 01 	addl   $0x1,0x1684(%ecx)
784e95f2:	8b 4d 38             	mov    0x38(%ebp),%ecx
784e95f5:	b8 01 00 00 00       	mov    $0x1,%eax
784e95fa:	d3 e0                	shl    %cl,%eax
784e95fc:	09 42 0c             	or     %eax,0xc(%edx)
784e95ff:	e9 1b fe ff ff       	jmp    784e941f <ata_qc_issue+0x2f>
784e9604:	8b 45 38             	mov    0x38(%ebp),%eax
784e9607:	8b 4c 24 08          	mov    0x8(%esp),%ecx
784e960b:	c1 e0 02             	shl    $0x2,%eax
784e960e:	89 44 24 0c          	mov    %eax,0xc(%esp)
784e9612:	8b 49 24             	mov    0x24(%ecx),%ecx
784e9615:	01 c8                	add    %ecx,%eax
784e9617:	89 44 24 0c          	mov    %eax,0xc(%esp)
784e961b:	c7 00 00 00 00 00    	movl   $0x0,(%eax)
784e9621:	8b 5c 24 10          	mov    0x10(%esp),%ebx
784e9625:	8b 7c 24 10          	mov    0x10(%esp),%edi
784e9629:	8b 53 04             	mov    0x4(%ebx),%edx
784e962c:	03 53 0c             	add    0xc(%ebx),%edx
784e962f:	8b 07                	mov    (%edi),%eax
784e9631:	8b 1d f8 ec d7 78    	mov    0x78d7ecf8,%ebx
784e9637:	2b 55 4c             	sub    0x4c(%ebp),%edx
784e963a:	29 d8                	sub    %ebx,%eax
784e963c:	89 d1                	mov    %edx,%ecx
784e963e:	c1 f8 05             	sar    $0x5,%eax
784e9641:	81 e2 ff 0f 00 00    	and    $0xfff,%edx
784e9647:	c1 e9 0c             	shr    $0xc,%ecx
784e964a:	01 c8                	add    %ecx,%eax
784e964c:	c1 e0 05             	shl    $0x5,%eax
784e964f:	01 c3                	add    %eax,%ebx
784e9651:	f6 45 10 08          	testb  $0x8,0x10(%ebp)
784e9655:	89 5d 74             	mov    %ebx,0x74(%ebp)
784e9658:	89 55 78             	mov    %edx,0x78(%ebp)
784e965b:	0f 85 88 00 00 00    	jne    784e96e9 <ata_qc_issue+0x2f9>
784e9661:	8b 54 24 08          	mov    0x8(%esp),%edx
784e9665:	8b 45 38             	mov    0x38(%ebp),%eax
784e9668:	c1 e0 02             	shl    $0x2,%eax
784e966b:	03 42 28             	add    0x28(%edx),%eax
784e966e:	c7 85 80 00 00 00 04 	movl   $0x4,0x80(%ebp)
784e9675:	00 00 00 
784e9678:	89 45 7c             	mov    %eax,0x7c(%ebp)
784e967b:	8b 4c 24 10          	mov    0x10(%esp),%ecx
784e967f:	8b 41 0c             	mov    0xc(%ecx),%eax
784e9682:	2b 45 4c             	sub    0x4c(%ebp),%eax
784e9685:	85 c0                	test   %eax,%eax
784e9687:	89 41 0c             	mov    %eax,0xc(%ecx)
784e968a:	75 32                	jne    784e96be <ata_qc_issue+0x2ce>
784e968c:	8b 4d 3c             	mov    0x3c(%ebp),%ecx
784e968f:	85 c9                	test   %ecx,%ecx
784e9691:	74 08                	je     784e969b <ata_qc_issue+0x2ab>
784e9693:	83 e9 01             	sub    $0x1,%ecx
784e9696:	e9 18 fe ff ff       	jmp    784e94b3 <ata_qc_issue+0xc3>
784e969b:	31 c0                	xor    %eax,%eax
784e969d:	8d 76 00             	lea    0x0(%esi),%esi
784e96a0:	e9 59 fe ff ff       	jmp    784e94fe <ata_qc_issue+0x10e>
784e96a5:	8b 85 84 00 00 00    	mov    0x84(%ebp),%eax
784e96ab:	f0 83 44 24 00 00    	lock addl $0x0,0x0(%esp)
784e96b1:	2d 00 00 00 78       	sub    $0x78000000,%eax
784e96b6:	89 42 08             	mov    %eax,0x8(%edx)
784e96b9:	e9 56 fe ff ff       	jmp    784e9514 <ata_qc_issue+0x124>
784e96be:	8b 75 3c             	mov    0x3c(%ebp),%esi
784e96c1:	e9 eb fd ff ff       	jmp    784e94b1 <ata_qc_issue+0xc1>
784e96c6:	8b 45 4c             	mov    0x4c(%ebp),%eax
784e96c9:	8b 72 0c             	mov    0xc(%edx),%esi
784e96cc:	03 b5 84 00 00 00    	add    0x84(%ebp),%esi
784e96d2:	89 c1                	mov    %eax,%ecx
784e96d4:	c1 e9 02             	shr    $0x2,%ecx
784e96d7:	29 c6                	sub    %eax,%esi
784e96d9:	f3 a5                	rep movsl %ds:(%esi),%es:(%edi)
784e96db:	89 c1                	mov    %eax,%ecx
784e96dd:	83 e1 03             	and    $0x3,%ecx
784e96e0:	74 02                	je     784e96e4 <ata_qc_issue+0x2f4>
784e96e2:	f3 a4                	rep movsb %ds:(%esi),%es:(%edi)
784e96e4:	e9 a3 fe ff ff       	jmp    784e958c <ata_qc_issue+0x19c>
784e96e9:	89 e2                	mov    %esp,%edx
784e96eb:	81 e2 00 e0 ff ff    	and    $0xffffe000,%edx
784e96f1:	83 42 14 01          	addl   $0x1,0x14(%edx)
784e96f5:	8b 45 4c             	mov    0x4c(%ebp),%eax
784e96f8:	2b 1d f8 ec d7 78    	sub    0x78d7ecf8,%ebx
784e96fe:	8b 7c 24 0c          	mov    0xc(%esp),%edi
784e9702:	c1 fb 05             	sar    $0x5,%ebx
784e9705:	89 c1                	mov    %eax,%ecx
784e9707:	c1 e3 0c             	shl    $0xc,%ebx
784e970a:	8d b3 00 00 00 78    	lea    0x78000000(%ebx),%esi
784e9710:	c1 e9 02             	shr    $0x2,%ecx
784e9713:	03 75 78             	add    0x78(%ebp),%esi
784e9716:	f3 a5                	rep movsl %ds:(%esi),%es:(%edi)
784e9718:	89 c1                	mov    %eax,%ecx
784e971a:	83 e1 03             	and    $0x3,%ecx
784e971d:	74 02                	je     784e9721 <ata_qc_issue+0x331>
784e971f:	f3 a4                	rep movsb %ds:(%esi),%es:(%edi)
784e9721:	83 6a 14 01          	subl   $0x1,0x14(%edx)
784e9725:	e9 37 ff ff ff       	jmp    784e9661 <ata_qc_issue+0x271>
784e972a:	8b 54 24 10          	mov    0x10(%esp),%edx
784e972e:	8b 45 4c             	mov    0x4c(%ebp),%eax
784e9731:	01 42 0c             	add    %eax,0xc(%edx)
784e9734:	83 65 34 f9          	andl   $0xfffffff9,0x34(%ebp)
784e9738:	83 8d 8c 00 00 00 40 	orl    $0x40,0x8c(%ebp)
784e973f:	83 c4 14             	add    $0x14,%esp
784e9742:	89 e8                	mov    %ebp,%eax
784e9744:	5b                   	pop    %ebx
784e9745:	5e                   	pop    %esi
784e9746:	5f                   	pop    %edi
784e9747:	5d                   	pop    %ebp
784e9748:	e9 23 fc ff ff       	jmp    784e9370 <ata_qc_complete>
784e974d:	89 d1                	mov    %edx,%ecx
784e974f:	83 e1 fe             	and    $0xfffffffe,%ecx
784e9752:	e9 38 fd ff ff       	jmp    784e948f <ata_qc_issue+0x9f>
784e9757:	83 e0 fe             	and    $0xfffffffe,%eax
784e975a:	89 04 24             	mov    %eax,(%esp)
784e975d:	e9 88 fd ff ff       	jmp    784e94ea <ata_qc_issue+0xfa>
784e9762:	8d b4 26 00 00 00 00 	lea    0x0(%esi),%esi
784e9769:	8d bc 27 00 00 00 00 	lea    0x0(%edi),%edi


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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 17:08     ` Jens Axboe
  2007-10-17 17:21       ` Jens Axboe
  2007-10-17 17:28       ` Ingo Molnar
@ 2007-10-17 17:52       ` Linus Torvalds
  2007-10-17 18:00         ` Jens Axboe
  2 siblings, 1 reply; 151+ messages in thread
From: Linus Torvalds @ 2007-10-17 17:52 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Ingo Molnar, linux-kernel, Andrew Morton



On Wed, 17 Oct 2007, Jens Axboe wrote:
> 
> OK, the below should actually be safe, I don't know why I talked myself
> into the next_sg stuff in the beginning. It's always safe to zero sg,
> since it's a valid entry - nothing to save in ->page. Ingo, does this
> work for you?

I really don't think this should work.

Doing "sg_next()" on a valid sg is *always* ok. So if the old code didn't 
work, then "sg" wasn't valid to start with (and the code *after* the 
sg_next() would have oopsed even if you try to avoid using sg_next.

So avoiding the "sg_next()" on the last entry is pointless. 

Also, your patch makes the code almost totally unreadable, with that 
subtle issue of the "if (bvprv && cluster)" case not triggering on the 
first case, so the NULL initial sg is "safe".

So at a guess, I think the *real* problem is simply that the passed-in 
sglist was just too small. What guarantees that the sg list allocation 
(apparently done by scsi_alloc_sgtable()) is big enough? 

If I read things right, scsi_alloc_sgtable() will allocate "cmd->use_sg" 
SG enties, no? But I also notice that it does not seem to initialize the 
SG allocation, so those SG entries contain random crap - including, 
perhaps, a random - and bogus - chain pointer in sg->page..

Yes, we set sh->page *if* we create a chain, but if we don't chain, we 
leave the old random contents around which in turn may include old and 
stale chain pointers. Or am I missing something?

So when you added that "memset(sg, 0, sizeof(*sg))" into blk_rq_map_sg(), 
you did it way too late - it needs to be done when the sg chain is 
allocated, and for every entry (and then the "link" entry needs to be 
linked in separately)

I think.

		Linus


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 17:45             ` [bug] ata " Ingo Molnar
@ 2007-10-17 17:53               ` Jens Axboe
  2007-10-17 17:55                 ` Jens Axboe
  2007-10-17 18:37                 ` Jens Axboe
  2007-10-17 18:08               ` Linus Torvalds
  1 sibling, 2 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-17 17:53 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Linus Torvalds, linux-kernel, Jeff Garzik, Alan Cox

On Wed, Oct 17 2007, Ingo Molnar wrote:
> 
> ok, here's a different but similar crash that triggers on the testbox:
> 
> [  233.438890] BUG: unable to handle kernel paging request at virtual address 7d93e000
> [  233.446390] printing eip: 784e9480 *pde = 01000067 *pte = 0593e000 
> [  233.452630] Oops: 0000 [#1] DEBUG_PAGEALLOC
> [  233.456790] 
> [  233.458264] Pid: 0, comm: swapper Not tainted (2.6.23 #5)
> [  233.463637] EIP: 0060:[<784e9480>] EFLAGS: 00010087 CPU: 0
> [  233.469101] EIP is at ata_qc_issue+0x90/0x380
> [  233.473429] EAX: 7d93dff0 EBX: 0000001f ECX: 7d93dff0 EDX: 798daf80
> [  233.479668] ESI: 00000020 EDI: 7d93de00 EBP: 7b54007c ESP: 78a13e14
> [  233.485908]  DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068
> [  233.491282] Process swapper (pid: 0, ti=78a12000 task=789753e0 task.ti=78a12000)
> [  233.498473] Stack: 7d93de00 7b540000 7b540000 00000000 7d93dfe0 7b54007c 7d93db00 7b5417a4 
> [  233.506793]        784c2490 784ef69e 784f21f3 7b52de98 7d93db00 7b540000 7b5417a4 7d93db00 
> [  233.515112]        7b540000 7b524004 784f22e0 784ef380 784c2490 7d93db00 00000202 7b524004 
> [  233.523432] Call Trace:
> [  233.526033]  [<784c2490>] scsi_done+0x0/0x20
> [  233.530279]  [<784ef69e>] ata_scsi_translate+0xbe/0x140
> [  233.535478]  [<784f21f3>] ata_scsi_queuecmd+0x33/0x200
> [  233.540591]  [<784f22e0>] ata_scsi_queuecmd+0x120/0x200
> [  233.545791]  [<784ef380>] ata_scsi_rw_xlat+0x0/0x220
> [  233.550730]  [<784c2490>] scsi_done+0x0/0x20
> [  233.554976]  [<784c2d12>] scsi_dispatch_cmd+0x152/0x290
> [  233.560177]  [<78135c67>] trace_hardirqs_on+0x67/0xb0
> [  233.565202]  [<784c8c7e>] scsi_request_fn+0x1be/0x370
> [  233.570229]  [<78408086>] blk_run_queue+0x36/0x80
> [  233.574909]  [<784c7520>] scsi_next_command+0x30/0x50
> [  233.579935]  [<784c76ab>] scsi_end_request+0xab/0xe0
> [  233.584875]  [<784c83f9>] scsi_io_completion+0xa9/0x3d0
> [  233.590075]  [<78135c67>] trace_hardirqs_on+0x67/0xb0
> [  233.595100]  [<78405125>] blk_done_softirq+0x45/0x80
> [  233.600040]  [<78405153>] blk_done_softirq+0x73/0x80
> [  233.604981]  [<7811d4c3>] __do_softirq+0x53/0xb0
> [  233.609573]  [<7811d588>] do_softirq+0x68/0x70
> [  233.613993]  [<78105351>] do_IRQ+0x51/0x90
> [  233.618066]  [<78135c9c>] trace_hardirqs_on+0x9c/0xb0
> [  233.623092]  [<7810f2d0>] pgd_dtor+0x0/0x50
> [  233.627252]  [<7810388e>] common_interrupt+0x2e/0x40
> [  233.632192]  [<7810f2d0>] pgd_dtor+0x0/0x50
> [  233.636352]  [<7815f3be>] quicklist_trim+0x5e/0x90
> [  233.641118]  [<7810f2cb>] check_pgt_cache+0x1b/0x20
> [  233.645971]  [<78100c52>] cpu_idle+0x32/0x60
> [  233.650217]  [<78a14b35>] start_kernel+0x265/0x300
> [  233.654983]  [<78a14380>] unknown_bootoption+0x0/0x1e0
> [  233.660097]  =======================
> [  233.663649] Code: 00 00 00 8b 45 34 a8 02 0f 84 ed 00 00 00 8b bd 88 00 00 00 31 db 89 3c 24 8b 75 3c 89 f8 c7 44 24 10 00 00 00 00 eb 1b 8d 76 00 <8b> 50 10 8d 48 10 f6 c2 01 0f 85 be 02 00 00 89 44 24 10 83 c3 
> [  233.682455] EIP: [<784e9480>] ata_qc_issue+0x90/0x380 SS:ESP 0068:78a13e14
> [  233.689302] Kernel panic - not syncing: Fatal exception in interrupt
> 
> (gdb) list *0x784e9480
> 0x784e9480 is in ata_qc_issue (include/linux/scatterlist.h:48).
> 43       */
> 44      static inline struct scatterlist *sg_next(struct scatterlist *sg)
> 45      {
> 46              sg++;
> 47
> 48              if (unlikely(sg_is_chain(sg)))
> 49                      sg = sg_chain_ptr(sg);
> 50
> 51              return sg;
> 52      }
> (gdb)
> 
> so there's sg_next() involvement too. Below is the disassembly.

You must have a magic test box :-)

Will investigate... libata doesn't actually enable chaining, but since
i386 supports it, it ends up using the chain helpers anyway.

There seems to be some automatic inlining involved here, it must be
dying inside ata_sg_setup().

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 17:53               ` Jens Axboe
@ 2007-10-17 17:55                 ` Jens Axboe
  2007-10-17 17:58                   ` Ingo Molnar
  2007-10-17 18:37                 ` Jens Axboe
  1 sibling, 1 reply; 151+ messages in thread
From: Jens Axboe @ 2007-10-17 17:55 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Linus Torvalds, linux-kernel, Jeff Garzik, Alan Cox

On Wed, Oct 17 2007, Jens Axboe wrote:
> On Wed, Oct 17 2007, Ingo Molnar wrote:
> > 
> > ok, here's a different but similar crash that triggers on the testbox:
> > 
> > [  233.438890] BUG: unable to handle kernel paging request at virtual address 7d93e000
> > [  233.446390] printing eip: 784e9480 *pde = 01000067 *pte = 0593e000 
> > [  233.452630] Oops: 0000 [#1] DEBUG_PAGEALLOC
> > [  233.456790] 
> > [  233.458264] Pid: 0, comm: swapper Not tainted (2.6.23 #5)
> > [  233.463637] EIP: 0060:[<784e9480>] EFLAGS: 00010087 CPU: 0
> > [  233.469101] EIP is at ata_qc_issue+0x90/0x380
> > [  233.473429] EAX: 7d93dff0 EBX: 0000001f ECX: 7d93dff0 EDX: 798daf80
> > [  233.479668] ESI: 00000020 EDI: 7d93de00 EBP: 7b54007c ESP: 78a13e14
> > [  233.485908]  DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068
> > [  233.491282] Process swapper (pid: 0, ti=78a12000 task=789753e0 task.ti=78a12000)
> > [  233.498473] Stack: 7d93de00 7b540000 7b540000 00000000 7d93dfe0 7b54007c 7d93db00 7b5417a4 
> > [  233.506793]        784c2490 784ef69e 784f21f3 7b52de98 7d93db00 7b540000 7b5417a4 7d93db00 
> > [  233.515112]        7b540000 7b524004 784f22e0 784ef380 784c2490 7d93db00 00000202 7b524004 
> > [  233.523432] Call Trace:
> > [  233.526033]  [<784c2490>] scsi_done+0x0/0x20
> > [  233.530279]  [<784ef69e>] ata_scsi_translate+0xbe/0x140
> > [  233.535478]  [<784f21f3>] ata_scsi_queuecmd+0x33/0x200
> > [  233.540591]  [<784f22e0>] ata_scsi_queuecmd+0x120/0x200
> > [  233.545791]  [<784ef380>] ata_scsi_rw_xlat+0x0/0x220
> > [  233.550730]  [<784c2490>] scsi_done+0x0/0x20
> > [  233.554976]  [<784c2d12>] scsi_dispatch_cmd+0x152/0x290
> > [  233.560177]  [<78135c67>] trace_hardirqs_on+0x67/0xb0
> > [  233.565202]  [<784c8c7e>] scsi_request_fn+0x1be/0x370
> > [  233.570229]  [<78408086>] blk_run_queue+0x36/0x80
> > [  233.574909]  [<784c7520>] scsi_next_command+0x30/0x50
> > [  233.579935]  [<784c76ab>] scsi_end_request+0xab/0xe0
> > [  233.584875]  [<784c83f9>] scsi_io_completion+0xa9/0x3d0
> > [  233.590075]  [<78135c67>] trace_hardirqs_on+0x67/0xb0
> > [  233.595100]  [<78405125>] blk_done_softirq+0x45/0x80
> > [  233.600040]  [<78405153>] blk_done_softirq+0x73/0x80
> > [  233.604981]  [<7811d4c3>] __do_softirq+0x53/0xb0
> > [  233.609573]  [<7811d588>] do_softirq+0x68/0x70
> > [  233.613993]  [<78105351>] do_IRQ+0x51/0x90
> > [  233.618066]  [<78135c9c>] trace_hardirqs_on+0x9c/0xb0
> > [  233.623092]  [<7810f2d0>] pgd_dtor+0x0/0x50
> > [  233.627252]  [<7810388e>] common_interrupt+0x2e/0x40
> > [  233.632192]  [<7810f2d0>] pgd_dtor+0x0/0x50
> > [  233.636352]  [<7815f3be>] quicklist_trim+0x5e/0x90
> > [  233.641118]  [<7810f2cb>] check_pgt_cache+0x1b/0x20
> > [  233.645971]  [<78100c52>] cpu_idle+0x32/0x60
> > [  233.650217]  [<78a14b35>] start_kernel+0x265/0x300
> > [  233.654983]  [<78a14380>] unknown_bootoption+0x0/0x1e0
> > [  233.660097]  =======================
> > [  233.663649] Code: 00 00 00 8b 45 34 a8 02 0f 84 ed 00 00 00 8b bd 88 00 00 00 31 db 89 3c 24 8b 75 3c 89 f8 c7 44 24 10 00 00 00 00 eb 1b 8d 76 00 <8b> 50 10 8d 48 10 f6 c2 01 0f 85 be 02 00 00 89 44 24 10 83 c3 
> > [  233.682455] EIP: [<784e9480>] ata_qc_issue+0x90/0x380 SS:ESP 0068:78a13e14
> > [  233.689302] Kernel panic - not syncing: Fatal exception in interrupt
> > 
> > (gdb) list *0x784e9480
> > 0x784e9480 is in ata_qc_issue (include/linux/scatterlist.h:48).
> > 43       */
> > 44      static inline struct scatterlist *sg_next(struct scatterlist *sg)
> > 45      {
> > 46              sg++;
> > 47
> > 48              if (unlikely(sg_is_chain(sg)))
> > 49                      sg = sg_chain_ptr(sg);
> > 50
> > 51              return sg;
> > 52      }
> > (gdb)
> > 
> > so there's sg_next() involvement too. Below is the disassembly.
> 
> You must have a magic test box :-)
> 
> Will investigate... libata doesn't actually enable chaining, but since
> i386 supports it, it ends up using the chain helpers anyway.
> 
> There seems to be some automatic inlining involved here, it must be
> dying inside ata_sg_setup().

Also, can you send a dmesg from that system so I can see which libata
drivers are involved?

-- 
Jens Axboe


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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 17:29         ` Jens Axboe
  2007-10-17 17:34           ` Ingo Molnar
@ 2007-10-17 17:56           ` Linus Torvalds
  2007-10-17 18:02             ` Jens Axboe
  2007-10-17 18:02             ` Ingo Molnar
  2007-10-17 20:15           ` Luca Tettamanti
  2 siblings, 2 replies; 151+ messages in thread
From: Linus Torvalds @ 2007-10-17 17:56 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Ingo Molnar, linux-kernel, Andrew Morton



On Wed, 17 Oct 2007, Jens Axboe wrote:
> 
> OK, it is fine, as long as the sglist is cleared initially. And I don't
> think there's anyway around that, clearly I didn't think long enough
> before including the memset() removal from Tomo.

Ok, I think that one-liner fixes the real bug.

But I think the rest of your changes are simply bad.

The fix to block/ll_rw_block.c should likely be something like the 
appended instead:

 - remove the "memset()" you had added earlier. It's bogus. It cannot be 
   the right thing. If the sg list wasn't initialized correctly much 
   earlier, trying to initialize it late is pointless - it contains crap.

 - the old code was fine, but let's initialize "sg" to NULL to make it 
   clear that the initial value of sg is pointless, and only "next_sg" 
   matters (since sg had better be assigned from that).

Hmm?

		Linus

---
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 9e3f3cc..54d974e 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -1333,7 +1333,8 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
 	 * for each bio in rq
 	 */
 	bvprv = NULL;
-	sg = next_sg = &sglist[0];
+	sg = NULL;
+	next_sg = &sglist[0];
 	rq_for_each_segment(bvec, rq, iter) {
 		int nbytes = bvec->bv_len;
 
@@ -1352,7 +1353,6 @@ new_segment:
 			sg = next_sg;
 			next_sg = sg_next(sg);
 
-			memset(sg, 0, sizeof(*sg));
 			sg->page = bvec->bv_page;
 			sg->length = nbytes;
 			sg->offset = bvec->bv_offset;

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 17:55                 ` Jens Axboe
@ 2007-10-17 17:58                   ` Ingo Molnar
  0 siblings, 0 replies; 151+ messages in thread
From: Ingo Molnar @ 2007-10-17 17:58 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Linus Torvalds, linux-kernel, Jeff Garzik, Alan Cox

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


* Jens Axboe <jens.axboe@oracle.com> wrote:

> Also, can you send a dmesg from that system so I can see which libata 
> drivers are involved?

same system for which i sent the earlier bootlog - but here's the second 
crashlog too. Crash is reproducible - crashed twice in a row already. 
(NOTE: the attached log is from this second crash.)

	Ingo

[-- Attachment #2: crash2.log --]
[-- Type: text/plain, Size: 152967 bytes --]

[    0.000000] Linux version 2.6.23 (mingo@dione) (gcc version 4.2.2) #6 Wed Oct 17 19:36:57 CEST 2007
[    0.000000] BIOS-provided physical RAM map:
[    0.000000]  BIOS-e820: 0000000000000000 - 000000000009f800 (usable)
[    0.000000]  BIOS-e820: 000000000009f800 - 00000000000a0000 (reserved)
[    0.000000]  BIOS-e820: 00000000000f0000 - 0000000000100000 (reserved)
[    0.000000]  BIOS-e820: 0000000000100000 - 000000003fff0000 (usable)
[    0.000000]  BIOS-e820: 000000003fff0000 - 000000003fff3000 (ACPI NVS)
[    0.000000]  BIOS-e820: 000000003fff3000 - 0000000040000000 (ACPI data)
[    0.000000]  BIOS-e820: 00000000e0000000 - 00000000f0000000 (reserved)
[    0.000000]  BIOS-e820: 00000000fec00000 - 0000000100000000 (reserved)
[    0.000000] console [earlyser0] enabled
[    0.000000] using polling idle threads.
[    0.000000] using polling idle threads.
[    0.000000] ignoring highmem size on non-highmem kernel!
[    0.000000] 1023MB LOWMEM available.
[    0.000000] found SMP MP-table at 000f5680
[    0.000000] Entering add_active_range(0, 0, 262128) 0 entries of 256 used
[    0.000000] Zone PFN ranges:
[    0.000000]   DMA             0 ->     4096
[    0.000000]   Normal       4096 ->   262128
[    0.000000] Movable zone start PFN for each node
[    0.000000] early_node_map[1] active PFN ranges
[    0.000000]     0:        0 ->   262128
[    0.000000] On node 0 totalpages: 262128
[    0.000000]   DMA zone: 32 pages used for memmap
[    0.000000]   DMA zone: 0 pages reserved
[    0.000000]   DMA zone: 4064 pages, LIFO batch:0
[    0.000000]   Normal zone: 2015 pages used for memmap
[    0.000000]   Normal zone: 256017 pages, LIFO batch:31
[    0.000000]   Movable zone: 0 pages used for memmap
[    0.000000] DMI 2.3 present.
[    0.000000] Intel MultiProcessor Specification v1.4
[    0.000000]     Virtual Wire compatibility mode.
[    0.000000] OEM ID: OEM00000 Product ID: PROD00000000 APIC at: 0xFEE00000
[    0.000000] Processor #0 15:3 APIC version 17
[    0.000000] Processor #1 15:3 APIC version 17
[    0.000000] WARNING: NR_CPUS limit of 1 reached.  Processor ignored.
[    0.000000] I/O APIC #2 Version 17 at 0xFEC00000.
[    0.000000] Enabling APIC mode:  Flat.  Using 1 I/O APICs
[    0.000000] Processors: 1
[    0.000000] Allocating PCI resources starting at 50000000 (gap: 40000000:a0000000)
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 260081
[    0.000000] Kernel command line: root=/dev/sda1 console=tty 3 debug profile=0 initcall_debug selinux=0 enforcing=0 apic=verbose ignore_loglevel sysrq_always_enabled earlyprintk=serial,ttyS0,115200,keep idle=poll maxcpus=1 nosmp highres=0 lapic hpet=disable idle=poll highmem=512m
[    0.000000] kernel profiling enabled (shift: 0)
[    0.000000] debug: ignoring loglevel setting.
[    0.000000] debug: sysrq always enabled.
[    0.000000] mapped APIC to ffffb000 (fee00000)
[    0.000000] mapped IOAPIC to ffffa000 (fec00000)
[    0.000000] Enabling fast FPU save and restore... done.
[    0.000000] Enabling unmasked SIMD FPU exception support... done.
[    0.000000] Initializing CPU#0
[    0.000000] PID hash table entries: 4096 (order: 12, 16384 bytes)
[    0.000000] Detected 2160.236 MHz processor.
[   13.543809] spurious 8259A interrupt: IRQ7.
[   13.548674] Console: colour VGA+ 80x25
[   13.552245] console [tty0] enabled
[   13.852183] Lock dependency validator: Copyright (c) 2006 Red Hat, Inc., Ingo Molnar
[   13.859892] ... MAX_LOCKDEP_SUBCLASSES:    8
[   13.864139] ... MAX_LOCK_DEPTH:          30
[   13.868298] ... MAX_LOCKDEP_KEYS:        2048
[   13.872632] ... CLASSHASH_SIZE:           1024
[   13.877052] ... MAX_LOCKDEP_ENTRIES:     8192
[   13.881384] ... MAX_LOCKDEP_CHAINS:      16384
[   13.885804] ... CHAINHASH_SIZE:          8192
[   13.890137]  memory used by lock dependency info: 992 kB
[   13.895424]  per task-struct memory footprint: 1200 bytes
[   13.901086] Dentry cache hash table entries: 131072 (order: 7, 524288 bytes)
[   13.908333] Inode-cache hash table entries: 65536 (order: 6, 262144 bytes)
[   13.949067] Memory: 998396k/1048512k available (6599k kernel code, 49608k reserved, 2687k data, 372k init, 0k highmem)
[   13.959651] virtual kernel memory layout:
[   13.959652]     fixmap  : 0xfffb9000 - 0xfffff000   ( 280 kB)
[   13.959653]     vmalloc : 0xb8800000 - 0xfffb7000   (1143 MB)
[   13.959654]     lowmem  : 0x78000000 - 0xb7ff0000   (1023 MB)
[   13.959655]       .init : 0x78a14000 - 0x78a71000   ( 372 kB)
[   13.959656]       .data : 0x78771df2 - 0x78a11a74   (2687 kB)
[   13.959657]       .text : 0x78100000 - 0x78771df2   (6599 kB)
[   13.997953] Checking if this processor honours the WP bit even in supervisor mode... Ok.
[   14.089370] Calibrating delay using timer specific routine.. 4324.72 BogoMIPS (lpj=7204356)
[   14.097638] Security Framework initialized
[   14.101644] Capability LSM initialized
[   14.105376] Mount-cache hash table entries: 512
[   14.110252] CPU: After generic identify, caps: 178bfbff e3d3fbff 00000000 00000000 00000001 00000000 00000003 00000000
[   14.120778] CPU: L1 I Cache: 64K (64 bytes/line), D cache 64K (64 bytes/line)
[   14.127890] CPU: L2 Cache: 512K (64 bytes/line)
[   14.132396] CPU: After all inits, caps: 178bfbf7 e3d3fbff 00000000 00000410 00000001 00000000 00000003 00000000
[   14.142446] Compat vDSO mapped to ffffe000.
[   14.146611] CPU: AMD Athlon(tm) 64 X2 Dual Core Processor 3800+ stepping 02
[   14.153542] Checking 'hlt' instruction... OK.
[   14.170307] Freeing SMP alternatives: 0k freed
[   14.174750] enabled ExtINT on CPU#0
[   14.178166] ExtINT not setup in hardware but reported by MP table
[   14.184264] ENABLING IO-APIC IRQs
[   14.187469] init IO_APIC IRQs
[   14.190416]  IO-APIC (apicid-pin) 2-0 not connected.
[   14.195410]  IO-APIC (apicid-pin) 2-16, 2-17, 2-18, 2-19, 2-20, 2-21, 2-22, 2-23 not connected.
[   14.204147] ..TIMER: vector=0x31 apic1=0 pin1=2 apic2=0 pin2=0
[   14.242874] ..MP-BIOS bug: 8254 timer not connected to IO-APIC
[   14.248568] ...trying to set up timer (IRQ0) through the 8259A ... 
[   14.254634] ..... (found pin 0) ...works.
[   14.291700] number of MP IRQ sources: 17.
[   14.295690] number of IO-APIC #2 registers: 24.
[   14.300196] testing the IO APIC.......................
[   14.305311] IO APIC #2......
[   14.308168] .... register #00: 00000000
[   14.311982] .......    : physical APIC id: 00
[   14.316314] .......    : Delivery Type: 0
[   14.320301] .......    : LTS          : 0
[   14.324288] .... register #01: 00170011
[   14.328101] .......     : max redirection entries: 0017
[   14.333300] .......     : PRQ implemented: 0
[   14.337546] .......     : IO APIC version: 0011
[   14.342053] .... register #02: 00000000
[   14.345866] .......     : arbitration: 00
[   14.349853] .... IRQ redirection table:
[   14.353665]  NR Log Phy Mask Trig IRR Pol Stat Dest Deli Vect:   
[   14.359734]  00 001 01  0    0    0   0   0    1    1    31
[   14.365281]  01 001 01  0    0    0   0   0    1    1    39
[   14.370826]  02 000 00  1    0    0   0   0    0    0    00
[   14.376373]  03 001 01  1    1    0   1   0    1    1    41
[   14.381919]  04 001 01  0    0    0   0   0    1    1    49
[   14.387466]  05 001 01  1    1    0   1   0    1    1    51
[   14.393012]  06 001 01  0    0    0   0   0    1    1    59
[   14.398558]  07 001 01  1    0    0   0   0    1    1    61
[   14.404104]  08 001 01  0    0    0   0   0    1    1    69
[   14.409651]  09 001 01  0    0    0   0   0    1    1    71
[   14.415197]  0a 001 01  0    0    0   0   0    1    1    79
[   14.420744]  0b 001 01  1    1    0   1   0    1    1    81
[   14.426290]  0c 001 01  0    0    0   0   0    1    1    89
[   14.431836]  0d 001 01  0    0    0   0   0    1    1    91
[   14.437382]  0e 001 01  0    0    0   0   0    1    1    99
[   14.442929]  0f 001 01  0    0    0   0   0    1    1    A1
[   14.448476]  10 000 00  1    0    0   0   0    0    0    00
[   14.454022]  11 000 00  1    0    0   0   0    0    0    00
[   14.459568]  12 000 00  1    0    0   0   0    0    0    00
[   14.465114]  13 000 00  1    0    0   0   0    0    0    00
[   14.470660]  14 000 00  1    0    0   0   0    0    0    00
[   14.476207]  15 000 00  1    0    0   0   0    0    0    00
[   14.481753]  16 000 00  1    0    0   0   0    0    0    00
[   14.487300]  17 000 00  1    0    0   0   0    0    0    00
[   14.492844] IRQ to pin mappings:
[   14.496050] IRQ0 -> 0:0
[   14.498473] IRQ1 -> 0:1
[   14.500899] IRQ3 -> 0:3
[   14.503325] IRQ4 -> 0:4
[   14.505752] IRQ5 -> 0:5
[   14.508179] IRQ6 -> 0:6
[   14.510605] IRQ7 -> 0:7
[   14.513032] IRQ8 -> 0:8
[   14.515459] IRQ9 -> 0:9
[   14.517885] IRQ10 -> 0:10
[   14.520484] IRQ11 -> 0:11
[   14.523084] IRQ12 -> 0:12
[   14.525684] IRQ13 -> 0:13
[   14.528284] IRQ14 -> 0:14
[   14.530884] IRQ15 -> 0:15
[   14.533485] .................................... done.
[   14.538601] Using local APIC timer interrupts.
[   14.538602] calibrating APIC timer ...
[   14.652626] ... lapic delta = 1350030
[   14.656153] ... PM timer delta = 0
[   14.659533] ..... delta 1350030
[   14.662652] ..... mult: 57987127
[   14.665859] ..... calibration result: 720016
[   14.670106] ..... CPU clock speed is 2160.0877 MHz.
[   14.674958] ..... host bus clock speed is 216.0088 MHz.
[   14.680158] ... verify APIC timer
[   14.790104] ... jiffies delta = 30
[   14.793376] ... jiffies result ok
[   14.796813] Calling initcall 0x78a4ac70: init_cpufreq_transition_notifier_list+0x0/0x10()
[   14.804830] initcall 0x78a4ac70: init_cpufreq_transition_notifier_list+0x0/0x10() returned 0.
[   14.813322] initcall 0x78a4ac70 ran for 0 msecs: init_cpufreq_transition_notifier_list+0x0/0x10()
[   14.822163] Calling initcall 0x78a4d270: net_ns_init+0x0/0x180()
[   14.828141] net_namespace: 64 bytes
[   14.831639] initcall 0x78a4d270: net_ns_init+0x0/0x180() returned 0.
[   14.837934] initcall 0x78a4d270 ran for 3 msecs: net_ns_init+0x0/0x180()
[   14.844608] Calling initcall 0x78a19b40: cpufreq_tsc+0x0/0x10()
[   14.850500] initcall 0x78a19b40: cpufreq_tsc+0x0/0x10() returned 0.
[   14.856740] initcall 0x78a19b40 ran for 0 msecs: cpufreq_tsc+0x0/0x10()
[   14.863847] Calling initcall 0x78a1d9b0: reboot_init+0x0/0x10()
[   14.869741] initcall 0x78a1d9b0: reboot_init+0x0/0x10() returned 0.
[   14.875978] initcall 0x78a1d9b0 ran for 0 msecs: reboot_init+0x0/0x10()
[   14.882563] Calling initcall 0x78a232e0: print_banner+0x0/0x10()
[   14.888544] Booting paravirtualized kernel on bare hardware
[   14.894092] initcall 0x78a232e0: print_banner+0x0/0x10() returned 0.
[   14.900418] initcall 0x78a232e0 ran for 3 msecs: print_banner+0x0/0x10()
[   14.907090] Calling initcall 0x78a24840: sysctl_init+0x0/0x10()
[   14.912988] initcall 0x78a24840: sysctl_init+0x0/0x10() returned 0.
[   14.919221] initcall 0x78a24840 ran for 0 msecs: sysctl_init+0x0/0x10()
[   14.925807] Calling initcall 0x78a254b0: init_jiffies_clocksource+0x0/0x10()
[   14.932832] initcall 0x78a254b0: init_jiffies_clocksource+0x0/0x10() returned 0.
[   14.940195] initcall 0x78a254b0 ran for 0 msecs: init_jiffies_clocksource+0x0/0x10()
[   14.947908] Calling initcall 0x78a25980: ksysfs_init+0x0/0x50()
[   14.953803] initcall 0x78a25980: ksysfs_init+0x0/0x50() returned 0.
[   14.960041] initcall 0x78a25980 ran for 0 msecs: ksysfs_init+0x0/0x50()
[   14.966625] Calling initcall 0x78a27aa0: filelock_init+0x0/0x30()
[   14.972692] initcall 0x78a27aa0: filelock_init+0x0/0x30() returned 0.
[   14.979104] initcall 0x78a27aa0 ran for 0 msecs: filelock_init+0x0/0x30()
[   14.985863] Calling initcall 0x78a28480: init_misc_binfmt+0x0/0x40()
[   14.992197] initcall 0x78a28480: init_misc_binfmt+0x0/0x40() returned 0.
[   14.998863] initcall 0x78a28480 ran for 0 msecs: init_misc_binfmt+0x0/0x40()
[   15.005882] Calling initcall 0x78a284c0: init_script_binfmt+0x0/0x10()
[   15.012383] initcall 0x78a284c0: init_script_binfmt+0x0/0x10() returned 0.
[   15.019229] initcall 0x78a284c0 ran for 0 msecs: init_script_binfmt+0x0/0x10()
[   15.026422] Calling initcall 0x78a284d0: init_elf_binfmt+0x0/0x10()
[   15.032661] initcall 0x78a284d0: init_elf_binfmt+0x0/0x10() returned 0.
[   15.039247] initcall 0x78a284d0 ran for 0 msecs: init_elf_binfmt+0x0/0x10()
[   15.046180] Calling initcall 0x78a2a750: debugfs_init+0x0/0x40()
[   15.052163] initcall 0x78a2a750: debugfs_init+0x0/0x40() returned 0.
[   15.058486] initcall 0x78a2a750 ran for 0 msecs: debugfs_init+0x0/0x40()
[   15.065161] Calling initcall 0x78a2afc0: securityfs_init+0x0/0x40()
[   15.071401] initcall 0x78a2afc0: securityfs_init+0x0/0x40() returned 0.
[   15.077985] initcall 0x78a2afc0 ran for 0 msecs: securityfs_init+0x0/0x40()
[   15.084920] Calling initcall 0x78a2ba10: random32_init+0x0/0x20()
[   15.090984] initcall 0x78a2ba10: random32_init+0x0/0x20() returned 0.
[   15.097399] initcall 0x78a2ba10 ran for 0 msecs: random32_init+0x0/0x20()
[   15.104158] Calling initcall 0x78a4ac80: cpufreq_core_init+0x0/0x30()
[   15.110569] initcall 0x78a4ac80: cpufreq_core_init+0x0/0x30() returned 0.
[   15.117331] initcall 0x78a4ac80 ran for 0 msecs: cpufreq_core_init+0x0/0x30()
[   15.124437] Calling initcall 0x78a4d120: sock_init+0x0/0x60()
[   15.130188] initcall 0x78a4d120: sock_init+0x0/0x60() returned 0.
[   15.136222] initcall 0x78a4d120 ran for 0 msecs: sock_init+0x0/0x60()
[   15.142634] Calling initcall 0x78a4dc60: netpoll_init+0x0/0x40()
[   15.148614] initcall 0x78a4dc60: netpoll_init+0x0/0x40() returned 0.
[   15.154940] initcall 0x78a4dc60 ran for 0 msecs: netpoll_init+0x0/0x40()
[   15.161614] Calling initcall 0x78a4e370: netlink_proto_init+0x0/0x140()
[   15.168224] NET: Registered protocol family 16
[   15.172638] initcall 0x78a4e370: netlink_proto_init+0x0/0x140() returned 0.
[   15.179551] initcall 0x78a4e370 ran for 3 msecs: netlink_proto_init+0x0/0x140()
[   15.186832] Calling initcall 0x78a2bb30: pcibus_class_init+0x0/0x10()
[   15.193259] initcall 0x78a2bb30: pcibus_class_init+0x0/0x10() returned 0.
[   15.200005] initcall 0x78a2bb30 ran for 0 msecs: pcibus_class_init+0x0/0x10()
[   15.207111] Calling initcall 0x78a2d090: pci_driver_init+0x0/0x10()
[   15.213372] initcall 0x78a2d090: pci_driver_init+0x0/0x10() returned 0.
[   15.219936] initcall 0x78a2d090 ran for 0 msecs: pci_driver_init+0x0/0x10()
[   15.226870] Calling initcall 0x78a2d1d0: lcd_class_init+0x0/0x50()
[   15.233030] initcall 0x78a2d1d0: lcd_class_init+0x0/0x50() returned 0.
[   15.239522] initcall 0x78a2d1d0 ran for 0 msecs: lcd_class_init+0x0/0x50()
[   15.246367] Calling initcall 0x78a2d220: backlight_class_init+0x0/0x50()
[   15.253049] initcall 0x78a2d220: backlight_class_init+0x0/0x50() returned 0.
[   15.260062] initcall 0x78a2d220 ran for 0 msecs: backlight_class_init+0x0/0x50()
[   15.267428] Calling initcall 0x78a2d400: tty_class_init+0x0/0x20()
[   15.273588] initcall 0x78a2d400: tty_class_init+0x0/0x20() returned 0.
[   15.280080] initcall 0x78a2d400 ran for 0 msecs: tty_class_init+0x0/0x20()
[   15.286926] Calling initcall 0x78a2de20: vtconsole_class_init+0x0/0xd0()
[   15.293624] initcall 0x78a2de20: vtconsole_class_init+0x0/0xd0() returned 0.
[   15.300619] initcall 0x78a2de20 ran for 0 msecs: vtconsole_class_init+0x0/0xd0()
[   15.307985] Calling initcall 0x78a199b0: init_pit_clocksource+0x0/0x70()
[   15.314668] initcall 0x78a199b0: init_pit_clocksource+0x0/0x70() returned 0.
[   15.321678] initcall 0x78a199b0 ran for 0 msecs: init_pit_clocksource+0x0/0x70()
[   15.329046] Calling initcall 0x78a4b930: pci_access_init+0x0/0x30()
[   15.339864] PCI: PCI BIOS revision 3.00 entry at 0xf21d0, last bus=5
[   15.346084] initcall 0x78a4b930: pci_access_init+0x0/0x30() returned 0.
[   15.352667] initcall 0x78a4b930 ran for 6 msecs: pci_access_init+0x0/0x30()
[   15.359602] Calling initcall 0x78a19010: request_standard_resources+0x0/0x3a0()
[   15.366879] Setting up standard PCI resources
[   15.374039] initcall 0x78a19010: request_standard_resources+0x0/0x3a0() returned 0.
[   15.381536] initcall 0x78a19010 ran for 6 msecs: request_standard_resources+0x0/0x3a0()
[   15.389510] Calling initcall 0x78a198e0: topology_init+0x0/0x10()
[   15.395582] initcall 0x78a198e0: topology_init+0x0/0x10() returned 0.
[   15.401988] initcall 0x78a198e0 ran for 0 msecs: topology_init+0x0/0x10()
[   15.408749] Calling initcall 0x78a1d9f0: mca_init+0x0/0x330()
[   15.414476] initcall 0x78a1d9f0: mca_init+0x0/0x330() returned -19.
[   15.420705] initcall 0x78a1d9f0 ran for 0 msecs: mca_init+0x0/0x330()
[   15.427119] Calling initcall 0x78a24de0: param_sysfs_init+0x0/0x180()
[   15.434892] initcall 0x78a24de0: param_sysfs_init+0x0/0x180() returned 0.
[   15.441522] initcall 0x78a24de0 ran for 0 msecs: param_sysfs_init+0x0/0x180()
[   15.448630] Calling initcall 0x78a27820: readahead_init+0x0/0x10()
[   15.454783] initcall 0x78a27820: readahead_init+0x0/0x10() returned 0.
[   15.461279] initcall 0x78a27820 ran for 0 msecs: readahead_init+0x0/0x10()
[   15.468129] Calling initcall 0x78a28190: init_bio+0x0/0x100()
[   15.473871] initcall 0x78a28190: init_bio+0x0/0x100() returned 0.
[   15.479911] initcall 0x78a28190 ran for 0 msecs: init_bio+0x0/0x100()
[   15.486326] Calling initcall 0x78a2b760: genhd_device_init+0x0/0x60()
[   15.492769] initcall 0x78a2b760: genhd_device_init+0x0/0x60() returned 0.
[   15.499496] initcall 0x78a2b760 ran for 0 msecs: genhd_device_init+0x0/0x60()
[   15.506606] Calling initcall 0x78a2d8e0: misc_init+0x0/0x80()
[   15.512338] initcall 0x78a2d8e0: misc_init+0x0/0x80() returned 0.
[   15.518391] initcall 0x78a2d8e0 ran for 0 msecs: misc_init+0x0/0x80()
[   15.524805] Calling initcall 0x78a392a0: init_dvbdev+0x0/0xd0()
[   15.530701] initcall 0x78a392a0: init_dvbdev+0x0/0xd0() returned 0.
[   15.536936] initcall 0x78a392a0 ran for 0 msecs: init_dvbdev+0x0/0xd0()
[   15.543522] Calling initcall 0x78a39370: init_scsi+0x0/0xa0()
[   15.549391] SCSI subsystem initialized
[   15.553015] initcall 0x78a39370: init_scsi+0x0/0xa0() returned 0.
[   15.559078] initcall 0x78a39370 ran for 3 msecs: init_scsi+0x0/0xa0()
[   15.565491] Calling initcall 0x78a399c0: ata_init+0x0/0x70()
[   15.571166] libata version 3.00 loaded.
[   15.574940] initcall 0x78a399c0: ata_init+0x0/0x70() returned 0.
[   15.580917] initcall 0x78a399c0 ran for 3 msecs: ata_init+0x0/0x70()
[   15.587242] Calling initcall 0x78a3c920: spi_init+0x0/0x70()
[   15.592889] initcall 0x78a3c920: spi_init+0x0/0x70() returned 0.
[   15.598856] initcall 0x78a3c920 ran for 0 msecs: spi_init+0x0/0x70()
[   15.605182] Calling initcall 0x78a3d350: usb_init+0x0/0xd0()
[   15.610852] usbcore: registered new interface driver usbfs
[   15.616288] usbcore: registered new interface driver hub
[   15.621593] usbcore: registered new device driver usb
[   15.626590] initcall 0x78a3d350: usb_init+0x0/0xd0() returned 0.
[   15.632564] initcall 0x78a3d350 ran for 9 msecs: usb_init+0x0/0xd0()
[   15.638893] Calling initcall 0x78a3f3e0: serio_init+0x0/0xb0()
[   15.644737] initcall 0x78a3f3e0: serio_init+0x0/0xb0() returned 0.
[   15.650852] initcall 0x78a3f3e0 ran for 0 msecs: serio_init+0x0/0xb0()
[   15.657351] Calling initcall 0x78a3ff00: gameport_init+0x0/0xb0()
[   15.663470] initcall 0x78a3ff00: gameport_init+0x0/0xb0() returned 0.
[   15.669829] initcall 0x78a3ff00 ran for 0 msecs: gameport_init+0x0/0xb0()
[   15.676593] Calling initcall 0x78a40770: input_init+0x0/0x100()
[   15.682493] initcall 0x78a40770: input_init+0x0/0x100() returned 0.
[   15.688723] initcall 0x78a40770 ran for 0 msecs: input_init+0x0/0x100()
[   15.695309] Calling initcall 0x78a40ca0: i2c_init+0x0/0x20()
[   15.700956] initcall 0x78a40ca0: i2c_init+0x0/0x20() returned 0.
[   15.706921] initcall 0x78a40ca0 ran for 0 msecs: i2c_init+0x0/0x20()
[   15.713248] Calling initcall 0x78a42fe0: hwmon_init+0x0/0x40()
[   15.719057] initcall 0x78a42fe0: hwmon_init+0x0/0x40() returned 0.
[   15.725208] initcall 0x78a42fe0 ran for 0 msecs: hwmon_init+0x0/0x40()
[   15.731709] Calling initcall 0x78a4ad50: leds_init+0x0/0x20()
[   15.737433] initcall 0x78a4ad50: leds_init+0x0/0x20() returned 0.
[   15.743493] initcall 0x78a4ad50 ran for 0 msecs: leds_init+0x0/0x20()
[   15.749906] Calling initcall 0x78a4b570: ssb_modinit+0x0/0x80()
[   15.755834] initcall 0x78a4b570: ssb_modinit+0x0/0x80() returned 0.
[   15.762039] initcall 0x78a4b570 ran for 0 msecs: ssb_modinit+0x0/0x80()
[   15.768624] Calling initcall 0x78a4c190: pci_legacy_init+0x0/0x100()
[   15.774949] PCI: Probing PCI hardware
[   15.778606] PCI: Probing PCI hardware (bus 00)
[   15.785980] PCI: Transparent bridge - 0000:00:09.0
[   15.792938] initcall 0x78a4c190: pci_legacy_init+0x0/0x100() returned 0.
[   15.799474] initcall 0x78a4c190 ran for 12 msecs: pci_legacy_init+0x0/0x100()
[   15.806584] Calling initcall 0x78a4c7b0: pcibios_irq_init+0x0/0x510()
[   15.813253] PCI: Using IRQ router default [10de/005e] at 0000:00:00.0
[   15.819594] PCI->APIC IRQ transform: 0000:00:04.0[A] -> IRQ 3
[   15.825290] PCI->APIC IRQ transform: 0000:00:0a.0[A] -> IRQ 11
[   15.831120] PCI->APIC IRQ transform: 0000:05:07.0[A] -> IRQ 11
[   15.836894] PCI->APIC IRQ transform: 0000:01:00.0[A] -> IRQ 5
[   15.842614] initcall 0x78a4c7b0: pcibios_irq_init+0x0/0x510() returned 0.
[   15.849365] initcall 0x78a4c7b0 ran for 19 msecs: pcibios_irq_init+0x0/0x510()
[   15.856561] Calling initcall 0x78a4cd20: pcibios_init+0x0/0xa0()
[   15.916136] initcall 0x78a4cd20: pcibios_init+0x0/0xa0() returned 0.
[   15.922327] initcall 0x78a4cd20 ran for 50 msecs: pcibios_init+0x0/0xa0()
[   15.929087] Calling initcall 0x78a4d1e0: proto_init+0x0/0x30()
[   15.934892] initcall 0x78a4d1e0: proto_init+0x0/0x30() returned 0.
[   15.941045] initcall 0x78a4d1e0 ran for 0 msecs: proto_init+0x0/0x30()
[   15.947544] Calling initcall 0x78a4d5f0: net_dev_init+0x0/0x110()
[   15.953643] initcall 0x78a4d5f0: net_dev_init+0x0/0x110() returned 0.
[   15.960024] initcall 0x78a4d5f0 ran for 0 msecs: net_dev_init+0x0/0x110()
[   15.966786] Calling initcall 0x78a4d750: neigh_init+0x0/0x80()
[   15.972589] initcall 0x78a4d750: neigh_init+0x0/0x80() returned 0.
[   15.978743] initcall 0x78a4d750 ran for 0 msecs: neigh_init+0x0/0x80()
[   15.985243] Calling initcall 0x78a4e060: pktsched_init+0x0/0xd0()
[   15.991319] initcall 0x78a4e060: pktsched_init+0x0/0xd0() returned 0.
[   15.998244] initcall 0x78a4e060 ran for 0 msecs: pktsched_init+0x0/0xd0()
[   16.005004] Calling initcall 0x78a4e140: tc_filter_init+0x0/0x60()
[   16.011153] initcall 0x78a4e140: tc_filter_init+0x0/0x60() returned 0.
[   16.017653] initcall 0x78a4e140 ran for 0 msecs: tc_filter_init+0x0/0x60()
[   16.024500] Calling initcall 0x78a4e1a0: tc_action_init+0x0/0x60()
[   16.030651] initcall 0x78a4e1a0: tc_action_init+0x0/0x60() returned 0.
[   16.037153] initcall 0x78a4e1a0 ran for 0 msecs: tc_action_init+0x0/0x60()
[   16.043999] Calling initcall 0x78a4e4b0: genl_init+0x0/0xd0()
[   16.056537] initcall 0x78a4e4b0: genl_init+0x0/0xd0() returned 0.
[   16.062474] initcall 0x78a4e4b0 ran for 9 msecs: genl_init+0x0/0xd0()
[   16.068889] Calling initcall 0x78a50f70: cipso_v4_init+0x0/0x80()
[   16.074966] initcall 0x78a50f70: cipso_v4_init+0x0/0x80() returned 0.
[   16.081368] initcall 0x78a50f70 ran for 0 msecs: cipso_v4_init+0x0/0x80()
[   16.088129] Calling initcall 0x78a52490: wanrouter_init+0x0/0x60()
[   16.094279] Sangoma WANPIPE Router v1.1 (c) 1995-2000 Sangoma Technologies Inc.
[   16.101566] initcall 0x78a52490: wanrouter_init+0x0/0x60() returned 0.
[   16.108059] initcall 0x78a52490 ran for 3 msecs: wanrouter_init+0x0/0x60()
[   16.114908] Calling initcall 0x78a529f0: irda_init+0x0/0x90()
[   16.120653] NET: Registered protocol family 23
[   16.125070] initcall 0x78a529f0: irda_init+0x0/0x90() returned 0.
[   16.131110] initcall 0x78a529f0 ran for 3 msecs: irda_init+0x0/0x90()
[   16.137524] Calling initcall 0x78a53910: wireless_nlevent_init+0x0/0x40()
[   16.144282] initcall 0x78a53910: wireless_nlevent_init+0x0/0x40() returned 0.
[   16.151391] initcall 0x78a53910 ran for 0 msecs: wireless_nlevent_init+0x0/0x40()
[   16.158845] Calling initcall 0x78730680: cfg80211_init+0x0/0x50()
[   16.165022] initcall 0x78730680: cfg80211_init+0x0/0x50() returned 0.
[   16.171322] initcall 0x78730680 ran for 0 msecs: cfg80211_init+0x0/0x50()
[   16.178084] Calling initcall 0x78a53950: ieee80211_init+0x0/0x40()
[   16.184234] initcall 0x78a53950: ieee80211_init+0x0/0x40() returned 0.
[   16.190733] initcall 0x78a53950 ran for 0 msecs: ieee80211_init+0x0/0x40()
[   16.197580] Calling initcall 0x78a53990: rate_control_simple_init+0x0/0x10()
[   16.204607] initcall 0x78a53990: rate_control_simple_init+0x0/0x10() returned 0.
[   16.211967] initcall 0x78a53990 ran for 0 msecs: rate_control_simple_init+0x0/0x10()
[   16.219681] Calling initcall 0x78a53b50: netlbl_init+0x0/0x80()
[   16.225570] NetLabel: Initializing
[   16.228954] NetLabel:  domain hash size = 128
[   16.233286] NetLabel:  protocols = UNLABELED CIPSOv4
[   16.238276] NetLabel:  unlabeled traffic allowed by default
[   16.243773] initcall 0x78a53b50: netlbl_init+0x0/0x80() returned 0.
[   16.250010] initcall 0x78a53b50 ran for 12 msecs: netlbl_init+0x0/0x80()
[   16.256683] Calling initcall 0x78a253c0: clocksource_done_booting+0x0/0x10()
[   16.263701] initcall 0x78a253c0<6>Time: tsc clocksource has been installed.
[   16.270645] : clocksource_done_booting+0x0/0x10() returned 0.
[   16.276353] initcall 0x78a253c0 ran for 0 msecs: clocksource_done_booting+0x0/0x10()
[   16.284071] Calling initcall 0x78a27a20: init_pipe_fs+0x0/0x50()
[   16.290076] initcall 0x78a27a20: init_pipe_fs+0x0/0x50() returned 0.
[   16.296372] initcall 0x78a27a20 ran for 0 msecs: init_pipe_fs+0x0/0x50()
[   16.303048] Calling initcall 0x78a28300: eventpoll_init+0x0/0x90()
[   16.309199] initcall 0x78a28300: eventpoll_init+0x0/0x90() returned 0.
[   16.315700] initcall 0x78a28300 ran for 0 msecs: eventpoll_init+0x0/0x90()
[   16.322546] Calling initcall 0x78a28390: anon_inode_init+0x0/0xf0()
[   16.328818] initcall 0x78a28390: anon_inode_init+0x0/0xf0() returned 0.
[   16.335372] initcall 0x78a28390 ran for 0 msecs: anon_inode_init+0x0/0xf0()
[   16.342305] Calling initcall 0x78a2d2e0: chr_dev_init+0x0/0xe0()
[   16.348383] initcall 0x78a2d2e0: chr_dev_init+0x0/0xe0() returned 0.
[   16.354611] initcall 0x78a2d2e0 ran for 0 msecs: chr_dev_init+0x0/0xe0()
[   16.361285] Calling initcall 0x78a311a0: firmware_class_init+0x0/0x70()
[   16.367877] initcall 0x78a311a0: firmware_class_init+0x0/0x70() returned 0.
[   16.374803] initcall 0x78a311a0 ran for 0 msecs: firmware_class_init+0x0/0x70()
[   16.382084] Calling initcall 0x78a33aa0: loopback_init+0x0/0x10()
[   16.388288] initcall 0x78a33aa0: loopback_init+0x0/0x10() returned 0.
[   16.394570] initcall 0x78a33aa0 ran for 0 msecs: loopback_init+0x0/0x10()
[   16.401331] Calling initcall 0x78a4ad30: cpufreq_gov_userspace_init+0x0/0x10()
[   16.408527] initcall 0x78a4ad30: cpufreq_gov_userspace_init+0x0/0x10() returned 0.
[   16.416060] initcall 0x78a4ad30 ran for 0 msecs: cpufreq_gov_userspace_init+0x0/0x10()
[   16.423950] Calling initcall 0x78a4b600: pcibios_assign_resources+0x0/0xa0()
[   16.431006] PCI: Bridge: 0000:00:09.0
[   16.434613]   IO window: c000-cfff
[   16.438001]   MEM window: da000000-da0fffff
[   16.442157]   PREFETCH window: disabled.
[   16.446061] PCI: Bridge: 0000:00:0b.0
[   16.449688]   IO window: disabled.
[   16.453079]   MEM window: disabled.
[   16.456542]   PREFETCH window: disabled.
[   16.460447] PCI: Bridge: 0000:00:0c.0
[   16.464074]   IO window: disabled.
[   16.467465]   MEM window: disabled.
[   16.470927]   PREFETCH window: disabled.
[   16.474832] PCI: Bridge: 0000:00:0d.0
[   16.478460]   IO window: disabled.
[   16.481851]   MEM window: disabled.
[   16.485313]   PREFETCH window: disabled.
[   16.489221] PCI: Bridge: 0000:00:0e.0
[   16.492850]   IO window: b000-bfff
[   16.496237]   MEM window: d8000000-d9ffffff
[   16.500393]   PREFETCH window: d0000000-d7ffffff
[   16.505012] PCI: Setting latency timer of device 0000:00:09.0 to 64
[   16.511264] PCI: Setting latency timer of device 0000:00:0b.0 to 64
[   16.517503] PCI: Setting latency timer of device 0000:00:0c.0 to 64
[   16.523743] PCI: Setting latency timer of device 0000:00:0d.0 to 64
[   16.529983] PCI: Setting latency timer of device 0000:00:0e.0 to 64
[   16.536181] initcall 0x78a4b600: pcibios_assign_resources+0x0/0xa0() returned 0.
[   16.543540] initcall 0x78a4b600 ran for 100 msecs: pcibios_assign_resources+0x0/0xa0()
[   16.551429] Calling initcall 0x78a4eef0: inet_init+0x0/0x300()
[   16.557236] NET: Registered protocol family 2
[   16.589825] IP route cache hash table entries: 32768 (order: 5, 131072 bytes)
[   16.597088] TCP established hash table entries: 131072 (order: 10, 4194304 bytes)
[   16.613117] TCP bind hash table entries: 65536 (order: 9, 2097152 bytes)
[   16.623764] TCP: Hash tables configured (established 131072 bind 65536)
[   16.630268] TCP reno registered
[   16.643146] initcall 0x78a4eef0: inet_init+0x0/0x300() returned 0.
[   16.649170] initcall 0x78a4eef0 ran for 81 msecs: inet_init+0x0/0x300()
[   16.655758] Calling initcall 0x78a17600: populate_rootfs+0x0/0xa0()
[   16.662333] initcall 0x78a17600: populate_rootfs+0x0/0xa0() returned 0.
[   16.668792] initcall 0x78a17600 ran for 0 msecs: populate_rootfs+0x0/0xa0()
[   16.675725] Calling initcall 0x78a186b0: i8259A_init_sysfs+0x0/0x20()
[   16.682147] initcall 0x78a186b0: i8259A_init_sysfs+0x0/0x20() returned 0.
[   16.688898] initcall 0x78a186b0 ran for 0 msecs: i8259A_init_sysfs+0x0/0x20()
[   16.696004] Calling initcall 0x78a18830: sbf_init+0x0/0xd0()
[   16.701634] initcall 0x78a18830: sbf_init+0x0/0xd0() returned 0.
[   16.707616] initcall 0x78a18830 ran for 0 msecs: sbf_init+0x0/0xd0()
[   16.713942] Calling initcall 0x78a198c0: i8237A_init_sysfs+0x0/0x20()
[   16.720359] initcall 0x78a198c0: i8237A_init_sysfs+0x0/0x20() returned 0.
[   16.727115] initcall 0x78a198c0 ran for 0 msecs: i8237A_init_sysfs+0x0/0x20()
[   16.734221] Calling initcall 0x78a1cba0: cache_sysfs_init+0x0/0x200()
[   16.740678] initcall 0x78a1cba0: cache_sysfs_init+0x0/0x200() returned 0.
[   16.747393] initcall 0x78a1cba0 ran for 0 msecs: cache_sysfs_init+0x0/0x200()
[   16.754501] Calling initcall 0x78a1d450: longrun_init+0x0/0x30()
[   16.760477] initcall 0x78a1d450: longrun_init+0x0/0x30() returned -19.
[   16.766979] initcall 0x78a1d450 ran for 0 msecs: longrun_init+0x0/0x30()
[   16.773651] Calling initcall 0x78a1dd20: microcode_init+0x0/0xa0()
[   16.779901] microcode: CPU0 not a capable Intel processor
[   16.785182] IA-32 Microcode Update Driver: v1.14a <tigran@aivazian.fsnet.co.uk>
[   16.792460] initcall 0x78a1dd20: microcode_init+0x0/0xa0() returned 0.
[   16.798957] initcall 0x78a1dd20 ran for 12 msecs: microcode_init+0x0/0xa0()
[   16.805891] Calling initcall 0x78a20290: ioapic_init_sysfs+0x0/0xe0()
[   16.812311] initcall 0x78a20290: ioapic_init_sysfs+0x0/0xe0() returned 0.
[   16.819061] initcall 0x78a20290 ran for 0 msecs: ioapic_init_sysfs+0x0/0xe0()
[   16.826169] Calling initcall 0x78a22fe0: init_vmi_clocksource+0x0/0x130()
[   16.832926] initcall 0x78a22fe0: init_vmi_clocksource+0x0/0x130() returned 0.
[   16.840034] initcall 0x78a22fe0 ran for 0 msecs: init_vmi_clocksource+0x0/0x130()
[   16.847487] Calling initcall 0x78a23310: add_pcspkr+0x0/0x60()
[   16.853304] initcall 0x78a23310: add_pcspkr+0x0/0x60() returned 0.
[   16.859444] initcall 0x78a23310 ran for 0 msecs: add_pcspkr+0x0/0x60()
[   16.865946] Calling initcall 0x78a23bc0: init+0x0/0x10()
[   16.871243] initcall 0x78a23bc0: init+0x0/0x10() returned 0.
[   16.876865] initcall 0x78a23bc0 ran for 0 msecs: init+0x0/0x10()
[   16.882843] Calling initcall 0x78a23bf0: init_sched_debug_procfs+0x0/0x30()
[   16.889779] initcall 0x78a23bf0: init_sched_debug_procfs+0x0/0x30() returned 0.
[   16.897058] initcall 0x78a23bf0 ran for 0 msecs: init_sched_debug_procfs+0x0/0x30()
[   16.904685] Calling initcall 0x78a24590: create_proc_profile+0x0/0x50()
[   16.911273] initcall 0x78a24590: create_proc_profile+0x0/0x50() returned 0.
[   16.918203] initcall 0x78a24590 ran for 0 msecs: create_proc_profile+0x0/0x50()
[   16.925485] Calling initcall 0x78a24720: ioresources_init+0x0/0x40()
[   16.931809] initcall 0x78a24720: ioresources_init+0x0/0x40() returned 0.
[   16.938482] initcall 0x78a24720 ran for 0 msecs: ioresources_init+0x0/0x40()
[   16.945503] Calling initcall 0x78a249e0: uid_cache_init+0x0/0x80()
[   16.951657] initcall 0x78a249e0: uid_cache_init+0x0/0x80() returned 0.
[   16.958153] initcall 0x78a249e0 ran for 0 msecs: uid_cache_init+0x0/0x80()
[   16.965002] Calling initcall 0x78a24f60: init_posix_timers+0x0/0x90()
[   16.971412] initcall 0x78a24f60: init_posix_timers+0x0/0x90() returned 0.
[   16.978173] initcall 0x78a24f60 ran for 0 msecs: <4>Clocksource tsc unstable (delta = 63281543 ns)
[   16.987108] init_posix_timers+0x0/0x90()
[   16.991011] Time: pit clocksource has been installed.
[   16.996032] Calling initcall 0x78a24ff0: init_posix_cpu_timers+0x0/0xa0()
[   17.002790] initcall 0x78a24ff0: init_posix_cpu_timers+0x0/0xa0() returned 0.
[   17.009894] initcall 0x78a24ff0 ran for 0 msecs: init_posix_cpu_timers+0x0/0xa0()
[   17.017348] Calling initcall 0x78a251b0: latency_init+0x0/0x20()
[   17.023334] initcall 0x78a251b0: latency_init+0x0/0x20() returned 0.
[   17.029647] initcall 0x78a251b0 ran for 0 msecs: latency_init+0x0/0x20()
[   17.036322] Calling initcall 0x78a251d0: nsproxy_cache_init+0x0/0x40()
[   17.043352] initcall 0x78a251d0: nsproxy_cache_init+0x0/0x40() returned 0.
[   17.050192] initcall 0x78a251d0 ran for 0 msecs: nsproxy_cache_init+0x0/0x40()
[   17.057384] Calling initcall 0x78a25210: timekeeping_init_device+0x0/0x20()
[   17.064324] initcall 0x78a25210: timekeeping_init_device+0x0/0x20() returned 0.
[   17.071594] initcall 0x78a25210 ran for 0 msecs: timekeeping_init_device+0x0/0x20()
[   17.079225] Calling initcall 0x78a253d0: init_clocksource_sysfs+0x0/0x40()
[   17.086081] initcall 0x78a253d0: init_clocksource_sysfs+0x0/0x40() returned 0.
[   17.093262] initcall 0x78a253d0 ran for 0 msecs: init_clocksource_sysfs+0x0/0x40()
[   17.100802] Calling initcall 0x78a254c0: init_timer_list_procfs+0x0/0x30()
[   17.107650] initcall 0x78a254c0: init_timer_list_procfs+0x0/0x30() returned 0.
[   17.114837] initcall 0x78a254c0 ran for 0 msecs: init_timer_list_procfs+0x0/0x30()
[   17.122383] Calling initcall 0x78a25500: init_tstats_procfs+0x0/0x30()
[   17.128884] initcall 0x78a25500: init_tstats_procfs+0x0/0x30() returned 0.
[   17.135720] initcall 0x78a25500 ran for 0 msecs: init_tstats_procfs+0x0/0x30()
[   17.142916] Calling initcall 0x78a25620: lockdep_proc_init+0x0/0x40()
[   17.149337] initcall 0x78a25620: lockdep_proc_init+0x0/0x40() returned 0.
[   17.156085] initcall 0x78a25620 ran for 0 msecs: lockdep_proc_init+0x0/0x40()
[   17.163200] Calling initcall 0x78a25660: init+0x0/0xf0()
[   17.168534] initcall 0x78a25660: init+0x0/0xf0() returned 0.
[   17.174117] initcall 0x78a25660 ran for 0 msecs: init+0x0/0xf0()
[   17.180096] Calling initcall 0x7813ac70: init_rttest+0x0/0x120()
[   17.186369] Initializing RT-Tester: OK
[   17.190004] initcall 0x7813ac70: init_rttest+0x0/0x120() returned 0.
[   17.196314] initcall 0x7813ac70 ran for 5 msecs: init_rttest+0x0/0x120()
[   17.202989] Calling initcall 0x78a25750: proc_dma_init+0x0/0x20()
[   17.209061] initcall 0x78a25750: proc_dma_init+0x0/0x20() returned 0.
[   17.215469] initcall 0x78a25750 ran for 0 msecs: proc_dma_init+0x0/0x20()
[   17.222228] Calling initcall 0x78a25770: kallsyms_init+0x0/0x20()
[   17.228301] initcall 0x78a25770: kallsyms_init+0x0/0x20() returned 0.
[   17.234707] initcall 0x78a25770 ran for 0 msecs: kallsyms_init+0x0/0x20()
[   17.241472] Calling initcall 0x78a25800: audit_init+0x0/0x100()
[   17.247362] audit: initializing netlink socket (disabled)
[   17.252768] audit(1192645292.849:1): initialized
[   17.257340] initcall 0x78a25800: audit_init+0x0/0x100() returned 0.
[   17.263569] initcall 0x78a25800 ran for 6 msecs: audit_init+0x0/0x100()
[   17.270154] Calling initcall 0x78a25a30: utsname_sysctl_init+0x0/0x10()
[   17.276745] initcall 0x78a25a30: utsname_sysctl_init+0x0/0x10() returned 0.
[   17.283673] initcall 0x78a25a30 ran for 0 msecs: utsname_sysctl_init+0x0/0x10()
[   17.290953] Calling initcall 0x78a27250: init_per_zone_pages_min+0x0/0x50()
[   17.297936] initcall 0x78a27250: init_per_zone_pages_min+0x0/0x50() returned 0.
[   17.305163] initcall 0x78a27250 ran for 0 msecs: init_per_zone_pages_min+0x0/0x50()
[   17.312794] Calling initcall 0x78a27810: pdflush_init+0x0/0x10()
[   17.318831] initcall 0x78a27810: pdflush_init+0x0/0x10() returned 0.
[   17.325095] initcall 0x78a27810 ran for 0 msecs: pdflush_init+0x0/0x10()
[   17.331773] Calling initcall 0x78a27860: kswapd_init+0x0/0x10()
[   17.337693] initcall 0x78a27860: kswapd_init+0x0/0x10() returned 0.
[   17.343904] initcall 0x78a27860 ran for 0 msecs: kswapd_init+0x0/0x10()
[   17.350490] Calling initcall 0x78a278b0: procswaps_init+0x0/0x20()
[   17.356647] initcall 0x78a278b0: procswaps_init+0x0/0x20() returned 0.
[   17.363142] initcall 0x78a278b0 ran for 0 msecs: procswaps_init+0x0/0x20()
[   17.369991] Calling initcall 0x78a278d0: init_tmpfs+0x0/0xd0()
[   17.375833] initcall 0x78a278d0: init_tmpfs+0x0/0xd0() returned 0.
[   17.381944] initcall 0x78a278d0 ran for 0 msecs: init_tmpfs+0x0/0xd0()
[   17.388444] Calling initcall 0x78a27a70: fasync_init+0x0/0x30()
[   17.394342] initcall 0x78a27a70: fasync_init+0x0/0x30() returned 0.
[   17.400580] initcall 0x78a27a70 ran for 0 msecs: fasync_init+0x0/0x30()
[   17.407166] Calling initcall 0x78a280d0: aio_setup+0x0/0x70()
[   17.412919] initcall 0x78a280d0: aio_setup+0x0/0x70() returned 0.
[   17.418946] initcall 0x78a280d0 ran for 0 msecs: aio_setup+0x0/0x70()
[   17.425362] Calling initcall 0x78a284e0: init_mbcache+0x0/0x10()
[   17.431348] initcall 0x78a284e0: init_mbcache+0x0/0x10() returned 0.
[   17.437665] initcall 0x78a284e0 ran for 0 msecs: init_mbcache+0x0/0x10()
[   17.444344] Calling initcall 0x78a284f0: dquot_init+0x0/0xf0()
[   17.450147] VFS: Disk quotas dquot_6.5.1
[   17.454058] Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
[   17.460556] initcall 0x78a284f0: dquot_init+0x0/0xf0() returned 0.
[   17.466702] initcall 0x78a284f0 ran for 6 msecs: dquot_init+0x0/0xf0()
[   17.473202] Calling initcall 0x78a285e0: dnotify_init+0x0/0x30()
[   17.479185] initcall 0x78a285e0: dnotify_init+0x0/0x30() returned 0.
[   17.485505] initcall 0x78a285e0 ran for 0 msecs: dnotify_init+0x0/0x30()
[   17.492177] Calling initcall 0x78a28a90: configfs_init+0x0/0xd0()
[   17.498254] initcall 0x78a28a90: configfs_init+0x0/0xd0() returned 0.
[   17.504657] initcall 0x78a28a90 ran for 0 msecs: configfs_init+0x0/0xd0()
[   17.511422] Calling initcall 0x78a28b60: init_devpts_fs+0x0/0x30()
[   17.517630] initcall 0x78a28b60: init_devpts_fs+0x0/0x30() returned 0.
[   17.524072] initcall 0x78a28b60 ran for 0 msecs: init_devpts_fs+0x0/0x30()
[   17.530918] Calling initcall 0x78a28b90: init_reiserfs_fs+0x0/0x90()
[   17.537259] initcall 0x78a28b90: init_reiserfs_fs+0x0/0x90() returned 0.
[   17.543918] initcall 0x78a28b90 ran for 0 msecs: init_reiserfs_fs+0x0/0x90()
[   17.550937] Calling initcall 0x78a28d00: init_ext3_fs+0x0/0x70()
[   17.556929] initcall 0x78a28d00: init_ext3_fs+0x0/0x70() returned 0.
[   17.563243] initcall 0x78a28d00 ran for 0 msecs: init_ext3_fs+0x0/0x70()
[   17.569916] Calling initcall 0x78a28db0: init_ext4_fs+0x0/0x60()
[   17.575898] initcall 0x78a28db0: init_ext4_fs+0x0/0x60() returned 0.
[   17.582218] initcall 0x78a28db0 ran for 0 msecs: init_ext4_fs+0x0/0x60()
[   17.588892] Calling initcall 0x78a28e90: journal_init+0x0/0x100()
[   17.594965] initcall 0x78a28e90: journal_init+0x0/0x100() returned 0.
[   17.601370] initcall 0x78a28e90 ran for 0 msecs: journal_init+0x0/0x100()
[   17.608136] Calling initcall 0x78a29010: journal_init+0x0/0xd0()
[   17.614116] initcall 0x78a29010: journal_init+0x0/0xd0() returned 0.
[   17.620438] initcall 0x78a29010 ran for 0 msecs: journal_init+0x0/0xd0()
[   17.627112] Calling initcall 0x78a290e0: init_cramfs_fs+0x0/0x30()
[   17.633310] initcall 0x78a290e0: init_cramfs_fs+0x0/0x30() returned 0.
[   17.639764] initcall 0x78a290e0 ran for 0 msecs: init_cramfs_fs+0x0/0x30()
[   17.646613] Calling initcall 0x78a29110: init_ramfs_fs+0x0/0x10()
[   17.652681] initcall 0x78a29110: init_ramfs_fs+0x0/0x10() returned 0.
[   17.659085] initcall 0x78a29110 ran for 0 msecs: init_ramfs_fs+0x0/0x10()
[   17.665847] Calling initcall 0x78a29160: init_coda+0x0/0x190()
[   17.671714] initcall 0x78a29160: init_coda+0x0/0x190() returned 0.
[   17.677806] initcall 0x78a29160 ran for 0 msecs: init_coda+0x0/0x190()
[   17.684309] Calling initcall 0x78a292f0: init_minix_fs+0x0/0x60()
[   17.690378] initcall 0x78a292f0: init_minix_fs+0x0/0x60() returned 0.
[   17.696788] initcall 0x78a292f0 ran for 0 msecs: init_minix_fs+0x0/0x60()
[   17.703548] Calling initcall 0x78a29390: init_fat_fs+0x0/0x50()
[   17.709444] initcall 0x78a29390: init_fat_fs+0x0/0x50() returned 0.
[   17.715674] initcall 0x78a29390 ran for 0 msecs: init_fat_fs+0x0/0x50()
[   17.722263] Calling initcall 0x78a293e0: init_msdos_fs+0x0/0x10()
[   17.728336] initcall 0x78a293e0: init_msdos_fs+0x0/0x10() returned 0.
[   17.734743] initcall 0x78a293e0 ran for 0 msecs: init_msdos_fs+0x0/0x10()
[   17.741507] Calling initcall 0x78a293f0: init_vfat_fs+0x0/0x10()
[   17.747488] initcall 0x78a293f0: init_vfat_fs+0x0/0x10() returned 0.
[   17.753811] initcall 0x78a293f0 ran for 0 msecs: init_vfat_fs+0x0/0x10()
[   17.760483] Calling initcall 0x78a29400: init_iso9660_fs+0x0/0x70()
[   17.766743] initcall 0x78a29400: init_iso9660_fs+0x0/0x70() returned 0.
[   17.773310] initcall 0x78a29400 ran for 0 msecs: init_iso9660_fs+0x0/0x70()
[   17.780243] Calling initcall 0x78a29490: init_hfsplus_fs+0x0/0x70()
[   17.786485] initcall 0x78a29490: init_hfsplus_fs+0x0/0x70() returned 0.
[   17.793068] initcall 0x78a29490 ran for 0 msecs: init_hfsplus_fs+0x0/0x70()
[   17.800004] Calling initcall 0x78a29500: init_hfs_fs+0x0/0x70()
[   17.805897] initcall 0x78a29500: init_hfs_fs+0x0/0x70() returned 0.
[   17.812131] initcall 0x78a29500 ran for 0 msecs: init_hfs_fs+0x0/0x70()
[   17.818717] Calling initcall 0x78a29570: ecryptfs_init+0x0/0x1d0()
[   17.824944] initcall 0x78a29570: ecryptfs_init+0x0/0x1d0() returned 0.
[   17.831370] initcall 0x78a29570 ran for 0 msecs: ecryptfs_init+0x0/0x1d0()
[   17.838221] Calling initcall 0x78a29740: vxfs_init+0x0/0x70()
[   17.843943] initcall 0x78a29740: vxfs_init+0x0/0x70() returned 0.
[   17.850005] initcall 0x78a29740 ran for 0 msecs: vxfs_init+0x0/0x70()
[   17.856418] Calling initcall 0x78a297b0: init_nfsd+0x0/0xb0()
[   17.862136] Installing knfsd (copyright (C) 1996 okir@monad.swb.de).
[   17.868915] initcall 0x78a297b0: init_nfsd+0x0/0xb0() returned 0.
[   17.874847] initcall 0x78a297b0 ran for 2 msecs: init_nfsd+0x0/0xb0()
[   17.881265] Calling initcall 0x78a29860: init_nlm+0x0/0x20()
[   17.886900] initcall 0x78a29860: init_nlm+0x0/0x20() returned 0.
[   17.892871] initcall 0x78a29860 ran for 0 msecs: init_nlm+0x0/0x20()
[   17.899200] Calling initcall 0x78a29880: init_nls_cp437+0x0/0x10()
[   17.905365] initcall 0x78a29880: init_nls_cp437+0x0/0x10() returned 0.
[   17.911851] initcall 0x78a29880 ran for 0 msecs: init_nls_cp437+0x0/0x10()
[   17.918698] Calling initcall 0x78a29890: init_nls_cp775+0x0/0x10()
[   17.924857] initcall 0x78a29890: init_nls_cp775+0x0/0x10() returned 0.
[   17.931351] initcall 0x78a29890 ran for 0 msecs: init_nls_cp775+0x0/0x10()
[   17.938202] Calling initcall 0x78a298a0: init_nls_cp852+0x0/0x10()
[   17.944357] initcall 0x78a298a0: init_nls_cp852+0x0/0x10() returned 0.
[   17.950847] initcall 0x78a298a0 ran for 0 msecs: init_nls_cp852+0x0/0x10()
[   17.957701] Calling initcall 0x78a298b0: init_nls_cp857+0x0/0x10()
[   17.963854] initcall 0x78a298b0: init_nls_cp857+0x0/0x10() returned 0.
[   17.970351] initcall 0x78a298b0 ran for 0 msecs: init_nls_cp857+0x0/0x10()
[   17.977197] Calling initcall 0x78a298c0: init_nls_cp860+0x0/0x10()
[   17.983353] initcall 0x78a298c0: init_nls_cp860+0x0/0x10() returned 0.
[   17.989850] initcall 0x78a298c0 ran for 0 msecs: init_nls_cp860+0x0/0x10()
[   17.996696] Calling initcall 0x78a298d0: init_nls_cp861+0x0/0x10()
[   18.002851] initcall 0x78a298d0: init_nls_cp861+0x0/0x10() returned 0.
[   18.009343] initcall 0x78a298d0 ran for 0 msecs: init_nls_cp861+0x0/0x10()
[   18.016192] Calling initcall 0x78a298e0: init_nls_cp863+0x0/0x10()
[   18.022350] initcall 0x78a298e0: init_nls_cp863+0x0/0x10() returned 0.
[   18.028844] initcall 0x78a298e0 ran for 0 msecs: init_nls_cp863+0x0/0x10()
[   18.035691] Calling initcall 0x78a298f0: init_nls_cp864+0x0/0x10()
[   18.041850] initcall 0x78a298f0: init_nls_cp864+0x0/0x10() returned 0.
[   18.048343] initcall 0x78a298f0 ran for 0 msecs: init_nls_cp864+0x0/0x10()
[   18.055194] Calling initcall 0x78a29900: init_nls_cp869+0x0/0x10()
[   18.061348] initcall 0x78a29900: init_nls_cp869+0x0/0x10() returned 0.
[   18.067842] initcall 0x78a29900 ran for 0 msecs: init_nls_cp869+0x0/0x10()
[   18.074693] Calling initcall 0x78a29910: init_nls_cp874+0x0/0x10()
[   18.080847] initcall 0x78a29910: init_nls_cp874+0x0/0x10() returned 0.
[   18.087344] initcall 0x78a29910 ran for 0 msecs: init_nls_cp874+0x0/0x10()
[   18.094189] Calling initcall 0x78a29920: init_nls_cp932+0x0/0x10()
[   18.100345] initcall 0x78a29920: init_nls_cp932+0x0/0x10() returned 0.
[   18.106843] initcall 0x78a29920 ran for 0 msecs: init_nls_cp932+0x0/0x10()
[   18.113689] Calling initcall 0x78a29930: init_nls_euc_jp+0x0/0x40()
[   18.119931] initcall 0x78a29930: init_nls_euc_jp+0x0/0x40() returned 0.
[   18.127035] initcall 0x78a29930 ran for 0 msecs: init_nls_euc_jp+0x0/0x40()
[   18.133967] Calling initcall 0x78a29970: init_nls_cp936+0x0/0x10()
[   18.140123] initcall 0x78a29970: init_nls_cp936+0x0/0x10() returned 0.
[   18.146620] initcall 0x78a29970 ran for 0 msecs: init_nls_cp936+0x0/0x10()
[   18.153466] Calling initcall 0x78a29980: init_nls_cp1250+0x0/0x10()
[   18.159714] initcall 0x78a29980: init_nls_cp1250+0x0/0x10() returned 0.
[   18.166292] initcall 0x78a29980 ran for 0 msecs: init_nls_cp1250+0x0/0x10()
[   18.173227] Calling initcall 0x78a29990: init_nls_ascii+0x0/0x10()
[   18.179380] initcall 0x78a29990: init_nls_ascii+0x0/0x10() returned 0.
[   18.185872] initcall 0x78a29990 ran for 0 msecs: init_nls_ascii+0x0/0x10()
[   18.192721] Calling initcall 0x78a299a0: init_nls_iso8859_3+0x0/0x10()
[   18.199226] initcall 0x78a299a0: init_nls_iso8859_3+0x0/0x10() returned 0.
[   18.206064] initcall 0x78a299a0 ran for 0 msecs: init_nls_iso8859_3+0x0/0x10()
[   18.213265] Calling initcall 0x78a299b0: init_nls_iso8859_5+0x0/0x10()
[   18.219765] initcall 0x78a299b0: init_nls_iso8859_5+0x0/0x10() returned 0.
[   18.226609] initcall 0x78a299b0 ran for 0 msecs: init_nls_iso8859_5+0x0/0x10()
[   18.233801] Calling initcall 0x78a299c0: init_nls_iso8859_6+0x0/0x10()
[   18.240303] initcall 0x78a299c0: init_nls_iso8859_6+0x0/0x10() returned 0.
[   18.247147] initcall 0x78a299c0 ran for 0 msecs: init_nls_iso8859_6+0x0/0x10()
[   18.254342] Calling initcall 0x78a299d0: init_nls_iso8859_15+0x0/0x10()
[   18.260928] initcall 0x78a299d0: init_nls_iso8859_15+0x0/0x10() returned 0.
[   18.267855] initcall 0x78a299d0 ran for 0 msecs: init_nls_iso8859_15+0x0/0x10()
[   18.275140] Calling initcall 0x78a299e0: init_nls_koi8_r+0x0/0x10()
[   18.281380] initcall 0x78a299e0: init_nls_koi8_r+0x0/0x10() returned 0.
[   18.287962] initcall 0x78a299e0 ran for 0 msecs: init_nls_koi8_r+0x0/0x10()
[   18.294900] Calling initcall 0x78a299f0: init_nls_koi8_u+0x0/0x10()
[   18.301138] initcall 0x78a299f0: init_nls_koi8_u+0x0/0x10() returned 0.
[   18.307720] initcall 0x78a299f0 ran for 0 msecs: init_nls_koi8_u+0x0/0x10()
[   18.314658] Calling initcall 0x78a29a00: init_nls_koi8_ru+0x0/0x40()
[   18.320987] initcall 0x78a29a00: init_nls_koi8_ru+0x0/0x40() returned 0.
[   18.327652] initcall 0x78a29a00 ran for 0 msecs: init_nls_koi8_ru+0x0/0x40()
[   18.334676] Calling initcall 0x78a29a40: init_nls_utf8+0x0/0x30()
[   18.340744] initcall 0x78a29a40: init_nls_utf8+0x0/0x30() returned 0.
[   18.347153] initcall 0x78a29a40 ran for 0 msecs: init_nls_utf8+0x0/0x30()
[   18.353914] Calling initcall 0x78a29a70: init_cifs+0x0/0x510()
[   18.359849] initcall 0x78a29a70: init_cifs+0x0/0x510() returned 0.
[   18.365867] initcall 0x78a29a70 ran for 0 msecs: init_cifs+0x0/0x510()
[   18.372369] Calling initcall 0x78a29f80: init_ncp_fs+0x0/0x60()
[   18.378270] initcall 0x78a29f80: init_ncp_fs+0x0/0x60() returned 0.
[   18.384502] initcall 0x78a29f80 ran for 0 msecs: init_ncp_fs+0x0/0x60()
[   18.391093] Calling initcall 0x78a29fe0: init_hpfs_fs+0x0/0x60()
[   18.397075] initcall 0x78a29fe0: init_hpfs_fs+0x0/0x60() returned 0.
[   18.403398] initcall 0x78a29fe0 ran for 0 msecs: init_hpfs_fs+0x0/0x60()
[   18.410069] Calling initcall 0x78a2a040: init_ntfs_fs+0x0/0x270()
[   18.416135] NTFS driver 2.1.29 [Flags: R/W DEBUG].
[   18.420913] initcall 0x78a2a040: init_ntfs_fs+0x0/0x270() returned 0.
[   18.427315] initcall 0x78a2a040 ran for 3 msecs: init_ntfs_fs+0x0/0x270()
[   18.434074] Calling initcall 0x78a2a2b0: init_romfs_fs+0x0/0x60()
[   18.440145] initcall 0x78a2a2b0: init_romfs_fs+0x0/0x60() returned 0.
[   18.446554] initcall 0x78a2a2b0 ran for 0 msecs: init_romfs_fs+0x0/0x60()
[   18.453314] Calling initcall 0x78a2a310: init_qnx4_fs+0x0/0x70()
[   18.459294] QNX4 filesystem 0.2.3 registered.
[   18.463632] initcall 0x78a2a310: init_qnx4_fs+0x0/0x70() returned 0.
[   18.469953] initcall 0x78a2a310 ran for 3 msecs: init_qnx4_fs+0x0/0x70()
[   18.476627] Calling initcall 0x78a2a380: init_autofs_fs+0x0/0x10()
[   18.482782] initcall 0x78a2a380: init_autofs_fs+0x0/0x10() returned 0.
[   18.489273] initcall 0x78a2a380 ran for 0 msecs: init_autofs_fs+0x0/0x10()
[   18.496121] Calling initcall 0x78a2a390: init_autofs4_fs+0x0/0x10()
[   18.502367] initcall 0x78a2a390: init_autofs4_fs+0x0/0x10() returned -16.
[   18.509118] initcall 0x78a2a390 ran for 0 msecs: init_autofs4_fs+0x0/0x10()
[   18.516054] initcall at 0x78a2a390: init_autofs4_fs+0x0/0x10(): returned with error code -16
[   18.524464] Calling initcall 0x78a2a3a0: init_adfs_fs+0x0/0x60()
[   18.530446] initcall 0x78a2a3a0: init_adfs_fs+0x0/0x60() returned 0.
[   18.536768] initcall 0x78a2a3a0 ran for 0 msecs: init_adfs_fs+0x0/0x60()
[   18.543441] Calling initcall 0x78a2a470: fuse_init+0x0/0x120()
[   18.549246] fuse init (API version 7.8)
[   18.553089] initcall 0x78a2a470: fuse_init+0x0/0x120() returned 0.
[   18.559208] initcall 0x78a2a470 ran for 2 msecs: fuse_init+0x0/0x120()
[   18.565710] Calling initcall 0x78a2a5a0: init_udf_fs+0x0/0x60()
[   18.571611] initcall 0x78a2a5a0: init_udf_fs+0x0/0x60() returned 0.
[   18.577843] initcall 0x78a2a5a0 ran for 0 msecs: init_udf_fs+0x0/0x60()
[   18.584436] Calling initcall 0x78a2a6d0: init_xfs_fs+0x0/0x60()
[   18.590324] SGI XFS with large block numbers, no debug enabled
[   18.596248] SGI XFS Quota Management subsystem
[   18.600572] initcall 0x78a2a6d0: init_xfs_fs+0x0/0x60() returned 0.
[   18.606800] initcall 0x78a2a6d0 ran for 9 msecs: init_xfs_fs+0x0/0x60()
[   18.613386] Calling initcall 0x78a2a730: init_v9fs+0x0/0x20()
[   18.619104] Installing v9fs 9p2000 file system support
[   18.624226] initcall 0x78a2a730: init_v9fs+0x0/0x20() returned 0.
[   18.630285] initcall 0x78a2a730 ran for 3 msecs: init_v9fs+0x0/0x20()
[   18.636697] Calling initcall 0x78a2a790: ocfs2_init+0x0/0x300()
[   18.642589] OCFS2 1.3.3
[   18.645066] initcall 0x78a2a790: ocfs2_init+0x0/0x300() returned 0.
[   18.651254] initcall 0x78a2a790 ran for 1 msecs: ocfs2_init+0x0/0x300()
[   18.657846] Calling initcall 0x78a2ab30: init_o2nm+0x0/0xd0()
[   18.663562] OCFS2 Node Manager 1.3.3
[   18.667363] initcall 0x78a2ab30: init_o2nm+0x0/0xd0() returned 0.
[   18.673304] initcall 0x78a2ab30 ran for 3 msecs: init_o2nm+0x0/0xd0()
[   18.679716] Calling initcall 0x78a2ac00: dlm_init+0x0/0x100()
[   18.685435] OCFS2 DLM 1.3.3
[   18.688228] initcall 0x78a2ac00: dlm_init+0x0/0x100() returned 0.
[   18.694273] initcall 0x78a2ac00 ran for 1 msecs: dlm_init+0x0/0x100()
[   18.700689] Calling initcall 0x78a2ad00: init_dlmfs_fs+0x0/0xd0()
[   18.706753] OCFS2 DLMFS 1.3.3
[   18.709739] OCFS2 User DLM kernel interface loaded
[   18.714475] initcall 0x78a2ad00: init_dlmfs_fs+0x0/0xd0() returned 0.
[   18.720874] initcall 0x78a2ad00 ran for 4 msecs: init_dlmfs_fs+0x0/0xd0()
[   18.727644] Calling initcall 0x78a2af10: key_proc_init+0x0/0x60()
[   18.733711] initcall 0x78a2af10: key_proc_init+0x0/0x60() returned 0.
[   18.740119] initcall 0x78a2af10 ran for 0 msecs: key_proc_init+0x0/0x60()
[   18.746878] Calling initcall 0x78a2b090: crypto_algapi_init+0x0/0x10()
[   18.753381] initcall 0x78a2b090: crypto_algapi_init+0x0/0x10() returned 0.
[   18.760224] initcall 0x78a2b090 ran for 0 msecs: crypto_algapi_init+0x0/0x10()
[   18.767417] Calling initcall 0x78a2b0c0: cryptomgr_init+0x0/0x10()
[   18.773572] initcall 0x78a2b0c0: cryptomgr_init+0x0/0x10() returned 0.
[   18.780070] initcall 0x78a2b0c0 ran for 0 msecs: cryptomgr_init+0x0/0x10()
[   18.786916] Calling initcall 0x78a2b0d0: hmac_module_init+0x0/0x10()
[   18.793258] initcall 0x78a2b0d0: hmac_module_init+0x0/0x10() returned 0.
[   18.799915] initcall 0x78a2b0d0 ran for 0 msecs: hmac_module_init+0x0/0x10()
[   18.806935] Calling initcall 0x78a2b0e0: crypto_xcbc_module_init+0x0/0x10()
[   18.813870] initcall 0x78a2b0e0: crypto_xcbc_module_init+0x0/0x10() returned 0.
[   18.821144] initcall 0x78a2b0e0 ran for 0 msecs: crypto_xcbc_module_init+0x0/0x10()
[   18.828776] Calling initcall 0x78a2b0f0: init+0x0/0x50()
[   18.834065] initcall 0x78a2b0f0: init+0x0/0x50() returned 0.
[   18.839693] initcall 0x78a2b0f0 ran for 0 msecs: init+0x0/0x50()
[   18.845669] Calling initcall 0x78a2b140: init+0x0/0x10()
[   18.850963] initcall 0x78a2b140: init+0x0/0x10() returned 0.
[   18.856592] initcall 0x78a2b140 ran for 0 msecs: init+0x0/0x10()
[   18.862566] Calling initcall 0x78a2b150: init+0x0/0x10()
[   18.867860] initcall 0x78a2b150: init+0x0/0x10() returned 0.
[   18.873490] initcall 0x78a2b150 ran for 0 msecs: init+0x0/0x10()
[   18.879464] Calling initcall 0x78a2b160: init+0x0/0x10()
[   18.884759] initcall 0x78a2b160: init+0x0/0x10() returned 0.
[   18.890390] initcall 0x78a2b160 ran for 0 msecs: init+0x0/0x10()
[   18.896369] Calling initcall 0x78a2b170: init+0x0/0x10()
[   18.901658] initcall 0x78a2b170: init+0x0/0x10() returned 0.
[   18.907288] initcall 0x78a2b170 ran for 0 msecs: init+0x0/0x10()
[   18.913268] Calling initcall 0x78a2b180: crypto_ecb_module_init+0x0/0x10()
[   18.920116] initcall 0x78a2b180: crypto_ecb_module_init+0x0/0x10() returned 0.
[   18.927307] initcall 0x78a2b180 ran for 0 msecs: crypto_ecb_module_init+0x0/0x10()
[   18.934850] Calling initcall 0x78a2b190: crypto_cbc_module_init+0x0/0x10()
[   18.941695] initcall 0x78a2b190: crypto_cbc_module_init+0x0/0x10() returned 0.
[   18.948880] initcall 0x78a2b190 ran for 0 msecs: crypto_cbc_module_init+0x0/0x10()
[   18.956428] Calling initcall 0x78a2b1a0: crypto_pcbc_module_init+0x0/0x10()
[   18.963360] initcall 0x78a2b1a0: crypto_pcbc_module_init+0x0/0x10() returned 0.
[   18.970638] initcall 0x78a2b1a0 ran for 0 msecs: crypto_pcbc_module_init+0x0/0x10()
[   18.978267] Calling initcall 0x78a2b1b0: init+0x0/0x40()
[   18.983554] initcall 0x78a2b1b0: init+0x0/0x40() returned 0.
[   18.989178] initcall 0x78a2b1b0 ran for 0 msecs: init+0x0/0x40()
[   18.995160] Calling initcall 0x78a2b1f0: init+0x0/0x10()
[   19.000451] initcall 0x78a2b1f0: init+0x0/0x10() returned 0.
[   19.006077] initcall 0x78a2b1f0 ran for 0 msecs: init+0x0/0x10()
[   19.012059] Calling initcall 0x78a2b200: init+0x0/0x10()
[   19.017351] initcall 0x78a2b200: init+0x0/0x10() returned 0.
[   19.022982] initcall 0x78a2b200 ran for 0 msecs: init+0x0/0x10()
[   19.028958] Calling initcall 0x78a2b210: init+0x0/0x40()
[   19.034254] initcall 0x78a2b210: init+0x0/0x40() returned 0.
[   19.039881] initcall 0x78a2b210 ran for 0 msecs: init+0x0/0x40()
[   19.045855] Calling initcall 0x78a2b250: aes_init+0x0/0x330()
[   19.051598] initcall 0x78a2b250: aes_init+0x0/0x330() returned 0.
[   19.057643] initcall 0x78a2b250 ran for 0 msecs: aes_init+0x0/0x330()
[   19.064059] Calling initcall 0x78a2b580: camellia_init+0x0/0x10()
[   19.070127] initcall 0x78a2b580: camellia_init+0x0/0x10() returned 0.
[   19.076538] initcall 0x78a2b580 ran for 0 msecs: camellia_init+0x0/0x10()
[   19.083298] Calling initcall 0x78a2b590: init+0x0/0x10()
[   19.088587] initcall 0x78a2b590: init+0x0/0x10() returned 0.
[   19.094214] initcall 0x78a2b590 ran for 0 msecs: init+0x0/0x10()
[   19.100196] Calling initcall 0x78a2b5a0: init+0x0/0x10()
[   19.105485] initcall 0x78a2b5a0: init+0x0/0x10() returned 0.
[   19.111113] initcall 0x78a2b5a0 ran for 0 msecs: init+0x0/0x10()
[   19.117095] Calling initcall 0x78a2b5b0: arc4_init+0x0/0x10()
[   19.122824] initcall 0x78a2b5b0: arc4_init+0x0/0x10() returned 0.
[   19.128875] initcall 0x78a2b5b0 ran for 0 msecs: arc4_init+0x0/0x10()
[   19.135291] Calling initcall 0x78a2b5c0: init+0x0/0x60()
[   19.140584] initcall 0x78a2b5c0: init+0x0/0x60() returned 0.
[   19.146213] initcall 0x78a2b5c0 ran for 0 msecs: init+0x0/0x60()
[   19.152719] Calling initcall 0x78a2b620: init+0x0/0x10()
[   19.158011] initcall 0x78a2b620: init+0x0/0x10() returned 0.
[   19.163641] initcall 0x78a2b620 ran for 0 msecs: init+0x0/0x10()
[   19.169621] Calling initcall 0x78a2b630: init+0x0/0x10()
[   19.174911] initcall 0x78a2b630: init+0x0/0x10() returned 0.
[   19.180540] initcall 0x78a2b630 ran for 0 msecs: init+0x0/0x10()
[   19.186520] Calling initcall 0x78a2b940: noop_init+0x0/0x10()
[   19.192248] io scheduler noop registered (default)
[   19.197011] initcall 0x78a2b940: noop_init+0x0/0x10() returned 0.
[   19.203072] initcall 0x78a2b940 ran for 3 msecs: noop_init+0x0/0x10()
[   19.209485] Calling initcall 0x78a2b950: deadline_init+0x0/0x10()
[   19.215550] io scheduler deadline registered
[   19.219804] initcall 0x78a2b950: deadline_init+0x0/0x10() returned 0.
[   19.226210] initcall 0x78a2b950 ran for 3 msecs: deadline_init+0x0/0x10()
[   19.232972] Calling initcall 0x78a2ba60: audit_classes_init+0x0/0x50()
[   19.239480] initcall 0x78a2ba60: audit_classes_init+0x0/0x50() returned 0.
[   19.246316] initcall 0x78a2ba60 ran for 0 msecs: audit_classes_init+0x0/0x50()
[   19.253509] Calling initcall 0x78a2be80: pci_init+0x0/0x30()
[   19.279463] Boot video device is 0000:01:00.0
[   19.283701] initcall 0x78a2be80: pci_init+0x0/0x30() returned 0.
[   19.289673] initcall 0x78a2be80 ran for 15 msecs: pci_init+0x0/0x30()
[   19.296085] Calling initcall 0x78a2d0e0: pci_proc_init+0x0/0x70()
[   19.302189] initcall 0x78a2d0e0: pci_proc_init+0x0/0x70() returned 0.
[   19.308561] initcall 0x78a2d0e0 ran for 0 msecs: pci_proc_init+0x0/0x70()
[   19.315321] Calling initcall 0x78a2d270: corgibl_init+0x0/0x10()
[   19.321318] initcall 0x78a2d270: corgibl_init+0x0/0x10() returned 0.
[   19.327627] initcall 0x78a2d270 ran for 0 msecs: corgibl_init+0x0/0x10()
[   19.334306] Calling initcall 0x78a2d280: progearbl_init+0x0/0x60()
[   19.340488] ALI M7101 PMU not found.
[   19.344036] initcall 0x78a2d280: progearbl_init+0x0/0x60() returned 0.
[   19.350509] initcall 0x78a2d280 ran for 3 msecs: progearbl_init+0x0/0x60()
[   19.357355] Calling initcall 0x78a2d3c0: rand_initialize+0x0/0x30()
[   19.363623] initcall 0x78a2d3c0: rand_initialize+0x0/0x30() returned 0.
[   19.370180] initcall 0x78a2d3c0 ran for 0 msecs: rand_initialize+0x0/0x30()
[   19.377114] Calling initcall 0x78a2d420: tty_init+0x0/0x1f0()
[   19.383734] initcall 0x78a2d420: tty_init+0x0/0x1f0() returned 0.
[   19.389671] initcall 0x78a2d420 ran for 0 msecs: tty_init+0x0/0x1f0()
[   19.396084] Calling initcall 0x78a2d640: pty_init+0x0/0x2a0()
[   19.401811] initcall 0x78a2d640: pty_init+0x0/0x2a0() returned 0.
[   19.407867] initcall 0x78a2d640 ran for 0 msecs: pty_init+0x0/0x2a0()
[   19.414285] Calling initcall 0x78a2df20: raw_init+0x0/0xd0()
[   19.419937] initcall 0x78a2df20: raw_init+0x0/0xd0() returned 0.
[   19.425890] initcall 0x78a2df20 ran for 0 msecs: raw_init+0x0/0xd0()
[   19.432219] Calling initcall 0x78a2dff0: applicom_init+0x0/0x4c0()
[   19.438373] Applicom driver: $Id: ac.c,v 1.30 2000/03/22 16:03:57 dwmw2 Exp $
[   19.445483] ac.o: No PCI boards found.
[   19.449210] ac.o: For an ISA board you must supply memory and irq parameters.
[   19.456319] initcall 0x78a2dff0: applicom_init+0x0/0x4c0() returned -6.
[   19.462899] initcall 0x78a2dff0 ran for 10 msecs: applicom_init+0x0/0x4c0()
[   19.469832] initcall at 0x78a2dff0: applicom_init+0x0/0x4c0(): returned with error code -6
[   19.478067] Calling initcall 0x78a2e4b0: rtc_init+0x0/0x1b0()
[   19.483829] Real Time Clock Driver v1.12ac
[   19.487866] initcall 0x78a2e4b0: rtc_init+0x0/0x1b0() returned 0.
[   19.493924] initcall 0x78a2e4b0 ran for 0 msecs: rtc_init+0x0/0x1b0()
[   19.500337] Calling initcall 0x78a2e660: nvram_init+0x0/0x80()
[   19.506168] Non-volatile memory driver v1.2
[   19.510310] initcall 0x78a2e660: nvram_init+0x0/0x80() returned 0.
[   19.516456] initcall 0x78a2e660 ran for 3 msecs: nvram_init+0x0/0x80()
[   19.522955] Calling initcall 0x78a2e6e0: i8k_init+0x0/0x250()
[   19.528679] initcall 0x78a2e6e0: i8k_init+0x0/0x250() returned -19.
[   19.534911] initcall 0x78a2e6e0 ran for 0 msecs: i8k_init+0x0/0x250()
[   19.541325] Calling initcall 0x78a2e930: mod_init+0x0/0x210()
[   19.547057] initcall 0x78a2e930: mod_init+0x0/0x210() returned -19.
[   19.553287] initcall 0x78a2e930 ran for 0 msecs: mod_init+0x0/0x210()
[   19.559700] Calling initcall 0x78a2ec30: mod_init+0x0/0xb0()
[   19.565340] initcall 0x78a2ec30: mod_init+0x0/0xb0() returned -19.
[   19.571483] initcall 0x78a2ec30 ran for 0 msecs: mod_init+0x0/0xb0()
[   19.577815] Calling initcall 0x78a2ece0: cs5535_gpio_init+0x0/0x1d0()
[   19.584227] cs5535_gpio: DIVIL not found
[   19.588132] initcall 0x78a2ece0: cs5535_gpio_init+0x0/0x1d0() returned -19.
[   19.595055] initcall 0x78a2ece0 ran for 0 msecs: cs5535_gpio_init+0x0/0x1d0()
[   19.602161] Calling initcall 0x78a2eeb0: mwave_init+0x0/0x340()
[   19.608061] smapi::smapi_init, ERROR invalid usSmapiID
[   19.613173] mwave: tp3780i::tp3780I_InitializeBoardData: Error: SMAPI is not available on this machine
[   19.622445] mwave: mwavedd::mwave_init: Error: Failed to initialize board data
[   19.629639] mwave: mwavedd::mwave_init: Error: Failed to initialize
[   19.635882] initcall 0x78a2eeb0: mwave_init+0x0/0x340() returned -5.
[   19.642196] initcall 0x78a2eeb0 ran for 13 msecs: mwave_init+0x0/0x340()
[   19.648872] initcall at 0x78a2eeb0: mwave_init+0x0/0x340(): returned with error code -5
[   19.656847] Calling initcall 0x78a2f230: agp_init+0x0/0x30()
[   19.662479] Linux agpgart interface v0.102
[   19.666560] initcall 0x78a2f230: agp_init+0x0/0x30() returned 0.
[   19.672528] initcall 0x78a2f230 ran for 2 msecs: agp_init+0x0/0x30()
[   19.678856] Calling initcall 0x78a2f3d0: agp_ali_init+0x0/0x30()
[   19.684864] initcall 0x78a2f3d0: agp_ali_init+0x0/0x30() returned 0.
[   19.691162] initcall 0x78a2f3d0 ran for 0 msecs: agp_ali_init+0x0/0x30()
[   19.697840] Calling initcall 0x78a2f4e0: agp_ati_init+0x0/0x30()
[   19.703839] initcall 0x78a2f4e0: agp_ati_init+0x0/0x30() returned 0.
[   19.710145] initcall 0x78a2f4e0 ran for 0 msecs: agp_ati_init+0x0/0x30()
[   19.716817] Calling initcall 0x78a2fc80: agp_amd64_init+0x0/0xd0()
[   19.722992] initcall 0x78a2fc80: agp_amd64_init+0x0/0xd0() returned 0.
[   19.729469] initcall 0x78a2fc80 ran for 0 msecs: agp_amd64_init+0x0/0xd0()
[   19.736318] Calling initcall 0x78a2feb0: agp_nvidia_init+0x0/0x30()
[   19.742576] initcall 0x78a2feb0: agp_nvidia_init+0x0/0x30() returned 0.
[   19.749136] initcall 0x78a2feb0 ran for 0 msecs: agp_nvidia_init+0x0/0x30()
[   19.756077] Calling initcall 0x78a30030: agp_sis_init+0x0/0x30()
[   19.762077] initcall 0x78a30030: agp_sis_init+0x0/0x30() returned 0.
[   19.768377] initcall 0x78a30030 ran for 0 msecs: agp_sis_init+0x0/0x30()
[   19.775050] Calling initcall 0x78a30060: drm_core_init+0x0/0x140()
[   19.781231] [drm] Initialized drm 1.1.0 20060810
[   19.785806] initcall 0x78a30060: drm_core_init+0x0/0x140() returned 0.
[   19.792293] initcall 0x78a30060 ran for 4 msecs: drm_core_init+0x0/0x140()
[   19.799142] Calling initcall 0x78a301a0: tdfx_init+0x0/0x10()
[   19.804869] initcall 0x78a301a0: tdfx_init+0x0/0x10() returned 0.
[   19.810928] initcall 0x78a301a0 ran for 0 msecs: tdfx_init+0x0/0x10()
[   19.817343] Calling initcall 0x78a301b0: radeon_init+0x0/0x20()
[   19.823446] [drm] Initialized radeon 1.28.0 20060524 on minor 0
[   19.829247] initcall 0x78a301b0: radeon_init+0x0/0x20() returned 0.
[   19.835468] initcall 0x78a301b0 ran for 2 msecs: radeon_init+0x0/0x20()
[   19.842057] Calling initcall 0x78a301d0: mga_init+0x0/0x20()
[   19.847695] initcall 0x78a301d0: mga_init+0x0/0x20() returned 0.
[   19.853673] initcall 0x78a301d0 ran for 0 msecs: mga_init+0x0/0x20()
[   19.859999] Calling initcall 0x78a301f0: sis_init+0x0/0x20()
[   19.865636] initcall 0x78a301f0: sis_init+0x0/0x20() returned 0.
[   19.871608] initcall 0x78a301f0 ran for 0 msecs: sis_init+0x0/0x20()
[   19.877934] Calling initcall 0x78a30210: via_init+0x0/0x20()
[   19.883578] initcall 0x78a30210: via_init+0x0/0x20() returned 0.
[   19.889549] initcall 0x78a30210 ran for 0 msecs: via_init+0x0/0x20()
[   19.895873] Calling initcall 0x78a302f0: hangcheck_init+0x0/0xb0()
[   19.902028] Hangcheck: starting hangcheck timer 0.9.0 (tick is 180 seconds, margin is 60 seconds).
[   19.910958] Hangcheck: Using get_cycles().
[   19.915035] initcall 0x78a302f0: hangcheck_init+0x0/0xb0() returned 0.
[   19.921525] initcall 0x78a302f0 ran for 5 msecs: hangcheck_init+0x0/0xb0()
[   19.928371] Calling initcall 0x78a30830: serial8250_init+0x0/0x140()
[   19.934699] Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing disabled
[   19.942650] serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
[   19.948706] initcall 0x78a30830: serial8250_init+0x0/0x140() returned 0.
[   19.955244] initcall 0x78a30830 ran for 7 msecs: serial8250_init+0x0/0x140()
[   19.962264] Calling initcall 0x78a30f60: mca_init+0x0/0x20()
[   19.967902] initcall 0x78a30f60: mca_init+0x0/0x20() returned -19.
[   19.974048] initcall 0x78a30f60 ran for 0 msecs: mca_init+0x0/0x20()
[   19.980380] Calling initcall 0x78a30f80: jsm_init_module+0x0/0x40()
[   19.986650] initcall 0x78a30f80: jsm_init_module+0x0/0x40() returned 0.
[   19.993205] initcall 0x78a30f80 ran for 0 msecs: jsm_init_module+0x0/0x40()
[   20.000139] Calling initcall 0x78a31210: e1000_init_module+0x0/0x90()
[   20.006550] Intel(R) PRO/1000 Network Driver - version 7.3.20-k2
[   20.012533] Copyright (c) 1999-2006 Intel Corporation.
[   20.017669] initcall 0x78a31210: e1000_init_module+0x0/0x90() returned 0.
[   20.024401] initcall 0x78a31210 ran for 4 msecs: e1000_init_module+0x0/0x90()
[   20.031513] Calling initcall 0x78a33200: e100_init_module+0x0/0x60()
[   20.037835] e100: Intel(R) PRO/100 Network Driver, 3.5.23-k4-NAPI
[   20.043904] e100: Copyright(c) 1999-2006 Intel Corporation
[   20.049385] initcall 0x78a33200: e100_init_module+0x0/0x60() returned 0.
[   20.056035] initcall 0x78a33200 ran for 7 msecs: e100_init_module+0x0/0x60()
[   20.063057] Calling initcall 0x78a33a10: net_olddevs_init+0x0/0x90()
[   20.069392] initcall 0x78a33a10: net_olddevs_init+0x0/0x90() returned 0.
[   20.076054] initcall 0x78a33a10 ran for 0 msecs: net_olddevs_init+0x0/0x90()
[   20.083076] Calling initcall 0x78a33b40: init_nic+0x0/0x20()
[   20.088720] forcedeth: Reverse Engineered nForce ethernet driver. Version 0.61.
[   20.096036] PCI: Setting latency timer of device 0000:00:0a.0 to 64
[   20.616198] forcedeth 0000:00:0a.0: ifname eth0, PHY OUI 0x5043 @ 1, addr 00:13:d4:dc:41:12
[   20.624441] forcedeth 0000:00:0a.0: highdma csum timirq gbit lnktim desc-v3
[   20.631386] initcall 0x78a33b40: init_nic+0x0/0x20() returned 0.
[   20.637347] initcall 0x78a33b40 ran for 503 msecs: init_nic+0x0/0x20()
[   20.643848] Calling initcall 0x78a35360: rtl8139_init_module+0x0/0x20()
[   20.650452] 8139too Fast Ethernet driver 0.9.28
[   20.655307] eth1: RealTek RTL8139 at 0xb8820000, 00:c0:df:03:68:5d, IRQ 11
[   20.662052] eth1:  Identified 8139 chip type 'RTL-8139B'
[   20.667344] initcall 0x78a35360: rtl8139_init_module+0x0/0x20() returned 0.
[   20.674264] initcall 0x78a35360 ran for 6 msecs: rtl8139_init_module+0x0/0x20()
[   20.681549] Calling initcall 0x78a35d90: ipddp_init_module+0x0/0x110()
[   20.688046] ipddp.c:v0.01 8/28/97 Bradford W. Johnson <johns393@maroon.tc.umn.edu>
[   20.695685] ipddp0: Appletalk-IP Decap. mode by Jay Schulist <jschlst@samba.org>
[   20.702976] initcall 0x78a35d90: ipddp_init_module+0x0/0x110() returned 0.
[   20.709815] initcall 0x78a35d90 ran for 7 msecs: ipddp_init_module+0x0/0x110()
[   20.717009] Calling initcall 0x78a35ea0: usb_irda_init+0x0/0x50()
[   20.723080] usbcore: registered new interface driver irda-usb
[   20.729333] USB IrDA support registered
[   20.733142] initcall 0x78a35ea0: usb_irda_init+0x0/0x50() returned 0.
[   20.739549] initcall 0x78a35ea0 ran for 6 msecs: usb_irda_init+0x0/0x50()
[   20.746308] Calling initcall 0x78a35ef0: w83977af_init+0x0/0x520()
[   20.752511] initcall 0x78a35ef0: w83977af_init+0x0/0x520() returned -19.
[   20.759129] initcall 0x78a35ef0 ran for 0 msecs: w83977af_init+0x0/0x520()
[   20.765983] Calling initcall 0x78a36410: donauboe_init+0x0/0x20()
[   20.772069] initcall 0x78a36410: donauboe_init+0x0/0x20() returned 0.
[   20.778457] initcall 0x78a36410 ran for 0 msecs: donauboe_init+0x0/0x20()
[   20.785216] Calling initcall 0x78a37340: smsc_ircc_init+0x0/0x5c0()
[   20.791590] initcall 0x78a37340: smsc_ircc_init+0x0/0x5c0() returned -19.
[   20.798216] initcall 0x78a37340 ran for 0 msecs: smsc_ircc_init+0x0/0x5c0()
[   20.805149] Calling initcall 0x78a37bc0: ali_ircc_init+0x0/0x6a0()
[   20.811362] initcall 0x78a37bc0: ali_ircc_init+0x0/0x6a0() returned -19.
[   20.817974] initcall 0x78a37bc0 ran for 0 msecs: ali_ircc_init+0x0/0x6a0()
[   20.824826] Calling initcall 0x78a38260: vlsi_mod_init+0x0/0x130()
[   20.831001] initcall 0x78a38260: vlsi_mod_init+0x0/0x130() returned 0.
[   20.837473] initcall 0x78a38260 ran for 0 msecs: vlsi_mod_init+0x0/0x130()
[   20.844325] Calling initcall 0x78a38c80: via_ircc_init+0x0/0x20()
[   20.850410] initcall 0x78a38c80: via_ircc_init+0x0/0x20() returned 0.
[   20.856802] initcall 0x78a38c80 ran for 0 msecs: via_ircc_init+0x0/0x20()
[   20.863561] Calling initcall 0x78a39060: irtty_sir_init+0x0/0x40()
[   20.869717] initcall 0x78a39060: irtty_sir_init+0x0/0x40() returned 0.
[   20.876213] initcall 0x78a39060 ran for 0 msecs: irtty_sir_init+0x0/0x40()
[   20.883060] Calling initcall 0x78a390a0: sir_wq_init+0x0/0x20()
[   20.888991] initcall 0x78a390a0: sir_wq_init+0x0/0x20() returned 0.
[   20.895187] initcall 0x78a390a0 ran for 0 msecs: sir_wq_init+0x0/0x20()
[   20.901776] Calling initcall 0x78a390c0: ksdazzle_init+0x0/0x20()
[   20.907850] usbcore: registered new interface driver ksdazzle-sir
[   20.913918] initcall 0x78a390c0: ksdazzle_init+0x0/0x20() returned 0.
[   20.920325] initcall 0x78a390c0 ran for 5 msecs: ksdazzle_init+0x0/0x20()
[   20.927084] Calling initcall 0x78a39100: init_netconsole+0x0/0x1a0()
[   20.933409] console [netcon0] enabled
[   27.249628] netconsole: network logging started
[   27.254137] initcall 0x78a39100: init_netconsole+0x0/0x1a0() returned 0.
[   27.260801] initcall 0x78a39100 ran for 7 msecs: init_netconsole+0x0/0x1a0()
[   27.267820] Calling initcall 0x78a39600: raid_init+0x0/0x10()
[   27.273550] initcall 0x78a39600: raid_init+0x0/0x10() returned 0.
[   27.279603] initcall 0x78a39600 ran for 0 msecs: raid_init+0x0/0x10()
[   27.286022] Calling initcall 0x78a39610: spi_transport_init+0x0/0x30()
[   27.292545] initcall 0x78a39610: spi_transport_init+0x0/0x30() returned 0.
[   27.299368] initcall 0x78a39610 ran for 0 msecs: spi_transport_init+0x0/0x30()
[   27.306563] Calling initcall 0x78a39640: fc_transport_init+0x0/0x50()
[   27.312994] initcall 0x78a39640: fc_transport_init+0x0/0x50() returned 0.
[   27.319728] initcall 0x78a39640 ran for 0 msecs: fc_transport_init+0x0/0x50()
[   27.326843] Calling initcall 0x78a39690: iscsi_transport_init+0x0/0xe0()
[   27.333511] Loading iSCSI transport class v2.0-724.
[   27.338398] initcall 0x78a39690: iscsi_transport_init+0x0/0xe0() returned 0.
[   27.345385] initcall 0x78a39690 ran for 4 msecs: iscsi_transport_init+0x0/0xe0()
[   27.352752] Calling initcall 0x78a39770: sas_transport_init+0x0/0xa0()
[   27.359304] initcall 0x78a39770: sas_transport_init+0x0/0xa0() returned 0.
[   27.366097] initcall 0x78a39770 ran for 0 msecs: sas_transport_init+0x0/0xa0()
[   27.373292] Calling initcall 0x78a39810: sas_class_init+0x0/0x40()
[   27.379445] initcall 0x78a39810: sas_class_init+0x0/0x40() returned 0.
[   27.385942] initcall 0x78a39810 ran for 0 msecs: sas_class_init+0x0/0x40()
[   27.392788] Calling initcall 0x78a39850: init_sd+0x0/0xd0()
[   27.398389] initcall 0x78a39850: init_sd+0x0/0xd0() returned 0.
[   27.404225] initcall 0x78a39850 ran for 3 msecs: init_sd+0x0/0xd0()
[   27.410465] Calling initcall 0x78a39920: init_ch_module+0x0/0xa0()
[   27.416619] SCSI Media Changer driver v0.25 
[   27.420899] initcall 0x78a39920: init_ch_module+0x0/0xa0() returned 0.
[   27.427364] initcall 0x78a39920 ran for 4 msecs: init_ch_module+0x0/0xa0()
[   27.434210] Calling initcall 0x78a39a30: ahci_init+0x0/0x20()
[   27.439962] initcall 0x78a39a30: ahci_init+0x0/0x20() returned 0.
[   27.445999] initcall 0x78a39a30 ran for 0 msecs: ahci_init+0x0/0x20()
[   27.452411] Calling initcall 0x78a39a50: piix_init+0x0/0x20()
[   27.458158] initcall 0x78a39a50: piix_init+0x0/0x20() returned 0.
[   27.464195] initcall 0x78a39a50 ran for 0 msecs: piix_init+0x0/0x20()
[   27.470607] Calling initcall 0x78a39a70: pdc_ata_init+0x0/0x20()
[   27.476613] initcall 0x78a39a70: pdc_ata_init+0x0/0x20() returned 0.
[   27.482912] initcall 0x78a39a70 ran for 0 msecs: pdc_ata_init+0x0/0x20()
[   27.489590] Calling initcall 0x78a39a90: qs_ata_init+0x0/0x20()
[   27.495503] initcall 0x78a39a90: qs_ata_init+0x0/0x20() returned 0.
[   27.501722] initcall 0x78a39a90 ran for 0 msecs: qs_ata_init+0x0/0x20()
[   27.508304] Calling initcall 0x78a39d70: vsc_sata_init+0x0/0x20()
[   27.514396] initcall 0x78a39d70: vsc_sata_init+0x0/0x20() returned 0.
[   27.520784] initcall 0x78a39d70 ran for 0 msecs: vsc_sata_init+0x0/0x20()
[   27.527543] Calling initcall 0x78a39d90: nv_init+0x0/0x20()
[   27.533120] initcall 0x78a39d90: nv_init+0x0/0x20() returned 0.
[   27.538986] initcall 0x78a39d90 ran for 0 msecs: nv_init+0x0/0x20()
[   27.545226] Calling initcall 0x78a39db0: mv_init+0x0/0x20()
[   27.550809] initcall 0x78a39db0: mv_init+0x0/0x20() returned 0.
[   27.556662] initcall 0x78a39db0 ran for 0 msecs: mv_init+0x0/0x20()
[   27.562905] Calling initcall 0x78a39dd0: inic_init+0x0/0x20()
[   27.568645] initcall 0x78a39dd0: inic_init+0x0/0x20() returned 0.
[   27.574685] initcall 0x78a39dd0 ran for 0 msecs: inic_init+0x0/0x20()
[   27.581101] Calling initcall 0x78a39df0: amd_init+0x0/0x20()
[   27.586754] pata_amd 0000:00:06.0: version 0.3.9
[   27.591447] PCI: Setting latency timer of device 0000:00:06.0 to 64
[   27.597683] scsi0 : pata_amd
[   27.600521] scsi1 : pata_amd
[   27.603344] ata1: PATA max UDMA/133 cmd 0x1f0 ctl 0x3f6 bmdma 0xf000 irq 14
[   27.610242] ata2: PATA max UDMA/133 cmd 0x170 ctl 0x376 bmdma 0xf008 irq 15
[   27.941995] ata1.00: ATA-5: MAXTOR 6L040J2, AR1.0500, max UDMA/133
[   27.948048] ata1.00: 78177792 sectors, multi 1: LBA 
[   27.953259] ata1.01: ATA-6: ST380011A, 3.06, max UDMA/100
[   27.958534] ata1.01: 156301488 sectors, multi 1: LBA48 
[   27.975254] ata1.00: configured for UDMA/133
[   27.991920] ata1.01: configured for UDMA/100
[   28.159362] scsi 0:0:0:0: Direct-Access     ATA      MAXTOR 6L040J2   AR1. PQ: 0 ANSI: 5
[   28.167531] sd 0:0:0:0: [sda] 78177792 512-byte hardware sectors (40027 MB)
[   28.174380] sd 0:0:0:0: [sda] Write Protect is off
[   28.179130] sd 0:0:0:0: [sda] Mode Sense: 00 3a 00 00
[   28.184183] sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[   28.193457] sd 0:0:0:0: [sda] 78177792 512-byte hardware sectors (40027 MB)
[   28.200314] sd 0:0:0:0: [sda] Write Protect is off
[   28.205060] sd 0:0:0:0: [sda] Mode Sense: 00 3a 00 00
[   28.210124] sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[   28.219123]  sda: sda1 sda2 sda3 sda4 < sda5 >
[   28.257607] sd 0:0:0:0: [sda] Attached SCSI disk
[   28.262233] scsi 0:0:1:0: Direct-Access     ATA      ST380011A        3.06 PQ: 0 ANSI: 5
[   28.270314] sd 0:0:1:0: [sdb] 156301488 512-byte hardware sectors (80026 MB)
[   28.277257] sd 0:0:1:0: [sdb] Write Protect is off
[   28.282005] sd 0:0:1:0: [sdb] Mode Sense: 00 3a 00 00
[   28.287058] sd 0:0:1:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[   28.296106] sd 0:0:1:0: [sdb] 156301488 512-byte hardware sectors (80026 MB)
[   28.303079] sd 0:0:1:0: [sdb] Write Protect is off
[   28.307830] sd 0:0:1:0: [sdb] Mode Sense: 00 3a 00 00
[   28.312884] sd 0:0:1:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[   28.321872]  sdb: sdb1 sdb2 sdb3 < sdb5 >
[   28.337075] sd 0:0:1:0: [sdb] Attached SCSI disk
[   28.341613] initcall 0x78a39df0: amd_init+0x0/0x20() returned 0.
[   28.347538] initcall 0x78a39df0 ran for 637 msecs: amd_init+0x0/0x20()
[   28.354041] Calling initcall 0x78a39e10: artop_init+0x0/0x20()
[   28.360402] initcall 0x78a39e10: artop_init+0x0/0x20() returned 0.
[   28.366529] initcall 0x78a39e10 ran for 0 msecs: artop_init+0x0/0x20()
[   28.373034] Calling initcall 0x78a39e30: atiixp_init+0x0/0x20()
[   28.378945] initcall 0x78a39e30: atiixp_init+0x0/0x20() returned 0.
[   28.385163] initcall 0x78a39e30 ran for 0 msecs: atiixp_init+0x0/0x20()
[   28.391750] Calling initcall 0x78a39e50: cmd640_init+0x0/0x20()
[   28.397664] initcall 0x78a39e50: cmd640_init+0x0/0x20() returned 0.
[   28.403879] initcall 0x78a39e50 ran for 0 msecs: cmd640_init+0x0/0x20()
[   28.410466] Calling initcall 0x78a39e70: cmd64x_init+0x0/0x20()
[   28.416388] initcall 0x78a39e70: cmd64x_init+0x0/0x20() returned 0.
[   28.422601] initcall 0x78a39e70 ran for 0 msecs: cmd64x_init+0x0/0x20()
[   28.429187] Calling initcall 0x78a39e90: cs5535_init+0x0/0x20()
[   28.435102] initcall 0x78a39e90: cs5535_init+0x0/0x20() returned 0.
[   28.441314] initcall 0x78a39e90 ran for 0 msecs: cs5535_init+0x0/0x20()
[   28.447903] Calling initcall 0x78a39eb0: cy82c693_init+0x0/0x20()
[   28.453994] initcall 0x78a39eb0: cy82c693_init+0x0/0x20() returned 0.
[   28.460383] initcall 0x78a39eb0 ran for 0 msecs: cy82c693_init+0x0/0x20()
[   28.467142] Calling initcall 0x78a39ed0: hpt37x_init+0x0/0x20()
[   28.473063] initcall 0x78a39ed0: hpt37x_init+0x0/0x20() returned 0.
[   28.479278] initcall 0x78a39ed0 ran for 0 msecs: hpt37x_init+0x0/0x20()
[   28.485864] Calling initcall 0x78a39ef0: hpt3x2n_init+0x0/0x20()
[   28.491866] initcall 0x78a39ef0: hpt3x2n_init+0x0/0x20() returned 0.
[   28.498165] initcall 0x78a39ef0 ran for 0 msecs: hpt3x2n_init+0x0/0x20()
[   28.504840] Calling initcall 0x78a39f10: hpt3x3_init+0x0/0x20()
[   28.510758] initcall 0x78a39f10: hpt3x3_init+0x0/0x20() returned 0.
[   28.516972] initcall 0x78a39f10 ran for 0 msecs: hpt3x3_init+0x0/0x20()
[   28.523564] Calling initcall 0x78a39f30: it8213_init+0x0/0x20()
[   28.529477] initcall 0x78a39f30: it8213_init+0x0/0x20() returned 0.
[   28.535694] initcall 0x78a39f30 ran for 0 msecs: it8213_init+0x0/0x20()
[   28.542280] Calling initcall 0x78a39f50: netcell_init+0x0/0x20()
[   28.548288] initcall 0x78a39f50: netcell_init+0x0/0x20() returned 0.
[   28.554581] initcall 0x78a39f50 ran for 0 msecs: netcell_init+0x0/0x20()
[   28.561256] Calling initcall 0x78a39f70: ns87410_init+0x0/0x20()
[   28.567261] initcall 0x78a39f70: ns87410_init+0x0/0x20() returned 0.
[   28.573562] initcall 0x78a39f70 ran for 0 msecs: ns87410_init+0x0/0x20()
[   28.580241] Calling initcall 0x78a39f90: ns87415_init+0x0/0x20()
[   28.586267] initcall 0x78a39f90: ns87415_init+0x0/0x20() returned 0.
[   28.592543] initcall 0x78a39f90 ran for 0 msecs: ns87415_init+0x0/0x20()
[   28.599217] Calling initcall 0x78a39fb0: opti_init+0x0/0x20()
[   28.604958] initcall 0x78a39fb0: opti_init+0x0/0x20() returned 0.
[   28.610998] initcall 0x78a39fb0 ran for 0 msecs: opti_init+0x0/0x20()
[   28.617412] Calling initcall 0x78a39fd0: marvell_init+0x0/0x20()
[   28.623412] initcall 0x78a39fd0: marvell_init+0x0/0x20() returned 0.
[   28.629718] initcall 0x78a39fd0 ran for 0 msecs: marvell_init+0x0/0x20()
[   28.636397] Calling initcall 0x78a39ff0: mpiix_init+0x0/0x20()
[   28.642217] initcall 0x78a39ff0: mpiix_init+0x0/0x20() returned 0.
[   28.648354] initcall 0x78a39ff0 ran for 0 msecs: mpiix_init+0x0/0x20()
[   28.654856] Calling initcall 0x78a3a010: oldpiix_init+0x0/0x20()
[   28.660850] initcall 0x78a3a010: oldpiix_init+0x0/0x20() returned 0.
[   28.667156] initcall 0x78a3a010 ran for 0 msecs: oldpiix_init+0x0/0x20()
[   28.673829] Calling initcall 0x78a3a030: pdc202xx_init+0x0/0x20()
[   28.679916] initcall 0x78a3a030: pdc202xx_init+0x0/0x20() returned 0.
[   28.686308] initcall 0x78a3a030 ran for 0 msecs: pdc202xx_init+0x0/0x20()
[   28.693073] Calling initcall 0x78a3a050: serverworks_init+0x0/0x20()
[   28.699414] initcall 0x78a3a050: serverworks_init+0x0/0x20() returned 0.
[   28.706064] initcall 0x78a3a050 ran for 0 msecs: serverworks_init+0x0/0x20()
[   28.713091] Calling initcall 0x78a3a4b0: sil680_init+0x0/0x20()
[   28.719000] initcall 0x78a3a4b0: sil680_init+0x0/0x20() returned 0.
[   28.725222] initcall 0x78a3a4b0 ran for 0 msecs: sil680_init+0x0/0x20()
[   28.731808] Calling initcall 0x78a3a4d0: via_init+0x0/0x20()
[   28.737460] initcall 0x78a3a4d0: via_init+0x0/0x20() returned 0.
[   28.743418] initcall 0x78a3a4d0 ran for 0 msecs: via_init+0x0/0x20()
[   28.749749] Calling initcall 0x78a3a4f0: triflex_init+0x0/0x20()
[   28.755744] initcall 0x78a3a4f0: triflex_init+0x0/0x20() returned 0.
[   28.762053] initcall 0x78a3a4f0 ran for 0 msecs: triflex_init+0x0/0x20()
[   28.768726] Calling initcall 0x78a3a510: pata_platform_init+0x0/0x10()
[   28.775237] initcall 0x78a3a510: pata_platform_init+0x0/0x10() returned 0.
[   28.782072] initcall 0x78a3a510 ran for 0 msecs: pata_platform_init+0x0/0x10()
[   28.789265] Calling initcall 0x78a3a880: ata_generic_init+0x0/0x20()
[   28.795609] initcall 0x78a3a880: ata_generic_init+0x0/0x20() returned 0.
[   28.802264] initcall 0x78a3a880 ran for 0 msecs: ata_generic_init+0x0/0x20()
[   28.809283] Calling initcall 0x78a3a8a0: i2o_iop_init+0x0/0x50()
[   28.815261] I2O subsystem v1.325
[   28.818472] i2o: max drivers = 8
[   28.821766] initcall 0x78a3a8a0: i2o_iop_init+0x0/0x50() returned 0.
[   28.827997] initcall 0x78a3a8a0 ran for 6 msecs: i2o_iop_init+0x0/0x50()
[   28.834672] Calling initcall 0x78a3b210: i2o_config_init+0x0/0xa0()
[   28.840913] I2O Configuration OSM v1.323
[   28.844853] initcall 0x78a3b210: i2o_config_init+0x0/0xa0() returned 0.
[   28.851395] initcall 0x78a3b210 ran for 6 msecs: i2o_config_init+0x0/0xa0()
[   28.858337] Calling initcall 0x78a3b2b0: i2o_bus_init+0x0/0x40()
[   28.864312] I2O Bus Adapter OSM v1.317
[   28.868057] initcall 0x78a3b2b0: i2o_bus_init+0x0/0x40() returned 0.
[   28.874361] initcall 0x78a3b2b0 ran for 2 msecs: i2o_bus_init+0x0/0x40()
[   28.881036] Calling initcall 0x78a3b2f0: i2o_block_init+0x0/0x120()
[   28.887277] I2O Block Device OSM v1.325
[   28.891222] initcall 0x78a3b2f0: i2o_block_init+0x0/0x120() returned 0.
[   28.897673] initcall 0x78a3b2f0 ran for 3 msecs: i2o_block_init+0x0/0x120()
[   28.904608] Calling initcall 0x78a3b410: i2o_proc_init+0x0/0x190()
[   28.910762] I2O ProcFS OSM v1.316
[   28.914071] initcall 0x78a3b410: i2o_proc_init+0x0/0x190() returned 0.
[   28.920554] initcall 0x78a3b410 ran for 2 msecs: i2o_proc_init+0x0/0x190()
[   28.927399] Calling initcall 0x78a3b5a0: fusion_init+0x0/0x110()
[   28.933382] Fusion MPT base driver 3.04.06
[   28.937458] Copyright (c) 1999-2007 LSI Corporation
[   28.942319] initcall 0x78a3b5a0: fusion_init+0x0/0x110() returned 0.
[   28.948634] initcall 0x78a3b5a0 ran for 8 msecs: fusion_init+0x0/0x110()
[   28.955307] Calling initcall 0x78a3b6b0: mptspi_init+0x0/0xd0()
[   28.961199] Fusion MPT SPI Host driver 3.04.06
[   28.965645] initcall 0x78a3b6b0: mptspi_init+0x0/0xd0() returned 0.
[   28.971859] initcall 0x78a3b6b0 ran for 3 msecs: mptspi_init+0x0/0xd0()
[   28.978446] Calling initcall 0x78a3b780: mptfc_init+0x0/0xf0()
[   28.984251] Fusion MPT FC Host driver 3.04.06
[   28.988612] initcall 0x78a3b780: mptfc_init+0x0/0xf0() returned 0.
[   28.994732] initcall 0x78a3b780 ran for 3 msecs: mptfc_init+0x0/0xf0()
[   29.001235] Calling initcall 0x78a3b870: mptsas_init+0x0/0xf0()
[   29.007129] Fusion MPT SAS Host driver 3.04.06
[   29.011577] initcall 0x78a3b870: mptsas_init+0x0/0xf0() returned 0.
[   29.017785] initcall 0x78a3b870 ran for 3 msecs: mptsas_init+0x0/0xf0()
[   29.024374] Calling initcall 0x78a3b960: mptctl_init+0x0/0x100()
[   29.030355] Fusion MPT misc device (ioctl) driver 3.04.06
[   29.035742] mptctl: Registered with Fusion MPT base driver
[   29.041194] mptctl: /dev/mptctl @ (major,minor=10,220)
[   29.046308] initcall 0x78a3b960: mptctl_init+0x0/0x100() returned 0.
[   29.052628] initcall 0x78a3b960 ran for 8 msecs: mptctl_init+0x0/0x100()
[   29.059300] Calling initcall 0x78a3ba60: ieee1394_init+0x0/0x250()
[   29.065547] initcall 0x78a3ba60: ieee1394_init+0x0/0x250() returned 0.
[   29.071953] initcall 0x78a3ba60 ran for 0 msecs: ieee1394_init+0x0/0x250()
[   29.078800] Calling initcall 0x78a3bcb0: ohci1394_init+0x0/0x20()
[   29.084888] initcall 0x78a3bcb0: ohci1394_init+0x0/0x20() returned 0.
[   29.091274] initcall 0x78a3bcb0 ran for 0 msecs: ohci1394_init+0x0/0x20()
[   29.098035] Calling initcall 0x78a3c720: video1394_init_module+0x0/0xc0()
[   29.104813] video1394: Installed video1394 module
[   29.109484] initcall 0x78a3c720: video1394_init_module+0x0/0xc0() returned 0.
[   29.116580] initcall 0x78a3c720 ran for 4 msecs: video1394_init_module+0x0/0xc0()
[   29.124039] Calling initcall 0x78537590: sbp2_module_init+0x0/0xa0()
[   29.130374] initcall 0x78537590: sbp2_module_init+0x0/0xa0() returned 0.
[   29.137033] initcall 0x78537590 ran for 0 msecs: sbp2_module_init+0x0/0xa0()
[   29.144052] Calling initcall 0x78a3c7e0: dv1394_init_module+0x0/0xc0()
[   29.150554] NOTE: The dv1394 driver is unsupported and may be removed in a future Linux release. Use raw1394 instead.
[   29.161145] initcall 0x78a3c7e0: dv1394_init_module+0x0/0xc0() returned 0.
[   29.167969] initcall 0x78a3c7e0 ran for 3 msecs: dv1394_init_module+0x0/0xc0()
[   29.175169] Calling initcall 0x78a3c8a0: ether1394_init_module+0x0/0x70()
[   29.181938] initcall 0x78a3c8a0: ether1394_init_module+0x0/0x70() returned 0.
[   29.189033] initcall 0x78a3c8a0 ran for 0 msecs: ether1394_init_module+0x0/0x70()
[   29.196488] Calling initcall 0x78a3c910: uio_init+0x0/0x10()
[   29.202121] initcall 0x78a3c910: uio_init+0x0/0x10() returned 0.
[   29.208093] initcall 0x78a3c910 ran for 0 msecs: uio_init+0x0/0x10()
[   29.214422] Calling initcall 0x78a3ca30: at25_init+0x0/0x10()
[   29.220152] initcall 0x78a3ca30: at25_init+0x0/0x10() returned 0.
[   29.226207] initcall 0x78a3ca30 ran for 0 msecs: at25_init+0x0/0x10()
[   29.232623] Calling initcall 0x78a3ca40: tle62x0_init+0x0/0x10()
[   29.238611] initcall 0x78a3ca40: tle62x0_init+0x0/0x10() returned 0.
[   29.244929] initcall 0x78a3ca40 ran for 0 msecs: tle62x0_init+0x0/0x10()
[   29.251605] Calling initcall 0x78a3cc00: kvm_init+0x0/0x120()
[   29.257401] initcall 0x78a3cc00: kvm_init+0x0/0x120() returned 0.
[   29.263385] initcall 0x78a3cc00 ran for 0 msecs: kvm_init+0x0/0x120()
[   29.269804] Calling initcall 0x78a3d070: vmx_init+0x0/0x110()
[   29.275532] kvm: no hardware support
[   29.279083] initcall 0x78a3d070: vmx_init+0x0/0x110() returned -95.
[   29.285314] initcall 0x78a3d070 ran for 3 msecs: vmx_init+0x0/0x110()
[   29.291727] initcall at 0x78a3d070: vmx_init+0x0/0x110(): returned with error code -95
[   29.299615] Calling initcall 0x78a3d180: svm_init+0x0/0x20()
[   29.305244] has_svm: svm not available
[   29.308975] kvm: no hardware support
[   29.312531] initcall 0x78a3d180: svm_init+0x0/0x20() returned -95.
[   29.318678] initcall 0x78a3d180 ran for 6 msecs: svm_init+0x0/0x20()
[   29.325004] initcall at 0x78a3d180: svm_init+0x0/0x20(): returned with error code -95
[   29.332804] Calling initcall 0x78a3d4c0: mon_init+0x0/0x120()
[   29.338571] initcall 0x78a3d4c0: mon_init+0x0/0x120() returned 0.
[   29.344584] initcall 0x78a3d4c0 ran for 0 msecs: mon_init+0x0/0x120()
[   29.351000] Calling initcall 0x78a3db40: ehci_hcd_init+0x0/0x20()
[   29.357129] PCI: No IRQ known for interrupt pin B of device 0000:00:02.1. Probably buggy MP table.
[   29.365999] ehci_hcd 0000:00:02.1: Found HC with no IRQ.  Check BIOS/PCI 0000:00:02.1 setup!
[   29.374414] ehci_hcd 0000:00:02.1: init 0000:00:02.1 fail, -19
[   29.380227] initcall 0x78a3db40: ehci_hcd_init+0x0/0x20() returned 0.
[   29.386617] initcall 0x78a3db40 ran for 9 msecs: ehci_hcd_init+0x0/0x20()
[   29.393382] Calling initcall 0x78a3db60: isp116x_init+0x0/0x40()
[   29.399357] 116x: driver isp116x-hcd, 03 Nov 2005
[   29.404060] initcall 0x78a3db60: isp116x_init+0x0/0x40() returned 0.
[   29.410362] initcall 0x78a3db60 ran for 1 msecs: isp116x_init+0x0/0x40()
[   29.417564] Calling initcall 0x78a3de80: ohci_hcd_mod_init+0x0/0x70()
[   29.423978] ohci_hcd: 2006 August 04 USB 1.1 'Open' Host Controller (OHCI) Driver
[   29.431502] PCI: No IRQ known for interrupt pin A of device 0000:00:02.0. Probably buggy MP table.
[   29.440362] ohci_hcd 0000:00:02.0: Found HC with no IRQ.  Check BIOS/PCI 0000:00:02.0 setup!
[   29.448776] ohci_hcd 0000:00:02.0: init 0000:00:02.0 fail, -19
[   29.454605] initcall 0x78a3de80: ohci_hcd_mod_init+0x0/0x70() returned 0.
[   29.461325] initcall 0x78a3de80 ran for 13 msecs: ohci_hcd_mod_init+0x0/0x70()
[   29.468526] Calling initcall 0x78a3df50: uhci_hcd_init+0x0/0xb0()
[   29.474589] USB Universal Host Controller Interface driver v3.0
[   29.480512] initcall 0x78a3df50: uhci_hcd_init+0x0/0xb0() returned 0.
[   29.486893] initcall 0x78a3df50 ran for 1 msecs: uhci_hcd_init+0x0/0xb0()
[   29.493653] Calling initcall 0x78a3e000: r8a66597_init+0x0/0x50()
[   29.499720] drivers/usb/host/r8a66597-hcd.c: driver r8a66597_hcd, 29 May 2007
[   29.506850] initcall 0x78a3e000: r8a66597_init+0x0/0x50() returned 0.
[   29.513238] initcall 0x78a3e000 ran for 3 msecs: r8a66597_init+0x0/0x50()
[   29.520003] Calling initcall 0x78a3e2e0: usblp_init+0x0/0x20()
[   29.525819] usbcore: registered new interface driver usblp
[   29.531274] initcall 0x78a3e2e0: usblp_init+0x0/0x20() returned 0.
[   29.537414] initcall 0x78a3e2e0 ran for 2 msecs: usblp_init+0x0/0x20()
[   29.543916] Calling initcall 0x78a3e300: usb_stor_init+0x0/0x50()
[   29.549984] Initializing USB Mass Storage driver...
[   29.554854] usbcore: registered new interface driver usb-storage
[   29.560821] USB Mass Storage support registered.
[   29.565425] initcall 0x78a3e300: usb_stor_init+0x0/0x50() returned 0.
[   29.571824] initcall 0x78a3e300 ran for 11 msecs: usb_stor_init+0x0/0x50()
[   29.578670] Calling initcall 0x78a3e350: usb_usual_init+0x0/0x50()
[   29.584841] usbcore: registered new interface driver libusual
[   29.590550] initcall 0x78a3e350: usb_usual_init+0x0/0x50() returned 0.
[   29.597040] initcall 0x78a3e350 ran for 2 msecs: usb_usual_init+0x0/0x50()
[   29.603886] Calling initcall 0x78a3e3a0: usb_mdc800_init+0x0/0x230()
[   29.610228] usbcore: registered new interface driver mdc800
[   29.615765] drivers/usb/image/mdc800.c: v0.7.5 (30/10/2000):USB Driver for Mustek MDC800 Digital Camera
[   29.625127] initcall 0x78a3e3a0: usb_mdc800_init+0x0/0x230() returned 0.
[   29.631794] initcall 0x78a3e3a0 ran for 7 msecs: usb_mdc800_init+0x0/0x230()
[   29.638813] Calling initcall 0x78a3e5d0: microtek_drv_init+0x0/0x20()
[   29.645236] usbcore: registered new interface driver microtekX6
[   29.651126] initcall 0x78a3e5d0: microtek_drv_init+0x0/0x20() returned 0.
[   29.657873] initcall 0x78a3e5d0 ran for 2 msecs: microtek_drv_init+0x0/0x20()
[   29.664987] Calling initcall 0x78a3e5f0: usb_serial_init+0x0/0x260()
[   29.671358] usbcore: registered new interface driver usbserial
[   29.677134] drivers/usb/serial/usb-serial.c: USB Serial support registered for generic
[   29.685018] usbcore: registered new interface driver usbserial_generic
[   29.691506] drivers/usb/serial/usb-serial.c: USB Serial Driver core
[   29.697749] initcall 0x78a3e5f0: usb_serial_init+0x0/0x260() returned 0.
[   29.704410] initcall 0x78a3e5f0 ran for 11 msecs: usb_serial_init+0x0/0x260()
[   29.711524] Calling initcall 0x78a3e850: aircable_init+0x0/0x40()
[   29.717599] drivers/usb/serial/usb-serial.c: USB Serial support registered for aircable
[   29.725576] usbcore: registered new interface driver aircable
[   29.731287] initcall 0x78a3e850: aircable_init+0x0/0x40() returned 0.
[   29.737687] initcall 0x78a3e850 ran for 5 msecs: aircable_init+0x0/0x40()
[   29.744450] Calling initcall 0x78a3e890: airprime_init+0x0/0x60()
[   29.750530] drivers/usb/serial/usb-serial.c: USB Serial support registered for airprime
[   29.758508] usbcore: registered new interface driver airprime
[   29.764219] initcall 0x78a3e890: airprime_init+0x0/0x60() returned 0.
[   29.770622] initcall 0x78a3e890 ran for 5 msecs: airprime_init+0x0/0x60()
[   29.777381] Calling initcall 0x78a3e8f0: ark3116_init+0x0/0x40()
[   29.783374] drivers/usb/serial/usb-serial.c: USB Serial support registered for ark3116
[   29.791264] usbcore: registered new interface driver ark3116
[   29.796891] initcall 0x78a3e8f0: ark3116_init+0x0/0x40() returned 0.
[   29.803207] initcall 0x78a3e8f0 ran for 6 msecs: ark3116_init+0x0/0x40()
[   29.809885] Calling initcall 0x78a3e930: cypress_init+0x0/0xd0()
[   29.815860] drivers/usb/serial/cypress_m8.c: cypress_init
[   29.821249] drivers/usb/serial/usb-serial.c: USB Serial support registered for DeLorme Earthmate USB
[   29.830350] drivers/usb/serial/usb-serial.c: USB Serial support registered for HID->COM RS232 Adapter
[   29.839535] drivers/usb/serial/usb-serial.c: USB Serial support registered for Nokia CA-42 V2 Adapter
[   29.848721] usbcore: registered new interface driver cypress
[   29.854343] drivers/usb/serial/cypress_m8.c: Cypress USB to Serial Driver v1.09
[   29.861625] initcall 0x78a3e930: cypress_init+0x0/0xd0() returned 0.
[   29.867940] initcall 0x78a3e930 ran for 18 msecs: cypress_init+0x0/0xd0()
[   29.874708] Calling initcall 0x78a3ea00: debug_init+0x0/0x40()
[   29.880522] drivers/usb/serial/usb-serial.c: USB Serial support registered for debug
[   29.888239] usbcore: registered new interface driver debug
[   29.893692] initcall 0x78a3ea00: debug_init+0x0/0x40() returned 0.
[   29.899834] initcall 0x78a3ea00 ran for 5 msecs: debug_init+0x0/0x40()
[   29.906339] Calling initcall 0x78a3ea40: empeg_init+0x0/0x120()
[   29.912270] drivers/usb/serial/usb-serial.c: USB Serial support registered for empeg
[   29.919957] usbcore: registered new interface driver empeg
[   29.925405] drivers/usb/serial/empeg.c: v1.2:USB Empeg Mark I/II Driver
[   29.931994] initcall 0x78a3ea40: empeg_init+0x0/0x120() returned 0.
[   29.938227] initcall 0x78a3ea40 ran for 9 msecs: empeg_init+0x0/0x120()
[   29.944817] Calling initcall 0x78a3eb60: ftdi_init+0x0/0xf0()
[   29.950544] drivers/usb/serial/usb-serial.c: USB Serial support registered for FTDI USB Serial Device
[   29.959734] usbcore: registered new interface driver ftdi_sio
[   29.965442] drivers/usb/serial/ftdi_sio.c: v1.4.3:USB FTDI Serial Converters Driver
[   29.973072] initcall 0x78a3eb60: ftdi_init+0x0/0xf0() returned 0.
[   29.979131] initcall 0x78a3eb60 ran for 7 msecs: ftdi_init+0x0/0xf0()
[   29.985545] Calling initcall 0x78a3ec50: funsoft_init+0x0/0x40()
[   29.991534] drivers/usb/serial/usb-serial.c: USB Serial support registered for funsoft
[   29.999426] usbcore: registered new interface driver funsoft
[   30.005051] initcall 0x78a3ec50: funsoft_init+0x0/0x40() returned 0.
[   30.011370] initcall 0x78a3ec50 ran for 6 msecs: funsoft_init+0x0/0x40()
[   30.018044] Calling initcall 0x78a3ec90: hp49gp_init+0x0/0x70()
[   30.023946] drivers/usb/serial/usb-serial.c: USB Serial support registered for hp4X
[   30.031578] usbcore: registered new interface driver hp4X
[   30.036939] drivers/usb/serial/hp4x.c: HP4x (48/49) Generic Serial driver v1.00
[   30.044220] initcall 0x78a3ec90: hp49gp_init+0x0/0x70() returned 0.
[   30.050451] initcall 0x78a3ec90 ran for 8 msecs: hp49gp_init+0x0/0x70()
[   30.057037] Calling initcall 0x7858aff0: usb_ipw_init+0x0/0x70()
[   30.063030] drivers/usb/serial/usb-serial.c: USB Serial support registered for IPWireless converter
[   30.072049] usbcore: registered new interface driver ipwtty
[   30.077582] drivers/usb/serial/ipw.c: IPWireless tty driver v0.3
[   30.083564] initcall 0x7858aff0: usb_ipw_init+0x0/0x70() returned 0.
[   30.089882] initcall 0x7858aff0 ran for 10 msecs: usb_ipw_init+0x0/0x70()
[   30.096646] Calling initcall 0x78a3ed00: keyspan_pda_init+0x0/0xa0()
[   30.102981] drivers/usb/serial/usb-serial.c: USB Serial support registered for Keyspan PDA
[   30.111218] drivers/usb/serial/usb-serial.c: USB Serial support registered for Keyspan PDA - (prerenumeration)
[   30.121184] drivers/usb/serial/usb-serial.c: USB Serial support registered for Xircom / Entregra PGS - (prerenumeration)
[   30.132017] usbcore: registered new interface driver keyspan_pda
[   30.137986] drivers/usb/serial/keyspan_pda.c: USB Keyspan PDA Converter driver v1.1
[   30.145614] initcall 0x78a3ed00: keyspan_pda_init+0x0/0xa0() returned 0.
[   30.152280] initcall 0x78a3ed00 ran for 18 msecs: keyspan_pda_init+0x0/0xa0()
[   30.159389] Calling initcall 0x78a3eda0: klsi_105_init+0x0/0x70()
[   30.165463] drivers/usb/serial/usb-serial.c: USB Serial support registered for KL5KUSB105D / PalmConnect
[   30.174914] usbcore: registered new interface driver kl5kusb105d
[   30.180882] drivers/usb/serial/kl5kusb105.c: KLSI KL5KUSB105 chipset USB->Serial Converter driver v0.3a
[   30.190244] initcall 0x78a3eda0: klsi_105_init+0x0/0x70() returned 0.
[   30.196648] initcall 0x78a3eda0 ran for 7 msecs: klsi_105_init+0x0/0x70()
[   30.203413] Calling initcall 0x78a3ee10: moschip7720_init+0x0/0x90()
[   30.209747] drivers/usb/serial/usb-serial.c: USB Serial support registered for Moschip 2 port adapter
[   30.218926] drivers/usb/serial/mos7720.c: Moschip USB Serial Driver 1.0.0.4F
[   30.225956] usbcore: registered new interface driver moschip7720
[   30.231930] initcall 0x78a3ee10: moschip7720_init+0x0/0x90() returned 0.
[   30.238595] initcall 0x78a3ee10 ran for 11 msecs: moschip7720_init+0x0/0x90()
[   30.245701] Calling initcall 0x78a3eea0: moschip7840_init+0x0/0xf0()
[   30.252038] drivers/usb/serial/usb-serial.c: USB Serial support registered for Moschip 7840/7820 USB Serial Driver
[   30.262344] drivers/usb/serial/mos7840.c: Moschip 7840/7820 USB Serial Driver 1.3.1
[   30.269981] usbcore: registered new interface driver mos7840
[   30.275607] initcall 0x78a3eea0: moschip7840_init+0x0/0xf0() returned 0.
[   30.282272] initcall 0x78a3eea0 ran for 9 msecs: moschip7840_init+0x0/0xf0()
[   30.289292] Calling initcall 0x78a3ef90: omninet_init+0x0/0x70()
[   30.295281] drivers/usb/serial/usb-serial.c: USB Serial support registered for ZyXEL - omni.net lcd plus usb
[   30.305080] usbcore: registered new interface driver omninet
[   30.310700] drivers/usb/serial/omninet.c: v1.1:USB ZyXEL omni.net LCD PLUS Driver
[   30.318156] initcall 0x78a3ef90: omninet_init+0x0/0x70() returned 0.
[   30.324471] initcall 0x78a3ef90 ran for 9 msecs: omninet_init+0x0/0x70()
[   30.331146] Calling initcall 0x78a3f000: sierra_init+0x0/0x80()
[   30.337052] drivers/usb/serial/usb-serial.c: USB Serial support registered for Sierra USB modem (1 port)
[   30.346504] drivers/usb/serial/usb-serial.c: USB Serial support registered for Sierra USB modem (3 port)
[   30.355950] usbcore: registered new interface driver sierra
[   30.361485] drivers/usb/serial/sierra.c: USB Driver for Sierra Wireless USB modems: v.1.2.5b
[   30.369892] initcall 0x78a3f000: sierra_init+0x0/0x80() returned 0.
[   30.376123] initcall 0x78a3f000 ran for 11 msecs: sierra_init+0x0/0x80()
[   30.382801] Calling initcall 0x78a3f080: whiteheat_init+0x0/0x80()
[   30.388962] drivers/usb/serial/usb-serial.c: USB Serial support registered for Connect Tech - WhiteHEAT - (prerenumeration)
[   30.400622] drivers/usb/serial/usb-serial.c: USB Serial support registered for Connect Tech - WhiteHEAT
[   30.409983] usbcore: registered new interface driver whiteheat
[   30.415777] drivers/usb/serial/whiteheat.c: USB ConnectTech WhiteHEAT driver v2.0
[   30.423233] initcall 0x78a3f080: whiteheat_init+0x0/0x80() returned 0.
[   30.429723] initcall 0x78a3f080 ran for 10 msecs: whiteheat_init+0x0/0x80()
[   30.436662] Calling initcall 0x78a3f100: appledisplay_init+0x0/0x50()
[   30.443119] usbcore: registered new interface driver appledisplay
[   30.449146] initcall 0x78a3f100: appledisplay_init+0x0/0x50() returned 0.
[   30.455892] initcall 0x78a3f100 ran for 5 msecs: appledisplay_init+0x0/0x50()
[   30.463007] Calling initcall 0x78a3f150: auerswald_init+0x0/0x40()
[   30.469161] usbcore: registered new interface driver auerswald
[   30.474969] initcall 0x78a3f150: auerswald_init+0x0/0x40() returned 0.
[   30.481463] initcall 0x78a3f150 ran for 2 msecs: auerswald_init+0x0/0x40()
[   30.488311] Calling initcall 0x78a3f190: berry_init+0x0/0x20()
[   30.494120] usbcore: registered new interface driver berry_charge
[   30.500189] initcall 0x78a3f190: berry_init+0x0/0x20() returned 0.
[   30.506332] initcall 0x78a3f190 ran for 1 msecs: berry_init+0x0/0x20()
[   30.512837] Calling initcall 0x78a3f1b0: emi26_init+0x0/0x20()
[   30.518644] usbcore: registered new interface driver emi26 - firmware loader
[   30.525666] initcall 0x78a3f1b0: emi26_init+0x0/0x20() returned 0.
[   30.531813] initcall 0x78a3f1b0 ran for 3 msecs: emi26_init+0x0/0x20()
[   30.538312] Calling initcall 0x78a3f1d0: usb_idmouse_init+0x0/0x50()
[   30.544643] drivers/usb/misc/idmouse.c: Siemens ID Mouse FingerTIP Sensor Driver 0.6
[   30.552361] usbcore: registered new interface driver idmouse
[   30.557991] initcall 0x78a3f1d0: usb_idmouse_init+0x0/0x50() returned 0.
[   30.564657] initcall 0x78a3f1d0 ran for 6 msecs: usb_idmouse_init+0x0/0x50()
[   30.571680] Calling initcall 0x78a3f220: ld_usb_init+0x0/0x40()
[   30.577575] usbcore: registered new interface driver ldusb
[   30.583037] initcall 0x78a3f220: ld_usb_init+0x0/0x40() returned 0.
[   30.589264] initcall 0x78a3f220 ran for 1 msecs: ld_usb_init+0x0/0x40()
[   30.595857] Calling initcall 0x78a3f260: usb_led_init+0x0/0x40()
[   30.601840] usbcore: registered new interface driver usbled
[   30.607388] initcall 0x78a3f260: usb_led_init+0x0/0x40() returned 0.
[   30.613706] initcall 0x78a3f260 ran for 2 msecs: usb_led_init+0x0/0x40()
[   30.620377] Calling initcall 0x78a3f2a0: lego_usb_tower_init+0x0/0xa0()
[   30.626972] usbcore: registered new interface driver legousbtower
[   30.633036] drivers/usb/misc/legousbtower.c: LEGO USB Tower Driver v0.96
[   30.639713] initcall 0x78a3f2a0: lego_usb_tower_init+0x0/0xa0() returned 0.
[   30.646637] initcall 0x78a3f2a0 ran for 5 msecs: lego_usb_tower_init+0x0/0xa0()
[   30.653921] Calling initcall 0x78a3f340: init_phidget+0x0/0x20()
[   30.659905] initcall 0x78a3f340: init_phidget+0x0/0x20() returned 0.
[   30.666221] initcall 0x78a3f340 ran for 0 msecs: init_phidget+0x0/0x20()
[   30.672900] Calling initcall 0x78a3f360: tv_init+0x0/0x60()
[   30.678455] usbcore: registered new interface driver trancevibrator
[   30.684688] drivers/usb/misc/trancevibrator.c: v1.1:PlayStation 2 Trance Vibrator driver
[   30.692750] initcall 0x78a3f360: tv_init+0x0/0x60() returned 0.
[   30.698636] initcall 0x78a3f360 ran for 4 msecs: tv_init+0x0/0x60()
[   30.704876] Calling initcall 0x78a3f3c0: usb_sisusb_init+0x0/0x20()
[   30.711125] usbcore: registered new interface driver sisusb
[   30.716669] initcall 0x78a3f3c0: usb_sisusb_init+0x0/0x20() returned 0.
[   30.723245] initcall 0x78a3f3c0 ran for 1 msecs: usb_sisusb_init+0x0/0x20()
[   30.730183] Calling initcall 0x78a3fcc0: i8042_init+0x0/0xe0()
[   30.738429] serio: i8042 KBD port at 0x60,0x64 irq 1
[   30.743287] serio: i8042 AUX port at 0x60,0x64 irq 12
[   30.748304] initcall 0x78a3fcc0: i8042_init+0x0/0xe0() returned 0.
[   30.754440] initcall 0x78a3fcc0 ran for 8 msecs: i8042_init+0x0/0xe0()
[   30.760943] Calling initcall 0x78a3fda0: pcips2_init+0x0/0x20()
[   30.766865] initcall 0x78a3fda0: pcips2_init+0x0/0x20() returned 0.
[   30.773076] initcall 0x78a3fda0 ran for 0 msecs: pcips2_init+0x0/0x20()
[   30.779667] Calling initcall 0x78a3fee0: serio_raw_init+0x0/0x20()
[   30.785835] initcall 0x78a3fee0: serio_raw_init+0x0/0x20() returned 0.
[   30.792317] initcall 0x78a3fee0 ran for 0 msecs: serio_raw_init+0x0/0x20()
[   30.799162] Calling initcall 0x78a40110: fm801_gp_init+0x0/0x20()
[   30.805252] initcall 0x78a40110: fm801_gp_init+0x0/0x20() returned 0.
[   30.811643] initcall 0x78a40110 ran for 0 msecs: fm801_gp_init+0x0/0x20()
[   30.818403] Calling initcall 0x78a40130: l4_init+0x0/0x2b0()
[   30.824048] initcall 0x78a40130: l4_init+0x0/0x2b0() returned -19.
[   30.830184] initcall 0x78a40130 ran for 0 msecs: l4_init+0x0/0x2b0()
[   30.836511] Calling initcall 0x78a403e0: ns558_init+0x0/0x390()
[   30.851150] initcall 0x78a403e0: ns558_init+0x0/0x390() returned -19.
[   30.857428] initcall 0x78a403e0 ran for 5 msecs: ns558_init+0x0/0x390()
[   30.864017] Calling initcall 0x78a40870: mousedev_init+0x0/0x90()
[   30.870127] mice: PS/2 mouse device common for all mice
[   30.875294] initcall 0x78a40870: mousedev_init+0x0/0x90() returned 0.
[   30.881700] initcall 0x78a40870 ran for 4 msecs: mousedev_init+0x0/0x90()
[   30.888458] Calling initcall 0x78a40900: evdev_init+0x0/0x10()
[   30.894267] initcall 0x78a40900: evdev_init+0x0/0x10() returned 0.
[   30.900415] initcall 0x78a40900 ran for 0 msecs: evdev_init+0x0/0x10()
[   30.906914] Calling initcall 0x78a40910: evbug_init+0x0/0x10()
[   30.912729] initcall 0x78a40910: evbug_init+0x0/0x10() returned 0.
[   30.918878] initcall 0x78a40910 ran for 0 msecs: evbug_init+0x0/0x10()
[   30.925377] Calling initcall 0x78a40920: atkbd_init+0x0/0x20()
[   30.931200] initcall 0x78a40920: atkbd_init+0x0/0x20() returned 0.
[   30.937330] initcall 0x78a40920 ran for 0 msecs: atkbd_init+0x0/0x20()
[   30.943832] Calling initcall 0x78a40940: sunkbd_init+0x0/0x20()
[   30.949746] initcall 0x78a40940: sunkbd_init+0x0/0x20() returned 0.
[   30.955965] initcall 0x78a40940 ran for 0 msecs: sunkbd_init+0x0/0x20()
[   30.962554] Calling initcall 0x78a40960: xtkbd_init+0x0/0x20()
[   30.968376] initcall 0x78a40960: xtkbd_init+0x0/0x20() returned 0.
[   30.974508] initcall 0x78a40960 ran for 0 msecs: xtkbd_init+0x0/0x20()
[   30.981010] Calling initcall 0x78a40980: a3d_init+0x0/0x10()
[   30.986660] initcall 0x78a40980: a3d_init+0x0/0x10() returned 0.
[   30.992622] initcall 0x78a40980 ran for 0 msecs: a3d_init+0x0/0x10()
[   30.998952] Calling initcall 0x78a40990: adi_init+0x0/0x10()
[   31.004594] initcall 0x78a40990: adi_init+0x0/0x10() returned 0.
[   31.010559] initcall 0x78a40990 ran for 0 msecs: adi_init+0x0/0x10()
[   31.016887] Calling initcall 0x78a409a0: analog_init+0x0/0x100()
[   31.022874] initcall 0x78a409a0: analog_init+0x0/0x100() returned 0.
[   31.029191] initcall 0x78a409a0 ran for 0 msecs: analog_init+0x0/0x100()
[   31.035869] Calling initcall 0x78a40aa0: cobra_init+0x0/0x10()
[   31.041679] initcall 0x78a40aa0: cobra_init+0x0/0x10() returned 0.
[   31.047823] initcall 0x78a40aa0 ran for 0 msecs: cobra_init+0x0/0x10()
[   31.054325] Calling initcall 0x78a40ab0: grip_init+0x0/0x10()
[   31.060051] initcall 0x78a40ab0: grip_init+0x0/0x10() returned 0.
[   31.066111] initcall 0x78a40ab0 ran for 0 msecs: grip_init+0x0/0x10()
[   31.072527] Calling initcall 0x78a40ac0: grip_init+0x0/0x10()
[   31.078251] initcall 0x78a40ac0: grip_init+0x0/0x10() returned 0.
[   31.084307] initcall 0x78a40ac0 ran for 0 msecs: grip_init+0x0/0x10()
[   31.090723] Calling initcall 0x78a40ad0: guillemot_init+0x0/0x10()
[   31.096881] initcall 0x78a40ad0: guillemot_init+0x0/0x10() returned 0.
[   31.103375] initcall 0x78a40ad0 ran for 0 msecs: guillemot_init+0x0/0x10()
[   31.110221] Calling initcall 0x78a40ae0: interact_init+0x0/0x10()
[   31.116293] initcall 0x78a40ae0: interact_init+0x0/0x10() returned 0.
[   31.122701] initcall 0x78a40ae0 ran for 0 msecs: interact_init+0x0/0x10()
[   31.129466] Calling initcall 0x78a40af0: joydump_init+0x0/0x10()
[   31.135446] initcall 0x78a40af0: joydump_init+0x0/0x10() returned 0.
[   31.141769] initcall 0x78a40af0 ran for 0 msecs: joydump_init+0x0/0x10()
[   31.148442] Calling initcall 0x78a40b00: magellan_init+0x0/0x20()
[   31.154531] initcall 0x78a40b00: magellan_init+0x0/0x20() returned 0.
[   31.160916] initcall 0x78a40b00 ran for 2 msecs: magellan_init+0x0/0x20()
[   31.167678] Calling initcall 0x78a40b20: sw_init+0x0/0x10()
[   31.173231] initcall 0x78a40b20: sw_init+0x0/0x10() returned 0.
[   31.179115] initcall 0x78a40b20 ran for 0 msecs: sw_init+0x0/0x10()
[   31.185360] Calling initcall 0x78a40b30: stinger_init+0x0/0x20()
[   31.191363] initcall 0x78a40b30: stinger_init+0x0/0x20() returned 0.
[   31.197661] initcall 0x78a40b30 ran for 0 msecs: stinger_init+0x0/0x20()
[   31.204336] Calling initcall 0x78a40b50: tmdc_init+0x0/0x10()
[   31.210062] initcall 0x78a40b50: tmdc_init+0x0/0x10() returned 0.
[   31.216122] initcall 0x78a40b50 ran for 0 msecs: tmdc_init+0x0/0x10()
[   31.222537] Calling initcall 0x78a40b60: usb_xpad_init+0x0/0x40()
[   31.228613] usbcore: registered new interface driver xpad
[   31.233981] drivers/input/joystick/xpad.c: X-Box pad driver:v0.0.6
[   31.240136] initcall 0x78a40b60: usb_xpad_init+0x0/0x40() returned 0.
[   31.246540] initcall 0x78a40b60 ran for 4 msecs: usb_xpad_init+0x0/0x40()
[   31.253305] Calling initcall 0x78a40ba0: iforce_init+0x0/0x20()
[   31.259213] initcall 0x78a40ba0: iforce_init+0x0/0x20() returned 0.
[   31.265435] initcall 0x78a40ba0 ran for 0 msecs: iforce_init+0x0/0x20()
[   31.272021] Calling initcall 0x78a40cc0: i2c_dev_init+0x0/0x90()
[   31.277999] i2c /dev entries driver
[   31.281514] initcall 0x78a40cc0: i2c_dev_init+0x0/0x90() returned 0.
[   31.287788] initcall 0x78a40cc0 ran for 3 msecs: i2c_dev_init+0x0/0x90()
[   31.294464] Calling initcall 0x78a40f70: ali1563_init+0x0/0x20()
[   31.300470] initcall 0x78a40f70: ali1563_init+0x0/0x20() returned 0.
[   31.306769] initcall 0x78a40f70 ran for 0 msecs: ali1563_init+0x0/0x20()
[   31.313442] Calling initcall 0x78a41140: i2c_amd8111_init+0x0/0x20()
[   31.319794] initcall 0x78a41140: i2c_amd8111_init+0x0/0x20() returned 0.
[   31.326441] initcall 0x78a41140 ran for 0 msecs: i2c_amd8111_init+0x0/0x20()
[   31.333466] Calling initcall 0x78a41230: i2c_i810_init+0x0/0x20()
[   31.339553] initcall 0x78a41230: i2c_i810_init+0x0/0x20() returned 0.
[   31.345940] initcall 0x78a41230 ran for 0 msecs: i2c_i810_init+0x0/0x20()
[   31.352706] Calling initcall 0x78a41250: i2c_parport_init+0x0/0x190()
[   31.359114] i2c-parport-light: adapter type unspecified
[   31.364321] initcall 0x78a41250: i2c_parport_init+0x0/0x190() returned -19.
[   31.371249] initcall 0x78a41250 ran for 1 msecs: i2c_parport_init+0x0/0x190()
[   31.378357] Calling initcall 0x78a41950: i2c_piix4_init+0x0/0x20()
[   31.384536] initcall 0x78a41950: i2c_piix4_init+0x0/0x20() returned 0.
[   31.391002] initcall 0x78a41950 ran for 0 msecs: i2c_piix4_init+0x0/0x20()
[   31.397855] Calling initcall 0x78a41b20: i2c_prosavage_init+0x0/0x20()
[   31.404376] initcall 0x78a41b20: i2c_prosavage_init+0x0/0x20() returned 0.
[   31.411199] initcall 0x78a41b20 ran for 0 msecs: i2c_prosavage_init+0x0/0x20()
[   31.418394] Calling initcall 0x78a41be0: i2c_savage4_init+0x0/0x20()
[   31.424742] initcall 0x78a41be0: i2c_savage4_init+0x0/0x20() returned 0.
[   31.431391] initcall 0x78a41be0 ran for 0 msecs: i2c_savage4_init+0x0/0x20()
[   31.438411] Calling initcall 0x78a41fc0: i2c_sis5595_init+0x0/0x20()
[   31.444760] initcall 0x78a41fc0: i2c_sis5595_init+0x0/0x20() returned 0.
[   31.451410] initcall 0x78a41fc0 ran for 0 msecs: i2c_sis5595_init+0x0/0x20()
[   31.458431] Calling initcall 0x78a42220: i2c_sis630_init+0x0/0x20()
[   31.464692] initcall 0x78a42220: i2c_sis630_init+0x0/0x20() returned 0.
[   31.471256] initcall 0x78a42220 ran for 0 msecs: i2c_sis630_init+0x0/0x20()
[   31.478190] Calling initcall 0x78a42240: usb_i2c_tiny_usb_init+0x0/0x20()
[   31.484958] usbcore: registered new interface driver i2c-tiny-usb
[   31.491022] initcall 0x78a42240: usb_i2c_tiny_usb_init+0x0/0x20() returned 0.
[   31.498121] initcall 0x78a42240 ran for 2 msecs: usb_i2c_tiny_usb_init+0x0/0x20()
[   31.506131] Calling initcall 0x78a42260: i2c_vt596_init+0x0/0x20()
[   31.512304] initcall 0x78a42260: i2c_vt596_init+0x0/0x20() returned 0.
[   31.518779] initcall 0x78a42260 ran for 0 msecs: i2c_vt596_init+0x0/0x20()
[   31.525627] Calling initcall 0x78a42730: i2c_voodoo3_init+0x0/0x20()
[   31.531976] initcall 0x78a42730: i2c_voodoo3_init+0x0/0x20() returned 0.
[   31.538626] initcall 0x78a42730 ran for 0 msecs: i2c_voodoo3_init+0x0/0x20()
[   31.545644] Calling initcall 0x78a42900: scx200_acb_init+0x0/0x220()
[   31.551970] scx200_acb: NatSemi SCx200 ACCESS.bus Driver
[   31.557266] initcall 0x78a42900: scx200_acb_init+0x0/0x220() returned -19.
[   31.564099] initcall 0x78a42900 ran for 1 msecs: scx200_acb_init+0x0/0x220()
[   31.571127] Calling initcall 0x78a42b20: ds1682_init+0x0/0x10()
[   31.577031] initcall 0x78a42b20: ds1682_init+0x0/0x10() returned 0.
[   31.583254] initcall 0x78a42b20 ran for 0 msecs: ds1682_init+0x0/0x10()
[   31.589845] Calling initcall 0x78a42b30: pcf8591_init+0x0/0x40()
[   31.595835] initcall 0x78a42b30: pcf8591_init+0x0/0x40() returned 0.
[   31.602148] initcall 0x78a42b30 ran for 0 msecs: pcf8591_init+0x0/0x40()
[   31.608821] Calling initcall 0x78a42d50: tsl2550_init+0x0/0x10()
[   31.614816] initcall 0x78a42d50: tsl2550_init+0x0/0x10() returned 0.
[   31.621127] initcall 0x78a42d50 ran for 0 msecs: tsl2550_init+0x0/0x10()
[   31.627803] Calling initcall 0x785c6a50: w1_init+0x0/0x120()
[   31.633432] Driver for 1-wire Dallas network protocol.
[   31.638953] initcall 0x785c6a50: w1_init+0x0/0x120() returned 0.
[   31.644804] initcall 0x785c6a50 ran for 3 msecs: w1_init+0x0/0x120()
[   31.651134] Calling initcall 0x78a42f90: matrox_w1_init+0x0/0x20()
[   31.657301] initcall 0x78a42f90: matrox_w1_init+0x0/0x20() returned 0.
[   31.663776] initcall 0x78a42f90 ran for 0 msecs: matrox_w1_init+0x0/0x20()
[   31.670624] Calling initcall 0x785c80c0: ds_init+0x0/0x40()
[   31.676180] usbcore: registered new interface driver DS9490R
[   31.681813] initcall 0x785c80c0: ds_init+0x0/0x40() returned 0.
[   31.687695] initcall 0x785c80c0 ran for 5 msecs: ds_init+0x0/0x40()
[   31.693937] Calling initcall 0x78a42fb0: w1_ds2760_init+0x0/0x30()
[   31.700091] 1-Wire driver for the DS2760 battery monitor  chip  - (c) 2004-2005, Szabolcs Gyurko
[   31.708869] initcall 0x78a42fb0: w1_ds2760_init+0x0/0x30() returned 0.
[   31.715345] initcall 0x78a42fb0 ran for 5 msecs: w1_ds2760_init+0x0/0x30()
[   31.722191] Calling initcall 0x78a43020: asb100_init+0x0/0x10()
[   31.728093] initcall 0x78a43020: asb100_init+0x0/0x10() returned 0.
[   31.734318] initcall 0x78a43020 ran for 0 msecs: asb100_init+0x0/0x10()
[   31.740908] Calling initcall 0x78a43030: sensors_w83792d_init+0x0/0x10()
[   31.747592] initcall 0x78a43030: sensors_w83792d_init+0x0/0x10() returned 0.
[   31.754603] initcall 0x78a43030 ran for 0 msecs: sensors_w83792d_init+0x0/0x10()
[   31.761971] Calling initcall 0x78a43200: sensors_w83781d_init+0x0/0x420()
[   31.768747] w83781d: Detection failed at step 3
[   31.773242] initcall 0x78a43200: sensors_w83781d_init+0x0/0x420() returned 0.
[   31.780338] initcall 0x78a43200 ran for 1 msecs: sensors_w83781d_init+0x0/0x420()
[   31.787797] Calling initcall 0x78a43620: ad7418_init+0x0/0x10()
[   31.793695] initcall 0x78a43620: ad7418_init+0x0/0x10() returned 0.
[   31.799923] initcall 0x78a43620 ran for 0 msecs: ad7418_init+0x0/0x10()
[   31.806510] Calling initcall 0x78a43630: sensors_adm1021_init+0x0/0x10()
[   31.813194] initcall 0x78a43630: sensors_adm1021_init+0x0/0x10() returned 0.
[   31.820202] initcall 0x78a43630 ran for 0 msecs: sensors_adm1021_init+0x0/0x10()
[   31.827568] Calling initcall 0x78a43640: sensors_adm1031_init+0x0/0x10()
[   31.834252] initcall 0x78a43640: sensors_adm1031_init+0x0/0x10() returned 0.
[   31.841264] initcall 0x78a43640 ran for 0 msecs: sensors_adm1031_init+0x0/0x10()
[   31.848633] Calling initcall 0x78a43650: applesmc_init+0x0/0x520()
[   31.854783] applesmc: supported laptop not found!
[   31.859466] applesmc: driver init failed (ret=-19)!
[   31.864321] initcall 0x78a43650: applesmc_init+0x0/0x520() returned -19.
[   31.870983] initcall 0x78a43650 ran for 5 msecs: applesmc_init+0x0/0x520()
[   31.877838] Calling initcall 0x78a43cc0: f71805f_init+0x0/0x170()
[   31.883928] initcall 0x78a43cc0: f71805f_init+0x0/0x170() returned -19.
[   31.890484] initcall 0x78a43cc0 ran for 0 msecs: f71805f_init+0x0/0x170()
[   31.897243] Calling initcall 0x78a44250: sensors_f75375_init+0x0/0x10()
[   31.903842] initcall 0x78a44250: sensors_f75375_init+0x0/0x10() returned 0.
[   31.910761] initcall 0x78a44250 ran for 0 msecs: sensors_f75375_init+0x0/0x10()
[   31.918048] Calling initcall 0x78a44260: sensors_fscher_init+0x0/0x10()
[   31.924641] initcall 0x78a44260: sensors_fscher_init+0x0/0x10() returned 0.
[   31.931565] initcall 0x78a44260 ran for 0 msecs: sensors_fscher_init+0x0/0x10()
[   31.938845] Calling initcall 0x78a44270: sensors_gl518sm_init+0x0/0x10()
[   31.945525] initcall 0x78a44270: sensors_gl518sm_init+0x0/0x10() returned 0.
[   31.952534] initcall 0x78a44270 ran for 0 msecs: sensors_gl518sm_init+0x0/0x10()
[   31.959905] Calling initcall 0x78a44280: sensors_gl520sm_init+0x0/0x10()
[   31.966585] initcall 0x78a44280: sensors_gl520sm_init+0x0/0x10() returned 0.
[   31.973592] initcall 0x78a44280 ran for 0 msecs: sensors_gl520sm_init+0x0/0x10()
[   31.980959] Calling initcall 0x78a442e0: hdaps_init+0x0/0x1f0()
[   31.986857] hdaps: supported laptop not found!
[   31.991277] hdaps: driver init failed (ret=-19)!
[   31.995874] initcall 0x78a442e0: hdaps_init+0x0/0x1f0() returned -19.
[   32.002280] initcall 0x78a442e0 ran for 4 msecs: hdaps_init+0x0/0x1f0()
[   32.008866] Calling initcall 0x78a444d0: init_lm70+0x0/0x10()
[   32.014602] initcall 0x78a444d0: init_lm70+0x0/0x10() returned 0.
[   32.020647] initcall 0x78a444d0 ran for 0 msecs: init_lm70+0x0/0x10()
[   32.027063] Calling initcall 0x78a44600: sensors_lm77_init+0x0/0x10()
[   32.033492] initcall 0x78a44600: sensors_lm77_init+0x0/0x10() returned 0.
[   32.040235] initcall 0x78a44600 ran for 0 msecs: sensors_lm77_init+0x0/0x10()
[   32.047341] Calling initcall 0x78a44610: sensors_lm80_init+0x0/0x10()
[   32.053770] initcall 0x78a44610: sensors_lm80_init+0x0/0x10() returned 0.
[   32.060511] initcall 0x78a44610 ran for 0 msecs: sensors_lm80_init+0x0/0x10()
[   32.067620] Calling initcall 0x78a44620: sm_lm85_init+0x0/0x10()
[   32.073616] initcall 0x78a44620: sm_lm85_init+0x0/0x10() returned 0.
[   32.079926] initcall 0x78a44620 ran for 0 msecs: sm_lm85_init+0x0/0x10()
[   32.086599] Calling initcall 0x78a44630: sensors_lm87_init+0x0/0x10()
[   32.093028] initcall 0x78a44630: sensors_lm87_init+0x0/0x10() returned 0.
[   32.099772] initcall 0x78a44630 ran for 0 msecs: sensors_lm87_init+0x0/0x10()
[   32.106883] Calling initcall 0x78a44640: lm93_init+0x0/0x10()
[   32.112617] initcall 0x78a44640: lm93_init+0x0/0x10() returned 0.
[   32.118666] initcall 0x78a44640 ran for 0 msecs: lm93_init+0x0/0x10()
[   32.125079] Calling initcall 0x78a44650: sensors_max1619_init+0x0/0x10()
[   32.131765] initcall 0x78a44650: sensors_max1619_init+0x0/0x10() returned 0.
[   32.138772] initcall 0x78a44650 ran for 0 msecs: sensors_max1619_init+0x0/0x10()
[   32.146141] Calling initcall 0x78a44660: sensors_max6650_init+0x0/0x10()
[   32.152826] initcall 0x78a44660: sensors_max6650_init+0x0/0x10() returned 0.
[   32.159828] initcall 0x78a44660 ran for 0 msecs: sensors_max6650_init+0x0/0x10()
[   32.167199] Calling initcall 0x78a45540: pc87360_init+0x0/0x1a0()
[   32.173275] pc87360: PC8736x not detected, module not inserted.
[   32.179163] initcall 0x78a45540: pc87360_init+0x0/0x1a0() returned -19.
[   32.185742] initcall 0x78a45540 ran for 2 msecs: pc87360_init+0x0/0x1a0()
[   32.192504] Calling initcall 0x78a45800: pc87427_init+0x0/0x140()
[   32.198584] initcall 0x78a45800: pc87427_init+0x0/0x140() returned -19.
[   32.205154] initcall 0x78a45800 ran for 0 msecs: pc87427_init+0x0/0x140()
[   32.211914] Calling initcall 0x78a45c30: sm_sis5595_init+0x0/0x20()
[   32.218178] initcall 0x78a45c30: sm_sis5595_init+0x0/0x20() returned 0.
[   32.224740] initcall 0x78a45c30 ran for 0 msecs: sm_sis5595_init+0x0/0x20()
[   32.231674] Calling initcall 0x78a46350: vt1211_init+0x0/0x180()
[   32.237672] initcall 0x78a46350: vt1211_init+0x0/0x180() returned -19.
[   32.244147] initcall 0x78a46350 ran for 0 msecs: vt1211_init+0x0/0x180()
[   32.250821] Calling initcall 0x78a46890: sm_vt8231_init+0x0/0x20()
[   32.257001] initcall 0x78a46890: sm_vt8231_init+0x0/0x20() returned 0.
[   32.263474] initcall 0x78a46890 ran for 0 msecs: sm_vt8231_init+0x0/0x20()
[   32.270321] Calling initcall 0x78a46c90: sensors_w83627ehf_init+0x0/0x180()
[   32.277287] initcall 0x78a46c90: sensors_w83627ehf_init+0x0/0x180() returned -19.
[   32.284710] initcall 0x78a46c90 ran for 0 msecs: sensors_w83627ehf_init+0x0/0x180()
[   32.292336] Calling initcall 0x78a477b0: wdtpci_init+0x0/0x20()
[   32.298252] initcall 0x78a477b0: wdtpci_init+0x0/0x20() returned 0.
[   32.304468] initcall 0x78a477b0 ran for 0 msecs: wdtpci_init+0x0/0x20()
[   32.311057] Calling initcall 0x78a47920: acq_init+0x0/0x70()
[   32.316686] WDT driver for Acquire single board computer initialising.
[   32.323229] acquirewdt: I/O address 0x0043 already in use
[   32.328568] acquirewdt: probe of acquirewdt failed with error -5
[   32.334547] initcall 0x78a47920: acq_init+0x0/0x70() returned 0.
[   32.340514] initcall 0x78a47920 ran for 9 msecs: acq_init+0x0/0x70()
[   32.346843] Calling initcall 0x78a47b20: advwdt_init+0x0/0x70()
[   32.352737] WDT driver for Advantech single board computer initialising.
[   32.359470] advantechwdt: initialized. timeout=60 sec (nowayout=0)
[   32.365574] initcall 0x78a47b20: advwdt_init+0x0/0x70() returned 0.
[   32.371803] initcall 0x78a47b20 ran for 9 msecs: advwdt_init+0x0/0x70()
[   32.378390] Calling initcall 0x78a47b90: watchdog_init+0x0/0x1a0()
[   32.384546] initcall 0x78a47b90: watchdog_init+0x0/0x1a0() returned -19.
[   32.391217] initcall 0x78a47b90 ran for 0 msecs: watchdog_init+0x0/0x1a0()
[   32.398065] Calling initcall 0x78a47d30: alim7101_wdt_init+0x0/0x200()
[   32.404560] alim7101_wdt: Steve Hill <steve@navaho.co.uk>.
[   32.410024] alim7101_wdt: ALi M7101 PMU not present - WDT not set
[   32.416093] initcall 0x78a47d30: alim7101_wdt_init+0x0/0x200() returned -16.
[   32.423104] initcall 0x78a47d30 ran for 4 msecs: alim7101_wdt_init+0x0/0x200()
[   32.430303] initcall at 0x78a47d30: alim7101_wdt_init+0x0/0x200(): returned with error code -16
[   32.438965] Calling initcall 0x78a47f30: sc520_wdt_init+0x0/0x110()
[   32.445208] sc520_wdt: cannot register miscdev on minor=130 (err=-16)
[   32.451628] initcall 0x78a47f30: sc520_wdt_init+0x0/0x110() returned -16.
[   32.458379] initcall 0x78a47f30 ran for 2 msecs: sc520_wdt_init+0x0/0x110()
[   32.465311] initcall at 0x78a47f30: sc520_wdt_init+0x0/0x110(): returned with error code -16
[   32.473720] Calling initcall 0x78a48040: watchdog_init+0x0/0x2e0()
[   32.479878] initcall 0x78a48040: watchdog_init+0x0/0x2e0() returned -19.
[   32.486540] initcall 0x78a48040 ran for 0 msecs: watchdog_init+0x0/0x2e0()
[   32.493386] Calling initcall 0x78a48320: iTCO_wdt_init_module+0x0/0x80()
[   32.500061] iTCO_wdt: Intel TCO WatchDog Timer Driver v1.02 (26-Jul-2007)
[   32.506873] iTCO_wdt: No card detected
[   32.510560] initcall 0x78a48320: iTCO_wdt_init_module+0x0/0x80() returned 0.
[   32.517563] initcall 0x78a48320 ran for 6 msecs: iTCO_wdt_init_module+0x0/0x80()
[   32.524937] Calling initcall 0x78a483a0: iTCO_vendor_init_module+0x0/0x20()
[   32.531866] iTCO_vendor_support: vendor-support=0
[   32.536553] initcall 0x78a483a0: iTCO_vendor_init_module+0x0/0x20() returned 0.
[   32.543821] initcall 0x78a483a0 ran for 1 msecs: iTCO_vendor_init_module+0x0/0x20()
[   32.552001] Calling initcall 0x78a483c0: cpu5wdt_init_module+0x0/0x150()
[   32.558671] cpu5wdt: misc_register failed
[   32.562665] initcall 0x78a483c0: cpu5wdt_init_module+0x0/0x150() returned -16.
[   32.569848] initcall 0x78a483c0 ran for 0 msecs: cpu5wdt_init_module+0x0/0x150()
[   32.577214] initcall at 0x78a483c0: cpu5wdt_init_module+0x0/0x150(): returned with error code -16
[   32.586058] Calling initcall 0x78a48510: wb_smsc_wdt_init+0x0/0x200()
[   32.592470] SMsC 37B787 watchdog component driver 1.1 initialising...
[   32.599923] smsc37b787_wdt: Unable to register miscdev on minor 130
[   32.606064] initcall 0x78a48510: wb_smsc_wdt_init+0x0/0x200() returned -16.
[   32.612988] initcall 0x78a48510 ran for 3 msecs: wb_smsc_wdt_init+0x0/0x200()
[   32.620099] initcall at 0x78a48510: wb_smsc_wdt_init+0x0/0x200(): returned with error code -16
[   32.628676] Calling initcall 0x78a48710: w83977f_wdt_init+0x0/0x160()
[   32.635087] W83977F WDT: W83977F WDT driver, v1.00
[   32.639860] W83977F WDT: cannot register miscdev on minor=130 (err=-16)
[   32.646448] initcall 0x78a48710: w83977f_wdt_init+0x0/0x160() returned -16.
[   32.653372] initcall 0x78a48710 ran for 4 msecs: w83977f_wdt_init+0x0/0x160()
[   32.660478] initcall at 0x78a48710: w83977f_wdt_init+0x0/0x160(): returned with error code -16
[   32.669062] Calling initcall 0x78a48870: zf_init+0x0/0x1c0()
[   32.674692] machzwd: MachZ ZF-Logic Watchdog driver initializing.
[   32.680764] machzwd: no ZF-Logic found
[   32.684492] initcall 0x78a48870: zf_init+0x0/0x1c0() returned -19.
[   32.690633] initcall 0x78a48870 ran for 6 msecs: zf_init+0x0/0x1c0()
[   32.696962] Calling initcall 0x78a48a30: watchdog_init+0x0/0xd0()
[   32.703031] epx_c3: cannot register miscdev on minor=130 (err=-16)
[   32.709191] initcall 0x78a48a30: watchdog_init+0x0/0xd0() returned -16.
[   32.715767] initcall 0x78a48a30 ran for 2 msecs: watchdog_init+0x0/0xd0()
[   32.722533] initcall at 0x78a48a30: watchdog_init+0x0/0xd0(): returned with error code -16
[   32.730760] Calling initcall 0x78a48b00: watchdog_init+0x0/0xe0()
[   32.736829] SoftDog: cannot register miscdev on minor=130 (err=-16)
[   32.743076] initcall 0x78a48b00: watchdog_init+0x0/0xe0() returned -16.
[   32.749652] initcall 0x78a48b00 ran for 1 msecs: watchdog_init+0x0/0xe0()
[   32.756418] initcall at 0x78a48b00: watchdog_init+0x0/0xe0(): returned with error code -16
[   32.764650] Calling initcall 0x78a48be0: telephony_init+0x0/0x50()
[   32.770799] Linux telephony interface: v1.00
[   32.775064] initcall 0x78a48be0: telephony_init+0x0/0x50() returned 0.
[   32.781547] initcall 0x78a48be0 ran for 3 msecs: telephony_init+0x0/0x50()
[   32.788392] Calling initcall 0x78a48c30: dm_init+0x0/0x70()
[   32.793969] device-mapper: ioctl: 4.11.0-ioctl (2006-10-12) initialised: dm-devel@redhat.com
[   32.802352] initcall 0x78a48c30: dm_init+0x0/0x70() returned 0.
[   32.808238] initcall 0x78a48c30 ran for 3 msecs: dm_init+0x0/0x70()
[   32.814478] Calling initcall 0x78a48e60: dm_crypt_init+0x0/0xa0()
[   32.820593] initcall 0x78a48e60: dm_crypt_init+0x0/0xa0() returned 0.
[   32.826951] initcall 0x78a48e60 ran for 0 msecs: dm_crypt_init+0x0/0xa0()
[   32.833714] Calling initcall 0x78a48f00: dm_delay_init+0x0/0xc0()
[   32.839818] initcall 0x78a48f00: dm_delay_init+0x0/0xc0() returned 0.
[   32.846193] initcall 0x78a48f00 ran for 0 msecs: dm_delay_init+0x0/0xc0()
[   32.852958] Calling initcall 0x78a48fc0: dm_snapshot_init+0x0/0x1e0()
[   32.859450] initcall 0x78a48fc0: dm_snapshot_init+0x0/0x1e0() returned 0.
[   32.866125] initcall 0x78a48fc0 ran for 0 msecs: dm_snapshot_init+0x0/0x1e0()
[   32.873237] Calling initcall 0x78a491f0: dm_mirror_init+0x0/0x40()
[   32.879401] initcall 0x78a491f0: dm_mirror_init+0x0/0x40() returned 0.
[   32.885884] initcall 0x78a491f0 ran for 0 msecs: dm_mirror_init+0x0/0x40()
[   32.892735] Calling initcall 0x78a49230: kcapi_init+0x0/0xb0()
[   32.898548] CAPI Subsystem Rev 1.1.2.8
[   32.902273] initcall 0x78a49230: kcapi_init+0x0/0xb0() returned 0.
[   32.908419] initcall 0x78a49230 ran for 3 msecs: kcapi_init+0x0/0xb0()
[   32.914918] Calling initcall 0x78a49aa0: b1pci_init+0x0/0xd0()
[   32.920747] b1pci: revision 1.1.2.2
[   32.924197] initcall 0x78a49aa0: b1pci_init+0x0/0xd0() returned 0.
[   32.930339] initcall 0x78a49aa0 ran for 2 msecs: b1pci_init+0x0/0xd0()
[   32.936840] Calling initcall 0x78a49b70: b1_init+0x0/0x80()
[   32.942391] b1: revision 1.1.2.2
[   32.945600] initcall 0x78a49b70: b1_init+0x0/0x80() returned 0.
[   32.951489] initcall 0x78a49b70 ran for 3 msecs: b1_init+0x0/0x80()
[   32.957729] Calling initcall 0x78a49bf0: b1dma_init+0x0/0x80()
[   32.963534] b1dma: revision 1.1.2.3
[   32.967008] initcall 0x78a49bf0: b1dma_init+0x0/0x80() returned 0.
[   32.973152] initcall 0x78a49bf0 ran for 2 msecs: b1dma_init+0x0/0x80()
[   32.979651] Calling initcall 0x78a49c70: b1pcmcia_init+0x0/0xa0()
[   32.985721] b1pci: revision 1.1.2.2
[   32.989193] initcall 0x78a49c70: b1pcmcia_init+0x0/0xa0() returned 0.
[   32.995594] initcall 0x78a49c70 ran for 0 msecs: b1pcmcia_init+0x0/0xa0()
[   33.002361] Calling initcall 0x78a4a050: t1pci_init+0x0/0xb0()
[   33.008179] t1pci: revision 1.1.2.2
[   33.011638] initcall 0x78a4a050: t1pci_init+0x0/0xb0() returned 0.
[   33.017785] initcall 0x78a4a050 ran for 3 msecs: t1pci_init+0x0/0xb0()
[   33.024287] Calling initcall 0x78a4aa00: c4_init+0x0/0xd0()
[   33.029847] c4: revision 1.1.2.2
[   33.033043] initcall 0x78a4aa00: c4_init+0x0/0xd0() returned 0.
[   33.038925] initcall 0x78a4aa00 ran for 1 msecs: c4_init+0x0/0xd0()
[   33.045169] Calling initcall 0x78a4acb0: cpufreq_stats_init+0x0/0x70()
[   33.051680] initcall 0x78a4acb0: cpufreq_stats_init+0x0/0x70() returned 0.
[   33.058516] initcall 0x78a4acb0 ran for 0 msecs: cpufreq_stats_init+0x0/0x70()
[   33.065712] Calling initcall 0x78a4ad20: cpufreq_gov_powersave_init+0x0/0x10()
[   33.072906] initcall 0x78a4ad20: cpufreq_gov_powersave_init+0x0/0x10() returned 0.
[   33.080435] initcall 0x78a4ad20 ran for 0 msecs: cpufreq_gov_powersave_init+0x0/0x10()
[   33.088329] Calling initcall 0x78a4ad40: cpufreq_gov_dbs_init+0x0/0x10()
[   33.095003] initcall 0x78a4ad40: cpufreq_gov_dbs_init+0x0/0x10() returned 0.
[   33.102020] initcall 0x78a4ad40 ran for 0 msecs: cpufreq_gov_dbs_init+0x0/0x10()
[   33.109388] Calling initcall 0x78a4b4c0: hid_init+0x0/0x10()
[   33.115021] initcall 0x78a4b4c0: hid_init+0x0/0x10() returned 0.
[   33.120998] initcall 0x78a4b4c0 ran for 0 msecs: hid_init+0x0/0x10()
[   33.127321] Calling initcall 0x78a4b4d0: hid_init+0x0/0x60()
[   33.132970] usbcore: registered new interface driver usbhid
[   33.138507] drivers/hid/usbhid/hid-core.c: v2.6:USB HID core driver
[   33.144750] initcall 0x78a4b4d0: hid_init+0x0/0x60() returned 0.
[   33.150718] initcall 0x78a4b4d0 ran for 6 msecs: hid_init+0x0/0x60()
[   33.157046] Calling initcall 0x78a4b530: usb_mouse_init+0x0/0x40()
[   33.163212] usbcore: registered new interface driver usbmouse
[   33.168926] drivers/hid/usbhid/usbmouse.c: v1.6:USB HID Boot Protocol mouse driver
[   33.176468] initcall 0x78a4b530: usb_mouse_init+0x0/0x40() returned 0.
[   33.182958] initcall 0x78a4b530 ran for 6 msecs: usb_mouse_init+0x0/0x40()
[   33.189810] Calling initcall 0x78a4d910: flow_cache_init+0x0/0x100()
[   33.196140] initcall 0x78a4d910: flow_cache_init+0x0/0x100() returned 0.
[   33.202804] initcall 0x78a4d910 ran for 0 msecs: flow_cache_init+0x0/0x100()
[   33.209829] Calling initcall 0x78a4da10: pg_init+0x0/0x250()
[   33.215458] pktgen v2.69: Packet Generator for packet performance testing.
[   33.222355] initcall 0x78a4da10: pg_init+0x0/0x250() returned 0.
[   33.228284] initcall 0x78a4da10 ran for 3 msecs: pg_init+0x0/0x250()
[   33.234611] Calling initcall 0x78a4dca0: llc_init+0x0/0x70()
[   33.240248] initcall 0x78a4dca0: llc_init+0x0/0x70() returned 0.
[   33.246221] initcall 0x78a4dca0 ran for 0 msecs: llc_init+0x0/0x70()
[   33.252552] Calling initcall 0x78a4dd90: llc2_init+0x0/0xd0()
[   33.258280] NET: Registered protocol family 26
[   33.262696] initcall 0x78a4dd90: llc2_init+0x0/0xd0() returned 0.
[   33.268756] initcall 0x78a4dd90 ran for 1 msecs: llc2_init+0x0/0xd0()
[   33.275168] Calling initcall 0x78a4e020: snap_init+0x0/0x40()
[   33.280911] initcall 0x78a4e020: snap_init+0x0/0x40() returned 0.
[   33.286949] initcall 0x78a4e020 ran for 2 msecs: snap_init+0x0/0x40()
[   33.293365] Calling initcall 0x78a4e130: blackhole_module_init+0x0/0x10()
[   33.300131] initcall 0x78a4e130: blackhole_module_init+0x0/0x10() returned 0.
[   33.307228] initcall 0x78a4e130 ran for 0 msecs: blackhole_module_init+0x0/0x10()
[   33.314689] Calling initcall 0x78a4e200: gact_init_module+0x0/0x20()
[   33.321016] GACT probability on
[   33.324141] initcall 0x78a4e200: gact_init_module+0x0/0x20() returned 0.
[   33.330800] initcall 0x78a4e200 ran for 0 msecs: gact_init_module+0x0/0x20()
[   33.337827] Calling initcall 0x78a4e220: simp_init_module+0x0/0x30()
[   33.344150] Simple TC action Loaded
[   33.347623] initcall 0x78a4e220: simp_init_module+0x0/0x30() returned 0.
[   33.354291] initcall 0x78a4e220 ran for 2 msecs: simp_init_module+0x0/0x30()
[   33.361313] Calling initcall 0x78a4e250: hfsc_init+0x0/0x10()
[   33.367032] initcall 0x78a4e250: hfsc_init+0x0/0x10() returned 0.
[   33.373093] initcall 0x78a4e250 ran for 0 msecs: hfsc_init+0x0/0x10()
[   33.379505] Calling initcall 0x78a4e260: gred_module_init+0x0/0x10()
[   33.385837] initcall 0x78a4e260: gred_module_init+0x0/0x10() returned 0.
[   33.392505] initcall 0x78a4e260 ran for 0 msecs: gred_module_init+0x0/0x10()
[   33.399530] Calling initcall 0x78a4e270: sfq_module_init+0x0/0x10()
[   33.405772] initcall 0x78a4e270: sfq_module_init+0x0/0x10() returned 0.
[   33.412351] initcall 0x78a4e270 ran for 0 msecs: sfq_module_init+0x0/0x10()
[   33.419289] Calling initcall 0x78a4e280: prio_module_init+0x0/0x40()
[   33.425615] initcall 0x78a4e280: prio_module_init+0x0/0x40() returned 0.
[   33.432280] initcall 0x78a4e280 ran for 0 msecs: prio_module_init+0x0/0x40()
[   33.439308] Calling initcall 0x78a4e2c0: netem_module_init+0x0/0x20()
[   33.445719] netem: version 1.2
[   33.448755] initcall 0x78a4e2c0: netem_module_init+0x0/0x20() returned 0.
[   33.455505] initcall 0x78a4e2c0 ran for 3 msecs: netem_module_init+0x0/0x20()
[   33.462620] Calling initcall 0x78a4e2e0: init_u32+0x0/0x30()
[   33.468248] u32 classifier
[   33.470939]     Actions configured 
[   33.474418] initcall 0x78a4e2e0: init_u32+0x0/0x30() returned 0.
[   33.480377] initcall 0x78a4e2e0 ran for 5 msecs: init_u32+0x0/0x30()
[   33.486705] Calling initcall 0x78a4e310: init_route4+0x0/0x10()
[   33.492605] initcall 0x78a4e310: init_route4+0x0/0x10() returned 0.
[   33.498835] initcall 0x78a4e310 ran for 0 msecs: init_route4+0x0/0x10()
[   33.505427] Calling initcall 0x78a4e320: init_rsvp+0x0/0x10()
[   33.511149] initcall 0x78a4e320: init_rsvp+0x0/0x10() returned 0.
[   33.517207] initcall 0x78a4e320 ran for 0 msecs: init_rsvp+0x0/0x10()
[   33.523623] Calling initcall 0x78a4e330: init_rsvp+0x0/0x10()
[   33.529348] initcall 0x78a4e330: init_rsvp+0x0/0x10() returned 0.
[   33.535407] initcall 0x78a4e330 ran for 0 msecs: init_rsvp+0x0/0x10()
[   33.541826] Calling initcall 0x78a4f4e0: ipip_init+0x0/0xa0()
[   33.547549] IPv4 over IPv4 tunneling driver
[   33.551826] initcall 0x78a4f4e0: ipip_init+0x0/0xa0() returned 0.
[   33.557771] initcall 0x78a4f4e0 ran for 4 msecs: ipip_init+0x0/0xa0()
[   33.564179] Calling initcall 0x78a4f5d0: ipgre_init+0x0/0xa0()
[   33.570508] GRE over IPv4 tunneling driver
[   33.574670] initcall 0x78a4f5d0: ipgre_init+0x0/0xa0() returned 0.
[   33.580730] initcall 0x78a4f5d0 ran for 3 msecs: ipgre_init+0x0/0xa0()
[   33.587233] Calling initcall 0x78a4f6c0: ah4_init+0x0/0x70()
[   33.592871] initcall 0x78a4f6c0: ah4_init+0x0/0x70() returned 0.
[   33.598843] initcall 0x78a4f6c0 ran for 0 msecs: ah4_init+0x0/0x70()
[   33.605174] Calling initcall 0x78a4f730: ipcomp4_init+0x0/0x70()
[   33.611158] initcall 0x78a4f730: ipcomp4_init+0x0/0x70() returned 0.
[   33.617474] initcall 0x78a4f730 ran for 0 msecs: ipcomp4_init+0x0/0x70()
[   33.624150] Calling initcall 0x78a4f7a0: ipip_init+0x0/0xb0()
[   33.629876] initcall 0x78a4f7a0: ipip_init+0x0/0xb0() returned 0.
[   33.635936] initcall 0x78a4f7a0 ran for 0 msecs: ipip_init+0x0/0xb0()
[   33.642354] Calling initcall 0x78a4f850: xfrm4_beet_init+0x0/0x10()
[   33.648595] initcall 0x78a4f850: xfrm4_beet_init+0x0/0x10() returned 0.
[   33.655178] initcall 0x78a4f850 ran for 0 msecs: xfrm4_beet_init+0x0/0x10()
[   33.662111] Calling initcall 0x78a4f860: tunnel4_init+0x0/0x70()
[   33.668092] initcall 0x78a4f860: tunnel4_init+0x0/0x70() returned 0.
[   33.674416] initcall 0x78a4f860 ran for 0 msecs: tunnel4_init+0x0/0x70()
[   33.681089] Calling initcall 0x78a4f8d0: xfrm4_transport_init+0x0/0x10()
[   33.687765] initcall 0x78a4f8d0: xfrm4_transport_init+0x0/0x10() returned 0.
[   33.694782] initcall 0x78a4f8d0 ran for 0 msecs: xfrm4_transport_init+0x0/0x10()
[   33.702148] Calling initcall 0x78a4f8e0: xfrm4_tunnel_init+0x0/0x10()
[   33.708563] initcall 0x78a4f8e0: xfrm4_tunnel_init+0x0/0x10() returned 0.
[   33.715321] initcall 0x78a4f8e0 ran for 0 msecs: xfrm4_tunnel_init+0x0/0x10()
[   33.722430] Calling initcall 0x78a50ed0: cubictcp_register+0x0/0xa0()
[   33.728839] TCP cubic registered
[   33.732053] initcall 0x78a50ed0: cubictcp_register+0x0/0xa0() returned 0.
[   33.738801] initcall 0x78a50ed0 ran for 3 msecs: cubictcp_register+0x0/0xa0()
[   33.745914] Calling initcall 0x78a511b0: af_unix_init+0x0/0x70()
[   33.751892] NET: Registered protocol family 1
[   33.756234] initcall 0x78a511b0: af_unix_init+0x0/0x70() returned 0.
[   33.762548] initcall 0x78a511b0 ran for 0 msecs: af_unix_init+0x0/0x70()
[   33.769226] Calling initcall 0x78a51220: inet6_init+0x0/0x2e0()
[   33.775130] NET: Registered protocol family 10
[   33.779648] lo: Disabled Privacy Extensions
[   33.783876] tunl0: Disabled Privacy Extensions
[   33.788274] initcall 0x78a51220: inet6_init+0x0/0x2e0() returned 0.
[   33.794434] initcall 0x78a51220 ran for 9 msecs: inet6_init+0x0/0x2e0()
[   33.801020] Calling initcall 0x78a51da0: xfrm6_tunnel_init+0x0/0x10()
[   33.807435] initcall 0x78a51da0: xfrm6_tunnel_init+0x0/0x10() returned 0.
[   33.814193] initcall 0x78a51da0 ran for 0 msecs: xfrm6_tunnel_init+0x0/0x10()
[   33.821301] Calling initcall 0x78a51db0: xfrm6_beet_init+0x0/0x10()
[   33.827547] initcall 0x78a51db0: xfrm6_beet_init+0x0/0x10() returned 0.
[   33.834120] initcall 0x78a51db0 ran for 0 msecs: xfrm6_beet_init+0x0/0x10()
[   33.841060] Calling initcall 0x78a51dc0: sit_init+0x0/0xa0()
[   33.846689] IPv6 over IPv4 tunneling driver
[   33.850959] sit0: Disabled Privacy Extensions
[   33.855206] initcall 0x78a51dc0: sit_init+0x0/0xa0() returned 0.
[   33.861171] initcall 0x78a51dc0 ran for 6 msecs: sit_init+0x0/0xa0()
[   33.867498] Calling initcall 0x78a51eb0: packet_init+0x0/0x50()
[   33.873390] NET: Registered protocol family 17
[   33.877832] initcall 0x78a51eb0: packet_init+0x0/0x50() returned 0.
[   33.884045] initcall 0x78a51eb0 ran for 3 msecs: packet_init+0x0/0x50()
[   33.890634] Calling initcall 0x78a51f00: br_init+0x0/0xb0()
[   33.896201] initcall 0x78a51f00: br_init+0x0/0xb0() returned 0.
[   33.902070] initcall 0x78a51f00 ran for 0 msecs: br_init+0x0/0xb0()
[   33.908316] Calling initcall 0x78a52050: ipx_init+0x0/0xf0()
[   33.913948] NET: Registered protocol family 4
[   33.921762] input: AT Translated Set 2 keyboard as /class/input/input0
[   33.930824] initcall 0x78a52050: ipx_init+0x0/0xf0() returned 0.
[   33.936677] initcall 0x78a52050 ran for 11 msecs: ipx_init+0x0/0xf0()
[   33.943089] Calling initcall 0x78a52270: atalk_init+0x0/0x90()
[   33.948900] NET: Registered protocol family 5
[   33.970808] evbug.c: Connected device: "AT Translated Set 2 keyboard", isa0060/serio0/input0
[   33.979265] initcall 0x78a52270: atalk_init+0x0/0x90() returned 0.
[   33.985288] initcall 0x78a52270 ran for 22 msecs: atalk_init+0x0/0x90()
[   33.991874] Calling initcall 0x78a524f0: x25_init+0x0/0x60()
[   33.997512] NET: Registered protocol family 9
[   34.001844] X.25 for Linux. Version 0.2 for Linux 2.1.15
[   34.007138] initcall 0x78a524f0: x25_init+0x0/0x60() returned 0.
[   34.013103] initcall 0x78a524f0 ran for 6 msecs: x25_init+0x0/0x60()
[   34.019429] Calling initcall 0x78a52b00: irlan_init+0x0/0x220()
[   34.025468] initcall 0x78a52b00: irlan_init+0x0/0x220() returned 0.
[   34.031584] initcall 0x78a52b00 ran for 0 msecs: irlan_init+0x0/0x220()
[   34.038168] Calling initcall 0x78a52d20: ircomm_init+0x0/0x80()
[   34.044062] IrCOMM protocol (Dag Brattli)
[   34.048054] initcall 0x78a52d20: ircomm_init+0x0/0x80() returned 0.
[   34.054288] initcall 0x78a52d20 ran for 2 msecs: ircomm_init+0x0/0x80()
[   34.060877] Calling initcall 0x78a52da0: ircomm_tty_init+0x0/0x170()
[   34.067661] initcall 0x78a52da0: ircomm_tty_init+0x0/0x170() returned 0.
[   34.074203] initcall 0x78a52da0 ran for 3 msecs: ircomm_tty_init+0x0/0x170()
[   34.081224] Calling initcall 0x78a52f40: init_sunrpc+0x0/0x60()
[   34.087314] RPC: Registered udp transport module.
[   34.091899] RPC: Registered tcp transport module.
[   34.096582] initcall 0x78a52f40: init_sunrpc+0x0/0x60() returned 0.
[   34.102807] initcall 0x78a52f40 ran for 4 msecs: init_sunrpc+0x0/0x60()
[   34.109398] Calling initcall 0x78a52fa0: init_rpcsec_gss+0x0/0x30()
[   34.115663] initcall 0x78a52fa0: init_rpcsec_gss+0x0/0x30() returned 0.
[   34.122218] initcall 0x78a52fa0 ran for 0 msecs: init_rpcsec_gss+0x0/0x30()
[   34.129156] Calling initcall 0x78a52fd0: init_kerberos_module+0x0/0x30()
[   34.135851] initcall 0x78a52fd0: init_kerberos_module+0x0/0x30() returned 0.
[   34.142843] initcall 0x78a52fd0 ran for 0 msecs: init_kerberos_module+0x0/0x30()
[   34.150215] Calling initcall 0x78a53000: decnet_init+0x0/0x80()
[   34.156104] NET4: DECnet for Linux: V.2.5.68s (C) 1995-2003 Linux DECnet Project Team
[   34.163935] DECnet: Routing cache hash table of 1024 buckets, 32Kbytes
[   34.170475] NET: Registered protocol family 12
[   34.174836] initcall 0x78a53000: decnet_init+0x0/0x80() returned 0.
[   34.181065] initcall 0x78a53000 ran for 11 msecs: decnet_init+0x0/0x80()
[   34.187737] Calling initcall 0x78a53360: econet_proto_init+0x0/0x40()
[   34.194154] NET: Registered protocol family 19
[   34.198578] initcall 0x78a53360: econet_proto_init+0x0/0x40() returned 0.
[   34.205324] initcall 0x78a53360 ran for 4 msecs: econet_proto_init+0x0/0x40()
[   34.212437] Calling initcall 0x78a533a0: vlan_proto_init+0x0/0xd0()
[   34.218673] 802.1Q VLAN Support v1.8 Ben Greear <greearb@candelatech.com>
[   34.225437] All bugs added by David S. Miller <davem@redhat.com>
[   34.231437] initcall 0x78a533a0: vlan_proto_init+0x0/0xd0() returned 0.
[   34.238000] initcall 0x78a533a0 ran for 5 msecs: vlan_proto_init+0x0/0xd0()
[   34.244933] Calling initcall 0x78a534d0: dccp_init+0x0/0x2c0()
[   34.259060] initcall 0x78a534d0: dccp_init+0x0/0x2c0() returned 0.
[   34.265092] initcall 0x78a534d0 ran for 8 msecs: dccp_init+0x0/0x2c0()
[   34.271591] Calling initcall 0x78a537d0: dccp_v4_init+0x0/0xa0()
[   34.287452] initcall 0x78a537d0: dccp_v4_init+0x0/0xa0() returned 0.
[   34.293649] initcall 0x78a537d0 ran for 9 msecs: dccp_v4_init+0x0/0xa0()
[   34.300324] Calling initcall 0x78a53870: dccp_v6_init+0x0/0xa0()
[   34.306330] initcall 0x78a53870: dccp_v6_init+0x0/0xa0() returned 0.
[   34.312630] initcall 0x78a53870 ran for 0 msecs: dccp_v6_init+0x0/0xa0()
[   34.319308] Calling initcall 0x78a539a0: ieee80211_init+0x0/0xb0()
[   34.325462] ieee80211: 802.11 data/management/control stack, git-1.1.13
[   34.332047] ieee80211: Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>
[   34.340371] initcall 0x78a539a0: ieee80211_init+0x0/0xb0() returned 0.
[   34.346859] initcall 0x78a539a0 ran for 4 msecs: ieee80211_init+0x0/0xb0()
[   34.353708] Calling initcall 0x78a53a50: ieee80211_crypto_init+0x0/0x10()
[   34.360496] ieee80211_crypt: registered algorithm 'NULL'
[   34.365763] initcall 0x78a53a50: ieee80211_crypto_init+0x0/0x10() returned 0.
[   34.372859] initcall 0x78a53a50 ran for 1 msecs: ieee80211_crypto_init+0x0/0x10()
[   34.380318] Calling initcall 0x78a53a60: tipc_init+0x0/0xf0()
[   34.386043] TIPC: Activated (version 1.6.2 compiled Oct 17 2007 19:33:19)
[   34.394334] NET: Registered protocol family 30
[   34.398661] TIPC: Started in single node mode
[   34.402993] initcall 0x78a53a60: tipc_init+0x0/0xf0() returned 0.
[   34.409050] initcall 0x78a53a60 ran for 12 msecs: tipc_init+0x0/0xf0()
[   34.415555] Calling initcall 0x78a53bd0: init_p9+0x0/0x60()
[   34.421111] Installing 9P2000 support
[   34.424799] initcall 0x78a53bd0: init_p9+0x0/0x60() returned 0.
[   34.430626] initcall 0x78a53bd0 ran for 3 msecs: init_p9+0x0/0x60()
[   34.436868] Calling initcall 0x78a1d910: centrino_init+0x0/0x20()
[   34.442940] initcall 0x78a1d910: centrino_init+0x0/0x20() returned -19.
[   34.449520] initcall 0x78a1d910 ran for 0 msecs: centrino_init+0x0/0x20()
[   34.456285] Calling initcall 0x78a1fb20: check_nmi_watchdog+0x0/0x140()
[   34.462871] initcall 0x78a1fb20: check_nmi_watchdog+0x0/0x140() returned 0.
[   34.469799] initcall 0x78a1fb20 ran for 0 msecs: check_nmi_watchdog+0x0/0x140()
[   34.477078] Calling initcall 0x78a1fd90: io_apic_bug_finalize+0x0/0x20()
[   34.483757] initcall 0x78a1fd90: io_apic_bug_finalize+0x0/0x20() returned 0.
[   34.490774] initcall 0x78a1fd90 ran for 0 msecs: io_apic_bug_finalize+0x0/0x20()
[   34.498142] Calling initcall 0x78a23a30: print_ipi_mode+0x0/0x30()
[   34.504291] Using IPI Shortcut mode
[   34.507766] initcall 0x78a23a30: print_ipi_mode+0x0/0x30() returned 0.
[   34.514259] initcall 0x78a23a30 ran for 3 msecs: print_ipi_mode+0x0/0x30()
[   34.521108] Calling initcall 0x78a24170: disable_boot_consoles+0x0/0x50()
[   34.527868] initcall 0x78a24170: disable_boot_consoles+0x0/0x50() returned 0.
[   34.534971] initcall 0x78a24170 ran for 0 msecs: disable_boot_consoles+0x0/0x50()
[   34.542427] Calling initcall 0x78a25a50: taskstats_init+0x0/0x70()
[   34.548590] initcall 0x78a25a50: taskstats_init+0x0/0x70() returned 0.
[   34.555077] initcall 0x78a25a50 ran for 0 msecs: taskstats_init+0x0/0x70()
[   34.561923] Calling initcall 0x78a2ba30: random32_reseed+0x0/0x30()
[   34.568170] initcall 0x78a2ba30: random32_reseed+0x0/0x30() returned 0.
[   34.574748] initcall 0x78a2ba30 ran for 0 msecs: random32_reseed+0x0/0x30()
[   34.581681] Calling initcall 0x78a2d0a0: pci_sysfs_init+0x0/0x40()
[   34.587941] initcall 0x78a2d0a0: pci_sysfs_init+0x0/0x40() returned 0.
[   34.594334] initcall 0x78a2d0a0 ran for 0 msecs: pci_sysfs_init+0x0/0x40()
[   34.601180] Calling initcall 0x78a2d3f0: seqgen_init+0x0/0x10()
[   34.607090] initcall 0x78a2d3f0: seqgen_init+0x0/0x10() returned 0.
[   34.613310] initcall 0x78a2d3f0 ran for 0 msecs: seqgen_init+0x0/0x10()
[   34.619895] Calling initcall 0x784c9750: scsi_complete_async_scans+0x0/0xe0()
[   34.627008] initcall 0x784c9750: scsi_complete_async_scans+0x0/0xe0() returned 0.
[   34.634458] initcall 0x784c9750 ran for 0 msecs: scsi_complete_async_scans+0x0/0xe0()
[   34.642260] Calling initcall 0x78a4ec80: tcp_congestion_default+0x0/0x10()
[   34.649106] initcall 0x78a4ec80: tcp_congestion_default+0x0/0x10() returned 0.
[   34.656839] initcall 0x78a4ec80 ran for 0 msecs: tcp_congestion_default+0x0/0x10()
[   34.664384] Calling initcall 0x78a4fcd0: ip_auto_config+0x0/0xdc0()
[   34.670627] initcall 0x78a4fcd0: ip_auto_config+0x0/0xdc0() returned 0.
[   34.677203] initcall 0x78a4fcd0 ran for 0 msecs: ip_auto_config+0x0/0xdc0()
[   34.702979] EXT3-fs: INFO: recovery required on readonly filesystem.
[   34.709208] EXT3-fs: write access will be enabled during recovery.
[   35.007671] (fs/jbd/recovery.c, 255): journal_recover: JBD: recovery, exit status 0, recovered transactions 51094 to 51120
[   35.018561] (fs/jbd/recovery.c, 257): journal_recover: JBD: Replayed 843 and revoked 183/307 blocks
[   35.088716] kjournald starting.  Commit interval 5 seconds
[   35.094109] EXT3-fs: recovery complete.
[   35.098960] EXT3-fs: mounted filesystem with ordered data mode.
[   35.104779] VFS: Mounted root (ext3 filesystem) readonly.
[   35.110490] Freeing unused kernel memory: 372k freed
[   38.379727] warning: process `kmodule' used the removed sysctl system call with 1.23.
[   39.747156] BUG: unable to handle kernel paging request at virtual address 7ca9e000
[   39.754656] printing eip: 784e9480 *pde = 00dda027 *pte = 04a9e000 
[   39.760896] Oops: 0000 [#1] DEBUG_PAGEALLOC
[   39.765056] 
[   39.766530] Pid: 0, comm: swapper Not tainted (2.6.23 #6)
[   39.771903] EIP: 0060:[<784e9480>] EFLAGS: 00010087 CPU: 0
[   39.777366] EIP is at ata_qc_issue+0x90/0x380
[   39.781694] EAX: 7ca9dff0 EBX: 0000001f ECX: 7ca9dff0 EDX: 79181e60
[   39.787934] ESI: 00000020 EDI: 7ca9de00 EBP: 7b54007c ESP: 78a13e18
[   39.794174]  DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068
[   39.799547] Process swapper (pid: 0, ti=78a12000 task=789753e0 task.ti=78a12000)
[   39.806739] Stack: 7ca9de00 7b540000 7b540000 00000000 7ca9dfe0 7b54007c 7ca14e00 7b5417a4 
[   39.815058]        784c2490 784ef69e 784f21f3 7b52de98 7ca14e00 7b540000 7b5417a4 7ca14e00 
[   39.823378]        7b540000 7b524004 784f22e0 784ef380 784c2490 7ca14e00 00000202 7b524004 
[   39.831698] Call Trace:
[   39.834299]  [<784c2490>] scsi_done+0x0/0x20
[   39.838545]  [<784ef69e>] ata_scsi_translate+0xbe/0x140
[   39.843743]  [<784f21f3>] ata_scsi_queuecmd+0x33/0x200
[   39.848857]  [<784f22e0>] ata_scsi_queuecmd+0x120/0x200
[   39.854057]  [<784ef380>] ata_scsi_rw_xlat+0x0/0x220
[   39.858996]  [<784c2490>] scsi_done+0x0/0x20
[   39.863243]  [<784c2d12>] scsi_dispatch_cmd+0x152/0x290
[   39.868442]  [<78135c67>] trace_hardirqs_on+0x67/0xb0
[   39.873468]  [<784c8c7e>] scsi_request_fn+0x1be/0x370
[   39.878495]  [<78408086>] blk_run_queue+0x36/0x80
[   39.883174]  [<784c7520>] scsi_next_command+0x30/0x50
[   39.888201]  [<784c76ab>] scsi_end_request+0xab/0xe0
[   39.893140]  [<784c83f9>] scsi_io_completion+0xa9/0x3d0
[   39.898340]  [<78135c67>] trace_hardirqs_on+0x67/0xb0
[   39.903367]  [<78405125>] blk_done_softirq+0x45/0x80
[   39.908306]  [<78405153>] blk_done_softirq+0x73/0x80
[   39.913246]  [<7811d4c3>] __do_softirq+0x53/0xb0
[   39.917839]  [<7811d588>] do_softirq+0x68/0x70
[   39.922258]  [<78105351>] do_IRQ+0x51/0x90
[   39.926332]  [<7810f2d0>] pgd_dtor+0x0/0x50
[   39.930491]  [<7810388e>] common_interrupt+0x2e/0x40
[   39.935431]  [<7810f2d0>] pgd_dtor+0x0/0x50
[   39.939591]  [<7815f3bf>] quicklist_trim+0x5f/0x90
[   39.944357]  [<7810f2cb>] check_pgt_cache+0x1b/0x20
[   39.949210]  [<78100c52>] cpu_idle+0x32/0x60
[   39.953457]  [<78a14b35>] start_kernel+0x265/0x300
[   39.958223]  [<78a14380>] unknown_bootoption+0x0/0x1e0
[   39.963336]  =======================
[   39.966889] Code: 00 00 00 8b 45 34 a8 02 0f 84 ed 00 00 00 8b bd 88 00 00 00 31 db 89 3c 24 8b 75 3c 89 f8 c7 44 24 10 00 00 00 00 eb 1b 8d 76 00 <8b> 50 10 8d 48 10 f6 c2 01 0f 85 be 02 00 00 89 44 24 10 83 c3 
[   39.985695] EIP: [<784e9480>] ata_qc_issue+0x90/0x380 SS:ESP 0068:78a13e18
[   39.992541] Kernel panic - not syncing: Fatal exception in interrupt

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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 17:52       ` Linus Torvalds
@ 2007-10-17 18:00         ` Jens Axboe
  2007-10-17 18:18           ` Linus Torvalds
  0 siblings, 1 reply; 151+ messages in thread
From: Jens Axboe @ 2007-10-17 18:00 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Ingo Molnar, linux-kernel, Andrew Morton

On Wed, Oct 17 2007, Linus Torvalds wrote:
> 
> 
> On Wed, 17 Oct 2007, Jens Axboe wrote:
> > 
> > OK, the below should actually be safe, I don't know why I talked myself
> > into the next_sg stuff in the beginning. It's always safe to zero sg,
> > since it's a valid entry - nothing to save in ->page. Ingo, does this
> > work for you?
> 
> I really don't think this should work.
> 
> Doing "sg_next()" on a valid sg is *always* ok. So if the old code didn't 
> work, then "sg" wasn't valid to start with (and the code *after* the 
> sg_next() would have oopsed even if you try to avoid using sg_next.
> 
> So avoiding the "sg_next()" on the last entry is pointless. 

Yeah, I didn't quite understand why if sg was valid, why dereferencing
*(sg + 1)->page would crap out :/

> Also, your patch makes the code almost totally unreadable, with that 
> subtle issue of the "if (bvprv && cluster)" case not triggering on the 
> first case, so the NULL initial sg is "safe".

Hmm I think it's quite readable, but perhaps that's just me :-). The
first is much cleaner, and the last part just reads 'if sg is not set
yet, set to list. otherwise, goto next entry'.

> So at a guess, I think the *real* problem is simply that the passed-in 
> sglist was just too small. What guarantees that the sg list allocation 
> (apparently done by scsi_alloc_sgtable()) is big enough? 
> 
> If I read things right, scsi_alloc_sgtable() will allocate "cmd->use_sg" 
> SG enties, no? But I also notice that it does not seem to initialize the 
> SG allocation, so those SG entries contain random crap - including, 
> perhaps, a random - and bogus - chain pointer in sg->page..

Right, we allocate an sgtable that will hold ->use_sg entries, which
contains request->nr_phys_segments. And that should definitely fit.

Regarding the init of the sglist, that was the revert I was talking
about. We do need that memset() in there, so all those sg entries will
be properly zeroed.

> Yes, we set sh->page *if* we create a chain, but if we don't chain, we 
> leave the old random contents around which in turn may include old and 
> stale chain pointers. Or am I missing something?
> 
> So when you added that "memset(sg, 0, sizeof(*sg))" into blk_rq_map_sg(), 
> you did it way too late - it needs to be done when the sg chain is 
> allocated, and for every entry (and then the "link" entry needs to be 
> linked in separately)
> 
> I think.

Yep, and that is what Ingo did test as well and it worked. For that
case, now libata is crapping out elsewhere in sg_next().

-- 
Jens Axboe


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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 17:56           ` [bug] block " Linus Torvalds
@ 2007-10-17 18:02             ` Jens Axboe
  2007-10-17 18:13               ` Linus Torvalds
  2007-10-17 18:02             ` Ingo Molnar
  1 sibling, 1 reply; 151+ messages in thread
From: Jens Axboe @ 2007-10-17 18:02 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Ingo Molnar, linux-kernel, Andrew Morton

On Wed, Oct 17 2007, Linus Torvalds wrote:
> 
> 
> On Wed, 17 Oct 2007, Jens Axboe wrote:
> > 
> > OK, it is fine, as long as the sglist is cleared initially. And I don't
> > think there's anyway around that, clearly I didn't think long enough
> > before including the memset() removal from Tomo.
> 
> Ok, I think that one-liner fixes the real bug.
> 
> But I think the rest of your changes are simply bad.
> 
> The fix to block/ll_rw_block.c should likely be something like the 
> appended instead:
> 
>  - remove the "memset()" you had added earlier. It's bogus. It cannot be 
>    the right thing. If the sg list wasn't initialized correctly much 
>    earlier, trying to initialize it late is pointless - it contains crap.

It's required to clear output members (like dma_len and so on), since
some of the IOMU code really wants that initialized.

>  - the old code was fine, but let's initialize "sg" to NULL to make it 
>    clear that the initial value of sg is pointless, and only "next_sg" 
>    matters (since sg had better be assigned from that).

If you prefer the old next_sg approach to my alternative, that is fine
with me. But we do need the memset().

-- 
Jens Axboe


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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 17:56           ` [bug] block " Linus Torvalds
  2007-10-17 18:02             ` Jens Axboe
@ 2007-10-17 18:02             ` Ingo Molnar
  2007-10-17 18:14               ` Linus Torvalds
  1 sibling, 1 reply; 151+ messages in thread
From: Ingo Molnar @ 2007-10-17 18:02 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Jens Axboe, linux-kernel, Andrew Morton


* Linus Torvalds <torvalds@linux-foundation.org> wrote:

> But I think the rest of your changes are simply bad.
> 
> The fix to block/ll_rw_block.c should likely be something like the 
> appended instead:
> 
>  - remove the "memset()" you had added earlier. It's bogus. It cannot be 
>    the right thing. If the sg list wasn't initialized correctly much 
>    earlier, trying to initialize it late is pointless - it contains crap.
> 
>  - the old code was fine, but let's initialize "sg" to NULL to make it 
>    clear that the initial value of sg is pointless, and only "next_sg" 
>    matters (since sg had better be assigned from that).
> 
> Hmm?

built and booted your patch (removed Jens's) but it still crashes in 
blk_rq_map_sg() - see below. Should i have left something from Jens's 
patch?

	Ingo

------------------->
[   34.698199] VFS: Mounted root (ext3 filesystem) readonly.
[   34.703917] Freeing unused kernel memory: 372k freed
[   34.746609] BUG: unable to handle kernel paging request at virtual address 6e616872
[   34.754106] printing eip: 7840503b *pde = 00000000 
[   34.758960] Oops: 0000 [#1] DEBUG_PAGEALLOC
[   34.763120] 
[   34.764594] Pid: 1, comm: swapper Not tainted (2.6.23 #7)
[   34.769965] EIP: 0060:[<7840503b>] EFLAGS: 00010006 CPU: 0
[   34.775429] EIP is at blk_rq_map_sg+0xbb/0x170
[   34.779845] EAX: 3ffcd000 EBX: 7c88a68c ECX: 3ffce000 EDX: 007ff9a0
[   34.786085] ESI: 6e616862 EDI: 798ea9a0 EBP: 00001000 ESP: 7b421bf4
[   34.792324]  DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068
[   34.797697] Process swapper (pid: 1, ti=7b420000 task=7b416000 task.ti=7b420000)
[   34.804890] Stack: 00000046 7b520000 00002000 3ffcf000 7c88ac80 00000001 00000001 00000001 
[   34.813209]        7c88a600 01000000 7c88ab00 7b521d1c 7c88a708 7b520000 784c7ac5 7b520000 
[   34.821529]        784c75ca 7c88a708 7b524ce4 7b521d1c 7c88a708 784e4570 7b416000 7813661b 
[   34.829847] Call Trace:
[   34.832448]  [<784c7ac5>] scsi_init_io+0x55/0xe0
[   34.837042]  [<784c75ca>] scsi_get_cmd_from_req+0x2a/0x40
[   34.842414]  [<784e4570>] sd_prep_fn+0x80/0x940
[   34.846920]  [<7813661b>] __lock_acquire+0x4ab/0xe20
[   34.851860]  [<781450a6>] add_to_page_cache+0x66/0xb0
[   34.856887]  [<78404633>] elv_dispatch_sort+0x23/0xe0
[   34.861912]  [<784041a0>] elv_next_request+0xa0/0x130
[   34.866938]  [<784c8c04>] scsi_request_fn+0x1e4/0x370
[   34.871965]  [<78120f02>] del_timer+0x62/0x70
[   34.876298]  [<78407445>] __generic_unplug_device+0x25/0x30
[   34.881844]  [<78407715>] generic_unplug_device+0x15/0x30
[   34.887217]  [<78404e00>] blk_backing_dev_unplug+0x0/0x10
[   34.892590]  [<78404e0c>] blk_backing_dev_unplug+0xc/0x10
[   34.897963]  [<78180a9d>] block_sync_page+0x2d/0x40
[   34.902817]  [<78144dc9>] sync_page+0x29/0x40
[   34.907150]  [<7876f5bc>] __wait_on_bit_lock+0x3c/0x70
[   34.912263]  [<78144da0>] sync_page+0x0/0x40
[   34.916509]  [<78144d82>] __lock_page+0x52/0x60
[   34.921016]  [<7812adb0>] wake_bit_function+0x0/0x60
[   34.925955]  [<7814554c>] do_generic_mapping_read+0x21c/0x450
[   34.931675]  [<78144b10>] file_read_actor+0x0/0x130
[   34.936528]  [<78147107>] generic_file_aio_read+0x137/0x180
[   34.942074]  [<78144b10>] file_read_actor+0x0/0x130
[   34.946927]  [<78161245>] do_sync_read+0xd5/0x120
[   34.951607]  [<78135646>] mark_lock+0x76/0x550
[   34.956027]  [<7812ad70>] autoremove_wake_function+0x0/0x40
[   34.961573]  [<78155026>] __vma_link+0x36/0x70
[   34.965993]  [<78161170>] do_sync_read+0x0/0x120
[   34.970586]  [<78161ae3>] vfs_read+0xb3/0x110
[   34.974919]  [<781652cd>] kernel_read+0x3d/0x60
[   34.979425]  [<7816539f>] prepare_binprm+0xaf/0xe0
[   34.984192]  [<78166973>] do_execve+0x123/0x1c0
[   34.988698]  [<78100f1f>] sys_execve+0x2f/0x90
[   34.993118]  [<781028a2>] syscall_call+0x7/0xb
[   34.997538]  [<78106f1c>] kernel_execve+0x1c/0x30
[   35.002217]  [<7810016e>] init_post+0x9e/0xe0
[   35.006550]  [<78a147b3>] kernel_init+0x163/0x280
[   35.011230]  [<78a14650>] kernel_init+0x0/0x280
[   35.015736]  [<78103a97>] kernel_thread_helper+0x7/0x10
[   35.020936]  =======================
[   35.024489] Code: 29 c1 c1 f9 05 c1 e1 0c 03 4a 08 8b 52 04 01 ca 89 54 24 0c 8b 3b 89 fa 29 c2 89 d0 c1 f8 05 c1 e0 0c 03 43 08 39 44 24 0c 74 7e <8b> 46 10 8d 56 10 a8 01 75 4c 89 3e 89 6e 0c 8b 43 08 89 46 04 
[   35.043294] EIP: [<7840503b>] blk_rq_map_sg+0xbb/0x170 SS:ESP 0068:7b421bf4
[   35.050228] Kernel panic - not syncing: Attempted to kill init!

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 17:45             ` [bug] ata " Ingo Molnar
  2007-10-17 17:53               ` Jens Axboe
@ 2007-10-17 18:08               ` Linus Torvalds
  2007-10-17 18:13                 ` Ingo Molnar
  1 sibling, 1 reply; 151+ messages in thread
From: Linus Torvalds @ 2007-10-17 18:08 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Jens Axboe, linux-kernel, Jeff Garzik, Alan Cox



On Wed, 17 Oct 2007, Ingo Molnar wrote:
> 
> ok, here's a different but similar crash that triggers on the testbox:

Just to confirm - is this with the added memset() in 
drivers/scsi/scsi_lib.c?

Or did you get this oops before that patch?

		Linus

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 18:08               ` Linus Torvalds
@ 2007-10-17 18:13                 ` Ingo Molnar
  0 siblings, 0 replies; 151+ messages in thread
From: Ingo Molnar @ 2007-10-17 18:13 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Jens Axboe, linux-kernel, Jeff Garzik, Alan Cox


* Linus Torvalds <torvalds@linux-foundation.org> wrote:

> 
> 
> On Wed, 17 Oct 2007, Ingo Molnar wrote:
> > 
> > ok, here's a different but similar crash that triggers on the testbox:
> 
> Just to confirm - is this with the added memset() in 
> drivers/scsi/scsi_lib.c?

yes, Jens's last patch was applied - apparently this ATA crash was 
masked by the other one. I got one successful bootup after applying 
Jens's patch and it has crashed on bootup twice since then.

	Ingo

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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 18:02             ` Jens Axboe
@ 2007-10-17 18:13               ` Linus Torvalds
  2007-10-17 18:20                 ` Jens Axboe
  0 siblings, 1 reply; 151+ messages in thread
From: Linus Torvalds @ 2007-10-17 18:13 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Ingo Molnar, linux-kernel, Andrew Morton



On Wed, 17 Oct 2007, Jens Axboe wrote:
> >
> >  - remove the "memset()" you had added earlier. It's bogus. It cannot be 
> >    the right thing. If the sg list wasn't initialized correctly much 
> >    earlier, trying to initialize it late is pointless - it contains crap.
> 
> It's required to clear output members (like dma_len and so on), since
> some of the IOMU code really wants that initialized.

No it's NOT!

The whole point here is that the sg had *already* better be cleared.

If it wasn't cleared before, that's a bug regardless of anything else. So 
a memset() is guaranteed to be either a no-op or hiding another bug!

So yes, those members had better be zero. It's just that they had better 
be zero long before that memset! The memset should have been done when 
allocating the SG list.

> If you prefer the old next_sg approach to my alternative, that is fine
> with me. But we do need the memset().

Really? Explain why. Entering that code with a non-initialized SG list is 
a bug to begin with.

		Linus

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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 18:02             ` Ingo Molnar
@ 2007-10-17 18:14               ` Linus Torvalds
  0 siblings, 0 replies; 151+ messages in thread
From: Linus Torvalds @ 2007-10-17 18:14 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Jens Axboe, linux-kernel, Andrew Morton



On Wed, 17 Oct 2007, Ingo Molnar wrote:
> 
> built and booted your patch (removed Jens's) but it still crashes in 
> blk_rq_map_sg() - see below. Should i have left something from Jens's 
> patch?

The *real* fix in Jens' patch (and the only thing that really matters) is 
the one to drivers/scsi/scsi_lib.c.

The rest is all fluff.

		Linus

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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 18:00         ` Jens Axboe
@ 2007-10-17 18:18           ` Linus Torvalds
  2007-10-17 18:22             ` Jens Axboe
  2007-10-17 18:22             ` Linus Torvalds
  0 siblings, 2 replies; 151+ messages in thread
From: Linus Torvalds @ 2007-10-17 18:18 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Ingo Molnar, linux-kernel, Andrew Morton



On Wed, 17 Oct 2007, Jens Axboe wrote:
> > 
> > So avoiding the "sg_next()" on the last entry is pointless. 
> 
> Yeah, I didn't quite understand why if sg was valid, why dereferencing
> *(sg + 1)->page would crap out :/

Actually, I take that back. If 'sg' is the last entry in a *non*linked 
scatter-gather list (ie we don't use the last entry as a link, we actually 
use it as a real SG entry), then "sg_next(sg)" will indeed access past the 
end of the whole allocated array, and will access one past the end.

And with page-alloc debugging, that *will* blow up.

So I think your change to use "sg_next()" only when you actually need a 
next pointer is the correct one after all.

				Linus

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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 18:13               ` Linus Torvalds
@ 2007-10-17 18:20                 ` Jens Axboe
  2007-10-17 18:58                   ` Linus Torvalds
  0 siblings, 1 reply; 151+ messages in thread
From: Jens Axboe @ 2007-10-17 18:20 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Ingo Molnar, linux-kernel, Andrew Morton

On Wed, Oct 17 2007, Linus Torvalds wrote:
> 
> 
> On Wed, 17 Oct 2007, Jens Axboe wrote:
> > >
> > >  - remove the "memset()" you had added earlier. It's bogus. It cannot be 
> > >    the right thing. If the sg list wasn't initialized correctly much 
> > >    earlier, trying to initialize it late is pointless - it contains crap.
> > 
> > It's required to clear output members (like dma_len and so on), since
> > some of the IOMU code really wants that initialized.
> 
> No it's NOT!
> 
> The whole point here is that the sg had *already* better be cleared.
> 
> If it wasn't cleared before, that's a bug regardless of anything else. So 
> a memset() is guaranteed to be either a no-op or hiding another bug!
> 
> So yes, those members had better be zero. It's just that they had better 
> be zero long before that memset! The memset should have been done when 
> allocating the SG list.

For the chain elements - yes, definitely! But we also want to clear dma
mapping output values, at least sparc64 wants that. You could argue that
the IOMMU code should be fixed up, but I don't think we should mix the
two.

So we need the memset() in blk_rq_map_sg() AS WELL AS the initial sg
table clear. I'm not arguing about the latter, we clearly do need that.

> > If you prefer the old next_sg approach to my alternative, that is fine
> > with me. But we do need the memset().
> 
> Really? Explain why. Entering that code with a non-initialized SG list is 
> a bug to begin with.

Not for the output members, they will be filled AFTER blk_rq_map_sg()
returns and someone use iommu_map_sg() to re-iterate the sglist and map
the pages appropriately.

-- 
Jens Axboe


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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 18:18           ` Linus Torvalds
@ 2007-10-17 18:22             ` Jens Axboe
  2007-10-18 10:52               ` Benny Halevy
  2007-10-17 18:22             ` Linus Torvalds
  1 sibling, 1 reply; 151+ messages in thread
From: Jens Axboe @ 2007-10-17 18:22 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Ingo Molnar, linux-kernel, Andrew Morton

On Wed, Oct 17 2007, Linus Torvalds wrote:
> 
> 
> On Wed, 17 Oct 2007, Jens Axboe wrote:
> > > 
> > > So avoiding the "sg_next()" on the last entry is pointless. 
> > 
> > Yeah, I didn't quite understand why if sg was valid, why dereferencing
> > *(sg + 1)->page would crap out :/
> 
> Actually, I take that back. If 'sg' is the last entry in a *non*linked 
> scatter-gather list (ie we don't use the last entry as a link, we actually 
> use it as a real SG entry), then "sg_next(sg)" will indeed access past the 
> end of the whole allocated array, and will access one past the end.
> 
> And with page-alloc debugging, that *will* blow up.
> 
> So I think your change to use "sg_next()" only when you actually need a 
> next pointer is the correct one after all.

Thanks, so I'm not totally crazy :-)

Can you just pull:

  git://git.kernel.dk/data/git/linux-2.6-block.git for-linus

then so we get those two pieces correct? Then the remaining issue seems
to be a new one that is biting Ingo elsewhere, at least we'll all be on
the same page then.

-- 
Jens Axboe


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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 18:18           ` Linus Torvalds
  2007-10-17 18:22             ` Jens Axboe
@ 2007-10-17 18:22             ` Linus Torvalds
  2007-10-17 18:40               ` Jens Axboe
  1 sibling, 1 reply; 151+ messages in thread
From: Linus Torvalds @ 2007-10-17 18:22 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Ingo Molnar, linux-kernel, Andrew Morton



On Wed, 17 Oct 2007, Linus Torvalds wrote:
> 
> So I think your change to use "sg_next()" only when you actually need a 
> next pointer is the correct one after all.

That still leaves the initialization issue. The link pointers need to all 
be initialized at SG allocation time (and not just the last one for the 
case where it's a linked entry).

And if you initialize them at allocation time, does an allocation ever get 
re-used without being free'd in between (if it does, you do indeed need to 
initialize the non-link pointers each time - but I don't see it being the 
case, so ..)

		Linus

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 17:53               ` Jens Axboe
  2007-10-17 17:55                 ` Jens Axboe
@ 2007-10-17 18:37                 ` Jens Axboe
  2007-10-17 19:04                   ` Ingo Molnar
  2007-10-17 19:09                   ` Ingo Molnar
  1 sibling, 2 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-17 18:37 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Linus Torvalds, linux-kernel, Jeff Garzik, Alan Cox

On Wed, Oct 17 2007, Jens Axboe wrote:
> On Wed, Oct 17 2007, Ingo Molnar wrote:
> > 
> > ok, here's a different but similar crash that triggers on the testbox:
> > 
> > [  233.438890] BUG: unable to handle kernel paging request at virtual address 7d93e000
> > [  233.446390] printing eip: 784e9480 *pde = 01000067 *pte = 0593e000 
> > [  233.452630] Oops: 0000 [#1] DEBUG_PAGEALLOC
> > [  233.456790] 
> > [  233.458264] Pid: 0, comm: swapper Not tainted (2.6.23 #5)
> > [  233.463637] EIP: 0060:[<784e9480>] EFLAGS: 00010087 CPU: 0
> > [  233.469101] EIP is at ata_qc_issue+0x90/0x380
> > [  233.473429] EAX: 7d93dff0 EBX: 0000001f ECX: 7d93dff0 EDX: 798daf80
> > [  233.479668] ESI: 00000020 EDI: 7d93de00 EBP: 7b54007c ESP: 78a13e14
> > [  233.485908]  DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068
> > [  233.491282] Process swapper (pid: 0, ti=78a12000 task=789753e0 task.ti=78a12000)
> > [  233.498473] Stack: 7d93de00 7b540000 7b540000 00000000 7d93dfe0 7b54007c 7d93db00 7b5417a4 
> > [  233.506793]        784c2490 784ef69e 784f21f3 7b52de98 7d93db00 7b540000 7b5417a4 7d93db00 
> > [  233.515112]        7b540000 7b524004 784f22e0 784ef380 784c2490 7d93db00 00000202 7b524004 
> > [  233.523432] Call Trace:
> > [  233.526033]  [<784c2490>] scsi_done+0x0/0x20
> > [  233.530279]  [<784ef69e>] ata_scsi_translate+0xbe/0x140
> > [  233.535478]  [<784f21f3>] ata_scsi_queuecmd+0x33/0x200
> > [  233.540591]  [<784f22e0>] ata_scsi_queuecmd+0x120/0x200
> > [  233.545791]  [<784ef380>] ata_scsi_rw_xlat+0x0/0x220
> > [  233.550730]  [<784c2490>] scsi_done+0x0/0x20
> > [  233.554976]  [<784c2d12>] scsi_dispatch_cmd+0x152/0x290
> > [  233.560177]  [<78135c67>] trace_hardirqs_on+0x67/0xb0
> > [  233.565202]  [<784c8c7e>] scsi_request_fn+0x1be/0x370
> > [  233.570229]  [<78408086>] blk_run_queue+0x36/0x80
> > [  233.574909]  [<784c7520>] scsi_next_command+0x30/0x50
> > [  233.579935]  [<784c76ab>] scsi_end_request+0xab/0xe0
> > [  233.584875]  [<784c83f9>] scsi_io_completion+0xa9/0x3d0
> > [  233.590075]  [<78135c67>] trace_hardirqs_on+0x67/0xb0
> > [  233.595100]  [<78405125>] blk_done_softirq+0x45/0x80
> > [  233.600040]  [<78405153>] blk_done_softirq+0x73/0x80
> > [  233.604981]  [<7811d4c3>] __do_softirq+0x53/0xb0
> > [  233.609573]  [<7811d588>] do_softirq+0x68/0x70
> > [  233.613993]  [<78105351>] do_IRQ+0x51/0x90
> > [  233.618066]  [<78135c9c>] trace_hardirqs_on+0x9c/0xb0
> > [  233.623092]  [<7810f2d0>] pgd_dtor+0x0/0x50
> > [  233.627252]  [<7810388e>] common_interrupt+0x2e/0x40
> > [  233.632192]  [<7810f2d0>] pgd_dtor+0x0/0x50
> > [  233.636352]  [<7815f3be>] quicklist_trim+0x5e/0x90
> > [  233.641118]  [<7810f2cb>] check_pgt_cache+0x1b/0x20
> > [  233.645971]  [<78100c52>] cpu_idle+0x32/0x60
> > [  233.650217]  [<78a14b35>] start_kernel+0x265/0x300
> > [  233.654983]  [<78a14380>] unknown_bootoption+0x0/0x1e0
> > [  233.660097]  =======================
> > [  233.663649] Code: 00 00 00 8b 45 34 a8 02 0f 84 ed 00 00 00 8b bd 88 00 00 00 31 db 89 3c 24 8b 75 3c 89 f8 c7 44 24 10 00 00 00 00 eb 1b 8d 76 00 <8b> 50 10 8d 48 10 f6 c2 01 0f 85 be 02 00 00 89 44 24 10 83 c3 
> > [  233.682455] EIP: [<784e9480>] ata_qc_issue+0x90/0x380 SS:ESP 0068:78a13e14
> > [  233.689302] Kernel panic - not syncing: Fatal exception in interrupt
> > 
> > (gdb) list *0x784e9480
> > 0x784e9480 is in ata_qc_issue (include/linux/scatterlist.h:48).
> > 43       */
> > 44      static inline struct scatterlist *sg_next(struct scatterlist *sg)
> > 45      {
> > 46              sg++;
> > 47
> > 48              if (unlikely(sg_is_chain(sg)))
> > 49                      sg = sg_chain_ptr(sg);
> > 50
> > 51              return sg;
> > 52      }
> > (gdb)
> > 
> > so there's sg_next() involvement too. Below is the disassembly.
> 
> You must have a magic test box :-)
> 
> Will investigate... libata doesn't actually enable chaining, but since
> i386 supports it, it ends up using the chain helpers anyway.
> 
> There seems to be some automatic inlining involved here, it must be
> dying inside ata_sg_setup().

OK, something to try out - libata doesn't enable sg chaining, since the
support isn't complete yet. Here's a dumb check just to verify that
scsi_alloc_sgtable() will NEVER return a chain entry for a host that
doesn't have it enabled. If this triggers for you, then that could
explain your problem.

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index aac8a02..cc89c86 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -777,8 +777,12 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
 		 * sglist must be the biggest one, or we would not have
 		 * ended up doing another loop.
 		 */
-		if (prev)
+		if (prev) {
+			struct Scsi_Host *shost = cmd->device->host;
+
+			BUG_ON(!shost->use_sg_chaining);
 			sg_chain(prev, SCSI_MAX_SG_SEGMENTS, sgl);
+		}
 
 		/*
 		 * don't allow subsequent mempool allocs to sleep, it would

-- 
Jens Axboe


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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 18:22             ` Linus Torvalds
@ 2007-10-17 18:40               ` Jens Axboe
  0 siblings, 0 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-17 18:40 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Ingo Molnar, linux-kernel, Andrew Morton

On Wed, Oct 17 2007, Linus Torvalds wrote:
> 
> 
> On Wed, 17 Oct 2007, Linus Torvalds wrote:
> > 
> > So I think your change to use "sg_next()" only when you actually need a 
> > next pointer is the correct one after all.
> 
> That still leaves the initialization issue. The link pointers need to all 
> be initialized at SG allocation time (and not just the last one for the 
> case where it's a linked entry).
> 
> And if you initialize them at allocation time, does an allocation ever get 
> re-used without being free'd in between (if it does, you do indeed need to 
> initialize the non-link pointers each time - but I don't see it being the 
> case, so ..)

The links will not change, so reuse should actually be OK. The reuse
cannot be larger than the original would hold, but that would be a bug
without chaining as well of course.

WRT reuse, if we end up requeuing a request, than we will go through the
whole thing again. I don't think Ingo is hitting that either, though.

-- 
Jens Axboe


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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 18:20                 ` Jens Axboe
@ 2007-10-17 18:58                   ` Linus Torvalds
  2007-10-17 19:03                     ` Jens Axboe
  0 siblings, 1 reply; 151+ messages in thread
From: Linus Torvalds @ 2007-10-17 18:58 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Ingo Molnar, linux-kernel, Andrew Morton



On Wed, 17 Oct 2007, Jens Axboe wrote:
> 
> For the chain elements - yes, definitely! But we also want to clear dma
> mapping output values, at least sparc64 wants that. You could argue that
> the IOMMU code should be fixed up, but I don't think we should mix the
> two.
> 
> So we need the memset() in blk_rq_map_sg() AS WELL AS the initial sg
> table clear. I'm not arguing about the latter, we clearly do need that.

I still don't see your argument.

The SG table is *already*zeroed*.

The fact that output values will be changed later is irrelevant. They 
haven't been changed *before* - or at least you haven't given a reasonable 
explanation for why they should have.

So explain to me why the memset() in blk_rq_map_sg() helps, considering 
that the memory must have been zeroed at allocation time anyway? Tell me 
what it is that fills any of the fields we don't already initialize, and 
that can happen *before* that memset?

		Linus

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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 18:58                   ` Linus Torvalds
@ 2007-10-17 19:03                     ` Jens Axboe
  2007-10-17 19:15                       ` Linus Torvalds
  0 siblings, 1 reply; 151+ messages in thread
From: Jens Axboe @ 2007-10-17 19:03 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Ingo Molnar, linux-kernel, Andrew Morton

On Wed, Oct 17 2007, Linus Torvalds wrote:
> 
> 
> On Wed, 17 Oct 2007, Jens Axboe wrote:
> > 
> > For the chain elements - yes, definitely! But we also want to clear dma
> > mapping output values, at least sparc64 wants that. You could argue that
> > the IOMMU code should be fixed up, but I don't think we should mix the
> > two.
> > 
> > So we need the memset() in blk_rq_map_sg() AS WELL AS the initial sg
> > table clear. I'm not arguing about the latter, we clearly do need that.
> 
> I still don't see your argument.
> 
> The SG table is *already*zeroed*.
> 
> The fact that output values will be changed later is irrelevant. They 
> haven't been changed *before* - or at least you haven't given a reasonable 
> explanation for why they should have.
> 
> So explain to me why the memset() in blk_rq_map_sg() helps, considering 
> that the memory must have been zeroed at allocation time anyway? Tell me 
> what it is that fills any of the fields we don't already initialize, and 
> that can happen *before* that memset?

Ah ok, I see why you are confused. The SCSI case is one, it allocs and
frees the sg table each time. The entries are thus always initialized
when they end up in blk_rq_map_sg(). However, other drivers allocate one
at driver init time and use that one all the time. It needs to be
initially cleared, but it wont be cleared before each request mapping.
And that is fine, as long as we do clear entries in blk_rq_map_sg().

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 18:37                 ` Jens Axboe
@ 2007-10-17 19:04                   ` Ingo Molnar
  2007-10-17 19:08                     ` Jens Axboe
  2007-10-17 19:09                   ` Ingo Molnar
  1 sibling, 1 reply; 151+ messages in thread
From: Ingo Molnar @ 2007-10-17 19:04 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Linus Torvalds, linux-kernel, Jeff Garzik, Alan Cox


btw., i get the following build warning:

drivers/scsi/scsi_lib.c: In function 'scsi_free_sgtable':
drivers/scsi/scsi_lib.c:708: warning: 'index' may be used uninitialized in this function
drivers/scsi/scsi_lib.c:708: note: 'index' was declared here
drivers/scsi/scsi_lib.c:708: warning: 'index' may be used uninitialized in this function
drivers/scsi/scsi_lib.c:708: note: 'index' was declared here
drivers/scsi/scsi_lib.c: In function 'scsi_alloc_sgtable':
drivers/scsi/scsi_lib.c:708: warning: 'index' may be used uninitialized in this function
drivers/scsi/scsi_lib.c:708: note: 'index' was declared here

not sure it matters.

	Ingo

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 19:04                   ` Ingo Molnar
@ 2007-10-17 19:08                     ` Jens Axboe
  2007-10-17 19:14                       ` Ingo Molnar
  0 siblings, 1 reply; 151+ messages in thread
From: Jens Axboe @ 2007-10-17 19:08 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Linus Torvalds, linux-kernel, Jeff Garzik, Alan Cox

On Wed, Oct 17 2007, Ingo Molnar wrote:
> 
> btw., i get the following build warning:
> 
> drivers/scsi/scsi_lib.c: In function 'scsi_free_sgtable':
> drivers/scsi/scsi_lib.c:708: warning: 'index' may be used uninitialized in this function
> drivers/scsi/scsi_lib.c:708: note: 'index' was declared here
> drivers/scsi/scsi_lib.c:708: warning: 'index' may be used uninitialized in this function
> drivers/scsi/scsi_lib.c:708: note: 'index' was declared here
> drivers/scsi/scsi_lib.c: In function 'scsi_alloc_sgtable':
> drivers/scsi/scsi_lib.c:708: warning: 'index' may be used uninitialized in this function
> drivers/scsi/scsi_lib.c:708: note: 'index' was declared here
> 
> not sure it matters.

Hmm, I don't see them here (gcc 4.2.1). Must be the BUG(), does it go
away if you add a index = -1 in the default: case? Just to be absolutely
sure...

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 18:37                 ` Jens Axboe
  2007-10-17 19:04                   ` Ingo Molnar
@ 2007-10-17 19:09                   ` Ingo Molnar
  2007-10-17 19:28                     ` Linus Torvalds
  1 sibling, 1 reply; 151+ messages in thread
From: Ingo Molnar @ 2007-10-17 19:09 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Linus Torvalds, linux-kernel, Jeff Garzik, Alan Cox


* Jens Axboe <jens.axboe@oracle.com> wrote:

> @@ -777,8 +777,12 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
>  		 * sglist must be the biggest one, or we would not have
>  		 * ended up doing another loop.
>  		 */
> -		if (prev)
> +		if (prev) {
> +			struct Scsi_Host *shost = cmd->device->host;
> +
> +			BUG_ON(!shost->use_sg_chaining);
>  			sg_chain(prev, SCSI_MAX_SG_SEGMENTS, sgl);
> +		}
>  

nope, this did not help. First bootup went fine, second bootup crashed 
again (see below), without hitting the BUG_ON().

	Ingo

[   39.351198] BUG: unable to handle kernel paging request at virtual address 7ca58000
[   39.358698] printing eip: 784e9480 *pde = 00dda027 *pte = 04a58000 
[   39.364939] Oops: 0000 [#1] DEBUG_PAGEALLOC
[   39.369099] 
[   39.370573] Pid: 0, comm: swapper Not tainted (2.6.23 #9)
[   39.375944] EIP: 0060:[<784e9480>] EFLAGS: 00010087 CPU: 0
[   39.381408] EIP is at ata_qc_issue+0x90/0x380
[   39.385737] EAX: 7ca57ff0 EBX: 0000001f ECX: 7ca57ff0 EDX: 79181c20
[   39.391977] ESI: 00000020 EDI: 7ca57e00 EBP: 7b54007c ESP: 78a13e10
[   39.398217]  DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068
[   39.403590] Process swapper (pid: 0, ti=78a12000 task=789753e0 task.ti=78a12000)
[   39.410781] Stack: 7ca57e00 7b540000 7b540000 00000000 7ca57fe0 7b54007c 7c991980 7b5417a4 
[   39.419101]        784c2490 784ef69e 784f21f3 7b52de98 7c991980 7b540000 7b5417a4 7c991980 
[   39.427421]        7b540000 7b524004 784f22e0 784ef380 784c2490 7c991980 00000206 7b524004 
[   39.435740] Call Trace:
[   39.438340]  [<784c2490>] scsi_done+0x0/0x20
[   39.442586]  [<784ef69e>] ata_scsi_translate+0xbe/0x140
[   39.447785]  [<784f21f3>] ata_scsi_queuecmd+0x33/0x200
[   39.452899]  [<784f22e0>] ata_scsi_queuecmd+0x120/0x200
[   39.458099]  [<784ef380>] ata_scsi_rw_xlat+0x0/0x220
[   39.463038]  [<784c2490>] scsi_done+0x0/0x20
[   39.467285]  [<784c2d12>] scsi_dispatch_cmd+0x152/0x290
[   39.472484]  [<78135c67>] trace_hardirqs_on+0x67/0xb0
[   39.477511]  [<784c8c7e>] scsi_request_fn+0x1be/0x370
[   39.482538]  [<78408086>] blk_run_queue+0x36/0x80
[   39.487217]  [<784c7520>] scsi_next_command+0x30/0x50
[   39.492243]  [<784c76ab>] scsi_end_request+0xab/0xe0
[   39.497183]  [<784c83f9>] scsi_io_completion+0xa9/0x3d0
[   39.502383]  [<78135c67>] trace_hardirqs_on+0x67/0xb0
[   39.507409]  [<78405125>] blk_done_softirq+0x45/0x80
[   39.512348]  [<78405153>] blk_done_softirq+0x73/0x80
[   39.517288]  [<7811d4c3>] __do_softirq+0x53/0xb0
[   39.521882]  [<7811d588>] do_softirq+0x68/0x70
[   39.526302]  [<78105351>] do_IRQ+0x51/0x90
[   39.530374]  [<78770a54>] _spin_unlock+0x14/0x20
[   39.534968]  [<7810290f>] restore_nocheck+0x12/0x15
[   39.539820]  [<7810f2d0>] pgd_dtor+0x0/0x50
[   39.543980]  [<7810388e>] common_interrupt+0x2e/0x40
[   39.548920]  [<7810f2d0>] pgd_dtor+0x0/0x50
[   39.553079]  [<7815f3bd>] quicklist_trim+0x5d/0x90
[   39.557846]  [<7810f2cb>] check_pgt_cache+0x1b/0x20
[   39.562698]  [<78100c52>] cpu_idle+0x32/0x60
[   39.566945]  [<78a14b35>] start_kernel+0x265/0x300
[   39.571712]  [<78a14380>] unknown_bootoption+0x0/0x1e0
[   39.576825]  =======================
[   39.580377] Code: 00 00 00 8b 45 34 a8 02 0f 84 ed 00 00 00 8b bd 88 00 00 00 31 db 89 3c 24 8b 75 3c 89 f8 c7 44 24 10 00 00 00 00 eb 1b 8d 76 00 <8b> 50 10 8d 48 10 f6 c2 01 0f 85 be 02 00 00 89 44 24 10 83 c3 
[   39.599183] EIP: [<784e9480>] ata_qc_issue+0x90/0x380 SS:ESP 0068:78a13e10
[   39.606030] Kernel panic - not syncing: Fatal exception in interrupt

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 19:08                     ` Jens Axboe
@ 2007-10-17 19:14                       ` Ingo Molnar
  2007-10-17 19:17                         ` Ingo Molnar
  2007-10-17 19:25                         ` Jens Axboe
  0 siblings, 2 replies; 151+ messages in thread
From: Ingo Molnar @ 2007-10-17 19:14 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Linus Torvalds, linux-kernel, Jeff Garzik, Alan Cox


* Jens Axboe <jens.axboe@oracle.com> wrote:

> On Wed, Oct 17 2007, Ingo Molnar wrote:
> > 
> > btw., i get the following build warning:
> > 
> > drivers/scsi/scsi_lib.c: In function 'scsi_free_sgtable':
> > drivers/scsi/scsi_lib.c:708: warning: 'index' may be used uninitialized in this function
> > drivers/scsi/scsi_lib.c:708: note: 'index' was declared here
> > drivers/scsi/scsi_lib.c:708: warning: 'index' may be used uninitialized in this function
> > drivers/scsi/scsi_lib.c:708: note: 'index' was declared here
> > drivers/scsi/scsi_lib.c: In function 'scsi_alloc_sgtable':
> > drivers/scsi/scsi_lib.c:708: warning: 'index' may be used uninitialized in this function
> > drivers/scsi/scsi_lib.c:708: note: 'index' was declared here
> > 
> > not sure it matters.
> 
> Hmm, I don't see them here (gcc 4.2.1). Must be the BUG(), does it go 
> away if you add a index = -1 in the default: case? Just to be 
> absolutely sure...

well if i initialize the variable then of course the warning goes away
:)

NOTE: i get the same warning even without the BUG_ON() patch, and 
without your other fix patch as well. I'm using gcc 4.2.2. (Do you get 
the warning if you pick up the config i sent you earlier today?)

	Ingo

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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 19:03                     ` Jens Axboe
@ 2007-10-17 19:15                       ` Linus Torvalds
  0 siblings, 0 replies; 151+ messages in thread
From: Linus Torvalds @ 2007-10-17 19:15 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Ingo Molnar, linux-kernel, Andrew Morton



On Wed, 17 Oct 2007, Jens Axboe wrote:
> 
> Ah ok, I see why you are confused. The SCSI case is one, it allocs and
> frees the sg table each time. The entries are thus always initialized
> when they end up in blk_rq_map_sg(). However, other drivers allocate one
> at driver init time and use that one all the time. It needs to be
> initially cleared, but it wont be cleared before each request mapping.
> And that is fine, as long as we do clear entries in blk_rq_map_sg().

Ahh, ok, thanks for clearing that up.

			Linus

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 19:14                       ` Ingo Molnar
@ 2007-10-17 19:17                         ` Ingo Molnar
  2007-10-17 19:25                           ` Jens Axboe
  2007-10-17 19:25                         ` Jens Axboe
  1 sibling, 1 reply; 151+ messages in thread
From: Ingo Molnar @ 2007-10-17 19:17 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Linus Torvalds, linux-kernel, Jeff Garzik, Alan Cox


* Ingo Molnar <mingo@elte.hu> wrote:

> > > drivers/scsi/scsi_lib.c:708: warning: 'index' may be used uninitialized in this function
> > > drivers/scsi/scsi_lib.c:708: note: 'index' was declared here
> > > 
> > > not sure it matters.
> > 
> > Hmm, I don't see them here (gcc 4.2.1). Must be the BUG(), does it go 
> > away if you add a index = -1 in the default: case? Just to be 
> > absolutely sure...
> 
> well if i initialize the variable then of course the warning goes away
> :)
> 
> NOTE: i get the same warning even without the BUG_ON() patch, and 
> without your other fix patch as well. I'm using gcc 4.2.2. (Do you get 
> the warning if you pick up the config i sent you earlier today?)

btw., i changed the initialization to -1 and the crash still occurs 
(as expected).

	Ingo

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 19:14                       ` Ingo Molnar
  2007-10-17 19:17                         ` Ingo Molnar
@ 2007-10-17 19:25                         ` Jens Axboe
  1 sibling, 0 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-17 19:25 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Linus Torvalds, linux-kernel, Jeff Garzik, Alan Cox

On Wed, Oct 17 2007, Ingo Molnar wrote:
> 
> * Jens Axboe <jens.axboe@oracle.com> wrote:
> 
> > On Wed, Oct 17 2007, Ingo Molnar wrote:
> > > 
> > > btw., i get the following build warning:
> > > 
> > > drivers/scsi/scsi_lib.c: In function 'scsi_free_sgtable':
> > > drivers/scsi/scsi_lib.c:708: warning: 'index' may be used uninitialized in this function
> > > drivers/scsi/scsi_lib.c:708: note: 'index' was declared here
> > > drivers/scsi/scsi_lib.c:708: warning: 'index' may be used uninitialized in this function
> > > drivers/scsi/scsi_lib.c:708: note: 'index' was declared here
> > > drivers/scsi/scsi_lib.c: In function 'scsi_alloc_sgtable':
> > > drivers/scsi/scsi_lib.c:708: warning: 'index' may be used uninitialized in this function
> > > drivers/scsi/scsi_lib.c:708: note: 'index' was declared here
> > > 
> > > not sure it matters.
> > 
> > Hmm, I don't see them here (gcc 4.2.1). Must be the BUG(), does it go 
> > away if you add a index = -1 in the default: case? Just to be 
> > absolutely sure...
> 
> well if i initialize the variable then of course the warning goes away
> :)

Just making 100% sure that was the missing place, I try not to take
anything for granted with crazy bugs like this :-)
> 
> NOTE: i get the same warning even without the BUG_ON() patch, and 
> without your other fix patch as well. I'm using gcc 4.2.2. (Do you get 
> the warning if you pick up the config i sent you earlier today?)

Let me check... Yep, I do!

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 19:17                         ` Ingo Molnar
@ 2007-10-17 19:25                           ` Jens Axboe
  0 siblings, 0 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-17 19:25 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Linus Torvalds, linux-kernel, Jeff Garzik, Alan Cox

On Wed, Oct 17 2007, Ingo Molnar wrote:
> 
> * Ingo Molnar <mingo@elte.hu> wrote:
> 
> > > > drivers/scsi/scsi_lib.c:708: warning: 'index' may be used uninitialized in this function
> > > > drivers/scsi/scsi_lib.c:708: note: 'index' was declared here
> > > > 
> > > > not sure it matters.
> > > 
> > > Hmm, I don't see them here (gcc 4.2.1). Must be the BUG(), does it go 
> > > away if you add a index = -1 in the default: case? Just to be 
> > > absolutely sure...
> > 
> > well if i initialize the variable then of course the warning goes away
> > :)
> > 
> > NOTE: i get the same warning even without the BUG_ON() patch, and 
> > without your other fix patch as well. I'm using gcc 4.2.2. (Do you get 
> > the warning if you pick up the config i sent you earlier today?)
> 
> btw., i changed the initialization to -1 and the crash still occurs 
> (as expected).

Would think so, thanks for checking though.

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 19:09                   ` Ingo Molnar
@ 2007-10-17 19:28                     ` Linus Torvalds
  2007-10-17 19:35                       ` Jens Axboe
  2007-10-17 19:42                       ` Linus Torvalds
  0 siblings, 2 replies; 151+ messages in thread
From: Linus Torvalds @ 2007-10-17 19:28 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Jens Axboe, linux-kernel, Jeff Garzik, Alan Cox



On Wed, 17 Oct 2007, Ingo Molnar wrote:
> 
> nope, this did not help. First bootup went fine, second bootup crashed 
> again (see below), without hitting the BUG_ON().

I think you'll always hit it if you have a scatter-gather list that is 
exactly filled up.

Why? Because those things do "sg_next()" on the last entry, and as 
mentioned, that ends up actually accessing one past the end - even if the 
end result is not actually ever *used* (because we just effectively 
incremented it to past the last entry when the code was done with the SG 
list).

So I think the sg_next() interface is fundamentally mis-designed. It 
should do the scatter-gather link following on *starting* to use the SG 
entry, not after finishing with it.

Put another way: I suspect pretty much every single sg_next() out there is 
likely to hit this issue. The way that blk_rq_map_sg() fixed its problem 
was exactly to move the "sg_next()" to *before* the use of the SG (and 
even that one is somewhat bogus, in that it just blindly assumes that the 
first entry is not a link entry).

I suspect the "the next entry is a link" bit should be in the *previous* 
entry, and then sg_next() could look like

	if (next_is_link(sg))
		sg = sg_chain_ptr(sg+1);
	else
		sg++;
	return sg;

and that would work. 

The alternative is to always make sure to allocate one more SG entry than 
required, so that the last entry is always either the link, or an unused 
entry!

		Linus

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 19:28                     ` Linus Torvalds
@ 2007-10-17 19:35                       ` Jens Axboe
  2007-10-17 19:45                         ` Linus Torvalds
                                           ` (2 more replies)
  2007-10-17 19:42                       ` Linus Torvalds
  1 sibling, 3 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-17 19:35 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Ingo Molnar, linux-kernel, Jeff Garzik, Alan Cox

On Wed, Oct 17 2007, Linus Torvalds wrote:
> 
> 
> On Wed, 17 Oct 2007, Ingo Molnar wrote:
> > 
> > nope, this did not help. First bootup went fine, second bootup crashed 
> > again (see below), without hitting the BUG_ON().
> 
> I think you'll always hit it if you have a scatter-gather list that is 
> exactly filled up.
> 
> Why? Because those things do "sg_next()" on the last entry, and as 
> mentioned, that ends up actually accessing one past the end - even if the 
> end result is not actually ever *used* (because we just effectively 
> incremented it to past the last entry when the code was done with the SG 
> list).
> 
> So I think the sg_next() interface is fundamentally mis-designed. It 
> should do the scatter-gather link following on *starting* to use the SG 
> entry, not after finishing with it.
> 
> Put another way: I suspect pretty much every single sg_next() out there is 
> likely to hit this issue. The way that blk_rq_map_sg() fixed its problem 
> was exactly to move the "sg_next()" to *before* the use of the SG (and 
> even that one is somewhat bogus, in that it just blindly assumes that the 
> first entry is not a link entry).
> 
> I suspect the "the next entry is a link" bit should be in the *previous* 
> entry, and then sg_next() could look like
> 
> 	if (next_is_link(sg))
> 		sg = sg_chain_ptr(sg+1);
> 	else
> 		sg++;
> 	return sg;
> 
> and that would work. 
> 
> The alternative is to always make sure to allocate one more SG entry than 
> required, so that the last entry is always either the link, or an unused 
> entry!

OK, I think you have a very good point here. Ingo, can you verify it
goes away if apply the below? I have to tend to Other Life stuff but
will take this up again tomorrow morning and fix the sg_next() usage.

Linus, please still pull the branch I asked you to earlier. Thanks!


diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index aac8a02..58ede7e 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -39,7 +39,7 @@
  * (unless chaining is used). Should ideally fit inside a single page, to
  * avoid a higher order allocation.
  */
-#define SCSI_MAX_SG_SEGMENTS	128
+#define SCSI_MAX_SG_SEGMENTS	129
 
 struct scsi_host_sg_pool {
 	size_t		size;


-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 19:28                     ` Linus Torvalds
  2007-10-17 19:35                       ` Jens Axboe
@ 2007-10-17 19:42                       ` Linus Torvalds
  2007-10-17 19:55                         ` Jens Axboe
  1 sibling, 1 reply; 151+ messages in thread
From: Linus Torvalds @ 2007-10-17 19:42 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Jens Axboe, linux-kernel, Jeff Garzik, Alan Cox



On Wed, 17 Oct 2007, Linus Torvalds wrote:
> 
> I think you'll always hit it if you have a scatter-gather list that is 
> exactly filled up.

In fact, I think you'll hit it even if you use the "for_each_sg()" 
helper function. Exactly because it does the sg = sg_next(sg) at the end 
of the for-loop, so it will do it for the last entry too, even though that 
will access one past the end.

So it really *is* the case that every *single* use of that SG chain needs 
to be switched over to only do the sg_next() when required, or sg_next() 
needs to be fixed to look at the current-in-use entry (which we *can* 
access) when it decides what to do about the next one (which we can *not* 
access).

Moving the sg_is_chain() bit to the previous entry would work, but it 
requires that nobody who could have a chained scatterlist must *ever* 
access "sg->page" directly - you'd always need to use some helper function 
that masks off the bit, eg

 - rename "sg->page" into "sh->page_and_flag", and make it "unsigned long" 
   instead of a pointer.

 - change every single "sg->page" access to use "sg_page(sg)" instead:

	#define sg_pointer(sg)	((void *)((sg)->page_and_flag & ~1ul))

	static inline struct page *sg_page(struct scatterist *sg)
	{
		return sg_pointer(sg);
	}

 - change "sg_next()" to do

	static inline struct scatterlist *sg_next(struct scatterlist *sg)
	{
		if (sg->page_and_flag & 1)
			sg = sg_pointer(sg+1)-1;
		return ++sg;
	}

where the magic is exactly the fact that now "sg_next()" will *not* 
derefence the next SG entry unless the current one was marked 
appropriately.

And then *creating* the chain obviously needs to properly mark the 
next-to-last entry with the "next entry is a pointer" flag.

Big diff, it sounds like. But I don't see many alternatives. Jens?

		Linus

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 19:35                       ` Jens Axboe
@ 2007-10-17 19:45                         ` Linus Torvalds
  2007-10-17 19:56                           ` Jens Axboe
  2007-10-17 19:49                         ` Jens Axboe
  2007-10-18  7:07                         ` Ingo Molnar
  2 siblings, 1 reply; 151+ messages in thread
From: Linus Torvalds @ 2007-10-17 19:45 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Ingo Molnar, linux-kernel, Jeff Garzik, Alan Cox



On Wed, 17 Oct 2007, Jens Axboe wrote:
> 
> OK, I think you have a very good point here. Ingo, can you verify it
> goes away if apply the below? I have to tend to Other Life stuff but
> will take this up again tomorrow morning and fix the sg_next() usage.

This one will only fix the ones that use the SCSI-lib routines, so it will 
leave everything else broken, no?

> Linus, please still pull the branch I asked you to earlier. Thanks!

Already did.

		Linus

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 19:35                       ` Jens Axboe
  2007-10-17 19:45                         ` Linus Torvalds
@ 2007-10-17 19:49                         ` Jens Axboe
  2007-10-17 20:05                           ` Ingo Molnar
  2007-10-17 20:10                           ` Linus Torvalds
  2007-10-18  7:07                         ` Ingo Molnar
  2 siblings, 2 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-17 19:49 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Ingo Molnar, linux-kernel, Jeff Garzik, Alan Cox

On Wed, Oct 17 2007, Jens Axboe wrote:
> On Wed, Oct 17 2007, Linus Torvalds wrote:
> > 
> > 
> > On Wed, 17 Oct 2007, Ingo Molnar wrote:
> > > 
> > > nope, this did not help. First bootup went fine, second bootup crashed 
> > > again (see below), without hitting the BUG_ON().
> > 
> > I think you'll always hit it if you have a scatter-gather list that is 
> > exactly filled up.
> > 
> > Why? Because those things do "sg_next()" on the last entry, and as 
> > mentioned, that ends up actually accessing one past the end - even if the 
> > end result is not actually ever *used* (because we just effectively 
> > incremented it to past the last entry when the code was done with the SG 
> > list).

Well, hang on - where does it end up doing sg_next() on the LAST sg
entry? I'd argue that this is a bug, like it was in ll_rw_blk.c. I still
agree that I should make the interface more robust, I just don't see
where libata ends up doing the sg_next() on the last entry.

I'm assuming that Ingo is using the previous patches, so that
blk_rq_map_sg() is using this construct:

new_segment:
       if (!sg)
               sg = sglist;
       else
               sg = sg_next(sg);

and the memset() in scsi_alloc_sgtable(), which I'm pretty sure he is.
I'm assuming we're not hitting pio paths, so there are no manual
sg_next() calls. Ingo, if you care, can you test this one as well?

No rush, as mentioned I'll be back tomorrow morning...

diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index bbaa545..0246b61 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4664,7 +4664,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
 {
 	struct ata_port *ap = qc->ap;
 	struct scatterlist *sg = qc->__sg;
-	struct scatterlist *lsg = sg_last(qc->__sg, qc->n_elem);
+	struct scatterlist *lsg = &qc->__sg[qc->n_elem - 1];
 	int n_elem, pre_n_elem, dir, trim_sg = 0;
 
 	VPRINTK("ENTER, ata%u\n", ap->print_id);

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 19:42                       ` Linus Torvalds
@ 2007-10-17 19:55                         ` Jens Axboe
  0 siblings, 0 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-17 19:55 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Ingo Molnar, linux-kernel, Jeff Garzik, Alan Cox

On Wed, Oct 17 2007, Linus Torvalds wrote:
> 
> 
> On Wed, 17 Oct 2007, Linus Torvalds wrote:
> > 
> > I think you'll always hit it if you have a scatter-gather list that is 
> > exactly filled up.
> 
> In fact, I think you'll hit it even if you use the "for_each_sg()" 
> helper function. Exactly because it does the sg = sg_next(sg) at the end 
> of the for-loop, so it will do it for the last entry too, even though that 
> will access one past the end.
> 
> So it really *is* the case that every *single* use of that SG chain needs 
> to be switched over to only do the sg_next() when required, or sg_next() 
> needs to be fixed to look at the current-in-use entry (which we *can* 
> access) when it decides what to do about the next one (which we can *not* 
> access).

Auch yes, ok nevermind that last email. There really is no way around
allocating an extra 'pad' entry right now, so the SCSI_MAX_SG_SEGMENTS
at 129 should fix Ingo's oops and the other crap is void.

> Moving the sg_is_chain() bit to the previous entry would work, but it 
> requires that nobody who could have a chained scatterlist must *ever* 
> access "sg->page" directly - you'd always need to use some helper function 
> that masks off the bit, eg
> 
>  - rename "sg->page" into "sh->page_and_flag", and make it "unsigned long" 
>    instead of a pointer.
> 
>  - change every single "sg->page" access to use "sg_page(sg)" instead:
> 
> 	#define sg_pointer(sg)	((void *)((sg)->page_and_flag & ~1ul))
> 
> 	static inline struct page *sg_page(struct scatterist *sg)
> 	{
> 		return sg_pointer(sg);
> 	}
> 
>  - change "sg_next()" to do
> 
> 	static inline struct scatterlist *sg_next(struct scatterlist *sg)
> 	{
> 		if (sg->page_and_flag & 1)
> 			sg = sg_pointer(sg+1)-1;
> 		return ++sg;
> 	}
> 
> where the magic is exactly the fact that now "sg_next()" will *not* 
> derefence the next SG entry unless the current one was marked 
> appropriately.
> 
> And then *creating* the chain obviously needs to properly mark the 
> next-to-last entry with the "next entry is a pointer" flag.
> 
> Big diff, it sounds like. But I don't see many alternatives. Jens?

Big diff is not a problem for me, my primary concern would be making
sure that the interface is solid. The above also has the nice side
effect of making all sg elements usable, so we don't waste any. IIRC
this was even debated months ago when I first proposed sg chaining, I
shied away from it because I thought it would seem huge and too
invasive. Ah well. I'll get digging on this.

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 19:45                         ` Linus Torvalds
@ 2007-10-17 19:56                           ` Jens Axboe
  2007-10-17 20:06                             ` Jens Axboe
  0 siblings, 1 reply; 151+ messages in thread
From: Jens Axboe @ 2007-10-17 19:56 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Ingo Molnar, linux-kernel, Jeff Garzik, Alan Cox

On Wed, Oct 17 2007, Linus Torvalds wrote:
> 
> 
> On Wed, 17 Oct 2007, Jens Axboe wrote:
> > 
> > OK, I think you have a very good point here. Ingo, can you verify it
> > goes away if apply the below? I have to tend to Other Life stuff but
> > will take this up again tomorrow morning and fix the sg_next() usage.
> 
> This one will only fix the ones that use the SCSI-lib routines, so it will 
> leave everything else broken, no?

Yes, it'll still crap out if you use debug page alloc for anything else
:/

> > Linus, please still pull the branch I asked you to earlier. Thanks!
> 
> Already did.

Thanks

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 19:49                         ` Jens Axboe
@ 2007-10-17 20:05                           ` Ingo Molnar
  2007-10-17 20:10                           ` Linus Torvalds
  1 sibling, 0 replies; 151+ messages in thread
From: Ingo Molnar @ 2007-10-17 20:05 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Linus Torvalds, linux-kernel


* Jens Axboe <jens.axboe@oracle.com> wrote:

> Ingo, if you care, can you test this one as well?

hm, it still crashes - find the log below.

	Ingo

[   34.653682] EXT3-fs: mounted filesystem with ordered data mode.
[   34.659487] VFS: Mounted root (ext3 filesystem) readonly.
[   34.665208] Freeing unused kernel memory: 372k freed
[   35.809988] BUG: unable to handle kernel paging request at virtual address 7c8d3000
[   35.817483] printing eip: 784e9480 *pde = 00dda027 *pte = 048d3000 
[   35.823723] Oops: 0000 [#1] DEBUG_PAGEALLOC
[   35.827883] 
[   35.829357] Pid: 47, comm: rc.sysinit Not tainted (2.6.23 #14)
[   35.835162] EIP: 0060:[<784e9480>] EFLAGS: 00010006 CPU: 0
[   35.840626] EIP is at ata_qc_issue+0xd0/0x340
[   35.844954] EAX: 3fd79000 EBX: 7c8d3000 ECX: 00000020 EDX: 00000020
[   35.851194] ESI: 7c8a1a80 EDI: 7c8d2e00 EBP: 7b54007c ESP: 7c8b3d5c
[   35.857434]  DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 0068
[   35.862807] Process rc.sysinit (pid: 47, ti=7c8b2000 task=7c86d000 task.ti=7c8b2000)
[   35.870346] Stack: 7c8d3000 7b540000 7b540000 00000000 7c8d2ff0 7b54007c 7c8a1a80 7b5417a4 
[   35.878665]        784c2490 784ef61e 784f2173 7b52de98 7c8a1a80 7b540000 7b5417a4 7c8a1a80 
[   35.886985]        7b540000 7b524004 784f2260 784ef300 784c2490 7c8a1a80 00000216 7b524004 
[   35.895304] Call Trace:
[   35.897905]  [<784c2490>] scsi_done+0x0/0x20
[   35.902151]  [<784ef61e>] ata_scsi_translate+0xbe/0x140
[   35.907350]  [<784f2173>] ata_scsi_queuecmd+0x33/0x200
[   35.912463]  [<784f2260>] ata_scsi_queuecmd+0x120/0x200
[   35.917663]  [<784ef300>] ata_scsi_rw_xlat+0x0/0x220
[   35.922602]  [<784c2490>] scsi_done+0x0/0x20
[   35.926849]  [<784c2d12>] scsi_dispatch_cmd+0x152/0x290
[   35.932049]  [<78135c9c>] trace_hardirqs_on+0x9c/0xb0
[   35.937075]  [<784c8c3e>] scsi_request_fn+0x1be/0x370
[   35.942102]  [<78120f02>] del_timer+0x62/0x70
[   35.946434]  [<784072d5>] __generic_unplug_device+0x25/0x30
[   35.951981]  [<784075a5>] generic_unplug_device+0x15/0x30
[   35.957354]  [<78404e00>] blk_backing_dev_unplug+0x0/0x10
[   35.962726]  [<78404e0c>] blk_backing_dev_unplug+0xc/0x10
[   35.968100]  [<78180a9d>] block_sync_page+0x2d/0x40
[   35.972952]  [<78144dc9>] sync_page+0x29/0x40
[   35.977286]  [<7876f5dc>] __wait_on_bit_lock+0x3c/0x70
[   35.982399]  [<78144da0>] sync_page+0x0/0x40
[   35.986645]  [<78144d82>] __lock_page+0x52/0x60
[   35.991152]  [<7812adb0>] wake_bit_function+0x0/0x60
[   35.996092]  [<78144f60>] find_lock_page+0x60/0xa0
[   36.000858]  [<781473b9>] filemap_fault+0x269/0x3b0
[   36.005711]  [<78150b7f>] __do_fault+0x4f/0x3e0
[   36.010217]  [<78147150>] filemap_fault+0x0/0x3b0
[   36.014897]  [<78152640>] handle_mm_fault+0xf0/0x6c0
[   36.019837]  [<7810fd5c>] do_page_fault+0x21c/0x670
[   36.024689]  [<7812e6fd>] down_read_trylock+0x4d/0x60
[   36.029716]  [<7810fdbb>] do_page_fault+0x27b/0x670
[   36.034568]  [<7810fb40>] do_page_fault+0x0/0x670
[   36.039248]  [<787710ea>] error_code+0x6a/0x70
[   36.043669]  =======================
[   36.047221] Code: 84 d9 01 00 00 7e 32 31 d2 89 f6 8b 1c 24 83 c2 01 8b 03 2b 05 f8 ec d7 78 c1 f8 05 c1 e0 0c 03 43 04 89 43 08 83 c3 10 89 1c 24 <8b> 03 a8 01 0f 85 58 02 00 00 39 ca 75 d2 f0 83 44 24 00 00 85 
[   36.066027] EIP: [<784e9480>] ata_qc_issue+0xd0/0x340 SS:ESP 0068:7c8b3d5c
[  100.077701] BUG: spinlock lockup on CPU#0, scsi_eh_0/32, 7b52de98
[  100.083667]  [<78414b9b>] _raw_spin_lock+0x13b/0x140
[  100.088605]  [<784c6610>] scsi_error_handler+0x0/0x4f0

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 19:56                           ` Jens Axboe
@ 2007-10-17 20:06                             ` Jens Axboe
  2007-10-17 20:24                               ` Linus Torvalds
  2007-10-17 20:51                               ` Ingo Molnar
  0 siblings, 2 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-17 20:06 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Ingo Molnar, linux-kernel, Jeff Garzik, Alan Cox

On Wed, Oct 17 2007, Jens Axboe wrote:
> On Wed, Oct 17 2007, Linus Torvalds wrote:
> > 
> > 
> > On Wed, 17 Oct 2007, Jens Axboe wrote:
> > > 
> > > OK, I think you have a very good point here. Ingo, can you verify it
> > > goes away if apply the below? I have to tend to Other Life stuff but
> > > will take this up again tomorrow morning and fix the sg_next() usage.
> > 
> > This one will only fix the ones that use the SCSI-lib routines, so it will 
> > leave everything else broken, no?
> 
> Yes, it'll still crap out if you use debug page alloc for anything else
> :/

So until that is fixed up, how about this? Should cover all block
devices, and I don't think sg_next()/for_each_sg() has spread outside of
that yet.

diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 3935469..8708ad0 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -631,7 +631,7 @@ void blk_queue_max_phys_segments(struct request_queue *q,
 		printk("%s: set to minimum %d\n", __FUNCTION__, max_segments);
 	}
 
-	q->max_phys_segments = max_segments;
+	q->max_phys_segments = max_segments - 1;
 }
 
 EXPORT_SYMBOL(blk_queue_max_phys_segments);

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 19:49                         ` Jens Axboe
  2007-10-17 20:05                           ` Ingo Molnar
@ 2007-10-17 20:10                           ` Linus Torvalds
  1 sibling, 0 replies; 151+ messages in thread
From: Linus Torvalds @ 2007-10-17 20:10 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Ingo Molnar, linux-kernel, Jeff Garzik, Alan Cox



On Wed, 17 Oct 2007, Jens Axboe wrote:
> 
> Well, hang on - where does it end up doing sg_next() on the LAST sg
> entry?

They pretty much *all* do, as far as I can tell.

For example, to look at the very first one:

	#define for_each_sg(sglist, sg, nr, __i)        \
		for (__i = 0, sg = (sglist); __i < (nr); __i++, sg = sg_next(sg))

let's say that "nr" is 1 (and that's also the allocation size), and look 
at what that causes.

Right. It causes us to do "sg = sg_next(sg)" once. Which will do what? It 
will increment sg (so that it now points past the single-entry array!) and 
then it will dereference that invalid entry to see if it's a chain entry!


And no, "1" is not the special case. The special case is *any* time when 
you iterate over as many sg entries as you allocated. You *always* have to 
leave the last one unused in order to avoid this "access past the end" 
problem.

The alternative is to rewrite the loop, but it's going to be ugly as hell, 
and you need to do that for *every*single*user* of sg_next(). You can 
re-write the above loop as something like

	define for_each_sg(sglist, sg, nr, __i)
		for (__i = 0, sg = NULL ;
			__i < (nr) && sg = (sg ? sglist : sg_next(sg) ;
			__i++))

but the important part here is that you must do that "sg_next()" *after* 
you have broken out of the loop, and you must basically do it one less 
time than you go through the loop.

IOW, any loop that leaves "sg" pointing to past the array is inevitably 
buggy, because it will have accessed that last past-tne-end entry as part 
of tryign to decide whether it should perhaps follow a link.

> I'd argue that this is a bug, like it was in ll_rw_blk.c. I still
> agree that I should make the interface more robust, I just don't see
> where libata ends up doing the sg_next() on the last entry.

See above. I think the exact sequence may be:

    ata_qc_issue()
	(implicitly inlined) ata_sg_setup()
		(explicitly inlined) dma_map_sg()
			(macro) for_each_sg()

but I didn't see if there are other possible chains that get you to one of 
those invalid sg loops.

And no, it's *not* just for_each_sg(). Pretty much any "natural" loop over 
the SG list will cause it, because that's how you write loops in C: you 
almost always end up pointing to one past the last entry after the loop.

			Linus

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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 17:29         ` Jens Axboe
  2007-10-17 17:34           ` Ingo Molnar
  2007-10-17 17:56           ` [bug] block " Linus Torvalds
@ 2007-10-17 20:15           ` Luca Tettamanti
  2 siblings, 0 replies; 151+ messages in thread
From: Luca Tettamanti @ 2007-10-17 20:15 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Linus Torvalds, Ingo Molnar, linux-kernel, Andrew Morton

Il Wed, Oct 17, 2007 at 07:29:32PM +0200, Jens Axboe ha scritto: 
> OK, it is fine, as long as the sglist is cleared initially. And I don't
> think there's anyway around that, clearly I didn't think long enough
> before including the memset() removal from Tomo.
> 
> Ingo, please try this rolled up version.
> 
> Linus, this should work. It would probably be best if you first did a
> git revert on f5c0dde4c66421a3a2d7d6fa604a712c9b0744e5 and then applied
> the ll_rw_blk.c bit alone. Do you want me to stuff that (revert + patch)
> into a branch for you to pull?
> 
> diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
> index 9e3f3cc..3935469 100644
> --- a/block/ll_rw_blk.c
> +++ b/block/ll_rw_blk.c
> @@ -1322,8 +1322,8 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
>  		  struct scatterlist *sglist)
>  {
>  	struct bio_vec *bvec, *bvprv;
> -	struct scatterlist *next_sg, *sg;
>  	struct req_iterator iter;
> +	struct scatterlist *sg;
>  	int nsegs, cluster;
>  
>  	nsegs = 0;
> @@ -1333,7 +1333,7 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
>  	 * for each bio in rq
>  	 */
>  	bvprv = NULL;
> -	sg = next_sg = &sglist[0];
> +	sg = NULL;
>  	rq_for_each_segment(bvec, rq, iter) {
>  		int nbytes = bvec->bv_len;
>  
> @@ -1349,8 +1349,10 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
>  			sg->length += nbytes;
>  		} else {
>  new_segment:
> -			sg = next_sg;
> -			next_sg = sg_next(sg);
> +			if (!sg)
> +				sg = sglist;
> +			else
> +				sg = sg_next(sg);
>  
>  			memset(sg, 0, sizeof(*sg));
>  			sg->page = bvec->bv_page;
> diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
> index 0c86be7..aac8a02 100644
> --- a/drivers/scsi/scsi_lib.c
> +++ b/drivers/scsi/scsi_lib.c
> @@ -764,6 +764,8 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
>  		if (unlikely(!sgl))
>  			goto enomem;
>  
> +		memset(sgl, 0, sizeof(*sgl) * sgp->size);
> +
>  		/*
>  		 * first loop through, set initial index and return value
>  		 */
> 

Hi Jens,
I just hit what I believe is the same bug, though with a slightly
different OOPS (I see a NULL pointer dereference, see below). The
patches fixes the bug, and - as Linus suggested - the piece touching
scsi_lib.c is enough.

The OOPS:

scsi4 : ata_piix
scsi5 : ata_piix
ata5: PATA max UDMA/100 cmd 0x1f0 ctl 0x3f6 bmdma 0xffa0 irq 14
ata6: PATA max UDMA/100 cmd 0x170 ctl 0x376 bmdma 0xffa8 irq 15
 sda1 sda2 sda3 < sda5 sda6 >
sd 0:0:0:0: [sda] Attached SCSI disk
ata5.00: ATAPI: MATSHITADVD-RAM UJ-850S, 1.22, max UDMA/33
Unable to handle kernel NULL pointer dereference at 0000000000000020 RIP: 
 [<ffffffff802d275e>] blk_rq_map_sg+0xf6/0x16a
PGD 4711067 PUD 508c067 PMD 0 
Oops: 0000 [1] PREEMPT SMP 
CPU 0 
Modules linked in: sd_mod ohci1394 ehci_hcd ata_piix ieee1394 ahci uhci_hcd libata scsi_mod usbcore thermal processor fan
Pid: 0, comm: swapper Not tainted 2.6.23-ge6d5a11d #3
RIP: 0010:[<ffffffff802d275e>]  [<ffffffff802d275e>] blk_rq_map_sg+0xf6/0x16a
RSP: 0018:ffffffff804eccd8  EFLAGS: 00010087
RAX: 0000000005331000 RBX: ffff810004740220 RCX: ffff810001000000
RDX: 0000000000000000 RSI: ffff8100052d4f50 RDI: 0000000005142c00
RBP: 0000000000001400 R08: 0000000000000000 R09: ffff8100052a3980
R10: 0000000005143000 R11: 0000000000000400 R12: ffff8100047a4000
R13: 0000000000000000 R14: 0000000000000002 R15: 0000000000000000
FS:  0000000000000000(0000) GS:ffffffff8049a000(0000) knlGS:0000000000000000
CS:  0010 DS: 0018 ES: 0018 CR0: 000000008005003b
CR2: 0000000000000020 CR3: 0000000005118000 CR4: 00000000000006e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process swapper (pid: 0, threadinfo ffffffff804ac000, task ffffffff8046c340)
Stack:  ffffffff88041834 000000010314ba00 ffff81000477fa80 ffff81000503dd80
 ffff81000503dd80 ffff81000517fc00 000000000000001e 0000000000001d4c
 ffffffff8804193c 0000000015925849 ffff81000473f800 ffff81000503dd80
Call Trace:
 <IRQ>  [<ffffffff88041834>] :scsi_mod:scsi_alloc_sgtable+0xad/0x13c
 [<ffffffff8804193c>] :scsi_mod:scsi_init_io+0x79/0xd9
 [<ffffffff880d1328>] :sd_mod:sd_prep_fn+0x59/0x367
 [<ffffffff802d07ff>] elv_next_request+0xc0/0x14a
 [<ffffffff88042367>] :scsi_mod:scsi_request_fn+0x88/0x356
 [<ffffffff802d46f7>] blk_run_queue+0x41/0x72
 [<ffffffff88041135>] :scsi_mod:scsi_next_command+0x2d/0x39
 [<ffffffff880412ae>] :scsi_mod:scsi_end_request+0xbb/0xc9
 [<ffffffff880415ac>] :scsi_mod:scsi_io_completion+0xf8/0x2d3
 [<ffffffff802d4a83>] blk_done_softirq+0x62/0x6f
 [<ffffffff80238f28>] __do_softirq+0x59/0xc3
 [<ffffffff8020d13c>] call_softirq+0x1c/0x28
 [<ffffffff8020ec26>] do_softirq+0x2c/0x7d
 [<ffffffff80238e30>] irq_exit+0x36/0x81
 [<ffffffff8020edb4>] do_IRQ+0x13d/0x161
 [<ffffffff8020c491>] ret_from_intr+0x0/0xa
 <EOI>  [<ffffffff88005249>] :processor:acpi_processor_idle+0x2cb/0x496
 [<ffffffff88005245>] :processor:acpi_processor_idle+0x2c7/0x496
 [<ffffffff88004f7e>] :processor:acpi_processor_idle+0x0/0x496
 [<ffffffff8020ad00>] default_idle+0x0/0x3d
 [<ffffffff8020adcd>] cpu_idle+0x90/0xcc
 [<ffffffff804b4a60>] start_kernel+0x2ab/0x2b7
 [<ffffffff804b411b>] _sinittext+0x11b/0x122


Code: 49 8b 40 20 4d 8d 50 20 4c 89 c7 fc b9 08 00 00 00 4c 89 c3 
RIP  [<ffffffff802d275e>] blk_rq_map_sg+0xf6/0x16a
 RSP <ffffffff804eccd8>
CR2: 0000000000000020
Kernel panic - not syncing: Aiee, killing interrupt handler!

Luca
-- 
The trouble with computers is that they do what you tell them, 
not what you want.
D. Cohen

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 20:06                             ` Jens Axboe
@ 2007-10-17 20:24                               ` Linus Torvalds
  2007-10-17 20:31                                 ` Jens Axboe
  2007-10-17 20:51                               ` Ingo Molnar
  1 sibling, 1 reply; 151+ messages in thread
From: Linus Torvalds @ 2007-10-17 20:24 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Ingo Molnar, linux-kernel, Jeff Garzik, Alan Cox



On Wed, 17 Oct 2007, Jens Axboe wrote:
> 
> So until that is fixed up, how about this? Should cover all block
> devices, and I don't think sg_next()/for_each_sg() has spread outside of
> that yet.

Heh. Not good. There are drivers that set max phys segmsnts to 1. Either 
through some host-specific setting (MMC), or explicitly (eg a grep shows 
viodasd uses just a constant 1 there).

		Linus

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 20:24                               ` Linus Torvalds
@ 2007-10-17 20:31                                 ` Jens Axboe
  2007-10-17 21:11                                   ` Linus Torvalds
  0 siblings, 1 reply; 151+ messages in thread
From: Jens Axboe @ 2007-10-17 20:31 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Ingo Molnar, linux-kernel, Jeff Garzik, Alan Cox

On Wed, Oct 17 2007, Linus Torvalds wrote:
> 
> 
> On Wed, 17 Oct 2007, Jens Axboe wrote:
> > 
> > So until that is fixed up, how about this? Should cover all block
> > devices, and I don't think sg_next()/for_each_sg() has spread outside of
> > that yet.
> 
> Heh. Not good. There are drivers that set max phys segmsnts to 1. Either 
> through some host-specific setting (MMC), or explicitly (eg a grep shows 
> viodasd uses just a constant 1 there).

That would hurt... Care to commit your for_each_sg() uglification fixup
for now then? Or disable the allocation debug config entry, so that the
sg+1 deref wont crash? Whichever your prefer, just don't want to cause
crash pains for the unfortunate souls that happen to run into this
before the real fix is done.

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 20:06                             ` Jens Axboe
  2007-10-17 20:24                               ` Linus Torvalds
@ 2007-10-17 20:51                               ` Ingo Molnar
  1 sibling, 0 replies; 151+ messages in thread
From: Ingo Molnar @ 2007-10-17 20:51 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Linus Torvalds, linux-kernel, Jeff Garzik, Alan Cox


* Jens Axboe <jens.axboe@oracle.com> wrote:

> --- a/block/ll_rw_blk.c
> +++ b/block/ll_rw_blk.c
> @@ -631,7 +631,7 @@ void blk_queue_max_phys_segments(struct request_queue *q,
>  		printk("%s: set to minimum %d\n", __FUNCTION__, max_segments);
>  	}
>  
> -	q->max_phys_segments = max_segments;
> +	q->max_phys_segments = max_segments - 1;

this one crashes too, if added ontop of all the other fixes so far.

	Ingo

[   34.711185] EXT3-fs: mounted filesystem with ordered data mode.
[   34.716991] VFS: Mounted root (ext3 filesystem) readonly.
[   34.722712] Freeing unused kernel memory: 372k freed
[   36.112742] BUG: unable to handle kernel paging request at virtual address 7c8b1000
[   36.120246] printing eip: 784e9490 *pde = 00dda027 *pte = 048b1000 
[   36.126486] Oops: 0000 [#1] DEBUG_PAGEALLOC
[   36.130645] 
[   36.132119] Pid: 0, comm: swapper Not tainted (2.6.23 #15)
[   36.137579] EIP: 0060:[<784e9490>] EFLAGS: 00010006 CPU: 0
[   36.143043] EIP is at ata_qc_issue+0xd0/0x340
[   36.147371] EAX: 3f896000 EBX: 7c8b1000 ECX: 00000008 EDX: 00000008
[   36.153610] ESI: 7c86de80 EDI: 7c8b0f80 EBP: 7b54007c ESP: 78a13e28
[   36.159851]  DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068
[   36.165223] Process swapper (pid: 0, ti=78a12000 task=789753e0 task.ti=78a12000)
[   36.172416] Stack: 7c8b1000 7b540000 7b540000 00000000 7c8b0ff0 7b54007c 7c86de80 7b5417a4 
[   36.180735]        784c24a0 784ef62e 784f2183 7b52de98 7c86de80 7b540000 7b5417a4 7c86de80 
[   36.189055]        7b540000 7b524004 784f2270 784ef310 784c24a0 7c86de80 00000206 7b524004 
[   36.197374] Call Trace:
[   36.199975]  [<784c24a0>] scsi_done+0x0/0x20
[   36.204221]  [<784ef62e>] ata_scsi_translate+0xbe/0x140
[   36.209420]  [<784f2183>] ata_scsi_queuecmd+0x33/0x200
[   36.214533]  [<784f2270>] ata_scsi_queuecmd+0x120/0x200
[   36.219733]  [<784ef310>] ata_scsi_rw_xlat+0x0/0x220
[   36.224672]  [<784c24a0>] scsi_done+0x0/0x20
[   36.228918]  [<784c2d22>] scsi_dispatch_cmd+0x152/0x290
[   36.234118]  [<78135c67>] trace_hardirqs_on+0x67/0xb0
[   36.239145]  [<784c8c4e>] scsi_request_fn+0x1be/0x370
[   36.244171]  [<78408096>] blk_run_queue+0x36/0x80
[   36.248850]  [<784c7530>] scsi_next_command+0x30/0x50
[   36.253877]  [<784c76bb>] scsi_end_request+0xab/0xe0
[   36.258817]  [<784c83c9>] scsi_io_completion+0xa9/0x3d0
[   36.264016]  [<78135c67>] trace_hardirqs_on+0x67/0xb0
[   36.269043]  [<78405125>] blk_done_softirq+0x45/0x80
[   36.273983]  [<78405153>] blk_done_softirq+0x73/0x80
[   36.278922]  [<7811d4c3>] __do_softirq+0x53/0xb0
[   36.283515]  [<7811d588>] do_softirq+0x68/0x70
[   36.287935]  [<78105351>] do_IRQ+0x51/0x90
[   36.292008]  [<78135c9c>] trace_hardirqs_on+0x9c/0xb0
[   36.297034]  [<7810388e>] common_interrupt+0x2e/0x40
[   36.301974]  [<78100c55>] cpu_idle+0x35/0x60
[   36.306220]  [<78a14b35>] start_kernel+0x265/0x300
[   36.310987]  [<78a14380>] unknown_bootoption+0x0/0x1e0
[   36.316100]  =======================
[   36.319653] Code: 84 d9 01 00 00 7e 32 31 d2 89 f6 8b 1c 24 83 c2 01 8b 03 2b 05 f8 ec d7 78 c1 f8 05 c1 e0 0c 03 43 04 89 43 08 83 c3 10 89 1c 24 <8b> 03 a8 01 0f 85 58 02 00 00 39 ca 75 d2 f0 83 44 24 00 00 85 
[   36.338458] EIP: [<784e9490>] ata_qc_issue+0xd0/0x340 SS:ESP 0068:78a13e28
[   36.345305] Kernel panic - not syncing: Fatal exception in interrupt

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 20:31                                 ` Jens Axboe
@ 2007-10-17 21:11                                   ` Linus Torvalds
  2007-10-17 23:00                                     ` FUJITA Tomonori
  0 siblings, 1 reply; 151+ messages in thread
From: Linus Torvalds @ 2007-10-17 21:11 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Ingo Molnar, linux-kernel, Jeff Garzik, Alan Cox



On Wed, 17 Oct 2007, Jens Axboe wrote:
>
> That would hurt... Care to commit your for_each_sg() uglification fixup
> for now then? Or disable the allocation debug config entry, so that the
> sg+1 deref wont crash?

Well, in practice, it will only crash with DEBUG_PAGEALLOC, so few enough 
are going to be hit by it. In that sense I don't think we're in any deep 
trouble yet.

That said, maybe this is an acceptable, if hacky, replacement for the 
current "for_each_sg()" loop.

It does:
 - starts at one *before* the sglist
 - does the sg_next() at the *top* of the loop rather than the bottom of it
 - has a "--count" before that sg_next, so that we don't do it for the 
   case when we break out and have used up all segments.

Totally untested, but it *may* work, and it doesn't look horribly ugly.

Ingo, does this actually make any difference?

		Linus

---
 include/linux/scatterlist.h |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index 2dc7464..f5c8e11 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -51,11 +51,18 @@ static inline struct scatterlist *sg_next(struct scatterlist *sg)
 	return sg;
 }
 
+static inline struct scatterlist *sg_safe_next(struct scatterlist *sg, int left)
+{
+	if (left < 0)
+		return NULL;
+	return sg_next(sg);
+}
+
 /*
  * Loop over each sg element, following the pointer to a new list if necessary
  */
 #define for_each_sg(sglist, sg, nr, __i)	\
-	for (__i = 0, sg = (sglist); __i < (nr); __i++, sg = sg_next(sg))
+	for (__i = (nr), sg = (sglist)-1; (sg = sg_safe_next(sg, --__i)) != NULL ; )
 
 /**
  * sg_last - return the last scatterlist entry in a list

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 21:11                                   ` Linus Torvalds
@ 2007-10-17 23:00                                     ` FUJITA Tomonori
  2007-10-18  1:07                                       ` Linus Torvalds
  0 siblings, 1 reply; 151+ messages in thread
From: FUJITA Tomonori @ 2007-10-17 23:00 UTC (permalink / raw)
  To: torvalds; +Cc: jens.axboe, mingo, linux-kernel, jgarzik, alan, tomof

On Wed, 17 Oct 2007 14:11:34 -0700 (PDT)
Linus Torvalds <torvalds@linux-foundation.org> wrote:

> 
> 
> On Wed, 17 Oct 2007, Jens Axboe wrote:
> >
> > That would hurt... Care to commit your for_each_sg() uglification fixup
> > for now then? Or disable the allocation debug config entry, so that the
> > sg+1 deref wont crash?
> 
> Well, in practice, it will only crash with DEBUG_PAGEALLOC, so few enough 
> are going to be hit by it. In that sense I don't think we're in any deep 
> trouble yet.
> 
> That said, maybe this is an acceptable, if hacky, replacement for the 
> current "for_each_sg()" loop.
> 
> It does:
>  - starts at one *before* the sglist
>  - does the sg_next() at the *top* of the loop rather than the bottom of it
>  - has a "--count" before that sg_next, so that we don't do it for the 
>    case when we break out and have used up all segments.
> 
> Totally untested, but it *may* work, and it doesn't look horribly ugly.
> 
> Ingo, does this actually make any difference?
> 
> 		Linus
> 
> ---
>  include/linux/scatterlist.h |    9 ++++++++-
>  1 files changed, 8 insertions(+), 1 deletions(-)
> 
> diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
> index 2dc7464..f5c8e11 100644
> --- a/include/linux/scatterlist.h
> +++ b/include/linux/scatterlist.h
> @@ -51,11 +51,18 @@ static inline struct scatterlist *sg_next(struct scatterlist *sg)
>  	return sg;
>  }
>  
> +static inline struct scatterlist *sg_safe_next(struct scatterlist *sg, int left)
> +{
> +	if (left < 0)
> +		return NULL;
> +	return sg_next(sg);
> +}
> +
>  /*
>   * Loop over each sg element, following the pointer to a new list if necessary
>   */
>  #define for_each_sg(sglist, sg, nr, __i)	\
> -	for (__i = 0, sg = (sglist); __i < (nr); __i++, sg = sg_next(sg))
> +	for (__i = (nr), sg = (sglist)-1; (sg = sg_safe_next(sg, --__i)) != NULL ; )

Looks that (sglist) - 1 isn't initialized and we use sg_next for it?

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 23:00                                     ` FUJITA Tomonori
@ 2007-10-18  1:07                                       ` Linus Torvalds
  2007-10-18  1:14                                         ` Jeff Garzik
  2007-10-18  1:19                                         ` David Miller
  0 siblings, 2 replies; 151+ messages in thread
From: Linus Torvalds @ 2007-10-18  1:07 UTC (permalink / raw)
  To: FUJITA Tomonori; +Cc: jens.axboe, mingo, linux-kernel, jgarzik, alan, tomof



On Thu, 18 Oct 2007, FUJITA Tomonori wrote:
> 
> Looks that (sglist) - 1 isn't initialized and we use sg_next for it?

sg_next() - as it stands now - never actually looks at the SG that its 
argument points to: it explicitly *only* looks at the next one.

That's the bug. If sg_next() looked at the actual *current* sg entry, we 
wouldn't have any issues to begin with, and that's what I'm arguing we 
should do in the longer run (where "longer run" is defined as "when Jens 
does it asap").

So the hacky solution as it stands right now is to actually use the 
behaviour of "sg_next()" to our advantage in for_each_sg(), and starting 
off by setting sg to (sglist)-1. That way we can do the "sg_next()" (which 
will *not* look at the uninitialized space before the array) before 
entering the loop, regardless of whether it's the first time through the 
loop or not.

So no, it's not technically "strictly conforming ANSI C", because we use a 
pointer (not do not dereference it!) outside of its allocation, which is 
strictly speaking against the standard. However, the kernel does those 
kinds of things all the time, since the kernel does its own memory 
allocation, so that's not actually relevant.

The *standard* may say that you cannot decrement a pointer to before the 
beginning of the object and then increment it back up again and be 
strictly conforming, but the fact is, we very much depend on contiguous 
and flat kernel pointer model, and always have (and probably always will)

		Linus

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  1:07                                       ` Linus Torvalds
@ 2007-10-18  1:14                                         ` Jeff Garzik
  2007-10-18  1:19                                         ` David Miller
  1 sibling, 0 replies; 151+ messages in thread
From: Jeff Garzik @ 2007-10-18  1:14 UTC (permalink / raw)
  To: Linus Torvalds, FUJITA Tomonori, jens.axboe
  Cc: mingo, linux-kernel, alan, tomof

On a related hardware note:

FWIW, most ATA controllers have scatter/gather tables that terminate 
themselves by a bit in the final s/g entry.  The 90% case needs to know 
the last scatterlist entry, at the end of the s/g walk.

So however this all gets worked out, please make sure not to unduly 
punish libata controllers with an expensive sg_last() inside a loop, or 
something like that.  :)

	Jeff





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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  1:07                                       ` Linus Torvalds
  2007-10-18  1:14                                         ` Jeff Garzik
@ 2007-10-18  1:19                                         ` David Miller
  2007-10-18  1:36                                           ` Linus Torvalds
  2007-10-18  8:21                                           ` Jens Axboe
  1 sibling, 2 replies; 151+ messages in thread
From: David Miller @ 2007-10-18  1:19 UTC (permalink / raw)
  To: torvalds
  Cc: fujita.tomonori, jens.axboe, mingo, linux-kernel, jgarzik, alan,
	tomof

From: Linus Torvalds <torvalds@linux-foundation.org>
Date: Wed, 17 Oct 2007 18:07:19 -0700 (PDT)

> sg_next() - as it stands now - never actually looks at the SG that its 
> argument points to: it explicitly *only* looks at the next one.
> 
> That's the bug. If sg_next() looked at the actual *current* sg entry, we 
> wouldn't have any issues to begin with, and that's what I'm arguing we 
> should do in the longer run (where "longer run" is defined as "when Jens 
> does it asap").

What the thing really wants is some kind of indication of state,
without having to bloat up the scatterlist structure.

I believe that we have enough of a limited set of accessors to
sg->page that we can more aggressively encode things in the lower
bits.

I'm thinking of encoding the low two bits of sg->page as
follows:

1) bits == 0

   then the SG list is linear and sg_next() is sg++

2) bits == 1

   the nest SG is an indirect chunk, sg_next() is
   therefore something like:

	next = *((struct scatterlist **)(sg + 1));

3) bits == 2

   this is the last entry in the scatterlist, sg_next() is NULL

So for the cases of ARCH_HAS_SG_CHAIN not being set (ie. back
compatible), we can do no bit encoding in page->flags and just do
sg_next() == sg++, as is done now.

When doing SG chaining, in each non-linear chunk we have to allocate
one more pointer past the end of the scatterlist array (instead of a
full extra scatterlist entry for the indirect pointer encode).  Next,
all sg->page accesses have to be guarded to clear the state bits
out first.

I don't know, maybe it would work, and would make the loop termination
issues easier to handle properly.

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  1:19                                         ` David Miller
@ 2007-10-18  1:36                                           ` Linus Torvalds
  2007-10-18  1:49                                             ` David Miller
  2007-10-18  3:44                                             ` Mark Lord
  2007-10-18  8:21                                           ` Jens Axboe
  1 sibling, 2 replies; 151+ messages in thread
From: Linus Torvalds @ 2007-10-18  1:36 UTC (permalink / raw)
  To: David Miller
  Cc: fujita.tomonori, jens.axboe, mingo, linux-kernel, jgarzik, alan,
	tomof



On Wed, 17 Oct 2007, David Miller wrote:
>
> I believe that we have enough of a limited set of accessors to
> sg->page that we can more aggressively encode things in the lower
> bits.
> 
> I'm thinking of encoding the low two bits of sg->page as
> follows:
> 
> 1) bits == 0
> 
>    then the SG list is linear and sg_next() is sg++
> 
> 2) bits == 1
> 
>    the nest SG is an indirect chunk, sg_next() is
>    therefore something like:
> 
> 	next = *((struct scatterlist **)(sg + 1));
> 
> 3) bits == 2
> 
>    this is the last entry in the scatterlist, sg_next() is NULL
> 
> So for the cases of ARCH_HAS_SG_CHAIN not being set (ie. back
> compatible), we can do no bit encoding in page->flags and just do
> sg_next() == sg++, as is done now.

Yes, that sounds sane.

Although I also wonder whether we want one global per-arch 
ARCH_HAS_SG_CHAIN, or perhaps have something more dynamic, which allows a 
per-SG-list choice (which in turn would require some kind of "head" entry 
that is passed into sg_next(), and in general descibes the SG list)

		Linus

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  1:36                                           ` Linus Torvalds
@ 2007-10-18  1:49                                             ` David Miller
  2007-10-18  3:44                                             ` Mark Lord
  1 sibling, 0 replies; 151+ messages in thread
From: David Miller @ 2007-10-18  1:49 UTC (permalink / raw)
  To: torvalds
  Cc: fujita.tomonori, jens.axboe, mingo, linux-kernel, jgarzik, alan,
	tomof

From: Linus Torvalds <torvalds@linux-foundation.org>
Date: Wed, 17 Oct 2007 18:36:34 -0700 (PDT)

> Although I also wonder whether we want one global per-arch 
> ARCH_HAS_SG_CHAIN

It's there because the DMA mapping support code for a platform has to
be converted to handle these chains and audited to make sure the
conversion is right.  Some platforms, such as sparc64, took a lot of
work to get right :-)

Once that macro is set, the block device driver has to support it too,
and there are knobs all the way down to the scsi host driver to
indicate this.

The idea is that all of this mess gets deleted in the end, it was
meant to be a safe transition scheme.


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  1:36                                           ` Linus Torvalds
  2007-10-18  1:49                                             ` David Miller
@ 2007-10-18  3:44                                             ` Mark Lord
  2007-10-18  4:01                                               ` Linus Torvalds
  1 sibling, 1 reply; 151+ messages in thread
From: Mark Lord @ 2007-10-18  3:44 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: David Miller, fujita.tomonori, jens.axboe, mingo, linux-kernel,
	jgarzik, alan, tomof

Linus Torvalds wrote:
> 
> On Wed, 17 Oct 2007, David Miller wrote:
>> I believe that we have enough of a limited set of accessors to
>> sg->page that we can more aggressively encode things in the lower
>> bits.
>>
>> I'm thinking of encoding the low two bits of sg->page as
>> follows:
...
> Yes, that sounds sane.


It would be good to have something soon-ish.
This "dead at boot time" issue is impacting the general ability to test
patches against latest -git in time for the current merge window.

:)

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  3:44                                             ` Mark Lord
@ 2007-10-18  4:01                                               ` Linus Torvalds
  2007-10-18  4:05                                                 ` Mark Lord
  2007-10-18  5:25                                                 ` Mark Lord
  0 siblings, 2 replies; 151+ messages in thread
From: Linus Torvalds @ 2007-10-18  4:01 UTC (permalink / raw)
  To: Mark Lord
  Cc: David Miller, fujita.tomonori, jens.axboe, mingo, linux-kernel,
	jgarzik, alan, tomof



On Wed, 17 Oct 2007, Mark Lord wrote:
> 
> It would be good to have something soon-ish.
> This "dead at boot time" issue is impacting the general ability to test
> patches against latest -git in time for the current merge window.

In the meantime, does the patch I sent out help people? I'd like to get 
feedback, but I'm a lazy bum, and don't use DEBUG_PAGEALLOC myself, so I 
was hoping that people who actually see this could comment on my untested 
suggestion.

		Linus

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  4:01                                               ` Linus Torvalds
@ 2007-10-18  4:05                                                 ` Mark Lord
  2007-10-18  4:14                                                   ` Jeff Garzik
                                                                     ` (2 more replies)
  2007-10-18  5:25                                                 ` Mark Lord
  1 sibling, 3 replies; 151+ messages in thread
From: Mark Lord @ 2007-10-18  4:05 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: David Miller, fujita.tomonori, jens.axboe, mingo, linux-kernel,
	jgarzik, alan, tomof

Linus Torvalds wrote:
> 
> On Wed, 17 Oct 2007, Mark Lord wrote:
>> It would be good to have something soon-ish.
>> This "dead at boot time" issue is impacting the general ability to test
>> patches against latest -git in time for the current merge window.
> 
> In the meantime, does the patch I sent out help people? I'd like to get 
> feedback, but I'm a lazy bum, and don't use DEBUG_PAGEALLOC myself, so I 
> was hoping that people who actually see this could comment on my untested 
> suggestion.

Oh.. so this bug is supposed to only bite with DEBUG_PAGEALLOC=y ??

Then something else is broken, perhaps.  I just saw a long traceback
scroll off the top of the screen, with lots of bio_* functions in the list
and assumed it was the same bug.

Mmm.. I'll get out the camera and try it again now..

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  4:05                                                 ` Mark Lord
@ 2007-10-18  4:14                                                   ` Jeff Garzik
  2007-10-18  4:18                                                   ` Mark Lord
  2007-10-18  4:20                                                   ` Linus Torvalds
  2 siblings, 0 replies; 151+ messages in thread
From: Jeff Garzik @ 2007-10-18  4:14 UTC (permalink / raw)
  To: Mark Lord
  Cc: Linus Torvalds, David Miller, fujita.tomonori, jens.axboe, mingo,
	linux-kernel, alan, tomof

Mark Lord wrote:
> Linus Torvalds wrote:
>>
>> On Wed, 17 Oct 2007, Mark Lord wrote:
>>> It would be good to have something soon-ish.
>>> This "dead at boot time" issue is impacting the general ability to test
>>> patches against latest -git in time for the current merge window.
>>
>> In the meantime, does the patch I sent out help people? I'd like to 
>> get feedback, but I'm a lazy bum, and don't use DEBUG_PAGEALLOC 
>> myself, so I was hoping that people who actually see this could 
>> comment on my untested suggestion.
> 
> Oh.. so this bug is supposed to only bite with DEBUG_PAGEALLOC=y ??
> 
> Then something else is broken, perhaps.  I just saw a long traceback
> scroll off the top of the screen, with lots of bio_* functions in the list
> and assumed it was the same bug.
> 
> Mmm.. I'll get out the camera and try it again now..

I'm currently bisecting on two machines (sata_mv and sata_nv).  sata_mv 
suddenly started spewing errors in recent kernels, but kernels from ~48 
hours ago are just fine.  AMD64 sata_nv machine will simply lock up if I 
push it too hard.  Again, reproducible, and kernels from ~48 hours ago 
are fine.

AHCI machine so far seems fine (kernel ~24 hours ago), storage-wise, but 
the hda_intel audio decided to stop working :)

I'm quite happy to test patches, but I never run with DEBUG_PAGEALLOC so 
that shouldn't be causing the problems here.

	Jeff




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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  4:05                                                 ` Mark Lord
  2007-10-18  4:14                                                   ` Jeff Garzik
@ 2007-10-18  4:18                                                   ` Mark Lord
  2007-10-18  4:31                                                     ` Jeff Garzik
                                                                       ` (2 more replies)
  2007-10-18  4:20                                                   ` Linus Torvalds
  2 siblings, 3 replies; 151+ messages in thread
From: Mark Lord @ 2007-10-18  4:18 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: David Miller, fujita.tomonori, jens.axboe, mingo, linux-kernel,
	jgarzik, alan, tomof

Mark Lord wrote:
> Linus Torvalds wrote:
>>
>> On Wed, 17 Oct 2007, Mark Lord wrote:
>>> It would be good to have something soon-ish.
>>> This "dead at boot time" issue is impacting the general ability to test
>>> patches against latest -git in time for the current merge window.
>>
>> In the meantime, does the patch I sent out help people? I'd like to 
>> get feedback, but I'm a lazy bum, and don't use DEBUG_PAGEALLOC 
>> myself, so I was hoping that people who actually see this could 
>> comment on my untested suggestion.
> 
> Oh.. so this bug is supposed to only bite with DEBUG_PAGEALLOC=y ??
> 
> Then something else is broken, perhaps.  I just saw a long traceback
> scroll off the top of the screen, with lots of bio_* functions in the list
> and assumed it was the same bug.
> 
> Mmm.. I'll get out the camera and try it again now..

Okay, mine is dying with EIP at blk_rq_map_sg+0xcb/0x160.

Screen photo is at http://rtr.ca/recent/2.6.23-git12-crash.jpg,
but the top was cut off (isn't there a new config option or patch
to do double-columns or scrollback or something ???.

Cheers

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  4:05                                                 ` Mark Lord
  2007-10-18  4:14                                                   ` Jeff Garzik
  2007-10-18  4:18                                                   ` Mark Lord
@ 2007-10-18  4:20                                                   ` Linus Torvalds
  2 siblings, 0 replies; 151+ messages in thread
From: Linus Torvalds @ 2007-10-18  4:20 UTC (permalink / raw)
  To: Mark Lord
  Cc: David Miller, fujita.tomonori, jens.axboe, mingo, linux-kernel,
	jgarzik, alan, tomof



On Thu, 18 Oct 2007, Mark Lord wrote:
> 
> Oh.. so this bug is supposed to only bite with DEBUG_PAGEALLOC=y ??

Yeah, this particular one really should only bite you with 
DEBUG_PAGEALLOC.

The SG code potentially _derefences_ a field past the end of the SG array, 
but it should be a read, and the result should never be used (it's used to 
calculate the pointer to past the end of the queue, so if it's used, 
there's another bug lurking).

> Then something else is broken, perhaps.  I just saw a long traceback 
> scroll off the top of the screen, with lots of bio_* functions in the 
> list and assumed it was the same bug.
> 
> Mmm.. I'll get out the camera and try it again now..

Please do. I wouldn't be surprised if it's also related to the SG changes, 
but I don't think it's the exact particular bug that Ingo saw.

		Linus

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  4:18                                                   ` Mark Lord
@ 2007-10-18  4:31                                                     ` Jeff Garzik
  2007-10-18  4:41                                                       ` Mark Lord
                                                                         ` (2 more replies)
  2007-10-18  4:45                                                     ` Linus Torvalds
  2007-10-18  4:54                                                     ` Mark Lord
  2 siblings, 3 replies; 151+ messages in thread
From: Jeff Garzik @ 2007-10-18  4:31 UTC (permalink / raw)
  To: Mark Lord
  Cc: Linus Torvalds, David Miller, fujita.tomonori, jens.axboe, mingo,
	linux-kernel, alan, tomof

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

Mark Lord wrote:
> Okay, mine is dying with EIP at blk_rq_map_sg+0xcb/0x160.
> 
> Screen photo is at http://rtr.ca/recent/2.6.23-git12-crash.jpg,
> but the top was cut off (isn't there a new config option or patch
> to do double-columns or scrollback or something ???.

Is this a sata_mv box?  If so, could you try this patch?

	Jeff




[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 1679 bytes --]

diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 4df8311..d8cf8b1 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -421,7 +421,6 @@ static void mv_error_handler(struct ata_port *ap);
 static void mv_post_int_cmd(struct ata_queued_cmd *qc);
 static void mv_eh_freeze(struct ata_port *ap);
 static void mv_eh_thaw(struct ata_port *ap);
-static int mv_slave_config(struct scsi_device *sdev);
 static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 
 static void mv5_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio,
@@ -459,7 +458,7 @@ static struct scsi_host_template mv5_sht = {
 	.use_clustering		= 1,
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= MV_DMA_BOUNDARY,
-	.slave_configure	= mv_slave_config,
+	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
 };
@@ -477,7 +476,7 @@ static struct scsi_host_template mv6_sht = {
 	.use_clustering		= 1,
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= MV_DMA_BOUNDARY,
-	.slave_configure	= mv_slave_config,
+	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
 };
@@ -756,17 +755,6 @@ static void mv_irq_clear(struct ata_port *ap)
 {
 }
 
-static int mv_slave_config(struct scsi_device *sdev)
-{
-	int rc = ata_scsi_slave_config(sdev);
-	if (rc)
-		return rc;
-
-	blk_queue_max_phys_segments(sdev->request_queue, MV_MAX_SG_CT / 2);
-
-	return 0;	/* scsi layer doesn't check return value, sigh */
-}
-
 static void mv_set_edma_ptrs(void __iomem *port_mmio,
 			     struct mv_host_priv *hpriv,
 			     struct mv_port_priv *pp)

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  4:31                                                     ` Jeff Garzik
@ 2007-10-18  4:41                                                       ` Mark Lord
  2007-10-18  4:53                                                       ` Linus Torvalds
  2007-10-18  7:05                                                       ` Jens Axboe
  2 siblings, 0 replies; 151+ messages in thread
From: Mark Lord @ 2007-10-18  4:41 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: Linus Torvalds, David Miller, fujita.tomonori, jens.axboe, mingo,
	linux-kernel, alan, tomof

Jeff Garzik wrote:
> Mark Lord wrote:
>> Okay, mine is dying with EIP at blk_rq_map_sg+0xcb/0x160.
>>
>> Screen photo is at http://rtr.ca/recent/2.6.23-git12-crash.jpg,
>> but the top was cut off (isn't there a new config option or patch
>> to do double-columns or scrollback or something ???.
> 
> Is this a sata_mv box?  If so, could you try this patch?


No.. it's a pretty ordinary ata_piix machine, with no serial ports either.

Cheers

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  4:18                                                   ` Mark Lord
  2007-10-18  4:31                                                     ` Jeff Garzik
@ 2007-10-18  4:45                                                     ` Linus Torvalds
  2007-10-18  4:54                                                     ` Mark Lord
  2 siblings, 0 replies; 151+ messages in thread
From: Linus Torvalds @ 2007-10-18  4:45 UTC (permalink / raw)
  To: Mark Lord
  Cc: David Miller, fujita.tomonori, jens.axboe, mingo, linux-kernel,
	jgarzik, alan, tomof



On Thu, 18 Oct 2007, Mark Lord wrote:
> 
> Okay, mine is dying with EIP at blk_rq_map_sg+0xcb/0x160.

Ok, I think your picture cut off the last hex digits on the right, but 
what I can make out of the disassembly, I have to admit that it looks 
very much like it might be exactly the same thing Ingo was seeing.

The disassembly is a bit scrambled, but the particular instruction that 
oopses for you is

	mov    0x10(%ebx),%eax

and the instructions around it do seem to bear some similarity to the 
whole "sg_next()" thing, ie I see a 

	test   $0x1,%al

and a

	lea    0x10(%ebx),%eax

around there too.

If you cut down the number of entries printed for the call trace (which 
involves editing the source code, no nice config options, I'm afraid), you 
could get the rest of it..

		Linus

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  4:31                                                     ` Jeff Garzik
  2007-10-18  4:41                                                       ` Mark Lord
@ 2007-10-18  4:53                                                       ` Linus Torvalds
  2007-10-18  7:05                                                       ` Jens Axboe
  2 siblings, 0 replies; 151+ messages in thread
From: Linus Torvalds @ 2007-10-18  4:53 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: Mark Lord, David Miller, fujita.tomonori, jens.axboe, mingo,
	linux-kernel, alan, tomof



On Thu, 18 Oct 2007, Jeff Garzik wrote:
>
> Is this a sata_mv box?  If so, could you try this patch?

That could explain it: if the SG allocation is simply too small, the 
scatter-gather code will run off the end of the SG list, and encounter 
random uninitialized entries, and if any of those have the low bit set, 
they will be considered to be "link" entries, and the SG list goes wild.

That SG code is really pretty fragile. I don't see it *ever* checking that 
the SG allocation is large enough when it fills it in. And these things 
take the sizes from different places (ie "cmd->use_sg" bs 
"req->nr_phys_segments" vs God knows what else..)

		Linus

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  4:18                                                   ` Mark Lord
  2007-10-18  4:31                                                     ` Jeff Garzik
  2007-10-18  4:45                                                     ` Linus Torvalds
@ 2007-10-18  4:54                                                     ` Mark Lord
  2007-10-18  5:09                                                       ` Mark Lord
  2 siblings, 1 reply; 151+ messages in thread
From: Mark Lord @ 2007-10-18  4:54 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: David Miller, fujita.tomonori, jens.axboe, mingo, linux-kernel,
	jgarzik, alan, tomof

Mark Lord wrote:
> Mark Lord wrote:
>> Linus Torvalds wrote:
>>>
>>> On Wed, 17 Oct 2007, Mark Lord wrote:
>>>> It would be good to have something soon-ish.
>>>> This "dead at boot time" issue is impacting the general ability to test
>>>> patches against latest -git in time for the current merge window.
>>>
>>> In the meantime, does the patch I sent out help people? I'd like to 
>>> get feedback, but I'm a lazy bum, and don't use DEBUG_PAGEALLOC 
>>> myself, so I was hoping that people who actually see this could 
>>> comment on my untested suggestion.
>>
>> Oh.. so this bug is supposed to only bite with DEBUG_PAGEALLOC=y ??
>>
>> Then something else is broken, perhaps.  I just saw a long traceback
>> scroll off the top of the screen, with lots of bio_* functions in the 
>> list
>> and assumed it was the same bug.
>>
>> Mmm.. I'll get out the camera and try it again now..
> 
> Okay, mine is dying with EIP at blk_rq_map_sg+0xcb/0x160.
> 
> Screen photo is at http://rtr.ca/recent/2.6.23-git12-crash.jpg,
> but the top was cut off (isn't there a new config option or patch
> to do double-columns or scrollback or something ???.

I tried the fancy "boot_delay=nnn" feature, but that doesn't slow down
the tracebacks at all.  So I hardcoded some mdelay(1000) lines into
the traceback code, and here's the top part of the oops now:

   http://rtr.ca/recent/2.6.23-git12-crash2.jpg

And here's the .config for the kernel, just in case it's of any use here:

#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.23-git12
# Thu Oct 18 00:28:52 2007
#
CONFIG_X86_32=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_CLOCKSOURCE_WATCHDOG=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_SEMAPHORE_SLEEPERS=y
CONFIG_X86=y
CONFIG_MMU=y
CONFIG_ZONE_DMA=y
CONFIG_QUICKLIST=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_IOMAP=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_DMI=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"

#
# General setup
#
CONFIG_EXPERIMENTAL=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_USER_NS is not set
# CONFIG_AUDIT is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=16
# CONFIG_CPUSETS is not set
# CONFIG_FAIR_GROUP_SCHED is not set
CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
# CONFIG_SLUB_DEBUG is not set
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_KMOD=y
CONFIG_STOP_MACHINE=y
CONFIG_BLOCK=y
# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_LSF is not set
CONFIG_BLK_DEV_BSG=y

#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
# CONFIG_IOSCHED_DEADLINE is not set
CONFIG_IOSCHED_CFQ=y
# CONFIG_DEFAULT_AS is not set
# CONFIG_DEFAULT_DEADLINE is not set
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"

#
# Processor type and features
#
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_SMP=y
CONFIG_X86_PC=y
# CONFIG_X86_ELAN is not set
# CONFIG_X86_VOYAGER is not set
# CONFIG_X86_NUMAQ is not set
# CONFIG_X86_SUMMIT is not set
# CONFIG_X86_BIGSMP is not set
# CONFIG_X86_VISWS is not set
# CONFIG_X86_GENERICARCH is not set
# CONFIG_X86_ES7000 is not set
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
# CONFIG_PARAVIRT is not set
# CONFIG_M386 is not set
# CONFIG_M486 is not set
# CONFIG_M586 is not set
# CONFIG_M586TSC is not set
# CONFIG_M586MMX is not set
# CONFIG_M686 is not set
# CONFIG_MPENTIUMII is not set
# CONFIG_MPENTIUMIII is not set
# CONFIG_MPENTIUMM is not set
CONFIG_MCORE2=y
# CONFIG_MPENTIUM4 is not set
# CONFIG_MK6 is not set
# CONFIG_MK7 is not set
# CONFIG_MK8 is not set
# CONFIG_MCRUSOE is not set
# CONFIG_MEFFICEON is not set
# CONFIG_MWINCHIPC6 is not set
# CONFIG_MWINCHIP2 is not set
# CONFIG_MWINCHIP3D is not set
# CONFIG_MGEODEGX1 is not set
# CONFIG_MGEODE_LX is not set
# CONFIG_MCYRIXIII is not set
# CONFIG_MVIAC3_2 is not set
# CONFIG_MVIAC7 is not set
# CONFIG_X86_GENERIC is not set
CONFIG_X86_CMPXCHG=y
CONFIG_X86_L1_CACHE_SHIFT=6
CONFIG_X86_XADD=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_X86_WP_WORKS_OK=y
CONFIG_X86_INVLPG=y
CONFIG_X86_BSWAP=y
CONFIG_X86_POPAD_OK=y
CONFIG_X86_GOOD_APIC=y
CONFIG_X86_INTEL_USERCOPY=y
CONFIG_X86_USE_PPRO_CHECKSUM=y
CONFIG_X86_TSC=y
CONFIG_X86_MINIMUM_CPU_FAMILY=4
CONFIG_HPET_TIMER=y
CONFIG_NR_CPUS=2
# CONFIG_SCHED_SMT is not set
CONFIG_SCHED_MC=y
# CONFIG_PREEMPT_NONE is not set
# CONFIG_PREEMPT_VOLUNTARY is not set
CONFIG_PREEMPT=y
CONFIG_PREEMPT_BKL=y
CONFIG_X86_LOCAL_APIC=y
CONFIG_X86_IO_APIC=y
# CONFIG_X86_MCE is not set
CONFIG_VM86=y
# CONFIG_TOSHIBA is not set
CONFIG_I8K=m
CONFIG_X86_REBOOTFIXUPS=y
CONFIG_MICROCODE=m
CONFIG_MICROCODE_OLD_INTERFACE=y
CONFIG_X86_MSR=m
CONFIG_X86_CPUID=m

#
# Firmware Drivers
#
CONFIG_EDD=m
CONFIG_DELL_RBU=m
CONFIG_DCDBAS=m
CONFIG_DMIID=y
# CONFIG_NOHIGHMEM is not set
CONFIG_HIGHMEM4G=y
# CONFIG_HIGHMEM64G is not set
CONFIG_VMSPLIT_3G=y
# CONFIG_VMSPLIT_3G_OPT is not set
# CONFIG_VMSPLIT_2G is not set
# CONFIG_VMSPLIT_2G_OPT is not set
# CONFIG_VMSPLIT_1G is not set
CONFIG_PAGE_OFFSET=0xC0000000
CONFIG_HIGHMEM=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_SPARSEMEM_STATIC=y
# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_RESOURCES_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
CONFIG_NR_QUICK=1
CONFIG_VIRT_TO_BUS=y
# CONFIG_HIGHPTE is not set
# CONFIG_MATH_EMULATION is not set
CONFIG_MTRR=y
# CONFIG_EFI is not set
# CONFIG_IRQBALANCE is not set
# CONFIG_SECCOMP is not set
# CONFIG_HZ_100 is not set
# CONFIG_HZ_250 is not set
CONFIG_HZ_300=y
# CONFIG_HZ_1000 is not set
CONFIG_HZ=300
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
CONFIG_PHYSICAL_START=0x100000
# CONFIG_RELOCATABLE is not set
CONFIG_PHYSICAL_ALIGN=0x100000
CONFIG_HOTPLUG_CPU=y
# CONFIG_COMPAT_VDSO is not set
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y

#
# Power management options (ACPI, APM)
#
CONFIG_PM=y
CONFIG_PM_LEGACY=y
# CONFIG_PM_DEBUG is not set
CONFIG_PM_SLEEP_SMP=y
CONFIG_PM_SLEEP=y
CONFIG_SUSPEND_SMP_POSSIBLE=y
CONFIG_SUSPEND=y
CONFIG_HIBERNATION_SMP_POSSIBLE=y
CONFIG_HIBERNATION=y
CONFIG_PM_STD_PARTITION="/dev/sda3"
CONFIG_ACPI=y
CONFIG_ACPI_SLEEP=y
CONFIG_ACPI_PROCFS=y
CONFIG_ACPI_PROC_EVENT=y
CONFIG_ACPI_AC=m
CONFIG_ACPI_BATTERY=m
CONFIG_ACPI_BUTTON=m
CONFIG_ACPI_FAN=m
# CONFIG_ACPI_DOCK is not set
CONFIG_ACPI_PROCESSOR=m
CONFIG_ACPI_HOTPLUG_CPU=y
CONFIG_ACPI_THERMAL=m
# CONFIG_ACPI_ASUS is not set
# CONFIG_ACPI_TOSHIBA is not set
CONFIG_ACPI_BLACKLIST_YEAR=0
# CONFIG_ACPI_DEBUG is not set
CONFIG_ACPI_EC=y
CONFIG_ACPI_POWER=y
CONFIG_ACPI_SYSTEM=y
CONFIG_X86_PM_TIMER=y
CONFIG_ACPI_CONTAINER=m
# CONFIG_ACPI_SBS is not set
# CONFIG_APM is not set

#
# CPU Frequency scaling
#
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_TABLE=y
# CONFIG_CPU_FREQ_DEBUG is not set
CONFIG_CPU_FREQ_STAT=m
CONFIG_CPU_FREQ_STAT_DETAILS=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
CONFIG_CPU_FREQ_GOV_USERSPACE=m
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m

#
# CPUFreq processor drivers
#
CONFIG_X86_ACPI_CPUFREQ=m
# CONFIG_X86_POWERNOW_K6 is not set
# CONFIG_X86_POWERNOW_K7 is not set
# CONFIG_X86_POWERNOW_K8 is not set
# CONFIG_X86_GX_SUSPMOD is not set
CONFIG_X86_SPEEDSTEP_CENTRINO=m
CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y
CONFIG_X86_SPEEDSTEP_ICH=m
# CONFIG_X86_SPEEDSTEP_SMI is not set
# CONFIG_X86_P4_CLOCKMOD is not set
# CONFIG_X86_CPUFREQ_NFORCE2 is not set
# CONFIG_X86_LONGRUN is not set
# CONFIG_X86_LONGHAUL is not set
# CONFIG_X86_E_POWERSAVER is not set

#
# shared options
#
# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
CONFIG_X86_SPEEDSTEP_LIB=m
# CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK is not set

#
# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
#
CONFIG_PCI=y
# CONFIG_PCI_GOBIOS is not set
# CONFIG_PCI_GOMMCONFIG is not set
# CONFIG_PCI_GODIRECT is not set
CONFIG_PCI_GOANY=y
CONFIG_PCI_BIOS=y
CONFIG_PCI_DIRECT=y
CONFIG_PCI_MMCONFIG=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCIEPORTBUS=y
CONFIG_HOTPLUG_PCI_PCIE=m
CONFIG_PCIEAER=y
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_HT_IRQ is not set
CONFIG_ISA_DMA_API=y
# CONFIG_ISA is not set
# CONFIG_MCA is not set
# CONFIG_SCx200 is not set
# CONFIG_PCCARD is not set
CONFIG_HOTPLUG_PCI=m
# CONFIG_HOTPLUG_PCI_FAKE is not set
# CONFIG_HOTPLUG_PCI_COMPAQ is not set
# CONFIG_HOTPLUG_PCI_IBM is not set
# CONFIG_HOTPLUG_PCI_ACPI is not set
# CONFIG_HOTPLUG_PCI_CPCI is not set
# CONFIG_HOTPLUG_PCI_SHPC is not set

#
# Executable file formats
#
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_AOUT=m
CONFIG_BINFMT_MISC=m

#
# Networking
#
CONFIG_NET=y

#
# Networking options
#
CONFIG_PACKET=m
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=m
CONFIG_XFRM=y
CONFIG_XFRM_USER=m
# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_XFRM_MIGRATE is not set
CONFIG_NET_KEY=m
# CONFIG_NET_KEY_MIGRATE is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_ASK_IP_FIB_HASH=y
# CONFIG_IP_FIB_TRIE is not set
CONFIG_IP_FIB_HASH=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_MULTIPATH=y
CONFIG_IP_ROUTE_VERBOSE=y
# CONFIG_IP_PNP is not set
CONFIG_NET_IPIP=m
CONFIG_NET_IPGRE=m
CONFIG_NET_IPGRE_BROADCAST=y
CONFIG_IP_MROUTE=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
# CONFIG_ARPD is not set
CONFIG_SYN_COOKIES=y
CONFIG_INET_AH=m
CONFIG_INET_ESP=m
CONFIG_INET_IPCOMP=m
CONFIG_INET_XFRM_TUNNEL=m
CONFIG_INET_TUNNEL=m
CONFIG_INET_XFRM_MODE_TRANSPORT=m
CONFIG_INET_XFRM_MODE_TUNNEL=m
CONFIG_INET_XFRM_MODE_BEET=m
CONFIG_INET_LRO=y
CONFIG_INET_DIAG=m
CONFIG_INET_TCP_DIAG=m
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_TCP_MD5SIG is not set
# CONFIG_IPV6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
CONFIG_IP_SCTP=m
# CONFIG_SCTP_DBG_MSG is not set
# CONFIG_SCTP_DBG_OBJCNT is not set
# CONFIG_SCTP_HMAC_NONE is not set
# CONFIG_SCTP_HMAC_SHA1 is not set
CONFIG_SCTP_HMAC_MD5=y
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
CONFIG_BRIDGE=m
CONFIG_VLAN_8021Q=m
# CONFIG_DECNET is not set
CONFIG_LLC=m
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set

#
# QoS and/or fair queueing
#
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_FIFO=y

#
# Queueing/Scheduling
#
CONFIG_NET_SCH_CBQ=m
CONFIG_NET_SCH_HTB=m
CONFIG_NET_SCH_HFSC=m
CONFIG_NET_SCH_PRIO=m
CONFIG_NET_SCH_RR=m
CONFIG_NET_SCH_RED=m
CONFIG_NET_SCH_SFQ=m
CONFIG_NET_SCH_TEQL=m
CONFIG_NET_SCH_TBF=m
CONFIG_NET_SCH_GRED=m
CONFIG_NET_SCH_DSMARK=m
CONFIG_NET_SCH_NETEM=m
CONFIG_NET_SCH_INGRESS=m

#
# Classification
#
CONFIG_NET_CLS=y
CONFIG_NET_CLS_BASIC=m
CONFIG_NET_CLS_TCINDEX=m
CONFIG_NET_CLS_ROUTE4=m
CONFIG_NET_CLS_ROUTE=y
CONFIG_NET_CLS_FW=m
CONFIG_NET_CLS_U32=m
CONFIG_CLS_U32_PERF=y
CONFIG_CLS_U32_MARK=y
CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m
CONFIG_NET_EMATCH=y
CONFIG_NET_EMATCH_STACK=32
CONFIG_NET_EMATCH_CMP=m
CONFIG_NET_EMATCH_NBYTE=m
CONFIG_NET_EMATCH_U32=m
CONFIG_NET_EMATCH_META=m
CONFIG_NET_EMATCH_TEXT=m
CONFIG_NET_CLS_ACT=y
CONFIG_NET_ACT_POLICE=m
CONFIG_NET_ACT_GACT=m
CONFIG_GACT_PROB=y
CONFIG_NET_ACT_MIRRED=m
# CONFIG_NET_ACT_NAT is not set
CONFIG_NET_ACT_PEDIT=m
CONFIG_NET_ACT_SIMP=m
# CONFIG_NET_CLS_POLICE is not set
# CONFIG_NET_CLS_IND is not set

#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
CONFIG_BT=m
CONFIG_BT_L2CAP=m
CONFIG_BT_SCO=m
CONFIG_BT_RFCOMM=m
CONFIG_BT_RFCOMM_TTY=y
CONFIG_BT_BNEP=m
CONFIG_BT_BNEP_MC_FILTER=y
CONFIG_BT_BNEP_PROTO_FILTER=y
CONFIG_BT_HIDP=m

#
# Bluetooth device drivers
#
CONFIG_BT_HCIUSB=m
CONFIG_BT_HCIUSB_SCO=y
CONFIG_BT_HCIUART=m
CONFIG_BT_HCIUART_H4=y
CONFIG_BT_HCIUART_BCSP=y
CONFIG_BT_HCIBCM203X=m
CONFIG_BT_HCIBPA10X=m
CONFIG_BT_HCIBFUSB=m
CONFIG_BT_HCIVHCI=m
# CONFIG_AF_RXRPC is not set
CONFIG_FIB_RULES=y

#
# Wireless
#
CONFIG_CFG80211=m
CONFIG_NL80211=y
CONFIG_WIRELESS_EXT=y
CONFIG_MAC80211=m
# CONFIG_MAC80211_DEBUG is not set
CONFIG_IEEE80211=m
# CONFIG_IEEE80211_DEBUG is not set
CONFIG_IEEE80211_CRYPT_WEP=m
CONFIG_IEEE80211_CRYPT_CCMP=m
CONFIG_IEEE80211_CRYPT_TKIP=m
CONFIG_IEEE80211_SOFTMAC=m
# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
CONFIG_RFKILL=m
CONFIG_RFKILL_INPUT=m
# CONFIG_NET_9P is not set

#
# Device Drivers
#

#
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_STANDALONE=y
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
CONFIG_FW_LOADER=m
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
# CONFIG_PARPORT is not set
CONFIG_PNP=y
# CONFIG_PNP_DEBUG is not set

#
# Protocols
#
CONFIG_PNPACPI=y
CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_FD=m
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_UMEM is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=m
CONFIG_BLK_DEV_CRYPTOLOOP=m
CONFIG_BLK_DEV_NBD=m
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_UB is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=4
CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
# CONFIG_CDROM_PKTCDVD_WCACHE is not set
CONFIG_ATA_OVER_ETH=m
CONFIG_MISC_DEVICES=y
# CONFIG_IBM_ASM is not set
# CONFIG_PHANTOM is not set
CONFIG_EEPROM_93CX6=m
# CONFIG_SGI_IOC4 is not set
CONFIG_TIFM_CORE=m
# CONFIG_TIFM_7XX1 is not set
# CONFIG_MSI_LAPTOP is not set
# CONFIG_SONY_LAPTOP is not set
# CONFIG_THINKPAD_ACPI is not set
# CONFIG_IDE is not set

#
# SCSI device support
#
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
# CONFIG_SCSI_TGT is not set
# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y

#
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=y
# CONFIG_CHR_DEV_ST is not set
# CONFIG_CHR_DEV_OSST is not set
CONFIG_BLK_DEV_SR=m
# CONFIG_BLK_DEV_SR_VENDOR is not set
CONFIG_CHR_DEV_SG=m
# CONFIG_CHR_DEV_SCH is not set

#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
CONFIG_SCSI_MULTI_LUN=y
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_SCSI_WAIT_SCAN=m

#
# SCSI Transports
#
# CONFIG_SCSI_SPI_ATTRS is not set
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
# CONFIG_SCSI_SAS_ATTRS is not set
# CONFIG_SCSI_SAS_LIBSAS is not set
# CONFIG_SCSI_SRP_ATTRS is not set
# CONFIG_SCSI_LOWLEVEL is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_ATA_ACPI=y
# CONFIG_SATA_AHCI is not set
# CONFIG_SATA_SVW is not set
CONFIG_ATA_PIIX=y
# CONFIG_SATA_MV is not set
# CONFIG_SATA_NV is not set
# CONFIG_PDC_ADMA is not set
# CONFIG_SATA_QSTOR is not set
# CONFIG_SATA_PROMISE is not set
# CONFIG_SATA_SX4 is not set
# CONFIG_SATA_SIL is not set
CONFIG_SATA_SIL24=m
# CONFIG_SATA_SIS is not set
# CONFIG_SATA_ULI is not set
# CONFIG_SATA_VIA is not set
# CONFIG_SATA_VITESSE is not set
# CONFIG_SATA_INIC162X is not set
# CONFIG_PATA_ACPI is not set
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
# CONFIG_PATA_CS5520 is not set
# CONFIG_PATA_CS5530 is not set
# CONFIG_PATA_CS5535 is not set
# CONFIG_PATA_CS5536 is not set
# CONFIG_PATA_CYPRESS is not set
# CONFIG_PATA_EFAR is not set
# CONFIG_ATA_GENERIC is not set
# CONFIG_PATA_HPT366 is not set
# CONFIG_PATA_HPT37X is not set
# CONFIG_PATA_HPT3X2N is not set
# CONFIG_PATA_HPT3X3 is not set
# CONFIG_PATA_IT821X is not set
# CONFIG_PATA_IT8213 is not set
# CONFIG_PATA_JMICRON is not set
# CONFIG_PATA_TRIFLEX is not set
# CONFIG_PATA_MARVELL is not set
# CONFIG_PATA_MPIIX is not set
# CONFIG_PATA_OLDPIIX is not set
# CONFIG_PATA_NETCELL is not set
# CONFIG_PATA_NS87410 is not set
# CONFIG_PATA_NS87415 is not set
# CONFIG_PATA_OPTI is not set
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
# CONFIG_PATA_PDC2027X is not set
# CONFIG_PATA_SIL680 is not set
# CONFIG_PATA_SIS is not set
# CONFIG_PATA_VIA is not set
# CONFIG_PATA_WINBOND is not set
# CONFIG_PATA_PLATFORM is not set
CONFIG_MD=y
CONFIG_BLK_DEV_MD=m
# CONFIG_MD_LINEAR is not set
CONFIG_MD_RAID0=m
CONFIG_MD_RAID1=m
# CONFIG_MD_RAID10 is not set
# CONFIG_MD_RAID456 is not set
# CONFIG_MD_MULTIPATH is not set
# CONFIG_MD_FAULTY is not set
CONFIG_BLK_DEV_DM=m
# CONFIG_DM_DEBUG is not set
CONFIG_DM_CRYPT=m
CONFIG_DM_SNAPSHOT=m
CONFIG_DM_MIRROR=m
# CONFIG_DM_ZERO is not set
# CONFIG_DM_MULTIPATH is not set
# CONFIG_DM_DELAY is not set
# CONFIG_FUSION is not set

#
# IEEE 1394 (FireWire) support
#
CONFIG_FIREWIRE=m
CONFIG_FIREWIRE_OHCI=m
CONFIG_FIREWIRE_SBP2=m
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
# CONFIG_MACINTOSH_DRIVERS is not set
CONFIG_NETDEVICES=y
# CONFIG_NETDEVICES_MULTIQUEUE is not set
# CONFIG_IFB is not set
CONFIG_DUMMY=m
CONFIG_BONDING=m
CONFIG_MACVLAN=m
CONFIG_EQUALIZER=m
CONFIG_TUN=m
# CONFIG_VETH is not set
# CONFIG_NET_SB1000 is not set
# CONFIG_IP1000 is not set
# CONFIG_ARCNET is not set
CONFIG_PHYLIB=m

#
# MII PHY device drivers
#
# CONFIG_MARVELL_PHY is not set
# CONFIG_DAVICOM_PHY is not set
# CONFIG_QSEMI_PHY is not set
# CONFIG_LXT_PHY is not set
# CONFIG_CICADA_PHY is not set
# CONFIG_VITESSE_PHY is not set
# CONFIG_SMSC_PHY is not set
# CONFIG_BROADCOM_PHY is not set
# CONFIG_ICPLUS_PHY is not set
CONFIG_FIXED_PHY=m
CONFIG_FIXED_MII_10_FDX=y
CONFIG_FIXED_MII_100_FDX=y
CONFIG_FIXED_MII_1000_FDX=y
CONFIG_FIXED_MII_AMNT=1
# CONFIG_MDIO_BITBANG is not set
CONFIG_NET_ETHERNET=y
CONFIG_MII=m
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
# CONFIG_AMD8111_ETH is not set
# CONFIG_ADAPTEC_STARFIRE is not set
CONFIG_B44=m
CONFIG_B44_PCI_AUTOSELECT=y
CONFIG_B44_PCICORE_AUTOSELECT=y
CONFIG_B44_PCI=y
# CONFIG_FORCEDETH is not set
# CONFIG_EEPRO100 is not set
# CONFIG_E100 is not set
# CONFIG_FEALNX is not set
# CONFIG_NATSEMI is not set
# CONFIG_NE2K_PCI is not set
# CONFIG_8139CP is not set
# CONFIG_8139TOO is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_SC92031 is not set
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set

#
# Wireless LAN
#
# CONFIG_WLAN_PRE80211 is not set
CONFIG_WLAN_80211=y
CONFIG_IPW2100=m
CONFIG_IPW2100_MONITOR=y
# CONFIG_IPW2100_DEBUG is not set
CONFIG_IPW2200=m
CONFIG_IPW2200_MONITOR=y
CONFIG_IPW2200_RADIOTAP=y
CONFIG_IPW2200_PROMISCUOUS=y
CONFIG_IPW2200_QOS=y
# CONFIG_IPW2200_DEBUG is not set
# CONFIG_LIBERTAS is not set
# CONFIG_AIRO is not set
# CONFIG_HERMES is not set
# CONFIG_ATMEL is not set
# CONFIG_PRISM54 is not set
CONFIG_USB_ZD1201=m
CONFIG_RTL8187=m
# CONFIG_ADM8211 is not set
# CONFIG_P54_COMMON is not set
# CONFIG_IWLWIFI is not set
# CONFIG_HOSTAP is not set
CONFIG_BCM43XX=m
# CONFIG_BCM43XX_DEBUG is not set
CONFIG_BCM43XX_DMA=y
CONFIG_BCM43XX_PIO=y
CONFIG_BCM43XX_DMA_AND_PIO_MODE=y
# CONFIG_BCM43XX_DMA_MODE is not set
# CONFIG_BCM43XX_PIO_MODE is not set
CONFIG_B43=m
CONFIG_B43_PCI_AUTOSELECT=y
CONFIG_B43_PCICORE_AUTOSELECT=y
CONFIG_B43_RFKILL=y
# CONFIG_B43_DEBUG is not set
CONFIG_B43_DMA=y
CONFIG_B43_PIO=y
CONFIG_B43_DMA_AND_PIO_MODE=y
# CONFIG_B43_DMA_MODE is not set
# CONFIG_B43_PIO_MODE is not set
CONFIG_B43LEGACY=m
CONFIG_B43LEGACY_PCI_AUTOSELECT=y
CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y
# CONFIG_B43LEGACY_DEBUG is not set
CONFIG_B43LEGACY_DMA=y
CONFIG_B43LEGACY_PIO=y
CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
# CONFIG_B43LEGACY_DMA_MODE is not set
# CONFIG_B43LEGACY_PIO_MODE is not set
CONFIG_ZD1211RW=m
# CONFIG_ZD1211RW_DEBUG is not set
# CONFIG_RT2X00 is not set

#
# USB Network Adapters
#
CONFIG_USB_CATC=m
CONFIG_USB_KAWETH=m
CONFIG_USB_PEGASUS=m
CONFIG_USB_RTL8150=m
CONFIG_USB_USBNET_MII=m
CONFIG_USB_USBNET=m
CONFIG_USB_NET_AX8817X=m
CONFIG_USB_NET_CDCETHER=m
CONFIG_USB_NET_DM9601=m
CONFIG_USB_NET_GL620A=m
CONFIG_USB_NET_NET1080=m
CONFIG_USB_NET_PLUSB=m
# CONFIG_USB_NET_MCS7830 is not set
CONFIG_USB_NET_RNDIS_HOST=m
CONFIG_USB_NET_CDC_SUBSET=m
CONFIG_USB_ALI_M5632=y
CONFIG_USB_AN2720=y
CONFIG_USB_BELKIN=y
CONFIG_USB_ARMLINUX=y
CONFIG_USB_EPSON2888=y
CONFIG_USB_KC2190=y
CONFIG_USB_NET_ZAURUS=m
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
CONFIG_PPP=m
CONFIG_PPP_MULTILINK=y
CONFIG_PPP_FILTER=y
CONFIG_PPP_ASYNC=m
CONFIG_PPP_SYNC_TTY=m
CONFIG_PPP_DEFLATE=m
CONFIG_PPP_BSDCOMP=m
CONFIG_PPP_MPPE=m
CONFIG_PPPOE=m
CONFIG_PPPOL2TP=m
# CONFIG_SLIP is not set
CONFIG_SLHC=m
# CONFIG_NET_FC is not set
CONFIG_SHAPER=m
CONFIG_NETCONSOLE=m
# CONFIG_NETCONSOLE_DYNAMIC is not set
CONFIG_NETPOLL=y
# CONFIG_NETPOLL_TRAP is not set
CONFIG_NET_POLL_CONTROLLER=y
# CONFIG_ISDN is not set
# CONFIG_PHONE is not set

#
# Input device support
#
CONFIG_INPUT=y
# CONFIG_INPUT_FF_MEMLESS is not set
CONFIG_INPUT_POLLDEV=m

#
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=m
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_EVBUG=m

#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_SUNKBD is not set
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=m
CONFIG_MOUSE_PS2_ALPS=y
CONFIG_MOUSE_PS2_LOGIPS2PP=y
CONFIG_MOUSE_PS2_SYNAPTICS=y
# CONFIG_MOUSE_PS2_LIFEBOOK is not set
# CONFIG_MOUSE_PS2_TRACKPOINT is not set
# CONFIG_MOUSE_PS2_TOUCHKIT is not set
CONFIG_MOUSE_SERIAL=m
# CONFIG_MOUSE_APPLETOUCH is not set
# CONFIG_MOUSE_VSXXXAA is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
CONFIG_INPUT_MISC=y
CONFIG_INPUT_PCSPKR=m
# CONFIG_INPUT_WISTRON_BTNS is not set
# CONFIG_INPUT_ATLAS_BTNS is not set
CONFIG_INPUT_ATI_REMOTE=m
CONFIG_INPUT_ATI_REMOTE2=m
CONFIG_INPUT_KEYSPAN_REMOTE=m
# CONFIG_INPUT_POWERMATE is not set
CONFIG_INPUT_YEALINK=m
CONFIG_INPUT_UINPUT=m

#
# Hardware I/O ports
#
CONFIG_SERIO=y
CONFIG_SERIO_I8042=y
CONFIG_SERIO_SERPORT=m
CONFIG_SERIO_CT82C710=m
CONFIG_SERIO_PCIPS2=m
CONFIG_SERIO_LIBPS2=y
CONFIG_SERIO_RAW=m
# CONFIG_GAMEPORT is not set

#
# Character devices
#
CONFIG_VT=y
# CONFIG_VT_UNICODE is not set
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
# CONFIG_VT_HW_CONSOLE_BINDING is not set
# CONFIG_SERIAL_NONSTANDARD is not set

#
# Serial drivers
#
CONFIG_SERIAL_8250=y
# CONFIG_SERIAL_8250_CONSOLE is not set
CONFIG_FIX_EARLYCON_MEM=y
# CONFIG_SERIAL_8250_PCI is not set
# CONFIG_SERIAL_8250_PNP is not set
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=2
# CONFIG_SERIAL_8250_EXTENDED is not set

#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
# CONFIG_WATCHDOG is not set
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_INTEL=m
# CONFIG_HW_RANDOM_AMD is not set
# CONFIG_HW_RANDOM_GEODE is not set
# CONFIG_HW_RANDOM_VIA is not set
CONFIG_NVRAM=m
# CONFIG_RTC is not set
CONFIG_GEN_RTC=y
CONFIG_GEN_RTC_X=y
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_SONYPI is not set
# CONFIG_MWAVE is not set
# CONFIG_PC8736x_GPIO is not set
# CONFIG_NSC_GPIO is not set
# CONFIG_CS5535_GPIO is not set
# CONFIG_RAW_DRIVER is not set
CONFIG_HPET=y
# CONFIG_HPET_RTC_IRQ is not set
CONFIG_HPET_MMAP=y
CONFIG_HANGCHECK_TIMER=m
# CONFIG_TCG_TPM is not set
# CONFIG_TELCLOCK is not set
CONFIG_DEVPORT=y
CONFIG_I2C=m
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=m

#
# I2C Algorithms
#
CONFIG_I2C_ALGOBIT=m
# CONFIG_I2C_ALGOPCF is not set
# CONFIG_I2C_ALGOPCA is not set

#
# I2C Hardware Bus support
#
# CONFIG_I2C_ALI1535 is not set
# CONFIG_I2C_ALI1563 is not set
# CONFIG_I2C_ALI15X3 is not set
# CONFIG_I2C_AMD756 is not set
# CONFIG_I2C_AMD8111 is not set
# CONFIG_I2C_I801 is not set
# CONFIG_I2C_I810 is not set
# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_PROSAVAGE is not set
# CONFIG_I2C_SAVAGE4 is not set
# CONFIG_I2C_SIMTEC is not set
# CONFIG_SCx200_ACB is not set
# CONFIG_I2C_SIS5595 is not set
# CONFIG_I2C_SIS630 is not set
# CONFIG_I2C_SIS96X is not set
# CONFIG_I2C_TAOS_EVM is not set
# CONFIG_I2C_STUB is not set
# CONFIG_I2C_TINY_USB is not set
# CONFIG_I2C_VIA is not set
# CONFIG_I2C_VIAPRO is not set
# CONFIG_I2C_VOODOO3 is not set

#
# Miscellaneous I2C Chip support
#
# CONFIG_SENSORS_DS1337 is not set
# CONFIG_SENSORS_DS1374 is not set
# CONFIG_DS1682 is not set
# CONFIG_SENSORS_EEPROM is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
# CONFIG_I2C_DEBUG_CHIP is not set

#
# SPI support
#
# CONFIG_SPI is not set
# CONFIG_SPI_MASTER is not set
# CONFIG_W1 is not set
CONFIG_POWER_SUPPLY=m
# CONFIG_POWER_SUPPLY_DEBUG is not set
# CONFIG_PDA_POWER is not set
# CONFIG_BATTERY_DS2760 is not set
# CONFIG_HWMON is not set

#
# Sonics Silicon Backplane
#
CONFIG_SSB_POSSIBLE=y
CONFIG_SSB=m
CONFIG_SSB_PCIHOST_POSSIBLE=y
CONFIG_SSB_PCIHOST=y
CONFIG_SSB_SILENT=y
CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
CONFIG_SSB_DRIVER_PCICORE=y

#
# Multifunction device drivers
#
# CONFIG_MFD_SM501 is not set

#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
# CONFIG_DVB_CORE is not set
# CONFIG_DAB is not set

#
# Graphics support
#
CONFIG_AGP=m
# CONFIG_AGP_ALI is not set
CONFIG_AGP_ATI=m
# CONFIG_AGP_AMD is not set
# CONFIG_AGP_AMD64 is not set
CONFIG_AGP_INTEL=m
# CONFIG_AGP_NVIDIA is not set
# CONFIG_AGP_SIS is not set
# CONFIG_AGP_SWORKS is not set
# CONFIG_AGP_VIA is not set
# CONFIG_AGP_EFFICEON is not set
CONFIG_DRM=m
# CONFIG_DRM_TDFX is not set
# CONFIG_DRM_R128 is not set
CONFIG_DRM_RADEON=m
# CONFIG_DRM_I810 is not set
# CONFIG_DRM_I830 is not set
# CONFIG_DRM_I915 is not set
# CONFIG_DRM_MGA is not set
# CONFIG_DRM_SIS is not set
# CONFIG_DRM_VIA is not set
# CONFIG_DRM_SAVAGE is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
CONFIG_FB_DDC=m
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
# CONFIG_FB_SYS_FILLRECT is not set
# CONFIG_FB_SYS_COPYAREA is not set
# CONFIG_FB_SYS_IMAGEBLIT is not set
# CONFIG_FB_SYS_FOPS is not set
CONFIG_FB_DEFERRED_IO=y
# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
CONFIG_FB_BACKLIGHT=y
CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_TILEBLITTING=y

#
# Frame buffer hardware drivers
#
# CONFIG_FB_CIRRUS is not set
# CONFIG_FB_PM2 is not set
# CONFIG_FB_CYBER2000 is not set
# CONFIG_FB_ARC is not set
# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not set
# CONFIG_FB_VGA16 is not set
CONFIG_FB_VESA=y
# CONFIG_FB_HECUBA is not set
# CONFIG_FB_HGA is not set
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_I810 is not set
# CONFIG_FB_LE80578 is not set
# CONFIG_FB_INTEL is not set
# CONFIG_FB_MATROX is not set
CONFIG_FB_RADEON=m
CONFIG_FB_RADEON_I2C=y
CONFIG_FB_RADEON_BACKLIGHT=y
# CONFIG_FB_RADEON_DEBUG is not set
# CONFIG_FB_ATY128 is not set
# CONFIG_FB_ATY is not set
# CONFIG_FB_S3 is not set
# CONFIG_FB_SAVAGE is not set
# CONFIG_FB_SIS is not set
# CONFIG_FB_NEOMAGIC is not set
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
# CONFIG_FB_VT8623 is not set
# CONFIG_FB_CYBLA is not set
# CONFIG_FB_TRIDENT is not set
# CONFIG_FB_ARK is not set
# CONFIG_FB_PM3 is not set
# CONFIG_FB_GEODE is not set
# CONFIG_FB_VIRTUAL is not set
CONFIG_BACKLIGHT_LCD_SUPPORT=y
# CONFIG_LCD_CLASS_DEVICE is not set
CONFIG_BACKLIGHT_CLASS_DEVICE=y
# CONFIG_BACKLIGHT_CORGI is not set
# CONFIG_BACKLIGHT_PROGEAR is not set

#
# Display device support
#
# CONFIG_DISPLAY_SUPPORT is not set

#
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
CONFIG_VGACON_SOFT_SCROLLBACK=y
CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
CONFIG_VIDEO_SELECT=y
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=m
# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
# CONFIG_LOGO is not set

#
# Sound
#
CONFIG_SOUND=m

#
# Advanced Linux Sound Architecture
#
CONFIG_SND=m
CONFIG_SND_TIMER=m
CONFIG_SND_PCM=m
CONFIG_SND_HWDEP=m
CONFIG_SND_RAWMIDI=m
CONFIG_SND_SEQUENCER=m
CONFIG_SND_SEQ_DUMMY=m
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=m
CONFIG_SND_PCM_OSS=m
CONFIG_SND_PCM_OSS_PLUGINS=y
CONFIG_SND_SEQUENCER_OSS=y
# CONFIG_SND_DYNAMIC_MINORS is not set
CONFIG_SND_SUPPORT_OLD_API=y
# CONFIG_SND_VERBOSE_PROCFS is not set
# CONFIG_SND_VERBOSE_PRINTK is not set
# CONFIG_SND_DEBUG is not set

#
# Generic devices
#
CONFIG_SND_AC97_CODEC=m
# CONFIG_SND_DUMMY is not set
# CONFIG_SND_VIRMIDI is not set
# CONFIG_SND_MTPAV is not set
# CONFIG_SND_SERIAL_U16550 is not set
# CONFIG_SND_MPU401 is not set

#
# PCI devices
#
CONFIG_SND_AD1889=m
# CONFIG_SND_ALS300 is not set
# CONFIG_SND_ALS4000 is not set
# CONFIG_SND_ALI5451 is not set
# CONFIG_SND_ATIIXP is not set
# CONFIG_SND_ATIIXP_MODEM is not set
# CONFIG_SND_AU8810 is not set
# CONFIG_SND_AU8820 is not set
# CONFIG_SND_AU8830 is not set
# CONFIG_SND_AZT3328 is not set
# CONFIG_SND_BT87X is not set
# CONFIG_SND_CA0106 is not set
# CONFIG_SND_CMIPCI is not set
# CONFIG_SND_CS4281 is not set
# CONFIG_SND_CS46XX is not set
# CONFIG_SND_CS5530 is not set
# CONFIG_SND_CS5535AUDIO is not set
# CONFIG_SND_DARLA20 is not set
# CONFIG_SND_GINA20 is not set
# CONFIG_SND_LAYLA20 is not set
# CONFIG_SND_DARLA24 is not set
# CONFIG_SND_GINA24 is not set
# CONFIG_SND_LAYLA24 is not set
# CONFIG_SND_MONA is not set
# CONFIG_SND_MIA is not set
# CONFIG_SND_ECHO3G is not set
# CONFIG_SND_INDIGO is not set
# CONFIG_SND_INDIGOIO is not set
# CONFIG_SND_INDIGODJ is not set
# CONFIG_SND_EMU10K1 is not set
# CONFIG_SND_EMU10K1X is not set
# CONFIG_SND_ENS1370 is not set
# CONFIG_SND_ENS1371 is not set
# CONFIG_SND_ES1938 is not set
# CONFIG_SND_ES1968 is not set
# CONFIG_SND_FM801 is not set
CONFIG_SND_HDA_INTEL=m
# CONFIG_SND_HDA_HWDEP is not set
CONFIG_SND_HDA_CODEC_REALTEK=y
CONFIG_SND_HDA_CODEC_ANALOG=y
CONFIG_SND_HDA_CODEC_SIGMATEL=y
CONFIG_SND_HDA_CODEC_VIA=y
CONFIG_SND_HDA_CODEC_ATIHDMI=y
CONFIG_SND_HDA_CODEC_CONEXANT=y
CONFIG_SND_HDA_CODEC_CMEDIA=y
CONFIG_SND_HDA_CODEC_SI3054=y
CONFIG_SND_HDA_GENERIC=y
CONFIG_SND_HDA_POWER_SAVE=y
CONFIG_SND_HDA_POWER_SAVE_DEFAULT=10
# CONFIG_SND_HDSP is not set
# CONFIG_SND_HDSPM is not set
# CONFIG_SND_ICE1712 is not set
# CONFIG_SND_ICE1724 is not set
CONFIG_SND_INTEL8X0=m
CONFIG_SND_INTEL8X0M=m
# CONFIG_SND_KORG1212 is not set
# CONFIG_SND_MAESTRO3 is not set
# CONFIG_SND_MIXART is not set
# CONFIG_SND_NM256 is not set
# CONFIG_SND_PCXHR is not set
# CONFIG_SND_RIPTIDE is not set
# CONFIG_SND_RME32 is not set
# CONFIG_SND_RME96 is not set
# CONFIG_SND_RME9652 is not set
# CONFIG_SND_SONICVIBES is not set
# CONFIG_SND_TRIDENT is not set
# CONFIG_SND_VIA82XX is not set
# CONFIG_SND_VIA82XX_MODEM is not set
# CONFIG_SND_VX222 is not set
# CONFIG_SND_YMFPCI is not set
CONFIG_SND_AC97_POWER_SAVE=y
CONFIG_SND_AC97_POWER_SAVE_DEFAULT=10

#
# USB devices
#
CONFIG_SND_USB_AUDIO=m
CONFIG_SND_USB_USX2Y=m
CONFIG_SND_USB_CAIAQ=m
# CONFIG_SND_USB_CAIAQ_INPUT is not set

#
# System on Chip audio support
#
# CONFIG_SND_SOC is not set

#
# SoC Audio support for SuperH
#

#
# Open Sound System
#
CONFIG_SOUND_PRIME=m
# CONFIG_SOUND_TRIDENT is not set
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
CONFIG_SOUND_OSS=m
# CONFIG_SOUND_TRACEINIT is not set
# CONFIG_SOUND_DMAP is not set
# CONFIG_SOUND_SSCAPE is not set
CONFIG_SOUND_VMIDI=m
# CONFIG_SOUND_TRIX is not set
CONFIG_SOUND_MSS=m
CONFIG_SOUND_MPU401=m
# CONFIG_SOUND_PAS is not set
# CONFIG_SOUND_PSS is not set
CONFIG_SOUND_SB=m
# CONFIG_SOUND_YM3812 is not set
CONFIG_SOUND_UART6850=m
# CONFIG_SOUND_AEDSP16 is not set
# CONFIG_SOUND_KAHLUA is not set
CONFIG_AC97_BUS=m
CONFIG_HID_SUPPORT=y
CONFIG_HID=m
# CONFIG_HID_DEBUG is not set
CONFIG_HIDRAW=y

#
# USB Input Devices
#
CONFIG_USB_HID=m
# CONFIG_USB_HIDINPUT_POWERBOOK is not set
# CONFIG_HID_FF is not set
CONFIG_USB_HIDDEV=y

#
# USB HID Boot Protocol drivers
#
# CONFIG_USB_KBD is not set
# CONFIG_USB_MOUSE is not set
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB_ARCH_HAS_EHCI=y
CONFIG_USB=m
# CONFIG_USB_DEBUG is not set

#
# Miscellaneous USB options
#
CONFIG_USB_DEVICEFS=y
CONFIG_USB_DEVICE_CLASS=y
# CONFIG_USB_DYNAMIC_MINORS is not set
CONFIG_USB_SUSPEND=y
CONFIG_USB_PERSIST=y
# CONFIG_USB_OTG is not set

#
# USB Host Controller Drivers
#
CONFIG_USB_EHCI_HCD=m
CONFIG_USB_EHCI_SPLIT_ISO=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_EHCI_TT_NEWSCHED=y
# CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_OHCI_HCD=m
# CONFIG_USB_OHCI_HCD_SSB is not set
# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB_UHCI_HCD=m
# CONFIG_USB_U132_HCD is not set
CONFIG_USB_SL811_HCD=m
# CONFIG_USB_R8A66597_HCD is not set

#
# USB Device Class drivers
#
CONFIG_USB_ACM=m
CONFIG_USB_PRINTER=m

#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
#

#
# may also be needed; see USB_STORAGE Help for more information
#
CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
CONFIG_USB_STORAGE_DATAFAB=y
CONFIG_USB_STORAGE_FREECOM=y
CONFIG_USB_STORAGE_DPCM=y
CONFIG_USB_STORAGE_USBAT=y
CONFIG_USB_STORAGE_SDDR09=y
CONFIG_USB_STORAGE_SDDR55=y
CONFIG_USB_STORAGE_JUMPSHOT=y
CONFIG_USB_STORAGE_ALAUDA=y
# CONFIG_USB_STORAGE_KARMA is not set
CONFIG_USB_LIBUSUAL=y

#
# USB Imaging devices
#
CONFIG_USB_MDC800=m
CONFIG_USB_MICROTEK=m
CONFIG_USB_MON=y

#
# USB port drivers
#

#
# USB Serial Converter support
#
CONFIG_USB_SERIAL=m
CONFIG_USB_SERIAL_GENERIC=y
CONFIG_USB_SERIAL_AIRCABLE=m
CONFIG_USB_SERIAL_AIRPRIME=m
CONFIG_USB_SERIAL_ARK3116=m
CONFIG_USB_SERIAL_BELKIN=m
CONFIG_USB_SERIAL_CH341=m
CONFIG_USB_SERIAL_WHITEHEAT=m
CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
CONFIG_USB_SERIAL_CP2101=m
CONFIG_USB_SERIAL_CYPRESS_M8=m
CONFIG_USB_SERIAL_EMPEG=m
CONFIG_USB_SERIAL_FTDI_SIO=m
CONFIG_USB_SERIAL_FUNSOFT=m
CONFIG_USB_SERIAL_VISOR=m
CONFIG_USB_SERIAL_IPAQ=m
CONFIG_USB_SERIAL_IR=m
CONFIG_USB_SERIAL_EDGEPORT=m
CONFIG_USB_SERIAL_EDGEPORT_TI=m
CONFIG_USB_SERIAL_GARMIN=m
CONFIG_USB_SERIAL_IPW=m
CONFIG_USB_SERIAL_KEYSPAN_PDA=m
CONFIG_USB_SERIAL_KEYSPAN=m
CONFIG_USB_SERIAL_KEYSPAN_MPR=y
CONFIG_USB_SERIAL_KEYSPAN_USA28=y
CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
CONFIG_USB_SERIAL_KEYSPAN_USA19=y
CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
CONFIG_USB_SERIAL_KLSI=m
CONFIG_USB_SERIAL_KOBIL_SCT=m
CONFIG_USB_SERIAL_MCT_U232=m
CONFIG_USB_SERIAL_MOS7720=m
CONFIG_USB_SERIAL_MOS7840=m
CONFIG_USB_SERIAL_NAVMAN=m
CONFIG_USB_SERIAL_PL2303=m
CONFIG_USB_SERIAL_OTI6858=m
# CONFIG_USB_SERIAL_HP4X is not set
CONFIG_USB_SERIAL_SAFE=m
CONFIG_USB_SERIAL_SAFE_PADDED=y
CONFIG_USB_SERIAL_SIERRAWIRELESS=m
CONFIG_USB_SERIAL_TI=m
CONFIG_USB_SERIAL_CYBERJACK=m
CONFIG_USB_SERIAL_XIRCOM=m
CONFIG_USB_SERIAL_OPTION=m
CONFIG_USB_SERIAL_OMNINET=m
# CONFIG_USB_SERIAL_DEBUG is not set
CONFIG_USB_EZUSB=y

#
# USB Miscellaneous drivers
#
CONFIG_USB_EMI62=m
CONFIG_USB_EMI26=m
CONFIG_USB_ADUTUX=m
CONFIG_USB_AUERSWALD=m
CONFIG_USB_RIO500=m
CONFIG_USB_LEGOTOWER=m
CONFIG_USB_LCD=m
# CONFIG_USB_BERRY_CHARGE is not set
CONFIG_USB_LED=m
CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
# CONFIG_USB_PHIDGET is not set
CONFIG_USB_IDMOUSE=m
CONFIG_USB_FTDI_ELAN=m
# CONFIG_USB_APPLEDISPLAY is not set
CONFIG_USB_SISUSBVGA=m
# CONFIG_USB_SISUSBVGA_CON is not set
CONFIG_USB_LD=m
# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_IOWARRIOR is not set
CONFIG_USB_TEST=m

#
# USB DSL modem support
#

#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
CONFIG_MMC=m
# CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_UNSAFE_RESUME is not set

#
# MMC/SD Card Drivers
#
CONFIG_MMC_BLOCK=m
CONFIG_MMC_BLOCK_BOUNCE=y
# CONFIG_SDIO_UART is not set

#
# MMC/SD Host Controller Drivers
#
CONFIG_MMC_SDHCI=m
CONFIG_MMC_RICOH_MMC=m
# CONFIG_MMC_WBSD is not set
CONFIG_MMC_TIFM_SD=m
# CONFIG_NEW_LEDS is not set
# CONFIG_INFINIBAND is not set
# CONFIG_EDAC is not set
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
# CONFIG_RTC_DEBUG is not set

#
# RTC interfaces
#
CONFIG_RTC_INTF_SYSFS=y
CONFIG_RTC_INTF_PROC=y
CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
CONFIG_RTC_DRV_TEST=m

#
# I2C RTC drivers
#
CONFIG_RTC_DRV_DS1307=m
CONFIG_RTC_DRV_DS1374=m
CONFIG_RTC_DRV_DS1672=m
CONFIG_RTC_DRV_MAX6900=m
CONFIG_RTC_DRV_RS5C372=m
CONFIG_RTC_DRV_ISL1208=m
CONFIG_RTC_DRV_X1205=m
CONFIG_RTC_DRV_PCF8563=m
CONFIG_RTC_DRV_PCF8583=m
# CONFIG_RTC_DRV_M41T80 is not set

#
# SPI RTC drivers
#

#
# Platform RTC drivers
#
CONFIG_RTC_DRV_CMOS=y
CONFIG_RTC_DRV_DS1553=m
# CONFIG_RTC_DRV_STK17TA8 is not set
CONFIG_RTC_DRV_DS1742=m
CONFIG_RTC_DRV_M48T86=m
# CONFIG_RTC_DRV_M48T59 is not set
CONFIG_RTC_DRV_V3020=m

#
# on-CPU RTC drivers
#
CONFIG_DMADEVICES=y

#
# DMA Devices
#
CONFIG_INTEL_IOATDMA=m
CONFIG_DMA_ENGINE=y

#
# DMA Clients
#
CONFIG_NET_DMA=y
CONFIG_DCA=m
# CONFIG_VIRTUALIZATION is not set

#
# Userspace I/O
#
CONFIG_UIO=m
# CONFIG_UIO_CIF is not set

#
# File systems
#
CONFIG_EXT2_FS=m
# CONFIG_EXT2_FS_XATTR is not set
CONFIG_EXT2_FS_XIP=y
CONFIG_FS_XIP=y
CONFIG_EXT3_FS=y
# CONFIG_EXT3_FS_XATTR is not set
# CONFIG_EXT4DEV_FS is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
CONFIG_FUSE_FS=m

#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
CONFIG_ZISOFS=y
CONFIG_UDF_FS=m
CONFIG_UDF_NLS=y

#
# DOS/FAT/NT Filesystems
#
CONFIG_FAT_FS=m
CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=m
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_NTFS_FS=m
# CONFIG_NTFS_DEBUG is not set
CONFIG_NTFS_RW=y

#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_CONFIGFS_FS=m

#
# Miscellaneous filesystems
#
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
CONFIG_HFS_FS=m
CONFIG_HFSPLUS_FS=m
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
CONFIG_NFS_DIRECTIO=y
CONFIG_NFSD=m
CONFIG_NFSD_V2_ACL=y
CONFIG_NFSD_V3=y
CONFIG_NFSD_V3_ACL=y
CONFIG_NFSD_V4=y
CONFIG_NFSD_TCP=y
CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=m
CONFIG_NFS_ACL_SUPPORT=m
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=m
CONFIG_SUNRPC_GSS=m
CONFIG_SUNRPC_BIND34=y
CONFIG_RPCSEC_GSS_KRB5=m
# CONFIG_RPCSEC_GSS_SPKM3 is not set
CONFIG_SMB_FS=m
CONFIG_SMB_NLS_DEFAULT=y
CONFIG_SMB_NLS_REMOTE="cp437"
CONFIG_CIFS=m
# CONFIG_CIFS_STATS is not set
CONFIG_CIFS_WEAK_PW_HASH=y
# CONFIG_CIFS_XATTR is not set
# CONFIG_CIFS_DEBUG2 is not set
# CONFIG_CIFS_EXPERIMENTAL is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set

#
# Partition Types
#
CONFIG_PARTITION_ADVANCED=y
# CONFIG_ACORN_PARTITION is not set
# CONFIG_OSF_PARTITION is not set
# CONFIG_AMIGA_PARTITION is not set
# CONFIG_ATARI_PARTITION is not set
CONFIG_MAC_PARTITION=y
CONFIG_MSDOS_PARTITION=y
# CONFIG_BSD_DISKLABEL is not set
# CONFIG_MINIX_SUBPARTITION is not set
# CONFIG_SOLARIS_X86_PARTITION is not set
# CONFIG_UNIXWARE_DISKLABEL is not set
CONFIG_LDM_PARTITION=y
# CONFIG_LDM_DEBUG is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_KARMA_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
# CONFIG_SYSV68_PARTITION is not set
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="cp437"
CONFIG_NLS_CODEPAGE_437=m
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
CONFIG_NLS_CODEPAGE_850=m
# CONFIG_NLS_CODEPAGE_852 is not set
# CONFIG_NLS_CODEPAGE_855 is not set
# CONFIG_NLS_CODEPAGE_857 is not set
# CONFIG_NLS_CODEPAGE_860 is not set
# CONFIG_NLS_CODEPAGE_861 is not set
# CONFIG_NLS_CODEPAGE_862 is not set
CONFIG_NLS_CODEPAGE_863=m
# CONFIG_NLS_CODEPAGE_864 is not set
# CONFIG_NLS_CODEPAGE_865 is not set
# CONFIG_NLS_CODEPAGE_866 is not set
# CONFIG_NLS_CODEPAGE_869 is not set
# CONFIG_NLS_CODEPAGE_936 is not set
# CONFIG_NLS_CODEPAGE_950 is not set
# CONFIG_NLS_CODEPAGE_932 is not set
# CONFIG_NLS_CODEPAGE_949 is not set
# CONFIG_NLS_CODEPAGE_874 is not set
# CONFIG_NLS_ISO8859_8 is not set
# CONFIG_NLS_CODEPAGE_1250 is not set
# CONFIG_NLS_CODEPAGE_1251 is not set
CONFIG_NLS_ASCII=m
CONFIG_NLS_ISO8859_1=m
CONFIG_NLS_ISO8859_2=m
CONFIG_NLS_ISO8859_3=m
CONFIG_NLS_ISO8859_4=m
CONFIG_NLS_ISO8859_5=m
CONFIG_NLS_ISO8859_6=m
CONFIG_NLS_ISO8859_7=m
CONFIG_NLS_ISO8859_9=m
CONFIG_NLS_ISO8859_13=m
CONFIG_NLS_ISO8859_14=m
CONFIG_NLS_ISO8859_15=m
CONFIG_NLS_KOI8_R=m
CONFIG_NLS_KOI8_U=m
CONFIG_NLS_UTF8=m
CONFIG_DLM=m
# CONFIG_DLM_DEBUG is not set
# CONFIG_INSTRUMENTATION is not set

#
# Kernel hacking
#
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_ENABLE_MUST_CHECK is not set
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHED_DEBUG is not set
# CONFIG_SCHEDSTATS is not set
CONFIG_TIMER_STATS=y
# CONFIG_DEBUG_PREEMPT is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_MUTEXES is not set
# CONFIG_DEBUG_LOCK_ALLOC is not set
# CONFIG_PROVE_LOCKING is not set
# CONFIG_LOCK_STAT is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_HIGHMEM is not set
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_FRAME_POINTER is not set
# CONFIG_FORCED_INLINING is not set
CONFIG_BOOT_PRINTK_DELAY=y
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_EARLY_PRINTK is not set
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set

#
# Page alloc debug is incompatible with Software Suspend on i386
#
# CONFIG_DEBUG_RODATA is not set
CONFIG_4KSTACKS=y
CONFIG_X86_FIND_SMP_CONFIG=y
CONFIG_X86_MPPARSE=y
CONFIG_DOUBLEFAULT=y

#
# Security options
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ABLKCIPHER=m
CONFIG_CRYPTO_BLKCIPHER=m
CONFIG_CRYPTO_HASH=m
CONFIG_CRYPTO_MANAGER=m
CONFIG_CRYPTO_HMAC=m
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_MD5=m
CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_GF128MUL=m
CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_CBC=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_LRW=m
# CONFIG_CRYPTO_XTS is not set
CONFIG_CRYPTO_CRYPTD=m
CONFIG_CRYPTO_DES=m
CONFIG_CRYPTO_FCRYPT=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_TWOFISH_COMMON=m
CONFIG_CRYPTO_TWOFISH_586=m
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
CONFIG_CRYPTO_AES_586=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
# CONFIG_CRYPTO_SEED is not set
CONFIG_CRYPTO_DEFLATE=m
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
CONFIG_CRYPTO_CAMELLIA=m
# CONFIG_CRYPTO_TEST is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_HW is not set

#
# Library routines
#
CONFIG_BITREVERSE=m
CONFIG_CRC_CCITT=m
CONFIG_CRC16=m
CONFIG_CRC_ITU_T=m
CONFIG_CRC32=m
CONFIG_CRC7=m
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=m
CONFIG_ZLIB_DEFLATE=m
CONFIG_TEXTSEARCH=y
CONFIG_TEXTSEARCH_KMP=m
CONFIG_TEXTSEARCH_BM=m
CONFIG_TEXTSEARCH_FSM=m
CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_PENDING_IRQ=y
CONFIG_X86_SMP=y
CONFIG_X86_HT=y
CONFIG_X86_BIOS_REBOOT=y
CONFIG_X86_TRAMPOLINE=y
CONFIG_KTIME_SCALAR=y

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  4:54                                                     ` Mark Lord
@ 2007-10-18  5:09                                                       ` Mark Lord
  0 siblings, 0 replies; 151+ messages in thread
From: Mark Lord @ 2007-10-18  5:09 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: David Miller, fujita.tomonori, jens.axboe, mingo, linux-kernel,
	jgarzik, alan, tomof

Mark Lord wrote:
> Mark Lord wrote:
>> Mark Lord wrote:
>>> Linus Torvalds wrote:
>>>>
>>>> On Wed, 17 Oct 2007, Mark Lord wrote:
>>>>> It would be good to have something soon-ish.
>>>>> This "dead at boot time" issue is impacting the general ability to 
>>>>> test
>>>>> patches against latest -git in time for the current merge window.
>>>>
>>>> In the meantime, does the patch I sent out help people? I'd like to 
>>>> get feedback, but I'm a lazy bum, and don't use DEBUG_PAGEALLOC 
>>>> myself, so I was hoping that people who actually see this could 
>>>> comment on my untested suggestion.
>>>
>>> Oh.. so this bug is supposed to only bite with DEBUG_PAGEALLOC=y ??
>>>
>>> Then something else is broken, perhaps.  I just saw a long traceback
>>> scroll off the top of the screen, with lots of bio_* functions in the 
>>> list
>>> and assumed it was the same bug.
>>>
>>> Mmm.. I'll get out the camera and try it again now..
>>
>> Okay, mine is dying with EIP at blk_rq_map_sg+0xcb/0x160.
>>
>> Screen photo is at http://rtr.ca/recent/2.6.23-git12-crash.jpg,
>> but the top was cut off (isn't there a new config option or patch
>> to do double-columns or scrollback or something ???.
> 
> I tried the fancy "boot_delay=nnn" feature, but that doesn't slow down
> the tracebacks at all.  So I hardcoded some mdelay(1000) lines into
> the traceback code, and here's the top part of the oops now:
> 
>   http://rtr.ca/recent/2.6.23-git12-crash2.jpg
...

And, yes, I make that out as being this line from blk_rq_map_sg():

    next_sg = sg_next(sg);

"objdump -d" output from my actual kernel:

00003ce0 <blk_rq_map_sg>:
    3ce0:       55                      push   %ebp
    3ce1:       57                      push   %edi
    3ce2:       56                      push   %esi
    3ce3:       53                      push   %ebx
    3ce4:       83 ec 24                sub    $0x24,%esp
    3ce7:       89 44 24 04             mov    %eax,0x4(%esp)
    3ceb:       8b 98 44 01 00 00       mov    0x144(%eax),%ebx
    3cf1:       83 e3 01                and    $0x1,%ebx
    3cf4:       89 5c 24 14             mov    %ebx,0x14(%esp)
    3cf8:       8b 52 34                mov    0x34(%edx),%edx
    3cfb:       c7 44 24 10 00 00 00    movl   $0x0,0x10(%esp)
    3d02:       00
    3d03:       85 d2                   test   %edx,%edx
    3d05:       89 54 24 1c             mov    %edx,0x1c(%esp)
    3d09:       0f 84 f4 00 00 00       je     3e03 <blk_rq_map_sg+0x123>
    3d0f:       89 cb                   mov    %ecx,%ebx
    3d11:       31 ff                   xor    %edi,%edi
    3d13:       89 4c 24 0c             mov    %ecx,0xc(%esp)
    3d17:       8b 44 24 1c             mov    0x1c(%esp),%eax
    3d1b:       0f b7 48 16             movzwl 0x16(%eax),%ecx
    3d1f:       8b 50 2c                mov    0x2c(%eax),%edx
    3d22:       89 4c 24 18             mov    %ecx,0x18(%esp)
    3d26:       0f b7 40 14             movzwl 0x14(%eax),%eax
    3d2a:       39 c1                   cmp    %eax,%ecx
    3d2c:       0f 8d be 00 00 00       jge    3df0 <blk_rq_map_sg+0x110>
    3d32:       8d 04 49                lea    (%ecx,%ecx,2),%eax
    3d35:       8d 34 82                lea    (%edx,%eax,4),%esi
    3d38:       0f b6 44 24 14          movzbl 0x14(%esp),%eax
    3d3d:       88 44 24 23             mov    %al,0x23(%esp)
    3d41:       eb 05                   jmp    3d48 <blk_rq_map_sg+0x68>
    3d43:       89 f7                   mov    %esi,%edi
    3d45:       83 c6 0c                add    $0xc,%esi
    3d48:       80 7c 24 23 00          cmpb   $0x0,0x23(%esp)
    3d4d:       8b 6e 04                mov    0x4(%esi),%ebp
    3d50:       74 4e                   je     3da0 <blk_rq_map_sg+0xc0>
    3d52:       85 ff                   test   %edi,%edi
    3d54:       74 4a                   je     3da0 <blk_rq_map_sg+0xc0>
    3d56:       8b 54 24 0c             mov    0xc(%esp),%edx
    3d5a:       8b 44 24 04             mov    0x4(%esp),%eax
    3d5e:       8b 4a 0c                mov    0xc(%edx),%ecx
    3d61:       01 e9                   add    %ebp,%ecx
    3d63:       89 4c 24 08             mov    %ecx,0x8(%esp)
    3d67:       3b 88 94 01 00 00       cmp    0x194(%eax),%ecx
    3d6d:       77 31                   ja     3da0 <blk_rq_map_sg+0xc0>
    3d6f:       8b 15 00 00 00 00       mov    0x0,%edx
    3d75:       8b 0f                   mov    (%edi),%ecx
    3d77:       8b 47 04                mov    0x4(%edi),%eax
    3d7a:       29 d1                   sub    %edx,%ecx
    3d7c:       c1 f9 05                sar    $0x5,%ecx
    3d7f:       c1 e1 0c                shl    $0xc,%ecx
    3d82:       03 4f 08                add    0x8(%edi),%ecx
    3d85:       8d 3c 01                lea    (%ecx,%eax,1),%edi
    3d88:       8b 06                   mov    (%esi),%eax
    3d8a:       29 d0                   sub    %edx,%eax
    3d8c:       c1 f8 05                sar    $0x5,%eax
    3d8f:       c1 e0 0c                shl    $0xc,%eax
    3d92:       03 46 08                add    0x8(%esi),%eax
    3d95:       39 c7                   cmp    %eax,%edi
    3d97:       74 76                   je     3e0f <blk_rq_map_sg+0x12f>
    3d99:       8d b4 26 00 00 00 00    lea    0x0(%esi),%esi
    3da0:       8d 43 10                lea    0x10(%ebx),%eax
    3da3:       b9 04 00 00 00          mov    $0x4,%ecx
    3da8:       89 04 24                mov    %eax,(%esp)
    3dab:       8b 43 10                mov    0x10(%ebx),%eax     <<<<--------- dies here
    3dae:       89 df                   mov    %ebx,%edi
    3db0:       89 c2                   mov    %eax,%edx
    3db2:       83 e2 fe                and    $0xfffffffe,%edx
    3db5:       a8 01                   test   $0x1,%al
    3db7:       0f 44 14 24             cmove  (%esp),%edx
    3dbb:       31 c0                   xor    %eax,%eax
    3dbd:       f3 ab                   rep stos %eax,%es:(%edi)
    3dbf:       8b 06                   mov    (%esi),%eax
    3dc1:       89 6b 0c                mov    %ebp,0xc(%ebx)
    3dc4:       89 03                   mov    %eax,(%ebx)
    3dc6:       8b 46 08                mov    0x8(%esi),%eax
    3dc9:       89 43 04                mov    %eax,0x4(%ebx)
    3dcc:       83 44 24 10 01          addl   $0x1,0x10(%esp)
    3dd1:       89 5c 24 0c             mov    %ebx,0xc(%esp)
    3dd5:       89 d3                   mov    %edx,%ebx
    3dd7:       8b 54 24 1c             mov    0x1c(%esp),%edx

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  4:01                                               ` Linus Torvalds
  2007-10-18  4:05                                                 ` Mark Lord
@ 2007-10-18  5:25                                                 ` Mark Lord
  2007-10-18  5:34                                                   ` Mark Lord
  1 sibling, 1 reply; 151+ messages in thread
From: Mark Lord @ 2007-10-18  5:25 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: David Miller, fujita.tomonori, jens.axboe, mingo, linux-kernel,
	jgarzik, alan, tomof

Linus Torvalds wrote:
> 
> On Wed, 17 Oct 2007, Mark Lord wrote:
>> It would be good to have something soon-ish.
>> This "dead at boot time" issue is impacting the general ability to test
>> patches against latest -git in time for the current merge window.
> 
> In the meantime, does the patch I sent out help people?

Your patch from this posting http://lkml.org/lkml/2007/10/17/285
does not seem to make much difference here.

It still crashes at exactly the same place.

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  5:25                                                 ` Mark Lord
@ 2007-10-18  5:34                                                   ` Mark Lord
  2007-10-18  5:45                                                     ` Jeff Garzik
  0 siblings, 1 reply; 151+ messages in thread
From: Mark Lord @ 2007-10-18  5:34 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: David Miller, fujita.tomonori, jens.axboe, mingo, linux-kernel,
	jgarzik, alan, tomof

Mark Lord wrote:
> Linus Torvalds wrote:
>>
>> On Wed, 17 Oct 2007, Mark Lord wrote:
>>> It would be good to have something soon-ish.
>>> This "dead at boot time" issue is impacting the general ability to test
>>> patches against latest -git in time for the current merge window.
>>
>> In the meantime, does the patch I sent out help people?
> 
> Your patch from this posting http://lkml.org/lkml/2007/10/17/285
> does not seem to make much difference here.
> 
> It still crashes at exactly the same place.


However, Jens's patch from that same thread:

     http://lkml.org/lkml/2007/10/17/269

..allowed me to boot and post this followup message from -git12

Jeff: try that one.

Patch reproduced here for convenience:

Jens Axboe wrote:
> OK, it is fine, as long as the sglist is cleared initially. And I don't
> think there's anyway around that, clearly I didn't think long enough
> before including the memset() removal from Tomo.
> 
> Ingo, please try this rolled up version.
> 
> Linus, this should work. It would probably be best if you first did a
> git revert on f5c0dde4c66421a3a2d7d6fa604a712c9b0744e5 and then applied
> the ll_rw_blk.c bit alone. Do you want me to stuff that (revert + patch)
> into a branch for you to pull?

diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 9e3f3cc..3935469 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -1322,8 +1322,8 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
 		  struct scatterlist *sglist)
 {
 	struct bio_vec *bvec, *bvprv;
-	struct scatterlist *next_sg, *sg;
 	struct req_iterator iter;
+	struct scatterlist *sg;
 	int nsegs, cluster;
 
 	nsegs = 0;
@@ -1333,7 +1333,7 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
 	 * for each bio in rq
 	 */
 	bvprv = NULL;
-	sg = next_sg = &sglist[0];
+	sg = NULL;
 	rq_for_each_segment(bvec, rq, iter) {
 		int nbytes = bvec->bv_len;
 
@@ -1349,8 +1349,10 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
 			sg->length += nbytes;
 		} else {
 new_segment:
-			sg = next_sg;
-			next_sg = sg_next(sg);
+			if (!sg)
+				sg = sglist;
+			else
+				sg = sg_next(sg);
 
 			memset(sg, 0, sizeof(*sg));
 			sg->page = bvec->bv_page;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 0c86be7..aac8a02 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -764,6 +764,8 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
 		if (unlikely(!sgl))
 			goto enomem;
 
+		memset(sgl, 0, sizeof(*sgl) * sgp->size);
+
 		/*
 		 * first loop through, set initial index and return value
 		 */


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  5:34                                                   ` Mark Lord
@ 2007-10-18  5:45                                                     ` Jeff Garzik
  2007-10-18  7:09                                                       ` Jens Axboe
  0 siblings, 1 reply; 151+ messages in thread
From: Jeff Garzik @ 2007-10-18  5:45 UTC (permalink / raw)
  To: Mark Lord
  Cc: Linus Torvalds, David Miller, fujita.tomonori, jens.axboe, mingo,
	linux-kernel, alan, tomof

Mark Lord wrote:
> Mark Lord wrote:
>> Linus Torvalds wrote:
>>>
>>> On Wed, 17 Oct 2007, Mark Lord wrote:
>>>> It would be good to have something soon-ish.
>>>> This "dead at boot time" issue is impacting the general ability to test
>>>> patches against latest -git in time for the current merge window.
>>>
>>> In the meantime, does the patch I sent out help people?
>>
>> Your patch from this posting http://lkml.org/lkml/2007/10/17/285
>> does not seem to make much difference here.
>>
>> It still crashes at exactly the same place.
> 
> 
> However, Jens's patch from that same thread:
> 
>     http://lkml.org/lkml/2007/10/17/269
> 
> ..allowed me to boot and post this followup message from -git12
> 
> Jeff: try that one.

That's already in my upstream kernel, here.  commits
ba951841ceb7fa5b06ad48caa5270cc2ae17941e and 
a3bec5c5aea0da263111c4d8f8eabc1f8560d7bf.

sata_mv and sata_nv still reliably poop themselves here, whereas its 
rock solid with 2.6.23.1.  Sounds like different issues from yours, as I 
see a stream of SATA errors on the bad kernels, errors which are often a 
symptom of something whacked in the DMA engine (misprogramming causes 
the silicon to generate bogus FIS's, which the device then chokes on)

	Jeff



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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  4:31                                                     ` Jeff Garzik
  2007-10-18  4:41                                                       ` Mark Lord
  2007-10-18  4:53                                                       ` Linus Torvalds
@ 2007-10-18  7:05                                                       ` Jens Axboe
  2007-10-18 13:13                                                         ` Mark Lord
  2 siblings, 1 reply; 151+ messages in thread
From: Jens Axboe @ 2007-10-18  7:05 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: Mark Lord, Linus Torvalds, David Miller, fujita.tomonori, mingo,
	linux-kernel, alan, tomof

On Thu, Oct 18 2007, Jeff Garzik wrote:
> Mark Lord wrote:
>> Okay, mine is dying with EIP at blk_rq_map_sg+0xcb/0x160.
>> Screen photo is at http://rtr.ca/recent/2.6.23-git12-crash.jpg,
>> but the top was cut off (isn't there a new config option or patch
>> to do double-columns or scrollback or something ???.
>
> Is this a sata_mv box?  If so, could you try this patch?

If anything, that shrinks the size of the resulting request. Did this
patch make any difference to you?

Now sata_mv should not be doing this (already discussed), but as long as
it's only lowering the physical sg count then it should not cause any
bugs at least.

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-17 19:35                       ` Jens Axboe
  2007-10-17 19:45                         ` Linus Torvalds
  2007-10-17 19:49                         ` Jens Axboe
@ 2007-10-18  7:07                         ` Ingo Molnar
  2007-10-18  7:10                           ` Jens Axboe
                                             ` (2 more replies)
  2 siblings, 3 replies; 151+ messages in thread
From: Ingo Molnar @ 2007-10-18  7:07 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Linus Torvalds, linux-kernel, Jeff Garzik, Alan Cox


* Jens Axboe <jens.axboe@oracle.com> wrote:

> --- a/drivers/scsi/scsi_lib.c
> +++ b/drivers/scsi/scsi_lib.c
> @@ -39,7 +39,7 @@
>   * (unless chaining is used). Should ideally fit inside a single page, to
>   * avoid a higher order allocation.
>   */
> -#define SCSI_MAX_SG_SEGMENTS	128
> +#define SCSI_MAX_SG_SEGMENTS	129

this one finally made the trick and it's booting fine now, without any 
crashes!

Tested-by: Ingo Molnar <mingo@elte.hu>

	Ingo

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  5:45                                                     ` Jeff Garzik
@ 2007-10-18  7:09                                                       ` Jens Axboe
  2007-10-18  7:30                                                         ` Jeff Garzik
  0 siblings, 1 reply; 151+ messages in thread
From: Jens Axboe @ 2007-10-18  7:09 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: Mark Lord, Linus Torvalds, David Miller, fujita.tomonori, mingo,
	linux-kernel, alan, tomof

On Thu, Oct 18 2007, Jeff Garzik wrote:
> Mark Lord wrote:
>> Mark Lord wrote:
>>> Linus Torvalds wrote:
>>>>
>>>> On Wed, 17 Oct 2007, Mark Lord wrote:
>>>>> It would be good to have something soon-ish.
>>>>> This "dead at boot time" issue is impacting the general ability to test
>>>>> patches against latest -git in time for the current merge window.
>>>>
>>>> In the meantime, does the patch I sent out help people?
>>>
>>> Your patch from this posting http://lkml.org/lkml/2007/10/17/285
>>> does not seem to make much difference here.
>>>
>>> It still crashes at exactly the same place.
>> However, Jens's patch from that same thread:
>>     http://lkml.org/lkml/2007/10/17/269
>> ..allowed me to boot and post this followup message from -git12
>> Jeff: try that one.
>
> That's already in my upstream kernel, here.  commits
> ba951841ceb7fa5b06ad48caa5270cc2ae17941e and 
> a3bec5c5aea0da263111c4d8f8eabc1f8560d7bf.
>
> sata_mv and sata_nv still reliably poop themselves here, whereas its rock 
> solid with 2.6.23.1.  Sounds like different issues from yours, as I see a 
> stream of SATA errors on the bad kernels, errors which are often a symptom 
> of something whacked in the DMA engine (misprogramming causes the silicon 
> to generate bogus FIS's, which the device then chokes on)

Do you know if this poop involves the segment padding that sometimes
goes on in libata?

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  7:07                         ` Ingo Molnar
@ 2007-10-18  7:10                           ` Jens Axboe
  2007-10-18  8:22                           ` Jeff Garzik
  2007-10-18 11:03                           ` Ingo Molnar
  2 siblings, 0 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-18  7:10 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Linus Torvalds, linux-kernel, Jeff Garzik, Alan Cox

On Thu, Oct 18 2007, Ingo Molnar wrote:
> 
> * Jens Axboe <jens.axboe@oracle.com> wrote:
> 
> > --- a/drivers/scsi/scsi_lib.c
> > +++ b/drivers/scsi/scsi_lib.c
> > @@ -39,7 +39,7 @@
> >   * (unless chaining is used). Should ideally fit inside a single page, to
> >   * avoid a higher order allocation.
> >   */
> > -#define SCSI_MAX_SG_SEGMENTS	128
> > +#define SCSI_MAX_SG_SEGMENTS	129
> 
> this one finally made the trick and it's booting fine now, without any 
> crashes!

Super, that validates the theory the theory that Linus put forth. So the
bug is clear now, this morning I'll work on proper sg looping.

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  7:09                                                       ` Jens Axboe
@ 2007-10-18  7:30                                                         ` Jeff Garzik
  0 siblings, 0 replies; 151+ messages in thread
From: Jeff Garzik @ 2007-10-18  7:30 UTC (permalink / raw)
  To: Jens Axboe
  Cc: Mark Lord, Linus Torvalds, David Miller, fujita.tomonori, mingo,
	linux-kernel, alan, tomof

Jens Axboe wrote:
> On Thu, Oct 18 2007, Jeff Garzik wrote:
>> Mark Lord wrote:
>>> Mark Lord wrote:
>>>> Linus Torvalds wrote:
>>>>> On Wed, 17 Oct 2007, Mark Lord wrote:
>>>>>> It would be good to have something soon-ish.
>>>>>> This "dead at boot time" issue is impacting the general ability to test
>>>>>> patches against latest -git in time for the current merge window.
>>>>> In the meantime, does the patch I sent out help people?
>>>> Your patch from this posting http://lkml.org/lkml/2007/10/17/285
>>>> does not seem to make much difference here.
>>>>
>>>> It still crashes at exactly the same place.
>>> However, Jens's patch from that same thread:
>>>     http://lkml.org/lkml/2007/10/17/269
>>> ..allowed me to boot and post this followup message from -git12
>>> Jeff: try that one.
>> That's already in my upstream kernel, here.  commits
>> ba951841ceb7fa5b06ad48caa5270cc2ae17941e and 
>> a3bec5c5aea0da263111c4d8f8eabc1f8560d7bf.
>>
>> sata_mv and sata_nv still reliably poop themselves here, whereas its rock 
>> solid with 2.6.23.1.  Sounds like different issues from yours, as I see a 
>> stream of SATA errors on the bad kernels, errors which are often a symptom 
>> of something whacked in the DMA engine (misprogramming causes the silicon 
>> to generate bogus FIS's, which the device then chokes on)
> 
> Do you know if this poop involves the segment padding that sometimes
> goes on in libata?

Definitely not, in this case -- it's all ATA, nothing ATAPI.

It throws SError { Handshk } which then triggers the EH to reset the 
link, and so it goes, over and over :)  The same thing happens when I 
intentionally screw up the PRD tables.  Not much more data points than 
that, so far.

I'll try the SCSI_MAX_SG_SEGMENTS patch too, to see if that fixes things.

	Jeff




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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  1:19                                         ` David Miller
  2007-10-18  1:36                                           ` Linus Torvalds
@ 2007-10-18  8:21                                           ` Jens Axboe
  2007-10-18 11:55                                             ` David Miller
  2007-10-18 16:55                                             ` Linus Torvalds
  1 sibling, 2 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-18  8:21 UTC (permalink / raw)
  To: David Miller
  Cc: torvalds, fujita.tomonori, mingo, linux-kernel, jgarzik, alan,
	tomof

On Wed, Oct 17 2007, David Miller wrote:
> From: Linus Torvalds <torvalds@linux-foundation.org>
> Date: Wed, 17 Oct 2007 18:07:19 -0700 (PDT)
> 
> > sg_next() - as it stands now - never actually looks at the SG that its 
> > argument points to: it explicitly *only* looks at the next one.
> > 
> > That's the bug. If sg_next() looked at the actual *current* sg entry, we 
> > wouldn't have any issues to begin with, and that's what I'm arguing we 
> > should do in the longer run (where "longer run" is defined as "when Jens 
> > does it asap").
> 
> What the thing really wants is some kind of indication of state,
> without having to bloat up the scatterlist structure.
> 
> I believe that we have enough of a limited set of accessors to
> sg->page that we can more aggressively encode things in the lower
> bits.
> 
> I'm thinking of encoding the low two bits of sg->page as
> follows:
> 
> 1) bits == 0
> 
>    then the SG list is linear and sg_next() is sg++
> 
> 2) bits == 1
> 
>    the nest SG is an indirect chunk, sg_next() is
>    therefore something like:
> 
> 	next = *((struct scatterlist **)(sg + 1));
> 
> 3) bits == 2
> 
>    this is the last entry in the scatterlist, sg_next() is NULL
> 
> So for the cases of ARCH_HAS_SG_CHAIN not being set (ie. back
> compatible), we can do no bit encoding in page->flags and just do
> sg_next() == sg++, as is done now.
> 
> When doing SG chaining, in each non-linear chunk we have to allocate
> one more pointer past the end of the scatterlist array (instead of a
> full extra scatterlist entry for the indirect pointer encode).  Next,
> all sg->page accesses have to be guarded to clear the state bits
> out first.
> 
> I don't know, maybe it would work, and would make the loop termination
> issues easier to handle properly.

I like it. Basically the only real change is using bit 2 as a
termination point, so we avoid going beyond the end of the sgtable.
Here's a starting point, it actually booted for me in the first go
(boggle). Only x86 so far, archs will need to be converted. And lots
more drivers I'm sure, I only fixed up the ones that botched my compile.

So just consider this a directional patch.

diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index 5cdfab6..daaf636 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -302,7 +302,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
 #endif
 
 	for_each_sg(sg, s, nents, i) {
-		unsigned long addr = page_to_phys(s->page) + s->offset; 
+		unsigned long addr = page_to_phys(sg_page(s)) + s->offset; 
 		if (nonforced_iommu(dev, addr, s->length)) { 
 			addr = dma_map_area(dev, addr, s->length, dir);
 			if (addr == bad_dma_address) { 
@@ -397,7 +397,7 @@ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 	start_sg = sgmap = sg;
 	ps = NULL; /* shut up gcc */
 	for_each_sg(sg, s, nents, i) {
-		dma_addr_t addr = page_to_phys(s->page) + s->offset;
+		dma_addr_t addr = page_to_phys(sg_page(s)) + s->offset;
 		s->dma_address = addr;
 		BUG_ON(s->length == 0); 
 
diff --git a/arch/x86/kernel/pci-nommu_64.c b/arch/x86/kernel/pci-nommu_64.c
index e85d436..d64a4a5 100644
--- a/arch/x86/kernel/pci-nommu_64.c
+++ b/arch/x86/kernel/pci-nommu_64.c
@@ -62,8 +62,8 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
 	int i;
 
 	for_each_sg(sg, s, nents, i) {
-		BUG_ON(!s->page);
-		s->dma_address = virt_to_bus(page_address(s->page) +s->offset);
+		BUG_ON(!sg_page(s));
+		s->dma_address = virt_to_bus(page_address(sg_page(s)) +s->offset);
 		if (!check_addr("map_sg", hwdev, s->dma_address, s->length))
 			return 0;
 		s->dma_length = s->length;
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 3935469..d02783c 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -1354,10 +1354,11 @@ new_segment:
 			else
 				sg = sg_next(sg);
 
-			memset(sg, 0, sizeof(*sg));
-			sg->page = bvec->bv_page;
+			sg_set_page(sg, bvec->bv_page);
 			sg->length = nbytes;
 			sg->offset = bvec->bv_offset;
+			sg_dma_len(sg) = 0;
+			sg_dma_address(sg) = 0;
 			nsegs++;
 		}
 		bvprv = bvec;
diff --git a/crypto/digest.c b/crypto/digest.c
index e56de67..8871dec 100644
--- a/crypto/digest.c
+++ b/crypto/digest.c
@@ -41,7 +41,7 @@ static int update2(struct hash_desc *desc,
 		return 0;
 
 	for (;;) {
-		struct page *pg = sg->page;
+		struct page *pg = sg_page(sg);
 		unsigned int offset = sg->offset;
 		unsigned int l = sg->length;
 
diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c
index d6852c3..b9bbda0 100644
--- a/crypto/scatterwalk.c
+++ b/crypto/scatterwalk.c
@@ -54,7 +54,7 @@ static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
 	if (out) {
 		struct page *page;
 
-		page = walk->sg->page + ((walk->offset - 1) >> PAGE_SHIFT);
+		page = sg_page(walk->sg) + ((walk->offset - 1) >> PAGE_SHIFT);
 		flush_dcache_page(page);
 	}
 
diff --git a/crypto/scatterwalk.h b/crypto/scatterwalk.h
index 9c73e37..87ed681 100644
--- a/crypto/scatterwalk.h
+++ b/crypto/scatterwalk.h
@@ -22,13 +22,13 @@
 
 static inline struct scatterlist *scatterwalk_sg_next(struct scatterlist *sg)
 {
-	return (++sg)->length ? sg : (void *)sg->page;
+	return (++sg)->length ? sg : (void *) sg_page(sg);
 }
 
 static inline unsigned long scatterwalk_samebuf(struct scatter_walk *walk_in,
 						struct scatter_walk *walk_out)
 {
-	return !(((walk_in->sg->page - walk_out->sg->page) << PAGE_SHIFT) +
+	return !(((sg_page(walk_in->sg) - sg_page(walk_out->sg)) << PAGE_SHIFT) +
 		 (int)(walk_in->offset - walk_out->offset));
 }
 
@@ -60,7 +60,7 @@ static inline unsigned int scatterwalk_aligned(struct scatter_walk *walk,
 
 static inline struct page *scatterwalk_page(struct scatter_walk *walk)
 {
-	return walk->sg->page + (walk->offset >> PAGE_SHIFT);
+	return sg_page(walk->sg) + (walk->offset >> PAGE_SHIFT);
 }
 
 static inline void scatterwalk_unmap(void *vaddr, int out)
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index bbaa545..b1fa70a 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4296,7 +4296,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
 		sg_last(sg, qc->orig_n_elem)->length += qc->pad_len;
 		if (pad_buf) {
 			struct scatterlist *psg = &qc->pad_sgent;
-			void *addr = kmap_atomic(psg->page, KM_IRQ0);
+			void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
 			memcpy(addr + psg->offset, pad_buf, qc->pad_len);
 			kunmap_atomic(addr, KM_IRQ0);
 		}
@@ -4686,11 +4686,11 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
 		 * data in this function or read data in ata_sg_clean.
 		 */
 		offset = lsg->offset + lsg->length - qc->pad_len;
-		psg->page = nth_page(lsg->page, offset >> PAGE_SHIFT);
+		sg_set_page(psg, nth_page(sg_page(lsg), offset >> PAGE_SHIFT));
 		psg->offset = offset_in_page(offset);
 
 		if (qc->tf.flags & ATA_TFLAG_WRITE) {
-			void *addr = kmap_atomic(psg->page, KM_IRQ0);
+			void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
 			memcpy(pad_buf, addr + psg->offset, qc->pad_len);
 			kunmap_atomic(addr, KM_IRQ0);
 		}
@@ -4836,7 +4836,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
 	if (qc->curbytes == qc->nbytes - qc->sect_size)
 		ap->hsm_task_state = HSM_ST_LAST;
 
-	page = qc->cursg->page;
+	page = sg_page(qc->cursg);
 	offset = qc->cursg->offset + qc->cursg_ofs;
 
 	/* get the current page and offset */
@@ -4988,7 +4988,7 @@ next_sg:
 
 	sg = qc->cursg;
 
-	page = sg->page;
+	page = sg_page(sg);
 	offset = sg->offset + qc->cursg_ofs;
 
 	/* get the current page and offset */
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 9fbb39c..5b758b9 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1544,7 +1544,7 @@ static unsigned int ata_scsi_rbuf_get(struct scsi_cmnd *cmd, u8 **buf_out)
 	struct scatterlist *sg = scsi_sglist(cmd);
 
 	if (sg) {
-		buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+		buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 		buflen = sg->length;
 	} else {
 		buf = NULL;
diff --git a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c
index 45d6055..25e113b 100644
--- a/drivers/ieee1394/dma.c
+++ b/drivers/ieee1394/dma.c
@@ -111,7 +111,7 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes,
 		unsigned long va =
 		    (unsigned long)dma->kvirt + (i << PAGE_SHIFT);
 
-		dma->sglist[i].page = vmalloc_to_page((void *)va);
+		sg_set_page(&dma->sglist[i], vmalloc_to_page((void *)va));
 		dma->sglist[i].length = PAGE_SIZE;
 	}
 
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 72ee4c9..46cae5a 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -625,7 +625,7 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
 	scsi_for_each_sg(scp, sg, scp->use_sg, k) {
 		if (active) {
 			kaddr = (unsigned char *)
-				kmap_atomic(sg->page, KM_USER0);
+				kmap_atomic(sg_page(sg), KM_USER0);
 			if (NULL == kaddr)
 				return (DID_ERROR << 16);
 			kaddr_off = (unsigned char *)kaddr + sg->offset;
@@ -672,7 +672,7 @@ static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
 	sg = scsi_sglist(scp);
 	req_len = fin = 0;
 	for (k = 0; k < scp->use_sg; ++k, sg = sg_next(sg)) {
-		kaddr = (unsigned char *)kmap_atomic(sg->page, KM_USER0);
+		kaddr = (unsigned char *)kmap_atomic(sg_page(sg), KM_USER0);
 		if (NULL == kaddr)
 			return -1;
 		kaddr_off = (unsigned char *)kaddr + sg->offset;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index aac8a02..4ee32e5 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -295,7 +295,7 @@ static int scsi_req_map_sg(struct request *rq, struct scatterlist *sgl,
 	int i, err, nr_vecs = 0;
 
 	for_each_sg(sgl, sg, nsegs, i) {
-		page = sg->page;
+		page = sg_page(sg);
 		off = sg->offset;
 		len = sg->length;
  		data_len += len;
@@ -781,6 +781,13 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
 			sg_chain(prev, SCSI_MAX_SG_SEGMENTS, sgl);
 
 		/*
+		 * if we have nothing left, mark the last segment as
+		 * end-of-list
+		 */
+		if (!left)
+			sg_mark_end(sgl, this);
+
+		/*
 		 * don't allow subsequent mempool allocs to sleep, it would
 		 * violate the mempool principle.
 		 */
@@ -2353,7 +2360,7 @@ void *scsi_kmap_atomic_sg(struct scatterlist *sgl, int sg_count,
 	*offset = *offset - len_complete + sg->offset;
 
 	/* Assumption: contiguous pages can be accessed as "page + i" */
-	page = nth_page(sg->page, (*offset >> PAGE_SHIFT));
+	page = nth_page(sg_page(sg), (*offset >> PAGE_SHIFT));
 	*offset &= ~PAGE_MASK;
 
 	/* Bytes in this sg-entry from *offset to the end of the page */
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 7238b2d..cc19710 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1169,7 +1169,7 @@ sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type)
 		len = vma->vm_end - sa;
 		len = (len < sg->length) ? len : sg->length;
 		if (offset < len) {
-			page = virt_to_page(page_address(sg->page) + offset);
+			page = virt_to_page(page_address(sg_page(sg)) + offset);
 			get_page(page);	/* increment page count */
 			break;
 		}
@@ -1717,13 +1717,13 @@ st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,
 		   goto out_unlock; */
         }
 
-	sgl[0].page = pages[0];
+	sg_set_page(sgl, pages[0]);
 	sgl[0].offset = uaddr & ~PAGE_MASK;
 	if (nr_pages > 1) {
 		sgl[0].length = PAGE_SIZE - sgl[0].offset;
 		count -= sgl[0].length;
 		for (i=1; i < nr_pages ; i++) {
-			sgl[i].page = pages[i]; 
+			sg_set_page(&sgl[i], pages[i]);
 			sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
 			count -= PAGE_SIZE;
 		}
@@ -1754,7 +1754,7 @@ st_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_pages,
 	int i;
 
 	for (i=0; i < nr_pages; i++) {
-		struct page *page = sgl[i].page;
+		struct page *page = sg_page(&sgl[i]);
 
 		if (dirtied)
 			SetPageDirty(page);
@@ -1854,7 +1854,7 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
 				scatter_elem_sz_prev = ret_sz;
 			}
 		}
-		sg->page = p;
+		sg_set_page(sg, p);
 		sg->length = (ret_sz > num) ? num : ret_sz;
 
 		SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k=%d, num=%d, "
@@ -1907,14 +1907,14 @@ sg_write_xfer(Sg_request * srp)
 		onum = 1;
 
 	ksglen = sg->length;
-	p = page_address(sg->page);
+	p = page_address(sg_page(sg));
 	for (j = 0, k = 0; j < onum; ++j) {
 		res = sg_u_iovec(hp, iovec_count, j, 1, &usglen, &up);
 		if (res)
 			return res;
 
 		for (; p; sg = sg_next(sg), ksglen = sg->length,
-		     p = page_address(sg->page)) {
+		     p = page_address(sg_page(sg))) {
 			if (usglen <= 0)
 				break;
 			if (ksglen > usglen) {
@@ -1991,12 +1991,12 @@ sg_remove_scat(Sg_scatter_hold * schp)
 		} else {
 			int k;
 
-			for (k = 0; (k < schp->k_use_sg) && sg->page;
+			for (k = 0; (k < schp->k_use_sg) && sg_page(sg);
 			     ++k, sg = sg_next(sg)) {
 				SCSI_LOG_TIMEOUT(5, printk(
 				    "sg_remove_scat: k=%d, pg=0x%p, len=%d\n",
-				    k, sg->page, sg->length));
-				sg_page_free(sg->page, sg->length);
+				    k, sg_page(sg), sg->length));
+				sg_page_free(sg_page(sg), sg->length);
 			}
 		}
 		kfree(schp->buffer);
@@ -2038,7 +2038,7 @@ sg_read_xfer(Sg_request * srp)
 	} else
 		onum = 1;
 
-	p = page_address(sg->page);
+	p = page_address(sg_page(sg));
 	ksglen = sg->length;
 	for (j = 0, k = 0; j < onum; ++j) {
 		res = sg_u_iovec(hp, iovec_count, j, 0, &usglen, &up);
@@ -2046,7 +2046,7 @@ sg_read_xfer(Sg_request * srp)
 			return res;
 
 		for (; p; sg = sg_next(sg), ksglen = sg->length,
-		     p = page_address(sg->page)) {
+		     p = page_address(sg_page(sg))) {
 			if (usglen <= 0)
 				break;
 			if (ksglen > usglen) {
@@ -2092,15 +2092,15 @@ sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer)
 	if ((!outp) || (num_read_xfer <= 0))
 		return 0;
 
-	for (k = 0; (k < schp->k_use_sg) && sg->page; ++k, sg = sg_next(sg)) {
+	for (k = 0; (k < schp->k_use_sg) && sg_page(sg); ++k, sg = sg_next(sg)) {
 		num = sg->length;
 		if (num > num_read_xfer) {
-			if (__copy_to_user(outp, page_address(sg->page),
+			if (__copy_to_user(outp, page_address(sg_page(sg)),
 					   num_read_xfer))
 				return -EFAULT;
 			break;
 		} else {
-			if (__copy_to_user(outp, page_address(sg->page),
+			if (__copy_to_user(outp, page_address(sg_page(sg)),
 					   num))
 				return -EFAULT;
 			num_read_xfer -= num;
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index c021af3..98c455d 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -443,7 +443,7 @@ int usb_sg_init (
 		} else {
 			/* hc may use _only_ transfer_buffer */
 			io->urbs [i]->transfer_buffer =
-				page_address (sg [i].page) + sg [i].offset;
+				page_address(sg_page(&sg[i])) + sg [i].offset;
 			len = sg [i].length;
 		}
 
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c
index cc8f7c5..889622b 100644
--- a/drivers/usb/storage/protocol.c
+++ b/drivers/usb/storage/protocol.c
@@ -195,7 +195,7 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
 		 * the *offset and *index values for the next loop. */
 		cnt = 0;
 		while (cnt < buflen) {
-			struct page *page = sg->page +
+			struct page *page = sg_page(sg) +
 					((sg->offset + *offset) >> PAGE_SHIFT);
 			unsigned int poff =
 					(sg->offset + *offset) & (PAGE_SIZE-1);
diff --git a/include/asm-x86/dma-mapping_32.h b/include/asm-x86/dma-mapping_32.h
index 6a2d26c..e0d38d8 100644
--- a/include/asm-x86/dma-mapping_32.h
+++ b/include/asm-x86/dma-mapping_32.h
@@ -45,9 +45,9 @@ dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
 	WARN_ON(nents == 0 || sglist[0].length == 0);
 
 	for_each_sg(sglist, sg, nents, i) {
-		BUG_ON(!sg->page);
+		BUG_ON(!sg_page(sg));
 
-		sg->dma_address = page_to_phys(sg->page) + sg->offset;
+		sg->dma_address = page_to_phys(sg_page(sg)) + sg->offset;
 	}
 
 	flush_write_buffers();
diff --git a/include/asm-x86/scatterlist_32.h b/include/asm-x86/scatterlist_32.h
index bd5164a..0e7d997 100644
--- a/include/asm-x86/scatterlist_32.h
+++ b/include/asm-x86/scatterlist_32.h
@@ -4,7 +4,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page		*page;
+#ifdef CONFIG_DEBUG_SG
+    unsigned long	sg_magic;
+#endif
+    unsigned long	page_link;
     unsigned int	offset;
     dma_addr_t		dma_address;
     unsigned int	length;
diff --git a/include/asm-x86/scatterlist_64.h b/include/asm-x86/scatterlist_64.h
index ef3986b..1847c72 100644
--- a/include/asm-x86/scatterlist_64.h
+++ b/include/asm-x86/scatterlist_64.h
@@ -4,7 +4,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page		*page;
+#ifdef CONFIG_DEBUG_SG
+    unsigned long	sg_magic;
+#endif
+    unsigned long	page_link;
     unsigned int	offset;
     unsigned int	length;
     dma_addr_t		dma_address;
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index 2dc7464..cbc2b57 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -5,10 +5,24 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 
+#define SG_MAGIC	0x87654321
+
+static inline void sg_set_page(struct scatterlist *sg, struct page *page)
+{
+	unsigned long page_link = sg->page_link & 0x3;
+
+	sg->page_link = page_link | (unsigned long) page;
+}
+
+#define sg_page(sg)	((struct page *) ((sg)->page_link & ~0x3))
+
 static inline void sg_set_buf(struct scatterlist *sg, const void *buf,
 			      unsigned int buflen)
 {
-	sg->page = virt_to_page(buf);
+#ifdef CONFIG_DEBUG_SG
+	sg->sg_magic = SG_MAGIC;
+#endif
+	sg_set_page(sg, virt_to_page(buf));
 	sg->offset = offset_in_page(buf);
 	sg->length = buflen;
 }
@@ -25,9 +39,9 @@ static inline void sg_init_one(struct scatterlist *sg, const void *buf,
  * a valid sg entry, or whether it points to the start of a new scatterlist.
  * Those low bits are there for everyone! (thanks mason :-)
  */
-#define sg_is_chain(sg)		((unsigned long) (sg)->page & 0x01)
-#define sg_chain_ptr(sg)	\
-	((struct scatterlist *) ((unsigned long) (sg)->page & ~0x01))
+#define sg_is_chain(sg)		((sg)->page_link & 0x01)
+#define sg_is_last(sg)		((sg)->page_link & 0x02)
+#define sg_chain_ptr(sg)	((struct scatterlist *) ((sg)->page_link & ~0x01))
 
 /**
  * sg_next - return the next scatterlist entry in a list
@@ -43,10 +57,15 @@ static inline void sg_init_one(struct scatterlist *sg, const void *buf,
  */
 static inline struct scatterlist *sg_next(struct scatterlist *sg)
 {
-	sg++;
-
-	if (unlikely(sg_is_chain(sg)))
+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(sg->sg_magic != SG_MAGIC);
+#endif
+	if (sg_is_last(sg))
+		sg = NULL;
+	else if (sg_is_chain(sg))
 		sg = sg_chain_ptr(sg);
+	else
+		sg++;
 
 	return sg;
 }
@@ -83,6 +102,9 @@ static inline struct scatterlist *sg_last(struct scatterlist *sgl,
 		ret = sg;
 
 #endif
+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(sgl[0].sg_magic != SG_MAGIC);
+#endif
 	return ret;
 }
 
@@ -101,7 +123,41 @@ static inline void sg_chain(struct scatterlist *prv, unsigned int prv_nents,
 #ifndef ARCH_HAS_SG_CHAIN
 	BUG();
 #endif
-	prv[prv_nents - 1].page = (struct page *) ((unsigned long) sgl | 0x01);
+	prv[prv_nents - 1].page_link = (unsigned long) sgl | 0x01;
+}
+
+/**
+ * sg_mark_end - Mark the end of the scatterlist
+ * @sgl:	Scatterlist
+ * @nents:	Number of entries in sgl
+ *
+ * Marks the last entry as the termination point for sg_next()
+ *
+ */
+static inline void sg_mark_end(struct scatterlist *sgl, unsigned int nents)
+{
+	sgl[nents - 1].page_link = 0x02;
+}
+
+/**
+ * sg_init_table - Initialize an sg table
+ * @sgl:	Scatterlist
+ * @nents:	Number of entries in sgl
+ *
+ * Marks the last entry as the termination point for sg_next()
+ *
+ */
+static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents)
+{
+	memset(sgl, 0, sizeof(*sgl) * nents);
+	sg_mark_end(sgl, nents);
+#ifdef CONFIG_DEBUG_SG
+	{
+		int i;
+		for (i = 0; i < nents; i++)
+			sgl[i].sg_magic = SG_MAGIC;
+	}
+#endif
 }
 
 #endif /* _LINUX_SCATTERLIST_H */
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 7d16e64..c17aace 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -389,6 +389,17 @@ config DEBUG_LIST
 
 	  If unsure, say N.
 
+config DEBUG_SG
+	bool "Debug SG table operations"
+	depends on DEBUG_KERNEL
+	help
+	  Enable this to turn on checks on scatter-gather tables. This can
+	  help find problems with drivers that do not properly initialize
+	  their sg tables. Runtime overhead is very small, but it does
+	  increase an sg entry by sizeof(unsigned long).
+
+	  If unsure, say N.
+
 config FRAME_POINTER
 	bool "Compile the kernel with frame pointers"
 	depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML || S390 || AVR32 || SUPERH || BFIN)
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 752fd95..e58909e 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -35,7 +35,7 @@
 #define OFFSET(val,align) ((unsigned long)	\
 	                   ( (val) & ( (align) - 1)))
 
-#define SG_ENT_VIRT_ADDRESS(sg)	(page_address((sg)->page) + (sg)->offset)
+#define SG_ENT_VIRT_ADDRESS(sg)	(page_address(sg_page((sg)) + (sg)->offset))
 #define SG_ENT_PHYS_ADDRESS(sg)	virt_to_bus(SG_ENT_VIRT_ADDRESS(sg))
 
 /*
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 70d9b5d..4e2c84f 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2045,7 +2045,7 @@ skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
 	if (copy > 0) {
 		if (copy > len)
 			copy = len;
-		sg[elt].page = virt_to_page(skb->data + offset);
+		sg_set_page(&sg[elt], virt_to_page(skb->data + offset));
 		sg[elt].offset = (unsigned long)(skb->data + offset) % PAGE_SIZE;
 		sg[elt].length = copy;
 		elt++;
@@ -2065,7 +2065,7 @@ skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
 
 			if (copy > len)
 				copy = len;
-			sg[elt].page = frag->page;
+			sg_set_page(&sg[elt], frag->page);
 			sg[elt].offset = frag->page_offset+offset-start;
 			sg[elt].length = copy;
 			elt++;
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
index 8d18245..1a77877 100644
--- a/net/ieee80211/ieee80211_crypt_wep.c
+++ b/net/ieee80211/ieee80211_crypt_wep.c
@@ -170,7 +170,8 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	icv[3] = crc >> 24;
 
 	crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
-	sg.page = virt_to_page(pos);
+	sg_init_table(&sg, 1);
+	sg_set_page(&sg, virt_to_page(pos));
 	sg.offset = offset_in_page(pos);
 	sg.length = len + 4;
 	return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
@@ -212,7 +213,8 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	plen = skb->len - hdr_len - 8;
 
 	crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
-	sg.page = virt_to_page(pos);
+	sg_init_table(&sg, 1);
+	sg_set_page(&sg, virt_to_page(pos));
 	sg.offset = offset_in_page(pos);
 	sg.length = plen + 4;
 	if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 6675261..9857961 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -138,7 +138,8 @@ void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
 	*icv = cpu_to_le32(~crc32_le(~0, data, data_len));
 
 	crypto_blkcipher_setkey(tfm, rc4key, klen);
-	sg.page = virt_to_page(data);
+	sg_init_table(&sg, 1);
+	sg_set_page(&sg, virt_to_page(data));
 	sg.offset = offset_in_page(data);
 	sg.length = data_len + WEP_ICV_LEN;
 	crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length);
@@ -204,7 +205,8 @@ int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
 	__le32 crc;
 
 	crypto_blkcipher_setkey(tfm, rc4key, klen);
-	sg.page = virt_to_page(data);
+	sg_init_table(&sg, 1);
+	sg_set_page(&sg, virt_to_page(data));
 	sg.offset = offset_in_page(data);
 	sg.length = data_len + WEP_ICV_LEN;
 	crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length);
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index bfb6a29..32be431 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -197,9 +197,9 @@ encryptor(struct scatterlist *sg, void *data)
 		int i = (page_pos + outbuf->page_base) >> PAGE_CACHE_SHIFT;
 		in_page = desc->pages[i];
 	} else {
-		in_page = sg->page;
+		in_page = sg_page(sg);
 	}
-	desc->infrags[desc->fragno].page = in_page;
+	sg_set_page(&desc->infrags[desc->fragno], in_page);
 	desc->fragno++;
 	desc->fraglen += sg->length;
 	desc->pos += sg->length;
@@ -215,11 +215,11 @@ encryptor(struct scatterlist *sg, void *data)
 	if (ret)
 		return ret;
 	if (fraglen) {
-		desc->outfrags[0].page = sg->page;
+		sg_set_page(&desc->outfrags[0], sg_page(sg));
 		desc->outfrags[0].offset = sg->offset + sg->length - fraglen;
 		desc->outfrags[0].length = fraglen;
 		desc->infrags[0] = desc->outfrags[0];
-		desc->infrags[0].page = in_page;
+		sg_set_page(&desc->infrags[0], in_page);
 		desc->fragno = 1;
 		desc->fraglen = fraglen;
 	} else {
@@ -287,7 +287,7 @@ decryptor(struct scatterlist *sg, void *data)
 	if (ret)
 		return ret;
 	if (fraglen) {
-		desc->frags[0].page = sg->page;
+		sg_set_page(&desc->frags[0], sg_page(sg));
 		desc->frags[0].offset = sg->offset + sg->length - fraglen;
 		desc->frags[0].length = fraglen;
 		desc->fragno = 1;
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 6a59180..3d1f7cd 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -1059,7 +1059,7 @@ xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len,
 		do {
 			if (thislen > page_len)
 				thislen = page_len;
-			sg->page = buf->pages[i];
+			sg_set_page(sg, buf->pages[i]);
 			sg->offset = page_offset;
 			sg->length = thislen;
 			ret = actor(sg, data);
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index 5ced62c..fb2220a 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -552,7 +552,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
 		if (copy > len)
 			copy = len;
 
-		sg.page = virt_to_page(skb->data + offset);
+		sg_set_page(&sg, virt_to_page(skb->data + offset));
 		sg.offset = (unsigned long)(skb->data + offset) % PAGE_SIZE;
 		sg.length = copy;
 
@@ -577,7 +577,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
 			if (copy > len)
 				copy = len;
 
-			sg.page = frag->page;
+			sg_set_page(&sg, frag->page);
 			sg.offset = frag->page_offset + offset-start;
 			sg.length = copy;
 

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  7:07                         ` Ingo Molnar
  2007-10-18  7:10                           ` Jens Axboe
@ 2007-10-18  8:22                           ` Jeff Garzik
  2007-10-18  8:32                             ` Jens Axboe
  2007-10-18 11:03                           ` Ingo Molnar
  2 siblings, 1 reply; 151+ messages in thread
From: Jeff Garzik @ 2007-10-18  8:22 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Ingo Molnar, Linus Torvalds, linux-kernel, Alan Cox

Ingo Molnar wrote:
> * Jens Axboe <jens.axboe@oracle.com> wrote:
> 
>> --- a/drivers/scsi/scsi_lib.c
>> +++ b/drivers/scsi/scsi_lib.c
>> @@ -39,7 +39,7 @@
>>   * (unless chaining is used). Should ideally fit inside a single page, to
>>   * avoid a higher order allocation.
>>   */
>> -#define SCSI_MAX_SG_SEGMENTS	128
>> +#define SCSI_MAX_SG_SEGMENTS	129
> 
> this one finally made the trick and it's booting fine now, without any 
> crashes!

Alas, this didn't help me here.  I did manage to capture the error 
messages this time, and in the two machines I'm actively testing on, 
sata_mv is the driver that's dying in both cases.  Machine A 
additionally has sata_nv, which is working.  Machine B additionally has 
ata_piix, which is working.  So in both cases, its sata_mv that is 
throwing SError complaints:

> ata7.00: exception Emask 0x0 SAct 0x0 SErr 0x400000 action 0x6 frozen
> ata7.00: edma_err 0x04000080, EDMA self-disable
> ata7: SError: { Handshk }
> ata7.00: cmd ca/00:08:c7:40:00/00:00:00:00:00/e0 tag 0 cdb 0x0 data 4096 out
>          res 50/00:00:ce:40:00/00:00:00:00:00/e0 Emask 0x100 (unknown error)
> ata7.00: status: { DRDY }
> ata7: hard resetting link
> ata7: SATA link up 1.5 Gbps (SStatus 113 SControl 300)

Still digging...  this behavior showed up after libata changes went in, 
FWIW.

	Jeff



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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  8:22                           ` Jeff Garzik
@ 2007-10-18  8:32                             ` Jens Axboe
  2007-10-18  8:38                               ` Jeff Garzik
                                                 ` (2 more replies)
  0 siblings, 3 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-18  8:32 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Ingo Molnar, Linus Torvalds, linux-kernel, Alan Cox

On Thu, Oct 18 2007, Jeff Garzik wrote:
> Ingo Molnar wrote:
>> * Jens Axboe <jens.axboe@oracle.com> wrote:
>>> --- a/drivers/scsi/scsi_lib.c
>>> +++ b/drivers/scsi/scsi_lib.c
>>> @@ -39,7 +39,7 @@
>>>   * (unless chaining is used). Should ideally fit inside a single page, 
>>> to
>>>   * avoid a higher order allocation.
>>>   */
>>> -#define SCSI_MAX_SG_SEGMENTS	128
>>> +#define SCSI_MAX_SG_SEGMENTS	129
>> this one finally made the trick and it's booting fine now, without any 
>> crashes!
>
> Alas, this didn't help me here.  I did manage to capture the error messages 
> this time, and in the two machines I'm actively testing on, sata_mv is the 
> driver that's dying in both cases.  Machine A additionally has sata_nv, 
> which is working.  Machine B additionally has ata_piix, which is working.  
> So in both cases, its sata_mv that is throwing SError complaints:

Theory - ata_sg_is_last() isn't returning true for the last entry. Can
you double check that it correcly marks the last entry in mv_fill_sg()?
Alternatively, just try this patch.


diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 4df8311..b858183 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -1139,6 +1139,7 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
 	struct mv_port_priv *pp = qc->ap->private_data;
 	struct scatterlist *sg;
 	struct mv_sg *mv_sg;
+	int end_marked = 0;
 
 	mv_sg = pp->sg_tbl;
 	ata_for_each_sg(sg, qc) {
@@ -1159,13 +1160,15 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
 			sg_len -= len;
 			addr += len;
 
-			if (!sg_len && ata_sg_is_last(sg, qc))
+			if (!sg_len && ata_sg_is_last(sg, qc)) {
 				mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
+				end_marked++;
+			}
 
 			mv_sg++;
 		}
-
 	}
+	BUG_ON(end_marked != 1);
 }
 
 static inline void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last)

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  8:32                             ` Jens Axboe
@ 2007-10-18  8:38                               ` Jeff Garzik
  2007-10-18  8:51                                 ` Jeff Garzik
  2007-10-18  9:01                               ` Jeff Garzik
  2007-10-20 11:55                               ` Torsten Kaiser
  2 siblings, 1 reply; 151+ messages in thread
From: Jeff Garzik @ 2007-10-18  8:38 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Ingo Molnar, Linus Torvalds, linux-kernel, Alan Cox

Jens Axboe wrote:
> On Thu, Oct 18 2007, Jeff Garzik wrote:
>> Ingo Molnar wrote:
>>> * Jens Axboe <jens.axboe@oracle.com> wrote:
>>>> --- a/drivers/scsi/scsi_lib.c
>>>> +++ b/drivers/scsi/scsi_lib.c
>>>> @@ -39,7 +39,7 @@
>>>>   * (unless chaining is used). Should ideally fit inside a single page, 
>>>> to
>>>>   * avoid a higher order allocation.
>>>>   */
>>>> -#define SCSI_MAX_SG_SEGMENTS	128
>>>> +#define SCSI_MAX_SG_SEGMENTS	129
>>> this one finally made the trick and it's booting fine now, without any 
>>> crashes!
>> Alas, this didn't help me here.  I did manage to capture the error messages 
>> this time, and in the two machines I'm actively testing on, sata_mv is the 
>> driver that's dying in both cases.  Machine A additionally has sata_nv, 
>> which is working.  Machine B additionally has ata_piix, which is working.  
>> So in both cases, its sata_mv that is throwing SError complaints:
> 
> Theory - ata_sg_is_last() isn't returning true for the last entry. Can
> you double check that it correcly marks the last entry in mv_fill_sg()?
> Alternatively, just try this patch.

Will check in a few minutes, after my current test:  I noticed that 
sg_tablesize in sata_mv is not LIBATA_MAX_PRD.  This is expected 
behavior, but I wonder if that difference -- most notably being smaller 
than SCSI_MAX_SG_SEGMENTS -- would trigger any latent bugs.

Anyway, we will both have answers momentarily...

	Jeff




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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  8:38                               ` Jeff Garzik
@ 2007-10-18  8:51                                 ` Jeff Garzik
  0 siblings, 0 replies; 151+ messages in thread
From: Jeff Garzik @ 2007-10-18  8:51 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Ingo Molnar, Linus Torvalds, linux-kernel, Alan Cox

Jeff Garzik wrote:
> I noticed that 
> sg_tablesize in sata_mv is not LIBATA_MAX_PRD.  This is expected 
> behavior, but I wonder if that difference -- most notably being smaller 
> than SCSI_MAX_SG_SEGMENTS -- would trigger any latent bugs.

Another sata_mv difference from the rest: the chip does not support 
ATAPI, so we never care about qc->pad

	Jeff



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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  8:32                             ` Jens Axboe
  2007-10-18  8:38                               ` Jeff Garzik
@ 2007-10-18  9:01                               ` Jeff Garzik
       [not found]                                 ` <bd58e4af0710180210tcc0d31ep9d05a0f2e9d6df29@mail.gmail.com>
  2007-10-18  9:17                                 ` Jens Axboe
  2007-10-20 11:55                               ` Torsten Kaiser
  2 siblings, 2 replies; 151+ messages in thread
From: Jeff Garzik @ 2007-10-18  9:01 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Ingo Molnar, Linus Torvalds, linux-kernel, Alan Cox

Jens Axboe wrote:
> index 4df8311..b858183 100644
> --- a/drivers/ata/sata_mv.c
> +++ b/drivers/ata/sata_mv.c
> @@ -1139,6 +1139,7 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
>  	struct mv_port_priv *pp = qc->ap->private_data;
>  	struct scatterlist *sg;
>  	struct mv_sg *mv_sg;
> +	int end_marked = 0;
>  
>  	mv_sg = pp->sg_tbl;
>  	ata_for_each_sg(sg, qc) {
> @@ -1159,13 +1160,15 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
>  			sg_len -= len;
>  			addr += len;
>  
> -			if (!sg_len && ata_sg_is_last(sg, qc))
> +			if (!sg_len && ata_sg_is_last(sg, qc)) {
>  				mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
> +				end_marked++;
> +			}
>  
>  			mv_sg++;
>  		}
> -
>  	}
> +	BUG_ON(end_marked != 1);


Your BUG_ON() does indeed trip, here.

Its surprising that other folks don't explode, considering that 
mv_fill_sg() intentionally mirrors the logic in ata_fill_sg().

	Jeff



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

* Re: [bug] ata subsystem related crash with latest -git
       [not found]                                 ` <bd58e4af0710180210tcc0d31ep9d05a0f2e9d6df29@mail.gmail.com>
@ 2007-10-18  9:14                                   ` Jeff Garzik
  0 siblings, 0 replies; 151+ messages in thread
From: Jeff Garzik @ 2007-10-18  9:14 UTC (permalink / raw)
  To: Benny Halevy
  Cc: Jens Axboe, Ingo Molnar, Linus Torvalds, linux-kernel, Alan Cox

Benny Halevy wrote:
> 
> 
> On 10/18/07, *Jeff Garzik* <jeff@garzik.org <mailto:jeff@garzik.org>> wrote:
> 
>     Jens Axboe wrote:
>      > index 4df8311..b858183 100644
>      > --- a/drivers/ata/sata_mv.c
>      > +++ b/drivers/ata/sata_mv.c
>      > @@ -1139,6 +1139,7 @@ static void mv_fill_sg(struct
>     ata_queued_cmd *qc)
>      >       struct mv_port_priv *pp = qc->ap->private_data;
>      >       struct scatterlist *sg;
>      >       struct mv_sg *mv_sg;
>      > +     int end_marked = 0;
>      >
>      >       mv_sg = pp->sg_tbl;
>      >       ata_for_each_sg(sg, qc) {
>      > @@ -1159,13 +1160,15 @@ static void mv_fill_sg(struct
>     ata_queued_cmd *qc)
>      >                       sg_len -= len;
>      >                       addr += len;
>      >
>      > -                     if (!sg_len && ata_sg_is_last(sg, qc))
>      > +                     if (!sg_len && ata_sg_is_last(sg, qc)) { 
> 
> 
> I'm not sure, but shouldn't that be || rather than &&?

sg_len is zero at the end of each scatterlist entry, so we need to test 
the additional ata_sg_is_last() condition to determine if we are really 
at the end of the PRD table.

	Jeff




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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  9:01                               ` Jeff Garzik
       [not found]                                 ` <bd58e4af0710180210tcc0d31ep9d05a0f2e9d6df29@mail.gmail.com>
@ 2007-10-18  9:17                                 ` Jens Axboe
  2007-10-18  9:32                                   ` Jeff Garzik
  1 sibling, 1 reply; 151+ messages in thread
From: Jens Axboe @ 2007-10-18  9:17 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Ingo Molnar, Linus Torvalds, linux-kernel, Alan Cox

On Thu, Oct 18 2007, Jeff Garzik wrote:
> Jens Axboe wrote:
>> index 4df8311..b858183 100644
>> --- a/drivers/ata/sata_mv.c
>> +++ b/drivers/ata/sata_mv.c
>> @@ -1139,6 +1139,7 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
>>  	struct mv_port_priv *pp = qc->ap->private_data;
>>  	struct scatterlist *sg;
>>  	struct mv_sg *mv_sg;
>> +	int end_marked = 0;
>>   	mv_sg = pp->sg_tbl;
>>  	ata_for_each_sg(sg, qc) {
>> @@ -1159,13 +1160,15 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
>>  			sg_len -= len;
>>  			addr += len;
>>  -			if (!sg_len && ata_sg_is_last(sg, qc))
>> +			if (!sg_len && ata_sg_is_last(sg, qc)) {
>>  				mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
>> +				end_marked++;
>> +			}
>>   			mv_sg++;
>>  		}
>> -
>>  	}
>> +	BUG_ON(end_marked != 1);
>
>
> Your BUG_ON() does indeed trip, here.
>
> Its surprising that other folks don't explode, considering that 
> mv_fill_sg() intentionally mirrors the logic in ata_fill_sg().

The sata_mv construct looks a bit odd. Does this work? That last
end_mv_sg test should always be true, just being paranoid...

diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 4df8311..5397eea 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -1138,8 +1138,9 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
 {
 	struct mv_port_priv *pp = qc->ap->private_data;
 	struct scatterlist *sg;
-	struct mv_sg *mv_sg;
+	struct mv_sg *mv_sg, *end_mv_sg;
 
+	end_mv_sg = NULL;
 	mv_sg = pp->sg_tbl;
 	ata_for_each_sg(sg, qc) {
 		dma_addr_t addr = sg_dma_address(sg);
@@ -1158,14 +1159,12 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
 
 			sg_len -= len;
 			addr += len;
-
-			if (!sg_len && ata_sg_is_last(sg, qc))
-				mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
-
+			end_mv_sg = mv_sg;
 			mv_sg++;
 		}
-
 	}
+	if (end_mv_sg)
+		end_mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
 }
 
 static inline void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last)

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  9:17                                 ` Jens Axboe
@ 2007-10-18  9:32                                   ` Jeff Garzik
  2007-10-18  9:41                                     ` Jens Axboe
  0 siblings, 1 reply; 151+ messages in thread
From: Jeff Garzik @ 2007-10-18  9:32 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Ingo Molnar, Linus Torvalds, linux-kernel, Alan Cox

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

Jens Axboe wrote:
> The sata_mv construct looks a bit odd. Does this work? That last

The sata_mv construct worked just fine before sg chaining :)


> end_mv_sg test should always be true, just being paranoid...
> 
> diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
> index 4df8311..5397eea 100644
> --- a/drivers/ata/sata_mv.c
> +++ b/drivers/ata/sata_mv.c
> @@ -1138,8 +1138,9 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
>  {
>  	struct mv_port_priv *pp = qc->ap->private_data;
>  	struct scatterlist *sg;
> -	struct mv_sg *mv_sg;
> +	struct mv_sg *mv_sg, *end_mv_sg;
>  
> +	end_mv_sg = NULL;
>  	mv_sg = pp->sg_tbl;
>  	ata_for_each_sg(sg, qc) {
>  		dma_addr_t addr = sg_dma_address(sg);
> @@ -1158,14 +1159,12 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
>  
>  			sg_len -= len;
>  			addr += len;
> -
> -			if (!sg_len && ata_sg_is_last(sg, qc))
> -				mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
> -
> +			end_mv_sg = mv_sg;
>  			mv_sg++;
>  		}
> -
>  	}
> +	if (end_mv_sg)
> +		end_mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
>  }
>  

I'm testing a similar patch based on ata_fill_sg()'s method, which 
basically does something similar to what you've done here (see 
attached).  I had noticed that ata_fill_sg() did not call ata_sg_is_last().

If this fixes the problem, I think the best solution would be to delete 
ata_sg_is_last().  In the few users that exist, we should be able to 
eliminate the test programmatically as you and ata_fill_sg() have done 
-- thereby eliminating a branch per loop in a hotpath.

Off to test the attached...  if that doesn't work I'll try your version, 
though there shouldn't be much difference.

	Jeff



[-- Attachment #2: patch.sata_mv-fill-sg --]
[-- Type: text/plain, Size: 2997 bytes --]

diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 4df8311..42b5a9e 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -421,7 +421,6 @@ static void mv_error_handler(struct ata_port *ap);
 static void mv_post_int_cmd(struct ata_queued_cmd *qc);
 static void mv_eh_freeze(struct ata_port *ap);
 static void mv_eh_thaw(struct ata_port *ap);
-static int mv_slave_config(struct scsi_device *sdev);
 static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 
 static void mv5_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio,
@@ -459,7 +458,7 @@ static struct scsi_host_template mv5_sht = {
 	.use_clustering		= 1,
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= MV_DMA_BOUNDARY,
-	.slave_configure	= mv_slave_config,
+	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
 };
@@ -477,7 +476,7 @@ static struct scsi_host_template mv6_sht = {
 	.use_clustering		= 1,
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= MV_DMA_BOUNDARY,
-	.slave_configure	= mv_slave_config,
+	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
 };
@@ -756,17 +755,6 @@ static void mv_irq_clear(struct ata_port *ap)
 {
 }
 
-static int mv_slave_config(struct scsi_device *sdev)
-{
-	int rc = ata_scsi_slave_config(sdev);
-	if (rc)
-		return rc;
-
-	blk_queue_max_phys_segments(sdev->request_queue, MV_MAX_SG_CT / 2);
-
-	return 0;	/* scsi layer doesn't check return value, sigh */
-}
-
 static void mv_set_edma_ptrs(void __iomem *port_mmio,
 			     struct mv_host_priv *hpriv,
 			     struct mv_port_priv *pp)
@@ -1138,34 +1126,35 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
 {
 	struct mv_port_priv *pp = qc->ap->private_data;
 	struct scatterlist *sg;
-	struct mv_sg *mv_sg;
+	struct mv_sg *mv_sg = pp->sg_tbl;
+	unsigned int idx = 0;
 
-	mv_sg = pp->sg_tbl;
 	ata_for_each_sg(sg, qc) {
-		dma_addr_t addr = sg_dma_address(sg);
-		u32 sg_len = sg_dma_len(sg);
+		u64 addr;
+		u32 offset, sg_len, len;
+
+		addr = sg_dma_address(sg);
+		sg_len = sg_dma_len(sg);
 
 		while (sg_len) {
-			u32 offset = addr & 0xffff;
-			u32 len = sg_len;
+			offset = addr & 0xffff;
+			len = sg_len;
 
 			if ((offset + sg_len > 0x10000))
 				len = 0x10000 - offset;
 
-			mv_sg->addr = cpu_to_le32(addr & 0xffffffff);
-			mv_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16);
-			mv_sg->flags_size = cpu_to_le32(len & 0xffff);
+			mv_sg[idx].addr = cpu_to_le32(addr & 0xffffffff);
+			mv_sg[idx].addr_hi = cpu_to_le32(addr >> 32);
+			mv_sg[idx].flags_size = cpu_to_le32(len & 0xffff);
 
+			idx++;
 			sg_len -= len;
 			addr += len;
-
-			if (!sg_len && ata_sg_is_last(sg, qc))
-				mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
-
-			mv_sg++;
 		}
-
 	}
+
+	if (idx)
+		mv_sg[idx - 1].flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
 }
 
 static inline void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last)

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  9:32                                   ` Jeff Garzik
@ 2007-10-18  9:41                                     ` Jens Axboe
  2007-10-18 10:04                                       ` Jeff Garzik
  0 siblings, 1 reply; 151+ messages in thread
From: Jens Axboe @ 2007-10-18  9:41 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Ingo Molnar, Linus Torvalds, linux-kernel, Alan Cox

On Thu, Oct 18 2007, Jeff Garzik wrote:
> Jens Axboe wrote:
>> The sata_mv construct looks a bit odd. Does this work? That last
>
> The sata_mv construct worked just fine before sg chaining :)

Yes I know, but I'm trying to works towards getting rid of sg_last() and
ata_sg_is_last() anyway :-)

>> end_mv_sg test should always be true, just being paranoid...
>> diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
>> index 4df8311..5397eea 100644
>> --- a/drivers/ata/sata_mv.c
>> +++ b/drivers/ata/sata_mv.c
>> @@ -1138,8 +1138,9 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
>>  {
>>  	struct mv_port_priv *pp = qc->ap->private_data;
>>  	struct scatterlist *sg;
>> -	struct mv_sg *mv_sg;
>> +	struct mv_sg *mv_sg, *end_mv_sg;
>>  +	end_mv_sg = NULL;
>>  	mv_sg = pp->sg_tbl;
>>  	ata_for_each_sg(sg, qc) {
>>  		dma_addr_t addr = sg_dma_address(sg);
>> @@ -1158,14 +1159,12 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
>>   			sg_len -= len;
>>  			addr += len;
>> -
>> -			if (!sg_len && ata_sg_is_last(sg, qc))
>> -				mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
>> -
>> +			end_mv_sg = mv_sg;
>>  			mv_sg++;
>>  		}
>> -
>>  	}
>> +	if (end_mv_sg)
>> +		end_mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
>>  }
>>  
>
> I'm testing a similar patch based on ata_fill_sg()'s method, which 
> basically does something similar to what you've done here (see attached).  
> I had noticed that ata_fill_sg() did not call ata_sg_is_last().
>
> If this fixes the problem, I think the best solution would be to delete 
> ata_sg_is_last().  In the few users that exist, we should be able to 
> eliminate the test programmatically as you and ata_fill_sg() have done -- 
> thereby eliminating a branch per loop in a hotpath.
>
> Off to test the attached...  if that doesn't work I'll try your version, 
> though there shouldn't be much difference.

That should work as well. WRT ata_sg_is_last(), if we go ahead with my
recent sg chaining updates, we can keep the test as it would be a single
conditional and not require any looping.

Let me know when you have tested this!

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  9:41                                     ` Jens Axboe
@ 2007-10-18 10:04                                       ` Jeff Garzik
  2007-10-18 10:10                                         ` Jens Axboe
  0 siblings, 1 reply; 151+ messages in thread
From: Jeff Garzik @ 2007-10-18 10:04 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Ingo Molnar, Linus Torvalds, linux-kernel, Alan Cox

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

Jens Axboe wrote:
> That should work as well. WRT ata_sg_is_last(), if we go ahead with my
> recent sg chaining updates, we can keep the test as it would be a single
> conditional and not require any looping.
> 
> Let me know when you have tested this!

The patch I attached to the last email got both sata_mv test boxes 
working reliably (so far).

I worked up a patch that kills ata_sg_is_last() (plus the 
max_phys_segments sata_mv fix), see attached.  I'm thinking this is what 
I like to see in upstream.

Of course, this doesn't explain why ata_sg_is_last() was broken, but 
since it's working _and_ slightly more efficient, I don't really care :)

	Jeff



[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 5649 bytes --]

diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c
index 8d1b03d..199f7e1 100644
--- a/drivers/ata/pdc_adma.c
+++ b/drivers/ata/pdc_adma.c
@@ -318,7 +318,7 @@ static int adma_fill_sg(struct ata_queued_cmd *qc)
 	struct scatterlist *sg;
 	struct ata_port *ap = qc->ap;
 	struct adma_port_priv *pp = ap->private_data;
-	u8  *buf = pp->pkt;
+	u8  *buf = pp->pkt, *last_buf = NULL;
 	int i = (2 + buf[3]) * 8;
 	u8 pFLAGS = pORD | ((qc->tf.flags & ATA_TFLAG_WRITE) ? pDIRO : 0);
 
@@ -334,8 +334,7 @@ static int adma_fill_sg(struct ata_queued_cmd *qc)
 		*(__le32 *)(buf + i) = cpu_to_le32(len);
 		i += 4;
 
-		if (ata_sg_is_last(sg, qc))
-			pFLAGS |= pEND;
+		last_buf = &buf[i];
 		buf[i++] = pFLAGS;
 		buf[i++] = qc->dev->dma_mode & 0xf;
 		buf[i++] = 0;	/* pPKLW */
@@ -348,6 +347,10 @@ static int adma_fill_sg(struct ata_queued_cmd *qc)
 		VPRINTK("PRD[%u] = (0x%lX, 0x%X)\n", i/4,
 					(unsigned long)addr, len);
 	}
+
+	if (likely(last_buf))
+		*last_buf |= pEND;
+
 	return i;
 }
 
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 4df8311..7f1b13e 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -421,7 +421,6 @@ static void mv_error_handler(struct ata_port *ap);
 static void mv_post_int_cmd(struct ata_queued_cmd *qc);
 static void mv_eh_freeze(struct ata_port *ap);
 static void mv_eh_thaw(struct ata_port *ap);
-static int mv_slave_config(struct scsi_device *sdev);
 static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 
 static void mv5_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio,
@@ -459,7 +458,7 @@ static struct scsi_host_template mv5_sht = {
 	.use_clustering		= 1,
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= MV_DMA_BOUNDARY,
-	.slave_configure	= mv_slave_config,
+	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
 };
@@ -477,7 +476,7 @@ static struct scsi_host_template mv6_sht = {
 	.use_clustering		= 1,
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= MV_DMA_BOUNDARY,
-	.slave_configure	= mv_slave_config,
+	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
 };
@@ -756,17 +755,6 @@ static void mv_irq_clear(struct ata_port *ap)
 {
 }
 
-static int mv_slave_config(struct scsi_device *sdev)
-{
-	int rc = ata_scsi_slave_config(sdev);
-	if (rc)
-		return rc;
-
-	blk_queue_max_phys_segments(sdev->request_queue, MV_MAX_SG_CT / 2);
-
-	return 0;	/* scsi layer doesn't check return value, sigh */
-}
-
 static void mv_set_edma_ptrs(void __iomem *port_mmio,
 			     struct mv_host_priv *hpriv,
 			     struct mv_port_priv *pp)
@@ -1138,7 +1126,7 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
 {
 	struct mv_port_priv *pp = qc->ap->private_data;
 	struct scatterlist *sg;
-	struct mv_sg *mv_sg;
+	struct mv_sg *mv_sg, *last_sg = NULL;
 
 	mv_sg = pp->sg_tbl;
 	ata_for_each_sg(sg, qc) {
@@ -1159,13 +1147,13 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
 			sg_len -= len;
 			addr += len;
 
-			if (!sg_len && ata_sg_is_last(sg, qc))
-				mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
-
+			last_sg = mv_sg;
 			mv_sg++;
 		}
-
 	}
+
+	if (likely(last_sg))
+		last_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
 }
 
 static inline void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last)
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index b061927..26ebffc 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -796,16 +796,19 @@ static inline void sil24_fill_sg(struct ata_queued_cmd *qc,
 				 struct sil24_sge *sge)
 {
 	struct scatterlist *sg;
+	struct sil24_sge *last_sge = NULL;
 
 	ata_for_each_sg(sg, qc) {
 		sge->addr = cpu_to_le64(sg_dma_address(sg));
 		sge->cnt = cpu_to_le32(sg_dma_len(sg));
-		if (ata_sg_is_last(sg, qc))
-			sge->flags = cpu_to_le32(SGE_TRM);
-		else
-			sge->flags = 0;
+		sge->flags = 0;
+
+		last_sge = sge;
 		sge++;
 	}
+
+	if (likely(last_sge))
+		last_sge->flags = cpu_to_le32(SGE_TRM);
 }
 
 static int sil24_qc_defer(struct ata_queued_cmd *qc)
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index b41dfb5..c316a0b 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -5134,6 +5134,7 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd,
 	u32 ioadl_flags = 0;
 	struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
 	struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
+	struct ipr_ioadl_desc *last_ioadl = NULL;
 	int len = qc->nbytes + qc->pad_len;
 	struct scatterlist *sg;
 
@@ -5156,11 +5157,13 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd,
 	ata_for_each_sg(sg, qc) {
 		ioadl->flags_and_data_len = cpu_to_be32(ioadl_flags | sg_dma_len(sg));
 		ioadl->address = cpu_to_be32(sg_dma_address(sg));
-		if (ata_sg_is_last(sg, qc))
-			ioadl->flags_and_data_len |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);
-		else
-			ioadl++;
+
+		last_ioadl = ioadl;
+		ioadl++;
 	}
+
+	if (likely(last_ioadl))
+		last_ioadl->flags_and_data_len |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);
 }
 
 /**
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 377e6d4..bc3b6fc 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -1037,18 +1037,6 @@ extern void ata_port_pbar_desc(struct ata_port *ap, int bar, ssize_t offset,
 /*
  * qc helpers
  */
-static inline int
-ata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc)
-{
-	if (sg == &qc->pad_sgent)
-		return 1;
-	if (qc->pad_len)
-		return 0;
-	if (qc->n_iter == qc->n_elem)
-		return 1;
-	return 0;
-}
-
 static inline struct scatterlist *
 ata_qc_first_sg(struct ata_queued_cmd *qc)
 {

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 10:04                                       ` Jeff Garzik
@ 2007-10-18 10:10                                         ` Jens Axboe
  2007-10-18 10:13                                           ` Ingo Molnar
  2007-10-18 10:42                                           ` [PATCH] " Jeff Garzik
  0 siblings, 2 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-18 10:10 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Ingo Molnar, Linus Torvalds, linux-kernel, Alan Cox

On Thu, Oct 18 2007, Jeff Garzik wrote:
> Jens Axboe wrote:
>> That should work as well. WRT ata_sg_is_last(), if we go ahead with my
>> recent sg chaining updates, we can keep the test as it would be a single
>> conditional and not require any looping.
>> Let me know when you have tested this!
>
> The patch I attached to the last email got both sata_mv test boxes working 
> reliably (so far).
>
> I worked up a patch that kills ata_sg_is_last() (plus the max_phys_segments 
> sata_mv fix), see attached.  I'm thinking this is what I like to see in 
> upstream.

Great!

> Of course, this doesn't explain why ata_sg_is_last() was broken, but since 
> it's working _and_ slightly more efficient, I don't really care :)

Tomo and I agreed to kill sg_last() a few days ago anyways, so this is
perfectly fine with me.

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 10:10                                         ` Jens Axboe
@ 2007-10-18 10:13                                           ` Ingo Molnar
  2007-10-18 10:16                                             ` Jens Axboe
  2007-10-18 10:42                                           ` [PATCH] " Jeff Garzik
  1 sibling, 1 reply; 151+ messages in thread
From: Ingo Molnar @ 2007-10-18 10:13 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Jeff Garzik, Linus Torvalds, linux-kernel, Alan Cox


* Jens Axboe <jens.axboe@oracle.com> wrote:

> > Of course, this doesn't explain why ata_sg_is_last() was broken, but 
> > since it's working _and_ slightly more efficient, I don't really 
> > care :)
> 
> Tomo and I agreed to kill sg_last() a few days ago anyways, so this is 
> perfectly fine with me.

it would still be nice to figure out exactly why it was broken.

	Ingo

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 10:13                                           ` Ingo Molnar
@ 2007-10-18 10:16                                             ` Jens Axboe
  2007-10-18 10:17                                               ` Jens Axboe
  0 siblings, 1 reply; 151+ messages in thread
From: Jens Axboe @ 2007-10-18 10:16 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Jeff Garzik, Linus Torvalds, linux-kernel, Alan Cox

On Thu, Oct 18 2007, Ingo Molnar wrote:
> 
> * Jens Axboe <jens.axboe@oracle.com> wrote:
> 
> > > Of course, this doesn't explain why ata_sg_is_last() was broken, but 
> > > since it's working _and_ slightly more efficient, I don't really 
> > > care :)
> > 
> > Tomo and I agreed to kill sg_last() a few days ago anyways, so this is 
> > perfectly fine with me.
> 
> it would still be nice to figure out exactly why it was broken.

It would always be nice. For this case I don't think it's very
interesting, if we pursue the improved sg iteration setup.

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 10:16                                             ` Jens Axboe
@ 2007-10-18 10:17                                               ` Jens Axboe
  2007-10-18 10:49                                                 ` Ingo Molnar
  0 siblings, 1 reply; 151+ messages in thread
From: Jens Axboe @ 2007-10-18 10:17 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Jeff Garzik, Linus Torvalds, linux-kernel, Alan Cox

On Thu, Oct 18 2007, Jens Axboe wrote:
> On Thu, Oct 18 2007, Ingo Molnar wrote:
> > 
> > * Jens Axboe <jens.axboe@oracle.com> wrote:
> > 
> > > > Of course, this doesn't explain why ata_sg_is_last() was broken, but 
> > > > since it's working _and_ slightly more efficient, I don't really 
> > > > care :)
> > > 
> > > Tomo and I agreed to kill sg_last() a few days ago anyways, so this is 
> > > perfectly fine with me.
> > 
> > it would still be nice to figure out exactly why it was broken.
> 
> It would always be nice. For this case I don't think it's very
> interesting, if we pursue the improved sg iteration setup.

BTW, I think it's pretty clear that ata_sg_is_last() is broken. It's
likely a one-off in the n_iter test.

-- 
Jens Axboe


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

* [PATCH] Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 10:10                                         ` Jens Axboe
  2007-10-18 10:13                                           ` Ingo Molnar
@ 2007-10-18 10:42                                           ` Jeff Garzik
  2007-10-18 10:54                                             ` Ingo Molnar
  2007-10-18 14:52                                             ` Olof Johansson
  1 sibling, 2 replies; 151+ messages in thread
From: Jeff Garzik @ 2007-10-18 10:42 UTC (permalink / raw)
  To: Jens Axboe
  Cc: Ingo Molnar, Linus Torvalds, linux-kernel, Alan Cox, Tejun Heo,
	Brian King

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

Jens Axboe wrote:
> On Thu, Oct 18 2007, Jeff Garzik wrote:
>> Jens Axboe wrote:
>>> That should work as well. WRT ata_sg_is_last(), if we go ahead with my
>>> recent sg chaining updates, we can keep the test as it would be a single
>>> conditional and not require any looping.
>>> Let me know when you have tested this!
>> The patch I attached to the last email got both sata_mv test boxes working 
>> reliably (so far).
>>
>> I worked up a patch that kills ata_sg_is_last() (plus the max_phys_segments 
>> sata_mv fix), see attached.  I'm thinking this is what I like to see in 
>> upstream.
> 
> Great!
> 
>> Of course, this doesn't explain why ata_sg_is_last() was broken, but since 
>> it's working _and_ slightly more efficient, I don't really care :)
> 
> Tomo and I agreed to kill sg_last() a few days ago anyways, so this is
> perfectly fine with me.

Yep, the [attached] patch that kills ata_sg_is_last() is working here on 
both machines that were previously croaking.

It would be nice to get pdc_adma, sata_sil24 and ipr it-works test done, 
but IMO the patch is pretty straightforward and should be OK.

	Jeff



[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 5649 bytes --]

diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c
index 8d1b03d..199f7e1 100644
--- a/drivers/ata/pdc_adma.c
+++ b/drivers/ata/pdc_adma.c
@@ -318,7 +318,7 @@ static int adma_fill_sg(struct ata_queued_cmd *qc)
 	struct scatterlist *sg;
 	struct ata_port *ap = qc->ap;
 	struct adma_port_priv *pp = ap->private_data;
-	u8  *buf = pp->pkt;
+	u8  *buf = pp->pkt, *last_buf = NULL;
 	int i = (2 + buf[3]) * 8;
 	u8 pFLAGS = pORD | ((qc->tf.flags & ATA_TFLAG_WRITE) ? pDIRO : 0);
 
@@ -334,8 +334,7 @@ static int adma_fill_sg(struct ata_queued_cmd *qc)
 		*(__le32 *)(buf + i) = cpu_to_le32(len);
 		i += 4;
 
-		if (ata_sg_is_last(sg, qc))
-			pFLAGS |= pEND;
+		last_buf = &buf[i];
 		buf[i++] = pFLAGS;
 		buf[i++] = qc->dev->dma_mode & 0xf;
 		buf[i++] = 0;	/* pPKLW */
@@ -348,6 +347,10 @@ static int adma_fill_sg(struct ata_queued_cmd *qc)
 		VPRINTK("PRD[%u] = (0x%lX, 0x%X)\n", i/4,
 					(unsigned long)addr, len);
 	}
+
+	if (likely(last_buf))
+		*last_buf |= pEND;
+
 	return i;
 }
 
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 4df8311..7f1b13e 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -421,7 +421,6 @@ static void mv_error_handler(struct ata_port *ap);
 static void mv_post_int_cmd(struct ata_queued_cmd *qc);
 static void mv_eh_freeze(struct ata_port *ap);
 static void mv_eh_thaw(struct ata_port *ap);
-static int mv_slave_config(struct scsi_device *sdev);
 static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 
 static void mv5_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio,
@@ -459,7 +458,7 @@ static struct scsi_host_template mv5_sht = {
 	.use_clustering		= 1,
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= MV_DMA_BOUNDARY,
-	.slave_configure	= mv_slave_config,
+	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
 };
@@ -477,7 +476,7 @@ static struct scsi_host_template mv6_sht = {
 	.use_clustering		= 1,
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= MV_DMA_BOUNDARY,
-	.slave_configure	= mv_slave_config,
+	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
 };
@@ -756,17 +755,6 @@ static void mv_irq_clear(struct ata_port *ap)
 {
 }
 
-static int mv_slave_config(struct scsi_device *sdev)
-{
-	int rc = ata_scsi_slave_config(sdev);
-	if (rc)
-		return rc;
-
-	blk_queue_max_phys_segments(sdev->request_queue, MV_MAX_SG_CT / 2);
-
-	return 0;	/* scsi layer doesn't check return value, sigh */
-}
-
 static void mv_set_edma_ptrs(void __iomem *port_mmio,
 			     struct mv_host_priv *hpriv,
 			     struct mv_port_priv *pp)
@@ -1138,7 +1126,7 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
 {
 	struct mv_port_priv *pp = qc->ap->private_data;
 	struct scatterlist *sg;
-	struct mv_sg *mv_sg;
+	struct mv_sg *mv_sg, *last_sg = NULL;
 
 	mv_sg = pp->sg_tbl;
 	ata_for_each_sg(sg, qc) {
@@ -1159,13 +1147,13 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
 			sg_len -= len;
 			addr += len;
 
-			if (!sg_len && ata_sg_is_last(sg, qc))
-				mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
-
+			last_sg = mv_sg;
 			mv_sg++;
 		}
-
 	}
+
+	if (likely(last_sg))
+		last_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
 }
 
 static inline void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last)
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index b061927..26ebffc 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -796,16 +796,19 @@ static inline void sil24_fill_sg(struct ata_queued_cmd *qc,
 				 struct sil24_sge *sge)
 {
 	struct scatterlist *sg;
+	struct sil24_sge *last_sge = NULL;
 
 	ata_for_each_sg(sg, qc) {
 		sge->addr = cpu_to_le64(sg_dma_address(sg));
 		sge->cnt = cpu_to_le32(sg_dma_len(sg));
-		if (ata_sg_is_last(sg, qc))
-			sge->flags = cpu_to_le32(SGE_TRM);
-		else
-			sge->flags = 0;
+		sge->flags = 0;
+
+		last_sge = sge;
 		sge++;
 	}
+
+	if (likely(last_sge))
+		last_sge->flags = cpu_to_le32(SGE_TRM);
 }
 
 static int sil24_qc_defer(struct ata_queued_cmd *qc)
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index b41dfb5..c316a0b 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -5134,6 +5134,7 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd,
 	u32 ioadl_flags = 0;
 	struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
 	struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
+	struct ipr_ioadl_desc *last_ioadl = NULL;
 	int len = qc->nbytes + qc->pad_len;
 	struct scatterlist *sg;
 
@@ -5156,11 +5157,13 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd,
 	ata_for_each_sg(sg, qc) {
 		ioadl->flags_and_data_len = cpu_to_be32(ioadl_flags | sg_dma_len(sg));
 		ioadl->address = cpu_to_be32(sg_dma_address(sg));
-		if (ata_sg_is_last(sg, qc))
-			ioadl->flags_and_data_len |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);
-		else
-			ioadl++;
+
+		last_ioadl = ioadl;
+		ioadl++;
 	}
+
+	if (likely(last_ioadl))
+		last_ioadl->flags_and_data_len |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);
 }
 
 /**
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 377e6d4..bc3b6fc 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -1037,18 +1037,6 @@ extern void ata_port_pbar_desc(struct ata_port *ap, int bar, ssize_t offset,
 /*
  * qc helpers
  */
-static inline int
-ata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc)
-{
-	if (sg == &qc->pad_sgent)
-		return 1;
-	if (qc->pad_len)
-		return 0;
-	if (qc->n_iter == qc->n_elem)
-		return 1;
-	return 0;
-}
-
 static inline struct scatterlist *
 ata_qc_first_sg(struct ata_queued_cmd *qc)
 {

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 10:17                                               ` Jens Axboe
@ 2007-10-18 10:49                                                 ` Ingo Molnar
  2007-10-18 10:50                                                   ` Jeff Garzik
  2007-10-18 10:56                                                   ` Jens Axboe
  0 siblings, 2 replies; 151+ messages in thread
From: Ingo Molnar @ 2007-10-18 10:49 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Jeff Garzik, Linus Torvalds, linux-kernel, Alan Cox


* Jens Axboe <jens.axboe@oracle.com> wrote:

> > It would always be nice. For this case I don't think it's very 
> > interesting, if we pursue the improved sg iteration setup.
> 
> BTW, I think it's pretty clear that ata_sg_is_last() is broken. It's 
> likely a one-off in the n_iter test.

fixing that would be a -stable candidate, as a potential data corruptor 
- or is it more benign?

	Ingo

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 10:49                                                 ` Ingo Molnar
@ 2007-10-18 10:50                                                   ` Jeff Garzik
  2007-10-18 10:56                                                   ` Jens Axboe
  1 sibling, 0 replies; 151+ messages in thread
From: Jeff Garzik @ 2007-10-18 10:50 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Jens Axboe, Linus Torvalds, linux-kernel, Alan Cox

Ingo Molnar wrote:
> * Jens Axboe <jens.axboe@oracle.com> wrote:
> 
>>> It would always be nice. For this case I don't think it's very 
>>> interesting, if we pursue the improved sg iteration setup.
>> BTW, I think it's pretty clear that ata_sg_is_last() is broken. It's 
>> likely a one-off in the n_iter test.
> 
> fixing that would be a -stable candidate, as a potential data corruptor 
> - or is it more benign?

It is confirmed working prior to the sg-chaining stuff, so 2.6.23.1 is OK...

	Jeff




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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-17 18:22             ` Jens Axboe
@ 2007-10-18 10:52               ` Benny Halevy
  2007-10-18 10:55                 ` Jens Axboe
  0 siblings, 1 reply; 151+ messages in thread
From: Benny Halevy @ 2007-10-18 10:52 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Linus Torvalds, Ingo Molnar, linux-kernel, Andrew Morton

On Oct. 17, 2007, 20:22 +0200, Jens Axboe <jens.axboe@oracle.com> wrote:
> On Wed, Oct 17 2007, Linus Torvalds wrote:
>>
>> On Wed, 17 Oct 2007, Jens Axboe wrote:
>>>> So avoiding the "sg_next()" on the last entry is pointless. 
>>> Yeah, I didn't quite understand why if sg was valid, why dereferencing
>>> *(sg + 1)->page would crap out :/
>> Actually, I take that back. If 'sg' is the last entry in a *non*linked 
>> scatter-gather list (ie we don't use the last entry as a link, we actually 
>> use it as a real SG entry), then "sg_next(sg)" will indeed access past the 
>> end of the whole allocated array, and will access one past the end.
>>
>> And with page-alloc debugging, that *will* blow up.
>>
>> So I think your change to use "sg_next()" only when you actually need a 
>> next pointer is the correct one after all.
> 
> Thanks, so I'm not totally crazy :-)
> 
> Can you just pull:
> 
>   git://git.kernel.dk/data/git/linux-2.6-block.git for-linus
> 
> then so we get those two pieces correct? Then the remaining issue seems
> to be a new one that is biting Ingo elsewhere, at least we'll all be on
> the same page then.
> 

Jens, for_each_sg still calls sg_next on the last entry which will
dereference a possibly bogus sg->page (for the sg_is_chain(sg)
condition in sg_next) if the last entry is the last one on the page
of unchained entry and sg+1 falls over into an uninitialized page.

How about the following?
(untested yet.
 sg.c included here as an example for usage out of scatterlist.h)

diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index 2dc7464..3a27e03 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -30,7 +30,7 @@ static inline void sg_init_one(struct scatterlist *sg, const void *buf,
        ((struct scatterlist *) ((unsigned long) (sg)->page & ~0x01))

 /**
- * sg_next - return the next scatterlist entry in a list
+ * sg_next_unsafe - return the next scatterlist entry in a list
  * @sg:                The current sg entry
  *
  * Usually the next entry will be @sg@ + 1, but if this sg element is part
@@ -41,7 +41,7 @@ static inline void sg_init_one(struct scatterlist *sg, const void *buf,
  * the current entry, this function will NOT return NULL for an end-of-list.
  *
  */
-static inline struct scatterlist *sg_next(struct scatterlist *sg)
+static inline struct scatterlist *sg_next_unsafe(struct scatterlist *sg)
 {
        sg++;

@@ -51,11 +51,27 @@ static inline struct scatterlist *sg_next(struct scatterlist *sg)
        return sg;
 }

+/**
+ * sg_next - return the next scatterlist entry in a list
+ * @sg:                The current sg entry
+ * @next:      Index of next sg entry
+ * @nr:                Number of sg entries in the list
+ *
+ * Note that the caller must ensure that there are further entries after
+ * the current entry, this function will NOT return NULL for an end-of-list.
+ *
+ */
+static inline struct scatterlist *sg_next(struct scatterlist *sg,
+                                          int next, int nr)
+{
+       return next < nr ? sg_next_unsafe(sg) : NULL;
+}
+
 /*
  * Loop over each sg element, following the pointer to a new list if necessary
  */
 #define for_each_sg(sglist, sg, nr, __i)       \
-       for (__i = 0, sg = (sglist); __i < (nr); __i++, sg = sg_next(sg))
+       for (__i = 0, sg = (sglist); sg; sg = sg_next(sg, ++__i, nr))

 /**
  * sg_last - return the last scatterlist entry in a list
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 7238b2d..57cc1dd 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1165,7 +1165,7 @@ sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type)
        sg = rsv_schp->buffer;
        sa = vma->vm_start;
        for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
-            ++k, sg = sg_next(sg)) {
+            sg = sg_next(sg, ++k, rsv_schp->k_use_sg)) {
                len = vma->vm_end - sa;
                len = (len < sg->length) ? len : sg->length;
                if (offset < len) {
@@ -1209,7 +1209,7 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma)
        sa = vma->vm_start;
        sg = rsv_schp->buffer;
        for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
-            ++k, sg = sg_next(sg)) {
+            sg = sg_next(sg, ++k, rsv_schp->k_use_sg)) {
                len = vma->vm_end - sa;
                len = (len < sg->length) ? len : sg->length;
                sa += len;
@@ -1840,7 +1840,7 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
        }
        for (k = 0, sg = schp->buffer, rem_sz = blk_size;
             (rem_sz > 0) && (k < mx_sc_elems);
-            ++k, rem_sz -= ret_sz, sg = sg_next(sg)) {
+            rem_sz -= ret_sz, sg = sg_next(sg, ++k, mx_sc_elems)) {

                num = (rem_sz > scatter_elem_sz_prev) ?
                      scatter_elem_sz_prev : rem_sz;
@@ -1913,7 +1913,7 @@ sg_write_xfer(Sg_request * srp)
                if (res)
                        return res;

-               for (; p; sg = sg_next(sg), ksglen = sg->length,
+               for (; p; sg = sg_next_unsafe(sg), ksglen = sg->length,
                     p = page_address(sg->page)) {
                        if (usglen <= 0)
                                break;
@@ -1991,8 +1991,8 @@ sg_remove_scat(Sg_scatter_hold * schp)
                } else {
                        int k;

-                       for (k = 0; (k < schp->k_use_sg) && sg->page;
-                            ++k, sg = sg_next(sg)) {
+                       for (k = 0; sg && sg->page;
+                            sg = sg_next(sg, ++k, schp->k_use_sg)) {
                                SCSI_LOG_TIMEOUT(5, printk(
                                    "sg_remove_scat: k=%d, pg=0x%p, len=%d\n",
                                    k, sg->page, sg->length));
@@ -2045,7 +2045,7 @@ sg_read_xfer(Sg_request * srp)
                if (res)
                        return res;

-               for (; p; sg = sg_next(sg), ksglen = sg->length,
+               for (; p; sg = sg_next_unsafe(sg), ksglen = sg->length,
                     p = page_address(sg->page)) {
                        if (usglen <= 0)
                                break;
@@ -2092,7 +2092,7 @@ sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer)
        if ((!outp) || (num_read_xfer <= 0))
                return 0;

-       for (k = 0; (k < schp->k_use_sg) && sg->page; ++k, sg = sg_next(sg)) {
+       for (k = 0; sg && sg->page; sg = sg_next(sg, ++k, schp->k_use_sg)) {
                num = sg->length;
                if (num > num_read_xfer) {
                        if (__copy_to_user(outp, page_address(sg->page),
@@ -2142,7 +2142,7 @@ sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size)
        SCSI_LOG_TIMEOUT(4, printk("sg_link_reserve: size=%d\n", size));
        rem = size;

-       for (k = 0; k < rsv_schp->k_use_sg; ++k, sg = sg_next(sg)) {
+       for (k = 0; sg; sg = sg_next(sg, ++k, rsv_schp->k_use_sg)) {
                num = sg->length;
                if (rem <= num) {
                        sfp->save_scat_len = num;


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

* Re: [PATCH] Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 10:42                                           ` [PATCH] " Jeff Garzik
@ 2007-10-18 10:54                                             ` Ingo Molnar
  2007-10-18 11:02                                               ` Jeff Garzik
  2007-10-18 14:52                                             ` Olof Johansson
  1 sibling, 1 reply; 151+ messages in thread
From: Ingo Molnar @ 2007-10-18 10:54 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: Jens Axboe, Linus Torvalds, linux-kernel, Alan Cox, Tejun Heo,
	Brian King


* Jeff Garzik <jeff@garzik.org> wrote:

> >Tomo and I agreed to kill sg_last() a few days ago anyways, so this 
> >is perfectly fine with me.
> 
> Yep, the [attached] patch that kills ata_sg_is_last() is working here 
> on both machines that were previously croaking.
> 
> It would be nice to get pdc_adma, sata_sil24 and ipr it-works test 
> done, but IMO the patch is pretty straightforward and should be OK.

just a quick question: i have Jens's workarounds applied right now (see 
patch below). Am i now crash/corruption-safe, or do i need your patch 
too? And once your patch [and the other sg_*() patches] are upstream i 
dont need the workaround anymore, correct?

	Ingo

---
 block/ll_rw_blk.c         |    2 +-
 drivers/ata/libata-core.c |    2 +-
 drivers/scsi/scsi_lib.c   |    2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

Index: linux/block/ll_rw_blk.c
===================================================================
--- linux.orig/block/ll_rw_blk.c
+++ linux/block/ll_rw_blk.c
@@ -631,7 +631,7 @@ void blk_queue_max_phys_segments(struct 
 		printk("%s: set to minimum %d\n", __FUNCTION__, max_segments);
 	}
 
-	q->max_phys_segments = max_segments;
+	q->max_phys_segments = max_segments - 1;
 }
 
 EXPORT_SYMBOL(blk_queue_max_phys_segments);
Index: linux/drivers/ata/libata-core.c
===================================================================
--- linux.orig/drivers/ata/libata-core.c
+++ linux/drivers/ata/libata-core.c
@@ -4664,7 +4664,7 @@ static int ata_sg_setup(struct ata_queue
 {
 	struct ata_port *ap = qc->ap;
 	struct scatterlist *sg = qc->__sg;
-	struct scatterlist *lsg = sg_last(qc->__sg, qc->n_elem);
+	struct scatterlist *lsg = &qc->__sg[qc->n_elem - 1];
 	int n_elem, pre_n_elem, dir, trim_sg = 0;
 
 	VPRINTK("ENTER, ata%u\n", ap->print_id);
Index: linux/drivers/scsi/scsi_lib.c
===================================================================
--- linux.orig/drivers/scsi/scsi_lib.c
+++ linux/drivers/scsi/scsi_lib.c
@@ -39,7 +39,7 @@
  * (unless chaining is used). Should ideally fit inside a single page, to
  * avoid a higher order allocation.
  */
-#define SCSI_MAX_SG_SEGMENTS	128
+#define SCSI_MAX_SG_SEGMENTS	129
 
 struct scsi_host_sg_pool {
 	size_t		size;

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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-18 10:52               ` Benny Halevy
@ 2007-10-18 10:55                 ` Jens Axboe
  2007-10-18 12:03                   ` David Miller
  0 siblings, 1 reply; 151+ messages in thread
From: Jens Axboe @ 2007-10-18 10:55 UTC (permalink / raw)
  To: Benny Halevy; +Cc: Linus Torvalds, Ingo Molnar, linux-kernel, Andrew Morton

On Thu, Oct 18 2007, Benny Halevy wrote:
> On Oct. 17, 2007, 20:22 +0200, Jens Axboe <jens.axboe@oracle.com> wrote:
> > On Wed, Oct 17 2007, Linus Torvalds wrote:
> >>
> >> On Wed, 17 Oct 2007, Jens Axboe wrote:
> >>>> So avoiding the "sg_next()" on the last entry is pointless. 
> >>> Yeah, I didn't quite understand why if sg was valid, why dereferencing
> >>> *(sg + 1)->page would crap out :/
> >> Actually, I take that back. If 'sg' is the last entry in a *non*linked 
> >> scatter-gather list (ie we don't use the last entry as a link, we actually 
> >> use it as a real SG entry), then "sg_next(sg)" will indeed access past the 
> >> end of the whole allocated array, and will access one past the end.
> >>
> >> And with page-alloc debugging, that *will* blow up.
> >>
> >> So I think your change to use "sg_next()" only when you actually need a 
> >> next pointer is the correct one after all.
> > 
> > Thanks, so I'm not totally crazy :-)
> > 
> > Can you just pull:
> > 
> >   git://git.kernel.dk/data/git/linux-2.6-block.git for-linus
> > 
> > then so we get those two pieces correct? Then the remaining issue seems
> > to be a new one that is biting Ingo elsewhere, at least we'll all be on
> > the same page then.
> > 
> 
> Jens, for_each_sg still calls sg_next on the last entry which will
> dereference a possibly bogus sg->page (for the sg_is_chain(sg)
> condition in sg_next) if the last entry is the last one on the page
> of unchained entry and sg+1 falls over into an uninitialized page.

Things have progressed a lot since, see my recent posting based on
Davem's proposal. Will post another patch soonish, that is also tested.

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 10:49                                                 ` Ingo Molnar
  2007-10-18 10:50                                                   ` Jeff Garzik
@ 2007-10-18 10:56                                                   ` Jens Axboe
  1 sibling, 0 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-18 10:56 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Jeff Garzik, Linus Torvalds, linux-kernel, Alan Cox

On Thu, Oct 18 2007, Ingo Molnar wrote:
> 
> * Jens Axboe <jens.axboe@oracle.com> wrote:
> 
> > > It would always be nice. For this case I don't think it's very 
> > > interesting, if we pursue the improved sg iteration setup.
> > 
> > BTW, I think it's pretty clear that ata_sg_is_last() is broken. It's 
> > likely a one-off in the n_iter test.
> 
> fixing that would be a -stable candidate, as a potential data corruptor 
> - or is it more benign?

I think it's safe to say that it was sg chaining introduced breakage, so
it should work fine in 2.6.23.x.

-- 
Jens Axboe


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

* Re: [PATCH] Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 10:54                                             ` Ingo Molnar
@ 2007-10-18 11:02                                               ` Jeff Garzik
  2007-10-18 11:40                                                 ` Ingo Molnar
  0 siblings, 1 reply; 151+ messages in thread
From: Jeff Garzik @ 2007-10-18 11:02 UTC (permalink / raw)
  To: Ingo Molnar, Jens Axboe
  Cc: Linus Torvalds, linux-kernel, Alan Cox, Tejun Heo, Brian King

Ingo Molnar wrote:
> * Jeff Garzik <jeff@garzik.org> wrote:
> 
>>> Tomo and I agreed to kill sg_last() a few days ago anyways, so this 
>>> is perfectly fine with me.
>> Yep, the [attached] patch that kills ata_sg_is_last() is working here 
>> on both machines that were previously croaking.
>>
>> It would be nice to get pdc_adma, sata_sil24 and ipr it-works test 
>> done, but IMO the patch is pretty straightforward and should be OK.
> 
> just a quick question: i have Jens's workarounds applied right now (see 
> patch below). Am i now crash/corruption-safe, or do i need your patch 
> too? And once your patch [and the other sg_*() patches] are upstream i 
> dont need the workaround anymore, correct?

You need my patch if and only if you use one of the drivers touched by 
the patch.  ata_sg_is_last() was a driver helper function, so my fix 
never really touched core code.

I never had to apply the changes you included, to fix problems here.

And looking at those changes...
> -	q->max_phys_segments = max_segments;
> +	q->max_phys_segments = max_segments - 1;
  ...
> -#define SCSI_MAX_SG_SEGMENTS	128
> +#define SCSI_MAX_SG_SEGMENTS	129

I wonder if libata should be doing

	blk_queue_max_phys_segments(q, q->max_phys_segments - 1)

to account for the pad entry that libata owns.

	Jeff




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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  7:07                         ` Ingo Molnar
  2007-10-18  7:10                           ` Jens Axboe
  2007-10-18  8:22                           ` Jeff Garzik
@ 2007-10-18 11:03                           ` Ingo Molnar
  2007-10-18 11:05                             ` Jens Axboe
  2 siblings, 1 reply; 151+ messages in thread
From: Ingo Molnar @ 2007-10-18 11:03 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Linus Torvalds, linux-kernel, Jeff Garzik, Alan Cox


* Ingo Molnar <mingo@elte.hu> wrote:

> > -#define SCSI_MAX_SG_SEGMENTS	128
> > +#define SCSI_MAX_SG_SEGMENTS	129
> 
> this one finally made the trick and it's booting fine now, without any 
> crashes!

hm, spoke too soon - i just got the ata_qc_issue() crash below. I've 
attached further below the current fixes/workarounds that i have applied 
at the moment. Any ideas?

	Ingo

------------->
[  155.259466] kjournald starting.  Commit interval 5 seconds
[  155.265103] EXT3 FS on sda5, internal journal
[  155.269319] EXT3-fs: mounted filesystem with ordered data mode.
[  156.458225] BUG: unable to handle kernel paging request at virtual address 7d5ac000
[  156.465723] printing eip: 784e9300 *pde = 00ddd027 *pte = 055ac000 
[  156.471964] Oops: 0000 [#1] DEBUG_PAGEALLOC
[  156.476123] 
[  156.477597] Pid: 0, comm: swapper Not tainted (2.6.23 #40)
[  156.483055] EIP: 0060:[<784e9300>] EFLAGS: 00010006 CPU: 0
[  156.488520] EIP is at ata_qc_issue+0xd0/0x340
[  156.492848] EAX: 3d328000 EBX: 7d5ac000 ECX: 00000020 EDX: 00000020
[  156.499087] ESI: 7d5ab480 EDI: 7d5abe00 EBP: 7b54007c ESP: 78a13e1c
[  156.505328]  DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068
[  156.510700] Process swapper (pid: 0, ti=78a12000 task=789753e0 task.ti=78a12000)
[  156.517893] Stack: 7d5ac000 7b540000 7b540000 00000000 7d5abff0 7b54007c 7d5ab480 7b5417a4 
[  156.526213]        784c2330 784ef49e 784f1ff3 7b52de98 7d5ab480 7b540000 7b5417a4 7d5ab480 
[  156.534531]        7b540000 7b524004 784f20e0 784ef180 784c2330 7d5ab480 00000216 7b524004 
[  156.542851] Call Trace:
[  156.545452]  [<784c2330>] scsi_done+0x0/0x20
[  156.549698]  [<784ef49e>] ata_scsi_translate+0xbe/0x140
[  156.554897]  [<784f1ff3>] ata_scsi_queuecmd+0x33/0x200
[  156.560010]  [<784f20e0>] ata_scsi_queuecmd+0x120/0x200
[  156.565210]  [<784ef180>] ata_scsi_rw_xlat+0x0/0x220
[  156.570150]  [<784c2330>] scsi_done+0x0/0x20
[  156.574395]  [<784c2bb2>] scsi_dispatch_cmd+0x152/0x290
[  156.579596]  [<78135aa7>] trace_hardirqs_on+0x67/0xb0
[  156.584622]  [<784c8abe>] scsi_request_fn+0x1be/0x370
[  156.589649]  [<78407ef6>] blk_run_queue+0x36/0x80
[  156.594328]  [<784c73c0>] scsi_next_command+0x30/0x50
[  156.599354]  [<784c754b>] scsi_end_request+0xab/0xe0
[  156.604294]  [<784c8239>] scsi_io_completion+0xa9/0x3d0
[  156.609493]  [<78135aa7>] trace_hardirqs_on+0x67/0xb0
[  156.614520]  [<78404f85>] blk_done_softirq+0x45/0x80
[  156.619460]  [<78404fb3>] blk_done_softirq+0x73/0x80
[  156.624400]  [<7811d2f3>] __do_softirq+0x53/0xb0
[  156.628992]  [<7811d3b8>] do_softirq+0x68/0x70
[  156.633412]  [<78105351>] do_IRQ+0x51/0x90
[  156.637486]  [<7810290f>] restore_nocheck+0x12/0x15
[  156.642339]  [<7810388e>] common_interrupt+0x2e/0x40
[  156.647277]  [<7810f4c0>] pgd_dtor+0x0/0x50
[  156.651437]  [<7815f1d0>] quicklist_trim+0x0/0x90
[  156.656117]  [<7810f4bb>] check_pgt_cache+0x1b/0x20
[  156.660970]  [<78100c52>] cpu_idle+0x32/0x60
[  156.665217]  [<78a14b35>] start_kernel+0x265/0x300
[  156.669983]  [<78a14380>] unknown_bootoption+0x0/0x1e0
[  156.675096]  =======================
[  156.678649] Code: 84 d9 01 00 00 7e 32 31 d2 89 f6 8b 1c 24 83 c2 01 8b 03 2b 05 18 ed d7 78 c1 f8 05 c1 e0 0c 03 43 04 89 43 08 83 c3 10 89 1c 24 <8b> 03 a8 01 0f 85 58 02 00 00 39 ca 75 d2 f0 83 44 24 00 00 85 
[  156.697455] EIP: [<784e9300>] ata_qc_issue+0xd0/0x340 SS:ESP 0068:78a13e1c
[  156.704822] Kernel panic - not syncing: Fatal exception in interrupt

---
 block/ll_rw_blk.c         |    2 +-
 drivers/ata/libata-core.c |    2 +-
 drivers/scsi/scsi_lib.c   |    2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

Index: linux/block/ll_rw_blk.c
===================================================================
--- linux.orig/block/ll_rw_blk.c
+++ linux/block/ll_rw_blk.c
@@ -631,7 +631,7 @@ void blk_queue_max_phys_segments(struct 
 		printk("%s: set to minimum %d\n", __FUNCTION__, max_segments);
 	}
 
-	q->max_phys_segments = max_segments;
+	q->max_phys_segments = max_segments - 1;
 }
 
 EXPORT_SYMBOL(blk_queue_max_phys_segments);
Index: linux/drivers/ata/libata-core.c
===================================================================
--- linux.orig/drivers/ata/libata-core.c
+++ linux/drivers/ata/libata-core.c
@@ -4664,7 +4664,7 @@ static int ata_sg_setup(struct ata_queue
 {
 	struct ata_port *ap = qc->ap;
 	struct scatterlist *sg = qc->__sg;
-	struct scatterlist *lsg = sg_last(qc->__sg, qc->n_elem);
+	struct scatterlist *lsg = &qc->__sg[qc->n_elem - 1];
 	int n_elem, pre_n_elem, dir, trim_sg = 0;
 
 	VPRINTK("ENTER, ata%u\n", ap->print_id);
Index: linux/drivers/scsi/scsi_lib.c
===================================================================
--- linux.orig/drivers/scsi/scsi_lib.c
+++ linux/drivers/scsi/scsi_lib.c
@@ -39,7 +39,7 @@
  * (unless chaining is used). Should ideally fit inside a single page, to
  * avoid a higher order allocation.
  */
-#define SCSI_MAX_SG_SEGMENTS	128
+#define SCSI_MAX_SG_SEGMENTS	129
 
 struct scsi_host_sg_pool {
 	size_t		size;

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 11:03                           ` Ingo Molnar
@ 2007-10-18 11:05                             ` Jens Axboe
  0 siblings, 0 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-18 11:05 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Linus Torvalds, linux-kernel, Jeff Garzik, Alan Cox

On Thu, Oct 18 2007, Ingo Molnar wrote:
> 
> * Ingo Molnar <mingo@elte.hu> wrote:
> 
> > > -#define SCSI_MAX_SG_SEGMENTS	128
> > > +#define SCSI_MAX_SG_SEGMENTS	129
> > 
> > this one finally made the trick and it's booting fine now, without any 
> > crashes!
> 
> hm, spoke too soon - i just got the ata_qc_issue() crash below. I've 
> attached further below the current fixes/workarounds that i have applied 
> at the moment. Any ideas?

Hang on Ingo, will post an updated patch soonish!

-- 
Jens Axboe


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

* Re: [PATCH] Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 11:02                                               ` Jeff Garzik
@ 2007-10-18 11:40                                                 ` Ingo Molnar
  0 siblings, 0 replies; 151+ messages in thread
From: Ingo Molnar @ 2007-10-18 11:40 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: Jens Axboe, Linus Torvalds, linux-kernel, Alan Cox, Tejun Heo,
	Brian King


* Jeff Garzik <jeff@garzik.org> wrote:

> I never had to apply the changes you included, to fix problems here.

perhaps because you are not running a CONFIG_DEBUG_PAGEALLOC=y kernel?

I recently fixed DEBUG_PAGEALLOC (it would crash upon bootup on x86 most 
of the time on any real hardware - so i doubt people were able to use it 
all that much). As long as you try Linus' latest -git tree (which has 
the latest arch/x86 merge) and use the 32-bit x86 kernel it should work 
fine for you too, and you will probably be able to trigger similar 
crashes too.

	Ingo

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  8:21                                           ` Jens Axboe
@ 2007-10-18 11:55                                             ` David Miller
  2007-10-18 11:57                                               ` Jens Axboe
  2007-10-18 16:55                                             ` Linus Torvalds
  1 sibling, 1 reply; 151+ messages in thread
From: David Miller @ 2007-10-18 11:55 UTC (permalink / raw)
  To: jens.axboe
  Cc: torvalds, fujita.tomonori, mingo, linux-kernel, jgarzik, alan,
	tomof

From: Jens Axboe <jens.axboe@oracle.com>
Date: Thu, 18 Oct 2007 10:21:45 +0200

> I like it. Basically the only real change is using bit 2 as a
> termination point, so we avoid going beyond the end of the sgtable.
> Here's a starting point, it actually booted for me in the first go
> (boggle). Only x86 so far, archs will need to be converted. And lots
> more drivers I'm sure, I only fixed up the ones that botched my compile.
> 
> So just consider this a directional patch.

Here are some sparc64 bits:

diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c
index 29af777..73852a2 100644
--- a/arch/sparc64/kernel/iommu.c
+++ b/arch/sparc64/kernel/iommu.c
@@ -473,7 +473,7 @@ static void dma_4u_unmap_single(struct device *dev, dma_addr_t bus_addr,
 }
 
 #define SG_ENT_PHYS_ADDRESS(SG)	\
-	(__pa(page_address((SG)->page)) + (SG)->offset)
+	(__pa(page_address(sg_page(SG))) + (SG)->offset)
 
 static void fill_sg(iopte_t *iopte, struct scatterlist *sg,
 		    int nused, int nelems,
@@ -566,7 +566,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
 	if (nelems == 1) {
 		sglist->dma_address =
 			dma_4u_map_single(dev,
-					  (page_address(sglist->page) +
+					  (page_address(sg_page(sglist)) +
 					   sglist->offset),
 					  sglist->length, direction);
 		if (unlikely(sglist->dma_address == DMA_ERROR_CODE))
diff --git a/arch/sparc64/kernel/iommu_common.c b/arch/sparc64/kernel/iommu_common.c
index d7ca900..ec863e0 100644
--- a/arch/sparc64/kernel/iommu_common.c
+++ b/arch/sparc64/kernel/iommu_common.c
@@ -73,7 +73,7 @@ static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg,
 
 	daddr = dma_sg->dma_address;
 	sglen = sg->length;
-	sgaddr = (unsigned long) (page_address(sg->page) + sg->offset);
+	sgaddr = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
 	while (dlen > 0) {
 		unsigned long paddr;
 
@@ -123,7 +123,7 @@ static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg,
 		sg = sg_next(sg);
 		if (--nents <= 0)
 			break;
-		sgaddr = (unsigned long) (page_address(sg->page) + sg->offset);
+		sgaddr = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
 		sglen = sg->length;
 	}
 	if (dlen < 0) {
@@ -191,7 +191,7 @@ void verify_sglist(struct scatterlist *sglist, int nents, iopte_t *iopte, int np
 			printk("sg(%d): page_addr(%p) off(%x) length(%x) "
 			       "dma_address[%016x] dma_length[%016x]\n",
 			       i,
-			       page_address(sg->page), sg->offset,
+			       page_address(sg_page(sg)), sg->offset,
 			       sg->length,
 			       sg->dma_address, sg->dma_length);
 		}
@@ -207,15 +207,15 @@ unsigned long prepare_sg(struct scatterlist *sg, int nents)
 	unsigned long prev;
 	u32 dent_addr, dent_len;
 
-	prev  = (unsigned long) (page_address(sg->page) + sg->offset);
+	prev  = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
 	prev += (unsigned long) (dent_len = sg->length);
-	dent_addr = (u32) ((unsigned long)(page_address(sg->page) + sg->offset)
+	dent_addr = (u32) ((unsigned long)(page_address(sg_page(sg)) + sg->offset)
 			   & (IO_PAGE_SIZE - 1UL));
 	while (--nents) {
 		unsigned long addr;
 
 		sg = sg_next(sg);
-		addr = (unsigned long) (page_address(sg->page) + sg->offset);
+		addr = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
 		if (! VCONTIG(prev, addr)) {
 			dma_sg->dma_address = dent_addr;
 			dma_sg->dma_length = dent_len;
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index fe46ace..5324a34 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -366,7 +366,7 @@ static void dma_4v_unmap_single(struct device *dev, dma_addr_t bus_addr,
 }
 
 #define SG_ENT_PHYS_ADDRESS(SG)	\
-	(__pa(page_address((SG)->page)) + (SG)->offset)
+	(__pa(page_address(sg_page(SG))) + (SG)->offset)
 
 static long fill_sg(long entry, struct device *dev,
 		    struct scatterlist *sg,
@@ -478,7 +478,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
 	if (nelems == 1) {
 		sglist->dma_address =
 			dma_4v_map_single(dev,
-					  (page_address(sglist->page) +
+					  (page_address(sg_page(sglist)) +
 					   sglist->offset),
 					  sglist->length, direction);
 		if (unlikely(sglist->dma_address == DMA_ERROR_CODE))
diff --git a/include/asm-sparc64/scatterlist.h b/include/asm-sparc64/scatterlist.h
index 703c5bb..6df23f0 100644
--- a/include/asm-sparc64/scatterlist.h
+++ b/include/asm-sparc64/scatterlist.h
@@ -6,7 +6,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page	*page;
+#ifdef CONFIG_DEBUG_SG
+	unsigned long	sg_magic;
+#endif
+	unsigned long	page_link;
 	unsigned int	offset;
 
 	unsigned int	length;

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 11:55                                             ` David Miller
@ 2007-10-18 11:57                                               ` Jens Axboe
  2007-10-18 12:05                                                 ` David Miller
  0 siblings, 1 reply; 151+ messages in thread
From: Jens Axboe @ 2007-10-18 11:57 UTC (permalink / raw)
  To: David Miller
  Cc: torvalds, fujita.tomonori, mingo, linux-kernel, jgarzik, alan,
	tomof

On Thu, Oct 18 2007, David Miller wrote:
> From: Jens Axboe <jens.axboe@oracle.com>
> Date: Thu, 18 Oct 2007 10:21:45 +0200
> 
> > I like it. Basically the only real change is using bit 2 as a
> > termination point, so we avoid going beyond the end of the sgtable.
> > Here's a starting point, it actually booted for me in the first go
> > (boggle). Only x86 so far, archs will need to be converted. And lots
> > more drivers I'm sure, I only fixed up the ones that botched my compile.
> > 
> > So just consider this a directional patch.
> 
> Here are some sparc64 bits:

Thanks a lot, Dave! The patch is a monster right now, I'll work on
splitting it into a 3-step process. Any arch help is greatly
appreciated.

-- 
Jens Axboe


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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-18 10:55                 ` Jens Axboe
@ 2007-10-18 12:03                   ` David Miller
  2007-10-18 12:28                     ` Jens Axboe
  0 siblings, 1 reply; 151+ messages in thread
From: David Miller @ 2007-10-18 12:03 UTC (permalink / raw)
  To: jens.axboe; +Cc: bhalevy, torvalds, mingo, linux-kernel, akpm

From: Jens Axboe <jens.axboe@oracle.com>
Date: Thu, 18 Oct 2007 12:55:17 +0200

> Things have progressed a lot since, see my recent posting based on
> Davem's proposal. Will post another patch soonish, that is also
> tested.

One core issue here is that we need to decide whether this thing to be
iterated like an array or like a linked list.  It's trying to be both.

If we decide upon a looping construct for consumers and stick to it,
we'll be in much better shape than we are now and bugs will be eaiser
to spot.  It would be so much simpler to audit if all we saw in the
consumers were things like:

	while (sg) {
		do_stuff(sg);
		sg = sg_next(sg);
	}

I would suggest that we just get it over with and convert the whole
tree now rather than trying to do this kind of thing in stages.
Because then we can say that ever scatterlist creator has to set
the "end" bit and therefore you use well established patterns
for scatterlist iteration such as "traverse sg_next() until NULL"
as shown above.

I also noticed that there is the issue of on-stack and embedded
scatterlist users.  We'll need some sort of "DECLARE_SCATTERLIST"
and a "scatterlist_init()" thing so that we can keep DEBUG_SG
working even in those cases.  But for all I know Jens could be
working on that already :-)

The only other real option if we don't convert the whole tree now to
the "end" marker stuff, is to enforce that every scatterlist iterator
only traverse the number of entries there were told are in the one
given to them.

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 11:57                                               ` Jens Axboe
@ 2007-10-18 12:05                                                 ` David Miller
  2007-10-18 12:09                                                   ` Jens Axboe
  0 siblings, 1 reply; 151+ messages in thread
From: David Miller @ 2007-10-18 12:05 UTC (permalink / raw)
  To: jens.axboe
  Cc: torvalds, fujita.tomonori, mingo, linux-kernel, jgarzik, alan,
	tomof

From: Jens Axboe <jens.axboe@oracle.com>
Date: Thu, 18 Oct 2007 13:57:02 +0200

> Thanks a lot, Dave! The patch is a monster right now, I'll work on
> splitting it into a 3-step process. Any arch help is greatly
> appreciated.

I have some other bits that my compile hit, such as some things in the
crypto layer.

But I hesitate to send them to you because I think the on-stack cases
need some helpers such that DEBUG_SG works for them.

BTW, you missed a case in drivers/usb/core/message.c because of
the config used in your build.  This thing below is a good
argument for trying to avoid HIGHMEM et al. ifdefs in drivers :-)

--- drivers/usb/core/message.c~	2007-10-18 01:46:44.000000000 -0700
+++ drivers/usb/core/message.c	2007-10-18 03:15:20.000000000 -0700
@@ -438,7 +438,7 @@
 			io->urbs[i]->transfer_buffer = NULL;
 #else
 			io->urbs[i]->transfer_buffer =
-				page_address(sg[i].page) + sg[i].offset;
+				page_address(sg_page(&sg[i])) + sg[i].offset;
 #endif
 		} else {
 			/* hc may use _only_ transfer_buffer */

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 12:05                                                 ` David Miller
@ 2007-10-18 12:09                                                   ` Jens Axboe
  2007-10-18 12:15                                                     ` Jens Axboe
  0 siblings, 1 reply; 151+ messages in thread
From: Jens Axboe @ 2007-10-18 12:09 UTC (permalink / raw)
  To: David Miller
  Cc: torvalds, fujita.tomonori, mingo, linux-kernel, jgarzik, alan,
	tomof

On Thu, Oct 18 2007, David Miller wrote:
> From: Jens Axboe <jens.axboe@oracle.com>
> Date: Thu, 18 Oct 2007 13:57:02 +0200
> 
> > Thanks a lot, Dave! The patch is a monster right now, I'll work on
> > splitting it into a 3-step process. Any arch help is greatly
> > appreciated.
> 
> I have some other bits that my compile hit, such as some things in the
> crypto layer.

Yeah, I have tons of that so far. I hope to have an allyesconfig
compiling pretty soonish, will send that out then.

> But I hesitate to send them to you because I think the on-stack cases
> need some helpers such that DEBUG_SG works for them.

Indeed. I convert where appropriate, but I'm not anal about it. If they
don't use sg_next() and/or for_each_sg() on their list, it should be ok.
Don't want to make the changes more than necessary right now.

> BTW, you missed a case in drivers/usb/core/message.c because of
> the config used in your build.  This thing below is a good
> argument for trying to avoid HIGHMEM et al. ifdefs in drivers :-)

Thanks :-)

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 12:09                                                   ` Jens Axboe
@ 2007-10-18 12:15                                                     ` Jens Axboe
  2007-10-18 12:36                                                       ` David Miller
                                                                         ` (2 more replies)
  0 siblings, 3 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-18 12:15 UTC (permalink / raw)
  To: David Miller
  Cc: torvalds, fujita.tomonori, mingo, linux-kernel, jgarzik, alan,
	tomof

On Thu, Oct 18 2007, Jens Axboe wrote:
> On Thu, Oct 18 2007, David Miller wrote:
> > From: Jens Axboe <jens.axboe@oracle.com>
> > Date: Thu, 18 Oct 2007 13:57:02 +0200
> > 
> > > Thanks a lot, Dave! The patch is a monster right now, I'll work on
> > > splitting it into a 3-step process. Any arch help is greatly
> > > appreciated.
> > 
> > I have some other bits that my compile hit, such as some things in the
> > crypto layer.
> 
> Yeah, I have tons of that so far. I hope to have an allyesconfig
> compiling pretty soonish, will send that out then.

OK here goes, this compiles with allyesconfig on x86-64. Not too bad,
the scsi/ drivers were by far the worst.

 arch/sparc64/kernel/iommu.c                 |    4 -
 arch/sparc64/kernel/iommu_common.c          |   12 ++--
 arch/sparc64/kernel/pci_sun4v.c             |    4 -
 arch/x86/kernel/pci-calgary_64.c            |   12 ++--
 arch/x86/kernel/pci-gart_64.c               |    4 -
 arch/x86/kernel/pci-nommu_64.c              |    4 -
 block/ll_rw_blk.c                           |    5 +
 crypto/digest.c                             |    2 
 crypto/hmac.c                               |    3 -
 crypto/scatterwalk.c                        |    2 
 crypto/scatterwalk.h                        |    6 +-
 crypto/tcrypt.c                             |    4 -
 crypto/xcbc.c                               |    2 
 drivers/ata/libata-core.c                   |   10 +--
 drivers/ata/libata-scsi.c                   |    2 
 drivers/block/cciss.c                       |    4 -
 drivers/block/cpqarray.c                    |    3 -
 drivers/block/cryptoloop.c                  |   12 ++--
 drivers/block/ub.c                          |    8 +-
 drivers/ide/ide-probe.c                     |    4 +
 drivers/ide/ide-taskfile.c                  |    2 
 drivers/ieee1394/dma.c                      |    2 
 drivers/ieee1394/sbp2.c                     |    2 
 drivers/infiniband/core/umem.c              |   11 ++-
 drivers/infiniband/hw/ipath/ipath_dma.c     |    4 -
 drivers/infiniband/hw/ipath/ipath_mr.c      |    2 
 drivers/infiniband/hw/mthca/mthca_memfree.c |   24 +++++---
 drivers/infiniband/ulp/iser/iser_memory.c   |    6 +-
 drivers/md/dm-crypt.c                       |   21 +++----
 drivers/media/common/saa7146_core.c         |    3 -
 drivers/media/video/ivtv/ivtv-udma.c        |    4 -
 drivers/media/video/videobuf-dma-sg.c       |    8 +-
 drivers/mmc/card/queue.c                    |   15 ++---
 drivers/mmc/host/mmc_spi.c                  |    8 +-
 drivers/mmc/host/sdhci.c                    |    2 
 drivers/mmc/host/tifm_sd.c                  |    8 +-
 drivers/mmc/host/wbsd.c                     |    6 +-
 drivers/net/mlx4/icm.c                      |   14 +++-
 drivers/net/ppp_mppe.c                      |    6 --
 drivers/scsi/3w-9xxx.c                      |    4 -
 drivers/scsi/3w-xxxx.c                      |    2 
 drivers/scsi/NCR5380.c                      |    4 -
 drivers/scsi/aacraid/aachba.c               |    2 
 drivers/scsi/arcmsr/arcmsr_hba.c            |    4 -
 drivers/scsi/fdomain.c                      |    6 +-
 drivers/scsi/gdth.c                         |    4 -
 drivers/scsi/ide-scsi.c                     |    8 +-
 drivers/scsi/imm.c                          |    4 -
 drivers/scsi/ipr.c                          |   19 ++++--
 drivers/scsi/ips.c                          |    6 +-
 drivers/scsi/iscsi_tcp.c                    |   15 ++---
 drivers/scsi/megaraid.c                     |    6 +-
 drivers/scsi/megaraid/megaraid_mbox.c       |    8 +-
 drivers/scsi/osst.c                         |   32 +++++-----
 drivers/scsi/pcmcia/sym53c500_cs.c          |    6 +-
 drivers/scsi/ppa.c                          |    4 -
 drivers/scsi/qlogicfas408.c                 |    2 
 drivers/scsi/scsi_debug.c                   |    4 -
 drivers/scsi/scsi_lib.c                     |   13 +++-
 drivers/scsi/sg.c                           |   30 +++++-----
 drivers/scsi/st.c                           |    8 +-
 drivers/scsi/tmscsim.c                      |    5 -
 drivers/usb/core/message.c                  |    4 -
 drivers/usb/image/microtek.c                |    4 -
 drivers/usb/misc/usbtest.c                  |    5 +
 drivers/usb/storage/protocol.c              |    2 
 fs/ecryptfs/crypto.c                        |   16 +++--
 fs/ecryptfs/keystore.c                      |    3 +
 fs/nfsd/nfs4recover.c                       |    8 +-
 include/asm-sparc64/scatterlist.h           |    5 +
 include/asm-x86/dma-mapping_32.h            |    4 -
 include/asm-x86/scatterlist_32.h            |    5 +
 include/asm-x86/scatterlist_64.h            |    5 +
 include/linux/scatterlist.h                 |   82 +++++++++++++++++++++++-----
 lib/Kconfig.debug                           |   10 +++
 lib/swiotlb.c                               |    2 
 net/core/skbuff.c                           |    4 -
 net/ieee80211/ieee80211_crypt_tkip.c        |   13 +---
 net/ieee80211/ieee80211_crypt_wep.c         |    8 --
 net/mac80211/wep.c                          |    8 --
 net/sctp/auth.c                             |    3 -
 net/sctp/sm_make_chunk.c                    |    6 +-
 net/sunrpc/auth_gss/gss_krb5_crypto.c       |   10 +--
 net/sunrpc/xdr.c                            |    2 
 net/xfrm/xfrm_algo.c                        |    4 -
 85 files changed, 389 insertions(+), 275 deletions(-)

diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c
index 29af777..73852a2 100644
--- a/arch/sparc64/kernel/iommu.c
+++ b/arch/sparc64/kernel/iommu.c
@@ -473,7 +473,7 @@ static void dma_4u_unmap_single(struct device *dev, dma_addr_t bus_addr,
 }
 
 #define SG_ENT_PHYS_ADDRESS(SG)	\
-	(__pa(page_address((SG)->page)) + (SG)->offset)
+	(__pa(page_address(sg_page(SG))) + (SG)->offset)
 
 static void fill_sg(iopte_t *iopte, struct scatterlist *sg,
 		    int nused, int nelems,
@@ -566,7 +566,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
 	if (nelems == 1) {
 		sglist->dma_address =
 			dma_4u_map_single(dev,
-					  (page_address(sglist->page) +
+					  (page_address(sg_page(sglist)) +
 					   sglist->offset),
 					  sglist->length, direction);
 		if (unlikely(sglist->dma_address == DMA_ERROR_CODE))
diff --git a/arch/sparc64/kernel/iommu_common.c b/arch/sparc64/kernel/iommu_common.c
index d7ca900..ec863e0 100644
--- a/arch/sparc64/kernel/iommu_common.c
+++ b/arch/sparc64/kernel/iommu_common.c
@@ -73,7 +73,7 @@ static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg,
 
 	daddr = dma_sg->dma_address;
 	sglen = sg->length;
-	sgaddr = (unsigned long) (page_address(sg->page) + sg->offset);
+	sgaddr = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
 	while (dlen > 0) {
 		unsigned long paddr;
 
@@ -123,7 +123,7 @@ static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg,
 		sg = sg_next(sg);
 		if (--nents <= 0)
 			break;
-		sgaddr = (unsigned long) (page_address(sg->page) + sg->offset);
+		sgaddr = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
 		sglen = sg->length;
 	}
 	if (dlen < 0) {
@@ -191,7 +191,7 @@ void verify_sglist(struct scatterlist *sglist, int nents, iopte_t *iopte, int np
 			printk("sg(%d): page_addr(%p) off(%x) length(%x) "
 			       "dma_address[%016x] dma_length[%016x]\n",
 			       i,
-			       page_address(sg->page), sg->offset,
+			       page_address(sg_page(sg)), sg->offset,
 			       sg->length,
 			       sg->dma_address, sg->dma_length);
 		}
@@ -207,15 +207,15 @@ unsigned long prepare_sg(struct scatterlist *sg, int nents)
 	unsigned long prev;
 	u32 dent_addr, dent_len;
 
-	prev  = (unsigned long) (page_address(sg->page) + sg->offset);
+	prev  = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
 	prev += (unsigned long) (dent_len = sg->length);
-	dent_addr = (u32) ((unsigned long)(page_address(sg->page) + sg->offset)
+	dent_addr = (u32) ((unsigned long)(page_address(sg_page(sg)) + sg->offset)
 			   & (IO_PAGE_SIZE - 1UL));
 	while (--nents) {
 		unsigned long addr;
 
 		sg = sg_next(sg);
-		addr = (unsigned long) (page_address(sg->page) + sg->offset);
+		addr = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
 		if (! VCONTIG(prev, addr)) {
 			dma_sg->dma_address = dent_addr;
 			dma_sg->dma_length = dent_len;
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index fe46ace..5324a34 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -366,7 +366,7 @@ static void dma_4v_unmap_single(struct device *dev, dma_addr_t bus_addr,
 }
 
 #define SG_ENT_PHYS_ADDRESS(SG)	\
-	(__pa(page_address((SG)->page)) + (SG)->offset)
+	(__pa(page_address(sg_page(SG))) + (SG)->offset)
 
 static long fill_sg(long entry, struct device *dev,
 		    struct scatterlist *sg,
@@ -478,7 +478,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
 	if (nelems == 1) {
 		sglist->dma_address =
 			dma_4v_map_single(dev,
-					  (page_address(sglist->page) +
+					  (page_address(sg_page(sglist)) +
 					   sglist->offset),
 					  sglist->length, direction);
 		if (unlikely(sglist->dma_address == DMA_ERROR_CODE))
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 5098f58..c9f0eb0 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -411,8 +411,10 @@ static int calgary_nontranslate_map_sg(struct device* dev,
 	int i;
 
 	for_each_sg(sg, s, nelems, i) {
-		BUG_ON(!s->page);
-		s->dma_address = virt_to_bus(page_address(s->page) +s->offset);
+		struct page *p = sg_page(s);
+
+		BUG_ON(!p);
+		s->dma_address = virt_to_bus(page_address(p) + s->offset);
 		s->dma_length = s->length;
 	}
 	return nelems;
@@ -432,9 +434,11 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
 		return calgary_nontranslate_map_sg(dev, sg, nelems, direction);
 
 	for_each_sg(sg, s, nelems, i) {
-		BUG_ON(!s->page);
+		struct page *p = sg_page(s);
+
+		BUG_ON(!p);
 
-		vaddr = (unsigned long)page_address(s->page) + s->offset;
+		vaddr = (unsigned long)page_address(p) + s->offset;
 		npages = num_dma_pages(vaddr, s->length);
 
 		entry = iommu_range_alloc(tbl, npages);
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index 5cdfab6..daaf636 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -302,7 +302,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
 #endif
 
 	for_each_sg(sg, s, nents, i) {
-		unsigned long addr = page_to_phys(s->page) + s->offset; 
+		unsigned long addr = page_to_phys(sg_page(s)) + s->offset; 
 		if (nonforced_iommu(dev, addr, s->length)) { 
 			addr = dma_map_area(dev, addr, s->length, dir);
 			if (addr == bad_dma_address) { 
@@ -397,7 +397,7 @@ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 	start_sg = sgmap = sg;
 	ps = NULL; /* shut up gcc */
 	for_each_sg(sg, s, nents, i) {
-		dma_addr_t addr = page_to_phys(s->page) + s->offset;
+		dma_addr_t addr = page_to_phys(sg_page(s)) + s->offset;
 		s->dma_address = addr;
 		BUG_ON(s->length == 0); 
 
diff --git a/arch/x86/kernel/pci-nommu_64.c b/arch/x86/kernel/pci-nommu_64.c
index e85d436..d64a4a5 100644
--- a/arch/x86/kernel/pci-nommu_64.c
+++ b/arch/x86/kernel/pci-nommu_64.c
@@ -62,8 +62,8 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
 	int i;
 
 	for_each_sg(sg, s, nents, i) {
-		BUG_ON(!s->page);
-		s->dma_address = virt_to_bus(page_address(s->page) +s->offset);
+		BUG_ON(!sg_page(s));
+		s->dma_address = virt_to_bus(page_address(sg_page(s)) +s->offset);
 		if (!check_addr("map_sg", hwdev, s->dma_address, s->length))
 			return 0;
 		s->dma_length = s->length;
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 3935469..ce9754f 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -1354,8 +1354,9 @@ new_segment:
 			else
 				sg = sg_next(sg);
 
-			memset(sg, 0, sizeof(*sg));
-			sg->page = bvec->bv_page;
+			sg_dma_len(sg) = 0;
+			sg_dma_address(sg) = 0;
+			sg_set_page(sg, bvec->bv_page);
 			sg->length = nbytes;
 			sg->offset = bvec->bv_offset;
 			nsegs++;
diff --git a/crypto/digest.c b/crypto/digest.c
index e56de67..8871dec 100644
--- a/crypto/digest.c
+++ b/crypto/digest.c
@@ -41,7 +41,7 @@ static int update2(struct hash_desc *desc,
 		return 0;
 
 	for (;;) {
-		struct page *pg = sg->page;
+		struct page *pg = sg_page(sg);
 		unsigned int offset = sg->offset;
 		unsigned int l = sg->length;
 
diff --git a/crypto/hmac.c b/crypto/hmac.c
index 8802fb6..e4eb6ac 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -159,7 +159,8 @@ static int hmac_digest(struct hash_desc *pdesc, struct scatterlist *sg,
 	desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP;
 
 	sg_set_buf(sg1, ipad, bs);
-	sg1[1].page = (void *)sg;
+
+	sg_set_page(&sg[1], (void *) sg);
 	sg1[1].length = 0;
 	sg_set_buf(sg2, opad, bs + ds);
 
diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c
index d6852c3..b9bbda0 100644
--- a/crypto/scatterwalk.c
+++ b/crypto/scatterwalk.c
@@ -54,7 +54,7 @@ static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
 	if (out) {
 		struct page *page;
 
-		page = walk->sg->page + ((walk->offset - 1) >> PAGE_SHIFT);
+		page = sg_page(walk->sg) + ((walk->offset - 1) >> PAGE_SHIFT);
 		flush_dcache_page(page);
 	}
 
diff --git a/crypto/scatterwalk.h b/crypto/scatterwalk.h
index 9c73e37..87ed681 100644
--- a/crypto/scatterwalk.h
+++ b/crypto/scatterwalk.h
@@ -22,13 +22,13 @@
 
 static inline struct scatterlist *scatterwalk_sg_next(struct scatterlist *sg)
 {
-	return (++sg)->length ? sg : (void *)sg->page;
+	return (++sg)->length ? sg : (void *) sg_page(sg);
 }
 
 static inline unsigned long scatterwalk_samebuf(struct scatter_walk *walk_in,
 						struct scatter_walk *walk_out)
 {
-	return !(((walk_in->sg->page - walk_out->sg->page) << PAGE_SHIFT) +
+	return !(((sg_page(walk_in->sg) - sg_page(walk_out->sg)) << PAGE_SHIFT) +
 		 (int)(walk_in->offset - walk_out->offset));
 }
 
@@ -60,7 +60,7 @@ static inline unsigned int scatterwalk_aligned(struct scatter_walk *walk,
 
 static inline struct page *scatterwalk_page(struct scatter_walk *walk)
 {
-	return walk->sg->page + (walk->offset >> PAGE_SHIFT);
+	return sg_page(walk->sg) + (walk->offset >> PAGE_SHIFT);
 }
 
 static inline void scatterwalk_unmap(void *vaddr, int out)
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 18d489c..d741c63 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -317,7 +317,7 @@ static void test_cipher(char *algo, int enc,
 				goto out;
 			}
 
-			q = kmap(sg[0].page) + sg[0].offset;
+			q = kmap(sg_page(&sg[0])) + sg[0].offset;
 			hexdump(q, cipher_tv[i].rlen);
 
 			printk("%s\n",
@@ -390,7 +390,7 @@ static void test_cipher(char *algo, int enc,
 			temp = 0;
 			for (k = 0; k < cipher_tv[i].np; k++) {
 				printk("page %u\n", k);
-				q = kmap(sg[k].page) + sg[k].offset;
+				q = kmap(sg_page(&sg[k])) + sg[k].offset;
 				hexdump(q, cipher_tv[i].tap[k]);
 				printk("%s\n",
 					memcmp(q, cipher_tv[i].result + temp,
diff --git a/crypto/xcbc.c b/crypto/xcbc.c
index 9f502b8..ac68f3b 100644
--- a/crypto/xcbc.c
+++ b/crypto/xcbc.c
@@ -120,7 +120,7 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc,
 
 	do {
 
-		struct page *pg = sg[i].page;
+		struct page *pg = sg_page(&sg[i]);
 		unsigned int offset = sg[i].offset;
 		unsigned int slen = sg[i].length;
 
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index bbaa545..b1fa70a 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4296,7 +4296,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
 		sg_last(sg, qc->orig_n_elem)->length += qc->pad_len;
 		if (pad_buf) {
 			struct scatterlist *psg = &qc->pad_sgent;
-			void *addr = kmap_atomic(psg->page, KM_IRQ0);
+			void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
 			memcpy(addr + psg->offset, pad_buf, qc->pad_len);
 			kunmap_atomic(addr, KM_IRQ0);
 		}
@@ -4686,11 +4686,11 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
 		 * data in this function or read data in ata_sg_clean.
 		 */
 		offset = lsg->offset + lsg->length - qc->pad_len;
-		psg->page = nth_page(lsg->page, offset >> PAGE_SHIFT);
+		sg_set_page(psg, nth_page(sg_page(lsg), offset >> PAGE_SHIFT));
 		psg->offset = offset_in_page(offset);
 
 		if (qc->tf.flags & ATA_TFLAG_WRITE) {
-			void *addr = kmap_atomic(psg->page, KM_IRQ0);
+			void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
 			memcpy(pad_buf, addr + psg->offset, qc->pad_len);
 			kunmap_atomic(addr, KM_IRQ0);
 		}
@@ -4836,7 +4836,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
 	if (qc->curbytes == qc->nbytes - qc->sect_size)
 		ap->hsm_task_state = HSM_ST_LAST;
 
-	page = qc->cursg->page;
+	page = sg_page(qc->cursg);
 	offset = qc->cursg->offset + qc->cursg_ofs;
 
 	/* get the current page and offset */
@@ -4988,7 +4988,7 @@ next_sg:
 
 	sg = qc->cursg;
 
-	page = sg->page;
+	page = sg_page(sg);
 	offset = sg->offset + qc->cursg_ofs;
 
 	/* get the current page and offset */
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 9fbb39c..5b758b9 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1544,7 +1544,7 @@ static unsigned int ata_scsi_rbuf_get(struct scsi_cmnd *cmd, u8 **buf_out)
 	struct scatterlist *sg = scsi_sglist(cmd);
 
 	if (sg) {
-		buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+		buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 		buflen = sg->length;
 	} else {
 		buf = NULL;
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 7c2cfde..5a6fe17 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -2610,7 +2610,7 @@ static void do_cciss_request(struct request_queue *q)
 	       (int)creq->nr_sectors);
 #endif				/* CCISS_DEBUG */
 
-	memset(tmp_sg, 0, sizeof(tmp_sg));
+	sg_init_table(tmp_sg, MAXSGENTRIES);
 	seg = blk_rq_map_sg(q, creq, tmp_sg);
 
 	/* get the DMA records for the setup */
@@ -2621,7 +2621,7 @@ static void do_cciss_request(struct request_queue *q)
 
 	for (i = 0; i < seg; i++) {
 		c->SG[i].Len = tmp_sg[i].length;
-		temp64.val = (__u64) pci_map_page(h->pdev, tmp_sg[i].page,
+		temp64.val = (__u64) pci_map_page(h->pdev, sg_page(&tmp_sg[i]),
 						  tmp_sg[i].offset,
 						  tmp_sg[i].length, dir);
 		c->SG[i].Addr.lower = temp64.val32.lower;
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index 568603d..efab27f 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -918,6 +918,7 @@ queue_next:
 DBGPX(
 	printk("sector=%d, nr_sectors=%d\n", creq->sector, creq->nr_sectors);
 );
+	sg_init_table(tmp_sg, SG_MAX);
 	seg = blk_rq_map_sg(q, creq, tmp_sg);
 
 	/* Now do all the DMA Mappings */
@@ -929,7 +930,7 @@ DBGPX(
 	{
 		c->req.sg[i].size = tmp_sg[i].length;
 		c->req.sg[i].addr = (__u32) pci_map_page(h->pci_dev,
-						 tmp_sg[i].page,
+						 sg_page(&tmp_sg[i]),
 						 tmp_sg[i].offset,
 						 tmp_sg[i].length, dir);
 	}
diff --git a/drivers/block/cryptoloop.c b/drivers/block/cryptoloop.c
index 4053503..1b58b01 100644
--- a/drivers/block/cryptoloop.c
+++ b/drivers/block/cryptoloop.c
@@ -26,6 +26,7 @@
 #include <linux/crypto.h>
 #include <linux/blkdev.h>
 #include <linux/loop.h>
+#include <linux/scatterlist.h>
 #include <asm/semaphore.h>
 #include <asm/uaccess.h>
 
@@ -119,14 +120,17 @@ cryptoloop_transfer(struct loop_device *lo, int cmd,
 		.tfm = tfm,
 		.flags = CRYPTO_TFM_REQ_MAY_SLEEP,
 	};
-	struct scatterlist sg_out = { NULL, };
-	struct scatterlist sg_in = { NULL, };
+	struct scatterlist sg_out;
+	struct scatterlist sg_in;
 
 	encdec_cbc_t encdecfunc;
 	struct page *in_page, *out_page;
 	unsigned in_offs, out_offs;
 	int err;
 
+	sg_init_table(&sg_out, 1);
+	sg_init_table(&sg_in, 1);
+
 	if (cmd == READ) {
 		in_page = raw_page;
 		in_offs = raw_off;
@@ -146,11 +150,11 @@ cryptoloop_transfer(struct loop_device *lo, int cmd,
 		u32 iv[4] = { 0, };
 		iv[0] = cpu_to_le32(IV & 0xffffffff);
 
-		sg_in.page = in_page;
+		sg_set_page(&sg_in, in_page);
 		sg_in.offset = in_offs;
 		sg_in.length = sz;
 
-		sg_out.page = out_page;
+		sg_set_page(&sg_out, out_page);
 		sg_out.offset = out_offs;
 		sg_out.length = sz;
 
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index c57dd2b..d6f7b43 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -25,6 +25,7 @@
 #include <linux/usb_usual.h>
 #include <linux/blkdev.h>
 #include <linux/timer.h>
+#include <linux/scatterlist.h>
 #include <scsi/scsi.h>
 
 #define DRV_NAME "ub"
@@ -656,6 +657,7 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq)
 	if ((cmd = ub_get_cmd(lun)) == NULL)
 		return -1;
 	memset(cmd, 0, sizeof(struct ub_scsi_cmd));
+	sg_init_table(cmd->sgv, UB_MAX_REQ_SG);
 
 	blkdev_dequeue_request(rq);
 
@@ -1310,7 +1312,7 @@ static void ub_data_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 		pipe = sc->send_bulk_pipe;
 	sc->last_pipe = pipe;
 	usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe,
-	    page_address(sg->page) + sg->offset, sg->length,
+	    page_address(sg_page(sg)) + sg->offset, sg->length,
 	    ub_urb_complete, sc);
 	sc->work_urb.actual_length = 0;
 	sc->work_urb.error_count = 0;
@@ -1427,7 +1429,7 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 	scmd->state = UB_CMDST_INIT;
 	scmd->nsg = 1;
 	sg = &scmd->sgv[0];
-	sg->page = virt_to_page(sc->top_sense);
+	sg_set_page(sg, virt_to_page(sc->top_sense));
 	sg->offset = (unsigned long)sc->top_sense & (PAGE_SIZE-1);
 	sg->length = UB_SENSE_SIZE;
 	scmd->len = UB_SENSE_SIZE;
@@ -1863,7 +1865,7 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
 	cmd->state = UB_CMDST_INIT;
 	cmd->nsg = 1;
 	sg = &cmd->sgv[0];
-	sg->page = virt_to_page(p);
+	sg_set_page(sg, virt_to_page(p));
 	sg->offset = (unsigned long)p & (PAGE_SIZE-1);
 	sg->length = 8;
 	cmd->len = 8;
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 3c945d6..7c640cd 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -1337,12 +1337,14 @@ static int hwif_init(ide_hwif_t *hwif)
 	if (!hwif->sg_max_nents)
 		hwif->sg_max_nents = PRD_ENTRIES;
 
-	hwif->sg_table = kzalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
+	hwif->sg_table = kmalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
 				 GFP_KERNEL);
 	if (!hwif->sg_table) {
 		printk(KERN_ERR "%s: unable to allocate SG table.\n", hwif->name);
 		goto out;
 	}
+
+	sg_init_table(hwif->sg_table, hwif->sg_max_nents);
 	
 	if (init_irq(hwif) == 0)
 		goto done;
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 2a3c8d4..086157f 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -278,7 +278,7 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
 		hwif->cursg = sg;
 	}
 
-	page = cursg->page;
+	page = sg_page(cursg);
 	offset = cursg->offset + hwif->cursg_ofs * SECTOR_SIZE;
 
 	/* get the current page and offset */
diff --git a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c
index 45d6055..25e113b 100644
--- a/drivers/ieee1394/dma.c
+++ b/drivers/ieee1394/dma.c
@@ -111,7 +111,7 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes,
 		unsigned long va =
 		    (unsigned long)dma->kvirt + (i << PAGE_SHIFT);
 
-		dma->sglist[i].page = vmalloc_to_page((void *)va);
+		sg_set_page(&dma->sglist[i], vmalloc_to_page((void *)va));
 		dma->sglist[i].length = PAGE_SIZE;
 	}
 
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 1b353b9..d5dfe11 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -1466,7 +1466,7 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb,
 		cmd->dma_size = sgpnt[0].length;
 		cmd->dma_type = CMD_DMA_PAGE;
 		cmd->cmd_dma = dma_map_page(hi->host->device.parent,
-					    sgpnt[0].page, sgpnt[0].offset,
+					    sg_page(&sgpnt[0]), sgpnt[0].offset,
 					    cmd->dma_size, cmd->dma_dir);
 
 		orb->data_descriptor_lo = cmd->cmd_dma;
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index 2f54e29..14159ff 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -55,9 +55,11 @@ static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int d
 		ib_dma_unmap_sg(dev, chunk->page_list,
 				chunk->nents, DMA_BIDIRECTIONAL);
 		for (i = 0; i < chunk->nents; ++i) {
+			struct page *page = sg_page(&chunk->page_list[i]);
+
 			if (umem->writable && dirty)
-				set_page_dirty_lock(chunk->page_list[i].page);
-			put_page(chunk->page_list[i].page);
+				set_page_dirty_lock(page);
+			put_page(page);
 		}
 
 		kfree(chunk);
@@ -164,11 +166,12 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
 			}
 
 			chunk->nents = min_t(int, ret, IB_UMEM_MAX_PAGE_CHUNK);
+			sg_init_table(chunk->page_list, chunk->nents);
 			for (i = 0; i < chunk->nents; ++i) {
 				if (vma_list &&
 				    !is_vm_hugetlb_page(vma_list[i + off]))
 					umem->hugetlb = 0;
-				chunk->page_list[i].page   = page_list[i + off];
+				sg_set_page(&chunk->page_list[i], page_list[i + off]);
 				chunk->page_list[i].offset = 0;
 				chunk->page_list[i].length = PAGE_SIZE;
 			}
@@ -179,7 +182,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
 						    DMA_BIDIRECTIONAL);
 			if (chunk->nmap <= 0) {
 				for (i = 0; i < chunk->nents; ++i)
-					put_page(chunk->page_list[i].page);
+					put_page(sg_page(&chunk->page_list[i]));
 				kfree(chunk);
 
 				ret = -ENOMEM;
diff --git a/drivers/infiniband/hw/ipath/ipath_dma.c b/drivers/infiniband/hw/ipath/ipath_dma.c
index 22709a4..e90a0ea 100644
--- a/drivers/infiniband/hw/ipath/ipath_dma.c
+++ b/drivers/infiniband/hw/ipath/ipath_dma.c
@@ -108,7 +108,7 @@ static int ipath_map_sg(struct ib_device *dev, struct scatterlist *sgl,
 	BUG_ON(!valid_dma_direction(direction));
 
 	for_each_sg(sgl, sg, nents, i) {
-		addr = (u64) page_address(sg->page);
+		addr = (u64) page_address(sg_page(sg));
 		/* TODO: handle highmem pages */
 		if (!addr) {
 			ret = 0;
@@ -127,7 +127,7 @@ static void ipath_unmap_sg(struct ib_device *dev,
 
 static u64 ipath_sg_dma_address(struct ib_device *dev, struct scatterlist *sg)
 {
-	u64 addr = (u64) page_address(sg->page);
+	u64 addr = (u64) page_address(sg_page(sg));
 
 	if (addr)
 		addr += sg->offset;
diff --git a/drivers/infiniband/hw/ipath/ipath_mr.c b/drivers/infiniband/hw/ipath/ipath_mr.c
index e442470..db4ba92 100644
--- a/drivers/infiniband/hw/ipath/ipath_mr.c
+++ b/drivers/infiniband/hw/ipath/ipath_mr.c
@@ -225,7 +225,7 @@ struct ib_mr *ipath_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
 		for (i = 0; i < chunk->nents; i++) {
 			void *vaddr;
 
-			vaddr = page_address(chunk->page_list[i].page);
+			vaddr = page_address(sg_page(&chunk->page_list[i]));
 			if (!vaddr) {
 				ret = ERR_PTR(-EINVAL);
 				goto bail;
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
index e61f3e6..007b381 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -71,7 +71,7 @@ static void mthca_free_icm_pages(struct mthca_dev *dev, struct mthca_icm_chunk *
 			     PCI_DMA_BIDIRECTIONAL);
 
 	for (i = 0; i < chunk->npages; ++i)
-		__free_pages(chunk->mem[i].page,
+		__free_pages(sg_page(&chunk->mem[i]),
 			     get_order(chunk->mem[i].length));
 }
 
@@ -81,7 +81,7 @@ static void mthca_free_icm_coherent(struct mthca_dev *dev, struct mthca_icm_chun
 
 	for (i = 0; i < chunk->npages; ++i) {
 		dma_free_coherent(&dev->pdev->dev, chunk->mem[i].length,
-				  lowmem_page_address(chunk->mem[i].page),
+				  lowmem_page_address(sg_page(&chunk->mem[i])),
 				  sg_dma_address(&chunk->mem[i]));
 	}
 }
@@ -107,10 +107,13 @@ void mthca_free_icm(struct mthca_dev *dev, struct mthca_icm *icm, int coherent)
 
 static int mthca_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_mask)
 {
-	mem->page = alloc_pages(gfp_mask, order);
-	if (!mem->page)
+	struct page *page;
+
+	page = alloc_pages(gfp_mask, order);
+	if (!page)
 		return -ENOMEM;
 
+	sg_set_page(mem, page);
 	mem->length = PAGE_SIZE << order;
 	mem->offset = 0;
 	return 0;
@@ -157,6 +160,7 @@ struct mthca_icm *mthca_alloc_icm(struct mthca_dev *dev, int npages,
 			if (!chunk)
 				goto fail;
 
+			sg_init_table(chunk->mem, MTHCA_ICM_CHUNK_LEN);
 			chunk->npages = 0;
 			chunk->nsg    = 0;
 			list_add_tail(&chunk->list, &icm->chunk_list);
@@ -304,7 +308,7 @@ void *mthca_table_find(struct mthca_icm_table *table, int obj, dma_addr_t *dma_h
 			 * so if we found the page, dma_handle has already
 			 * been assigned to. */
 			if (chunk->mem[i].length > offset) {
-				page = chunk->mem[i].page;
+				page = sg_page(&chunk->mem[i]);
 				goto out;
 			}
 			offset -= chunk->mem[i].length;
@@ -445,6 +449,7 @@ static u64 mthca_uarc_virt(struct mthca_dev *dev, struct mthca_uar *uar, int pag
 int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
 		      struct mthca_user_db_table *db_tab, int index, u64 uaddr)
 {
+	struct page *pages[1];
 	int ret = 0;
 	u8 status;
 	int i;
@@ -472,16 +477,17 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
 	}
 
 	ret = get_user_pages(current, current->mm, uaddr & PAGE_MASK, 1, 1, 0,
-			     &db_tab->page[i].mem.page, NULL);
+			     pages, NULL);
 	if (ret < 0)
 		goto out;
 
+	sg_set_page(&db_tab->page[i].mem, pages[0]);
 	db_tab->page[i].mem.length = MTHCA_ICM_PAGE_SIZE;
 	db_tab->page[i].mem.offset = uaddr & ~PAGE_MASK;
 
 	ret = pci_map_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
 	if (ret < 0) {
-		put_page(db_tab->page[i].mem.page);
+		put_page(pages[0]);
 		goto out;
 	}
 
@@ -491,7 +497,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
 		ret = -EINVAL;
 	if (ret) {
 		pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
-		put_page(db_tab->page[i].mem.page);
+		put_page(sg_page(&db_tab->page[i].mem));
 		goto out;
 	}
 
@@ -557,7 +563,7 @@ void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar,
 		if (db_tab->page[i].uvirt) {
 			mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, uar, i), 1, &status);
 			pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
-			put_page(db_tab->page[i].mem.page);
+			put_page(sg_page(&db_tab->page[i].mem));
 		}
 	}
 
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
index f3529b6..29c842e 100644
--- a/drivers/infiniband/ulp/iser/iser_memory.c
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -131,7 +131,7 @@ static int iser_start_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
 
 		p = mem;
 		for_each_sg(sgl, sg, data->size, i) {
-			from = kmap_atomic(sg->page, KM_USER0);
+			from = kmap_atomic(sg_page(sg), KM_USER0);
 			memcpy(p,
 			       from + sg->offset,
 			       sg->length);
@@ -191,7 +191,7 @@ void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
 
 		p = mem;
 		for_each_sg(sgl, sg, sg_size, i) {
-			to = kmap_atomic(sg->page, KM_SOFTIRQ0);
+			to = kmap_atomic(sg_page(sg), KM_SOFTIRQ0);
 			memcpy(to + sg->offset,
 			       p,
 			       sg->length);
@@ -336,7 +336,7 @@ static void iser_data_buf_dump(struct iser_data_buf *data,
 		iser_err("sg[%d] dma_addr:0x%lX page:0x%p "
 			 "off:0x%x sz:0x%x dma_len:0x%x\n",
 			 i, (unsigned long)ib_sg_dma_address(ibdev, sg),
-			 sg->page, sg->offset,
+			 sg_page(sg), sg->offset,
 			 sg->length, ib_sg_dma_len(ibdev, sg));
 }
 
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 64fee90..cde915f 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -346,16 +346,17 @@ static int crypt_convert(struct crypt_config *cc,
 	      ctx->idx_out < ctx->bio_out->bi_vcnt) {
 		struct bio_vec *bv_in = bio_iovec_idx(ctx->bio_in, ctx->idx_in);
 		struct bio_vec *bv_out = bio_iovec_idx(ctx->bio_out, ctx->idx_out);
-		struct scatterlist sg_in = {
-			.page = bv_in->bv_page,
-			.offset = bv_in->bv_offset + ctx->offset_in,
-			.length = 1 << SECTOR_SHIFT
-		};
-		struct scatterlist sg_out = {
-			.page = bv_out->bv_page,
-			.offset = bv_out->bv_offset + ctx->offset_out,
-			.length = 1 << SECTOR_SHIFT
-		};
+		struct scatterlist sg_in, sg_out;
+
+		sg_init_table(&sg_in, 1);
+		sg_set_page(&sg_in, bv_in->bv_page);
+		sg_in.offset = bv_in->bv_offset + ctx->offset_in;
+		sg_in.length = 1 << SECTOR_SHIFT;
+		
+		sg_init_table(&sg_out, 1);
+		sg_set_page(&sg_out, bv_out->bv_page);
+		sg_out.offset = bv_out->bv_offset + ctx->offset_out;
+		sg_out.length = 1 << SECTOR_SHIFT;
 
 		ctx->offset_in += sg_in.length;
 		if (ctx->offset_in >= bv_in->bv_len) {
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c
index 365a221..2b1f8b4 100644
--- a/drivers/media/common/saa7146_core.c
+++ b/drivers/media/common/saa7146_core.c
@@ -112,12 +112,13 @@ static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages)
 	sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL);
 	if (NULL == sglist)
 		return NULL;
+	sg_init_table(sglist, nr_pages);
 	for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
 		pg = vmalloc_to_page(virt);
 		if (NULL == pg)
 			goto err;
 		BUG_ON(PageHighMem(pg));
-		sglist[i].page   = pg;
+		sg_set_page(&sglist[i], pg);
 		sglist[i].length = PAGE_SIZE;
 	}
 	return sglist;
diff --git a/drivers/media/video/ivtv/ivtv-udma.c b/drivers/media/video/ivtv/ivtv-udma.c
index c4626d1..912b424 100644
--- a/drivers/media/video/ivtv/ivtv-udma.c
+++ b/drivers/media/video/ivtv/ivtv-udma.c
@@ -63,10 +63,10 @@ int ivtv_udma_fill_sg_list (struct ivtv_user_dma *dma, struct ivtv_dma_page_info
 			memcpy(page_address(dma->bouncemap[map_offset]) + offset, src, len);
 			kunmap_atomic(src, KM_BOUNCE_READ);
 			local_irq_restore(flags);
-			dma->SGlist[map_offset].page = dma->bouncemap[map_offset];
+			sg_set_page(&dma->SGlist[map_offset], dma->bouncemap[map_offset]);
 		}
 		else {
-			dma->SGlist[map_offset].page = dma->map[map_offset];
+			sg_set_page(&dma->SGlist[map_offset], dma->map[map_offset]);
 		}
 		offset = 0;
 		map_offset++;
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
index 3eb6123..0a18286 100644
--- a/drivers/media/video/videobuf-dma-sg.c
+++ b/drivers/media/video/videobuf-dma-sg.c
@@ -60,12 +60,13 @@ videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages)
 	sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL);
 	if (NULL == sglist)
 		return NULL;
+	sg_init_table(sglist, nr_pages);
 	for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
 		pg = vmalloc_to_page(virt);
 		if (NULL == pg)
 			goto err;
 		BUG_ON(PageHighMem(pg));
-		sglist[i].page   = pg;
+		sg_set_page(&sglist[i], pg);
 		sglist[i].length = PAGE_SIZE;
 	}
 	return sglist;
@@ -86,13 +87,14 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
 	sglist = kcalloc(nr_pages, sizeof(*sglist), GFP_KERNEL);
 	if (NULL == sglist)
 		return NULL;
+	sg_init_table(sglist, nr_pages);
 
 	if (NULL == pages[0])
 		goto nopage;
 	if (PageHighMem(pages[0]))
 		/* DMA to highmem pages might not work */
 		goto highmem;
-	sglist[0].page   = pages[0];
+	sg_set_page(&sglist[0], pages[0]);
 	sglist[0].offset = offset;
 	sglist[0].length = PAGE_SIZE - offset;
 	for (i = 1; i < nr_pages; i++) {
@@ -100,7 +102,7 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
 			goto nopage;
 		if (PageHighMem(pages[i]))
 			goto highmem;
-		sglist[i].page   = pages[i];
+		sg_set_page(&sglist[i], pages[i]);
 		sglist[i].length = PAGE_SIZE;
 	}
 	return sglist;
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index a5d0354..68c1fe9 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -13,6 +13,7 @@
 #include <linux/blkdev.h>
 #include <linux/freezer.h>
 #include <linux/kthread.h>
+#include <linux/scatterlist.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
@@ -153,19 +154,21 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
 			blk_queue_max_hw_segments(mq->queue, bouncesz / 512);
 			blk_queue_max_segment_size(mq->queue, bouncesz);
 
-			mq->sg = kzalloc(sizeof(struct scatterlist),
+			mq->sg = kmalloc(sizeof(struct scatterlist),
 				GFP_KERNEL);
 			if (!mq->sg) {
 				ret = -ENOMEM;
 				goto cleanup_queue;
 			}
+			sg_init_table(mq->sg, 1);
 
-			mq->bounce_sg = kzalloc(sizeof(struct scatterlist) *
+			mq->bounce_sg = kmalloc(sizeof(struct scatterlist) *
 				bouncesz / 512, GFP_KERNEL);
 			if (!mq->bounce_sg) {
 				ret = -ENOMEM;
 				goto cleanup_queue;
 			}
+			sg_init_table(mq->bounce_sg, bouncesz / 512);
 		}
 	}
 #endif
@@ -302,12 +305,12 @@ static void copy_sg(struct scatterlist *dst, unsigned int dst_len,
 		BUG_ON(dst_len == 0);
 
 		if (dst_size == 0) {
-			dst_buf = page_address(dst->page) + dst->offset;
+			dst_buf = page_address(sg_page(dst)) + dst->offset;
 			dst_size = dst->length;
 		}
 
 		if (src_size == 0) {
-			src_buf = page_address(src->page) + src->offset;
+			src_buf = page_address(sg_page(src)) + src->offset;
 			src_size = src->length;
 		}
 
@@ -353,9 +356,7 @@ unsigned int mmc_queue_map_sg(struct mmc_queue *mq)
 		return 1;
 	}
 
-	mq->sg[0].page = virt_to_page(mq->bounce_buf);
-	mq->sg[0].offset = offset_in_page(mq->bounce_buf);
-	mq->sg[0].length = 0;
+	sg_init_one(mq->sg, mq->bounce_buf, 0);
 
 	while (sg_len) {
 		mq->sg[0].length += mq->bounce_sg[sg_len - 1].length;
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 7ae18ea..12c2d80 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -813,7 +813,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
 					&& dir == DMA_FROM_DEVICE)
 				dir = DMA_BIDIRECTIONAL;
 
-			dma_addr = dma_map_page(dma_dev, sg->page, 0,
+			dma_addr = dma_map_page(dma_dev, sg_page(sg), 0,
 						PAGE_SIZE, dir);
 			if (direction == DMA_TO_DEVICE)
 				t->tx_dma = dma_addr + sg->offset;
@@ -822,7 +822,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
 		}
 
 		/* allow pio too; we don't allow highmem */
-		kmap_addr = kmap(sg->page);
+		kmap_addr = kmap(sg_page(sg));
 		if (direction == DMA_TO_DEVICE)
 			t->tx_buf = kmap_addr + sg->offset;
 		else
@@ -855,8 +855,8 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
 
 		/* discard mappings */
 		if (direction == DMA_FROM_DEVICE)
-			flush_kernel_dcache_page(sg->page);
-		kunmap(sg->page);
+			flush_kernel_dcache_page(sg_page(sg));
+		kunmap(sg_page(sg));
 		if (dma_dev)
 			dma_unmap_page(dma_dev, dma_addr, PAGE_SIZE, dir);
 
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index b397121..b6500e9 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -231,7 +231,7 @@ static void sdhci_deactivate_led(struct sdhci_host *host)
 
 static inline char* sdhci_sg_to_buffer(struct sdhci_host* host)
 {
-	return page_address(host->cur_sg->page) + host->cur_sg->offset;
+	return page_address(sg_page(host->cur_sg)) + host->cur_sg->offset;
 }
 
 static inline int sdhci_next_sg(struct sdhci_host* host)
diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c
index 9b90479..c11a3d2 100644
--- a/drivers/mmc/host/tifm_sd.c
+++ b/drivers/mmc/host/tifm_sd.c
@@ -192,7 +192,7 @@ static void tifm_sd_transfer_data(struct tifm_sd *host)
 		}
 		off = sg[host->sg_pos].offset + host->block_pos;
 
-		pg = nth_page(sg[host->sg_pos].page, off >> PAGE_SHIFT);
+		pg = nth_page(sg_page(&sg[host->sg_pos]), off >> PAGE_SHIFT);
 		p_off = offset_in_page(off);
 		p_cnt = PAGE_SIZE - p_off;
 		p_cnt = min(p_cnt, cnt);
@@ -241,18 +241,18 @@ static void tifm_sd_bounce_block(struct tifm_sd *host, struct mmc_data *r_data)
 		}
 		off = sg[host->sg_pos].offset + host->block_pos;
 
-		pg = nth_page(sg[host->sg_pos].page, off >> PAGE_SHIFT);
+		pg = nth_page(sg_page(&sg[host->sg_pos]), off >> PAGE_SHIFT);
 		p_off = offset_in_page(off);
 		p_cnt = PAGE_SIZE - p_off;
 		p_cnt = min(p_cnt, cnt);
 		p_cnt = min(p_cnt, t_size);
 
 		if (r_data->flags & MMC_DATA_WRITE)
-			tifm_sd_copy_page(host->bounce_buf.page,
+			tifm_sd_copy_page(sg_page(&host->bounce_buf),
 					  r_data->blksz - t_size,
 					  pg, p_off, p_cnt);
 		else if (r_data->flags & MMC_DATA_READ)
-			tifm_sd_copy_page(pg, p_off, host->bounce_buf.page,
+			tifm_sd_copy_page(pg, p_off, sg_page(&host->bounce_buf),
 					  r_data->blksz - t_size, p_cnt);
 
 		t_size -= p_cnt;
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c
index 80db11c..971ca0f 100644
--- a/drivers/mmc/host/wbsd.c
+++ b/drivers/mmc/host/wbsd.c
@@ -269,7 +269,7 @@ static inline int wbsd_next_sg(struct wbsd_host *host)
 
 static inline char *wbsd_sg_to_buffer(struct wbsd_host *host)
 {
-	return page_address(host->cur_sg->page) + host->cur_sg->offset;
+	return page_address(sg_page(host->cur_sg)) + host->cur_sg->offset;
 }
 
 static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data)
@@ -283,7 +283,7 @@ static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data)
 	len = data->sg_len;
 
 	for (i = 0; i < len; i++) {
-		sgbuf = page_address(sg[i].page) + sg[i].offset;
+		sgbuf = page_address(sg_page(&sg[i])) + sg[i].offset;
 		memcpy(dmabuf, sgbuf, sg[i].length);
 		dmabuf += sg[i].length;
 	}
@@ -300,7 +300,7 @@ static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data)
 	len = data->sg_len;
 
 	for (i = 0; i < len; i++) {
-		sgbuf = page_address(sg[i].page) + sg[i].offset;
+		sgbuf = page_address(sg_page(&sg[i])) + sg[i].offset;
 		memcpy(sgbuf, dmabuf, sg[i].length);
 		dmabuf += sg[i].length;
 	}
diff --git a/drivers/net/mlx4/icm.c b/drivers/net/mlx4/icm.c
index 4b3c109..887633b 100644
--- a/drivers/net/mlx4/icm.c
+++ b/drivers/net/mlx4/icm.c
@@ -60,7 +60,7 @@ static void mlx4_free_icm_pages(struct mlx4_dev *dev, struct mlx4_icm_chunk *chu
 			     PCI_DMA_BIDIRECTIONAL);
 
 	for (i = 0; i < chunk->npages; ++i)
-		__free_pages(chunk->mem[i].page,
+		__free_pages(sg_page(&chunk->mem[i]),
 			     get_order(chunk->mem[i].length));
 }
 
@@ -70,7 +70,7 @@ static void mlx4_free_icm_coherent(struct mlx4_dev *dev, struct mlx4_icm_chunk *
 
 	for (i = 0; i < chunk->npages; ++i)
 		dma_free_coherent(&dev->pdev->dev, chunk->mem[i].length,
-				  lowmem_page_address(chunk->mem[i].page),
+				  lowmem_page_address(sg_page(&chunk->mem[i])),
 				  sg_dma_address(&chunk->mem[i]));
 }
 
@@ -95,10 +95,13 @@ void mlx4_free_icm(struct mlx4_dev *dev, struct mlx4_icm *icm, int coherent)
 
 static int mlx4_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_mask)
 {
-	mem->page = alloc_pages(gfp_mask, order);
-	if (!mem->page)
+	struct page *page;
+
+	page = alloc_pages(gfp_mask, order);
+	if (!page)
 		return -ENOMEM;
 
+	sg_set_page(mem, page);
 	mem->length = PAGE_SIZE << order;
 	mem->offset = 0;
 	return 0;
@@ -145,6 +148,7 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
 			if (!chunk)
 				goto fail;
 
+			sg_init_table(chunk->mem, MLX4_ICM_CHUNK_LEN);
 			chunk->npages = 0;
 			chunk->nsg    = 0;
 			list_add_tail(&chunk->list, &icm->chunk_list);
@@ -334,7 +338,7 @@ void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_han
 			 * been assigned to.
 			 */
 			if (chunk->mem[i].length > offset) {
-				page = chunk->mem[i].page;
+				page = sg_page(&chunk->mem[i]);
 				goto out;
 			}
 			offset -= chunk->mem[i].length;
diff --git a/drivers/net/ppp_mppe.c b/drivers/net/ppp_mppe.c
index c0b6d19..bcb0885 100644
--- a/drivers/net/ppp_mppe.c
+++ b/drivers/net/ppp_mppe.c
@@ -55,7 +55,7 @@
 #include <linux/mm.h>
 #include <linux/ppp_defs.h>
 #include <linux/ppp-comp.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 
 #include "ppp_mppe.h"
 
@@ -68,9 +68,7 @@ MODULE_VERSION("1.0.2");
 static unsigned int
 setup_sg(struct scatterlist *sg, const void *address, unsigned int length)
 {
-	sg[0].page = virt_to_page(address);
-	sg[0].offset = offset_in_page(address);
-	sg[0].length = length;
+	sg_init_one(sg, address, length);
 	return length;
 }
 
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index fb14014..afb262b 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -1840,7 +1840,7 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
 			    (scsi_bufflen(srb) < TW_MIN_SGL_LENGTH)) {
 				if (srb->sc_data_direction == DMA_TO_DEVICE || srb->sc_data_direction == DMA_BIDIRECTIONAL) {
 					struct scatterlist *sg = scsi_sglist(srb);
-					char *buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+					char *buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 					memcpy(tw_dev->generic_buffer_virt[request_id], buf, sg->length);
 					kunmap_atomic(buf - sg->offset, KM_IRQ0);
 				}
@@ -1919,7 +1919,7 @@ static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int re
 			char *buf;
 			unsigned long flags = 0;
 			local_irq_save(flags);
-			buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+			buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 			memcpy(buf, tw_dev->generic_buffer_virt[request_id], sg->length);
 			kunmap_atomic(buf - sg->offset, KM_IRQ0);
 			local_irq_restore(flags);
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index a64153b..59716eb 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -1469,7 +1469,7 @@ static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id,
 	struct scatterlist *sg = scsi_sglist(cmd);
 
 	local_irq_save(flags);
-	buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+	buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 	transfer_len = min(sg->length, len);
 
 	memcpy(buf, data, transfer_len);
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index 988f0bc..7a76b4b 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -298,7 +298,7 @@ static __inline__ void initialize_SCp(Scsi_Cmnd * cmd)
 	if (cmd->use_sg) {
 		cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
 		cmd->SCp.buffers_residual = cmd->use_sg - 1;
-		cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+
+		cmd->SCp.ptr = page_address(sg_page(cmd->SCp.buffer))+
 			       cmd->SCp.buffer->offset;
 		cmd->SCp.this_residual = cmd->SCp.buffer->length;
 	} else {
@@ -2143,7 +2143,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
 					++cmd->SCp.buffer;
 					--cmd->SCp.buffers_residual;
 					cmd->SCp.this_residual = cmd->SCp.buffer->length;
-					cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+
+					cmd->SCp.ptr = page_address(sg_page(cmd->SCp.buffer))+
 						       cmd->SCp.buffer->offset;
 					dprintk(NDEBUG_INFORMATION, ("scsi%d : %d bytes and %d buffers left\n", instance->host_no, cmd->SCp.this_residual, cmd->SCp.buffers_residual));
 				}
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 80e448d..a77ab8d 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -356,7 +356,7 @@ static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigne
 	int transfer_len;
 	struct scatterlist *sg = scsi_sglist(scsicmd);
 
-	buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+	buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 	transfer_len = min(sg->length, len + offset);
 
 	transfer_len -= offset;
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index f817775..f7a2528 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -1343,7 +1343,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \
 						/* 4 bytes: Areca io control code */
 
 	sg = scsi_sglist(cmd);
-	buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+	buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 	if (scsi_sg_count(cmd) > 1) {
 		retvalue = ARCMSR_MESSAGE_FAIL;
 		goto message_out;
@@ -1593,7 +1593,7 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,
 		strncpy(&inqdata[32], "R001", 4); /* Product Revision */
 
 		sg = scsi_sglist(cmd);
-		buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+		buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 
 		memcpy(buffer, inqdata, sizeof(inqdata));
 		sg = scsi_sglist(cmd);
diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
index 5d282e6..dc4e463 100644
--- a/drivers/scsi/fdomain.c
+++ b/drivers/scsi/fdomain.c
@@ -1321,7 +1321,7 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id)
 	    if (current_SC->SCp.buffers_residual) {
 	       --current_SC->SCp.buffers_residual;
 	       ++current_SC->SCp.buffer;
-	       current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
+	       current_SC->SCp.ptr = page_address(sg_page(current_SC->SCp.buffer)) + current_SC->SCp.buffer->offset;
 	       current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
 	    } else
 		  break;
@@ -1354,7 +1354,7 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id)
 	     && current_SC->SCp.buffers_residual) {
 	    --current_SC->SCp.buffers_residual;
 	    ++current_SC->SCp.buffer;
-	    current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
+	    current_SC->SCp.ptr = page_address(sg_page(current_SC->SCp.buffer)) + current_SC->SCp.buffer->offset;
 	    current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
 	 }
       }
@@ -1439,7 +1439,7 @@ static int fdomain_16x0_queue(struct scsi_cmnd *SCpnt,
 
    if (scsi_sg_count(current_SC)) {
 	   current_SC->SCp.buffer = scsi_sglist(current_SC);
-	   current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page)
+	   current_SC->SCp.ptr = page_address(sg_page(current_SC->SCp.buffer))
 		   + current_SC->SCp.buffer->offset;
 	   current_SC->SCp.this_residual    = current_SC->SCp.buffer->length;
 	   current_SC->SCp.buffers_residual = scsi_sg_count(current_SC) - 1;
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 3ac080e..ac6c57a 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -2374,13 +2374,13 @@ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
             if (cpsum+cpnow > cpcount) 
                 cpnow = cpcount - cpsum;
             cpsum += cpnow;
-            if (!sl->page) {
+            if (!sg_page(sl)) {
                 printk("GDT-HA %d: invalid sc/gt element in gdth_copy_internal_data()\n",
                        ha->hanum);
                 return;
             }
             local_irq_save(flags);
-            address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset;
+            address = kmap_atomic(sg_page(sl), KM_BIO_SRC_IRQ) + sl->offset;
             if (to_buffer)
                 memcpy(buffer, address, cpnow);
             else
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index fa7ba64..7eb415d 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -179,14 +179,14 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
 			unsigned long flags;
 
 			local_irq_save(flags);
-			buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
+			buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) +
 					pc->sg->offset;
 			drive->hwif->atapi_input_bytes(drive,
 						buf + pc->b_count, count);
 			kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
 			local_irq_restore(flags);
 		} else {
-			buf = page_address(pc->sg->page) + pc->sg->offset;
+			buf = page_address(sg_page(pc->sg)) + pc->sg->offset;
 			drive->hwif->atapi_input_bytes(drive,
 						buf + pc->b_count, count);
 		}
@@ -216,14 +216,14 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
 			unsigned long flags;
 
 			local_irq_save(flags);
-			buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
+			buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) +
 						pc->sg->offset;
 			drive->hwif->atapi_output_bytes(drive,
 						buf + pc->b_count, count);
 			kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
 			local_irq_restore(flags);
 		} else {
-			buf = page_address(pc->sg->page) + pc->sg->offset;
+			buf = page_address(sg_page(pc->sg)) + pc->sg->offset;
 			drive->hwif->atapi_output_bytes(drive,
 						buf + pc->b_count, count);
 		}
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c
index 74cdc1f..da9b0ba 100644
--- a/drivers/scsi/imm.c
+++ b/drivers/scsi/imm.c
@@ -706,7 +706,7 @@ static int imm_completion(struct scsi_cmnd *cmd)
 				cmd->SCp.this_residual =
 				    cmd->SCp.buffer->length;
 				cmd->SCp.ptr =
-				    page_address(cmd->SCp.buffer->page) +
+				    page_address(sg_page(cmd->SCp.buffer)) +
 				    cmd->SCp.buffer->offset;
 
 				/*
@@ -845,7 +845,7 @@ static int imm_engine(imm_struct *dev, struct scsi_cmnd *cmd)
 			    (struct scatterlist *) cmd->request_buffer;
 			cmd->SCp.this_residual = cmd->SCp.buffer->length;
 			cmd->SCp.ptr =
-			    page_address(cmd->SCp.buffer->page) +
+			    page_address(sg_page(cmd->SCp.buffer)) +
 			    cmd->SCp.buffer->offset;
 		} else {
 			/* else fill the only available buffer */
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index b41dfb5..dc98a85 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -2872,6 +2872,7 @@ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len)
 	}
 
 	scatterlist = sglist->scatterlist;
+	sg_init_table(scatterlist, num_elem);
 
 	sglist->order = order;
 	sglist->num_sg = num_elem;
@@ -2884,12 +2885,12 @@ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len)
 
 			/* Free up what we already allocated */
 			for (j = i - 1; j >= 0; j--)
-				__free_pages(scatterlist[j].page, order);
+				__free_pages(sg_page(&scatterlist[j]), order);
 			kfree(sglist);
 			return NULL;
 		}
 
-		scatterlist[i].page = page;
+		sg_set_page(&scatterlist[i], page);
 	}
 
 	return sglist;
@@ -2910,7 +2911,7 @@ static void ipr_free_ucode_buffer(struct ipr_sglist *sglist)
 	int i;
 
 	for (i = 0; i < sglist->num_sg; i++)
-		__free_pages(sglist->scatterlist[i].page, sglist->order);
+		__free_pages(sg_page(&sglist->scatterlist[i]), sglist->order);
 
 	kfree(sglist);
 }
@@ -2940,9 +2941,11 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist,
 	scatterlist = sglist->scatterlist;
 
 	for (i = 0; i < (len / bsize_elem); i++, buffer += bsize_elem) {
-		kaddr = kmap(scatterlist[i].page);
+		struct page *page = sg_page(&scatterlist[i]);
+
+		kaddr = kmap(page);
 		memcpy(kaddr, buffer, bsize_elem);
-		kunmap(scatterlist[i].page);
+		kunmap(page);
 
 		scatterlist[i].length = bsize_elem;
 
@@ -2953,9 +2956,11 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist,
 	}
 
 	if (len % bsize_elem) {
-		kaddr = kmap(scatterlist[i].page);
+		struct page *page = sg_page(&scatterlist[i]);
+
+		kaddr = kmap(page);
 		memcpy(kaddr, buffer, len % bsize_elem);
-		kunmap(scatterlist[i].page);
+		kunmap(page);
 
 		scatterlist[i].length = len % bsize_elem;
 	}
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index edaac27..5c5a9b2 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -1515,7 +1515,7 @@ static int ips_is_passthru(struct scsi_cmnd *SC)
                 /* kmap_atomic() ensures addressability of the user buffer.*/
                 /* local_irq_save() protects the KM_IRQ0 address slot.     */
                 local_irq_save(flags);
-                buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+                buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
                 if (buffer && buffer[0] == 'C' && buffer[1] == 'O' &&
                     buffer[2] == 'P' && buffer[3] == 'P') {
                         kunmap_atomic(buffer - sg->offset, KM_IRQ0);
@@ -3523,7 +3523,7 @@ ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count)
                 /* kmap_atomic() ensures addressability of the data buffer.*/
                 /* local_irq_save() protects the KM_IRQ0 address slot.     */
                 local_irq_save(flags);
-                buffer = kmap_atomic(sg[i].page, KM_IRQ0) + sg[i].offset;
+                buffer = kmap_atomic(sg_page(&sg[i]), KM_IRQ0) + sg[i].offset;
                 memcpy(buffer, &cdata[xfer_cnt], min_cnt);
                 kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
                 local_irq_restore(flags);
@@ -3556,7 +3556,7 @@ ips_scmd_buf_read(struct scsi_cmnd *scmd, void *data, unsigned int count)
                 /* kmap_atomic() ensures addressability of the data buffer.*/
                 /* local_irq_save() protects the KM_IRQ0 address slot.     */
                 local_irq_save(flags);
-                buffer = kmap_atomic(sg[i].page, KM_IRQ0) + sg[i].offset;
+                buffer = kmap_atomic(sg_page(&sg[i]), KM_IRQ0) + sg[i].offset;
                 memcpy(&cdata[xfer_cnt], buffer, min_cnt);
                 kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
                 local_irq_restore(flags);
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index a21455d..6ce4109 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -70,9 +70,7 @@ module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);
 static inline void
 iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size)
 {
-	ibuf->sg.page = virt_to_page(vbuf);
-	ibuf->sg.offset = offset_in_page(vbuf);
-	ibuf->sg.length = size;
+	sg_init_one(&ibuf->sg, vbuf, size);
 	ibuf->sent = 0;
 	ibuf->use_sendmsg = 1;
 }
@@ -80,13 +78,14 @@ iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size)
 static inline void
 iscsi_buf_init_sg(struct iscsi_buf *ibuf, struct scatterlist *sg)
 {
-	ibuf->sg.page = sg->page;
+	sg_init_table(&ibuf->sg, 1);
+	sg_set_page(&ibuf->sg, sg_page(sg));
 	ibuf->sg.offset = sg->offset;
 	ibuf->sg.length = sg->length;
 	/*
 	 * Fastpath: sg element fits into single page
 	 */
-	if (sg->length + sg->offset <= PAGE_SIZE && !PageSlab(sg->page))
+	if (sg->length + sg->offset <= PAGE_SIZE && !PageSlab(sg_page(sg)))
 		ibuf->use_sendmsg = 0;
 	else
 		ibuf->use_sendmsg = 1;
@@ -716,7 +715,7 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn)
 	for (i = tcp_ctask->sg_count; i < scsi_sg_count(sc); i++) {
 		char *dest;
 
-		dest = kmap_atomic(sg[i].page, KM_SOFTIRQ0);
+		dest = kmap_atomic(sg_page(&sg[i]), KM_SOFTIRQ0);
 		rc = iscsi_ctask_copy(tcp_conn, ctask, dest + sg[i].offset,
 				      sg[i].length, offset);
 		kunmap_atomic(dest, KM_SOFTIRQ0);
@@ -1103,9 +1102,9 @@ iscsi_send(struct iscsi_conn *conn, struct iscsi_buf *buf, int size, int flags)
 	 * slab case.
 	 */
 	if (buf->use_sendmsg)
-		res = sock_no_sendpage(sk, buf->sg.page, offset, size, flags);
+		res = sock_no_sendpage(sk, sg_page(&buf->sg), offset, size, flags);
 	else
-		res = tcp_conn->sendpage(sk, buf->sg.page, offset, size, flags);
+		res = tcp_conn->sendpage(sk, sg_page(&buf->sg), offset, size, flags);
 
 	if (res >= 0) {
 		conn->txdata_octets += res;
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 10d1aff..0a848e8 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -658,7 +658,7 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
 			struct scatterlist *sg;
 
 			sg = scsi_sglist(cmd);
-			buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+			buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 
 			memset(buf, 0, cmd->cmnd[4]);
 			kunmap_atomic(buf - sg->offset, KM_IRQ0);
@@ -1542,9 +1542,9 @@ mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status)
 		if( cmd->cmnd[0] == INQUIRY && !islogical ) {
 
 			sgl = scsi_sglist(cmd);
-			if( sgl->page ) {
+			if( sg_page(sgl) ) {
 				c = *(unsigned char *)
-					page_address((&sgl[0])->page) +
+					page_address((sg_page(&sgl[0]))) +
 					(&sgl[0])->offset; 
 			} else {
 				printk(KERN_WARNING
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index e4e4c6a..376263c 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -1584,9 +1584,9 @@ megaraid_mbox_build_cmd(adapter_t *adapter, struct scsi_cmnd *scp, int *busy)
 			caddr_t			vaddr;
 
 			sgl = scsi_sglist(scp);
-			if (sgl->page) {
+			if (sg_page(sgl)) {
 				vaddr = (caddr_t)
-					(page_address((&sgl[0])->page)
+					(page_address(sg_page(&sgl[0]))
 					 + (&sgl[0])->offset);
 
 				memset(vaddr, 0, scp->cmnd[4]);
@@ -2328,9 +2328,9 @@ megaraid_mbox_dpc(unsigned long devp)
 				&& IS_RAID_CH(raid_dev, scb->dev_channel)) {
 
 			sgl = scsi_sglist(scp);
-			if (sgl->page) {
+			if (sg_page(sgl)) {
 				c = *(unsigned char *)
-					(page_address((&sgl[0])->page) +
+					(page_address(sg_page(&sgl[0])) +
 					 (&sgl[0])->offset);
 			} else {
 				con_log(CL_ANN, (KERN_WARNING
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 331b789..1c5c4b6 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -542,7 +542,7 @@ static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int q
 	if (STp->raw) {
 		if (STp->buffer->syscall_result) {
 			for (i=0; i < STp->buffer->sg_segs; i++)
-				memset(page_address(STp->buffer->sg[i].page),
+				memset(page_address(sg_page(&STp->buffer->sg[i])),
 				       0, STp->buffer->sg[i].length);
 			strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");
                 } else
@@ -4437,7 +4437,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp)
 		for (i = 0, b_size = 0; 
 		     (i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE); 
 		     b_size += STp->buffer->sg[i++].length);
-		STp->buffer->aux = (os_aux_t *) (page_address(STp->buffer->sg[i].page) + OS_DATA_SIZE - b_size);
+		STp->buffer->aux = (os_aux_t *) (page_address(sg_page(&STp->buffer->sg[i])) + OS_DATA_SIZE - b_size);
 #if DEBUG
 		printk(OSST_DEB_MSG "%s:D: b_data points to %p in segment 0 at %p\n", name,
 			STp->buffer->b_data, page_address(STp->buffer->sg[0].page));
@@ -5252,25 +5252,26 @@ static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
 	/* Try to allocate the first segment up to OS_DATA_SIZE and the others
 	   big enough to reach the goal (code assumes no segments in place) */
 	for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) {
-		STbuffer->sg[0].page = alloc_pages(priority, order);
+		struct page *page = alloc_pages(priority, order);
+
 		STbuffer->sg[0].offset = 0;
-		if (STbuffer->sg[0].page != NULL) {
+		if (page != NULL) {
+		    sg_set_page(&STbuffer->sg[0], page);
 		    STbuffer->sg[0].length = b_size;
-		    STbuffer->b_data = page_address(STbuffer->sg[0].page);
+		    STbuffer->b_data = page_address(page);
 		    break;
 		}
 	}
-	if (STbuffer->sg[0].page == NULL) {
+	if (sg_page(&STbuffer->sg[0]) == NULL) {
 		printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n");
 		return 0;
 	}
 	/* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */
 	for (segs=STbuffer->sg_segs=1, got=b_size;
 	     segs < max_segs && got < OS_FRAME_SIZE; ) {
-		STbuffer->sg[segs].page =
-				alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
+		struct page *page = alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
 		STbuffer->sg[segs].offset = 0;
-		if (STbuffer->sg[segs].page == NULL) {
+		if (page == NULL) {
 			if (OS_FRAME_SIZE - got <= (max_segs - segs) * b_size / 2 && order) {
 				b_size /= 2;  /* Large enough for the rest of the buffers */
 				order--;
@@ -5284,6 +5285,7 @@ static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
 			normalize_buffer(STbuffer);
 			return 0;
 		}
+		sg_set_page(&STbuffer->sg[segs], page);
 		STbuffer->sg[segs].length = (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size;
 		got += STbuffer->sg[segs].length;
 		STbuffer->buffer_size = got;
@@ -5316,7 +5318,7 @@ static void normalize_buffer(struct osst_buffer *STbuffer)
 		     b_size < STbuffer->sg[i].length;
 		     b_size *= 2, order++);
 
-		__free_pages(STbuffer->sg[i].page, order);
+		__free_pages(sg_page(&STbuffer->sg[i]), order);
 		STbuffer->buffer_size -= STbuffer->sg[i].length;
 	}
 #if DEBUG
@@ -5344,7 +5346,7 @@ static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, i
 	for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length - offset < do_count ?
 		      st_bp->sg[i].length - offset : do_count;
-		res = copy_from_user(page_address(st_bp->sg[i].page) + offset, ubp, cnt);
+		res = copy_from_user(page_address(sg_page(&st_bp->sg[i])) + offset, ubp, cnt);
 		if (res)
 			return (-EFAULT);
 		do_count -= cnt;
@@ -5377,7 +5379,7 @@ static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count
 	for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length - offset < do_count ?
 		      st_bp->sg[i].length - offset : do_count;
-		res = copy_to_user(ubp, page_address(st_bp->sg[i].page) + offset, cnt);
+		res = copy_to_user(ubp, page_address(sg_page(&st_bp->sg[i])) + offset, cnt);
 		if (res)
 			return (-EFAULT);
 		do_count -= cnt;
@@ -5410,7 +5412,7 @@ static int osst_zero_buffer_tail(struct osst_buffer *st_bp)
 	     i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length - offset < do_count ?
 		      st_bp->sg[i].length - offset : do_count ;
-		memset(page_address(st_bp->sg[i].page) + offset, 0, cnt);
+		memset(page_address(sg_page(&st_bp->sg[i])) + offset, 0, cnt);
 		do_count -= cnt;
 		offset = 0;
 	}
@@ -5430,7 +5432,7 @@ static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
 	for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length < do_count ?
 		      st_bp->sg[i].length : do_count ;
-		memcpy(page_address(st_bp->sg[i].page), ptr, cnt);
+		memcpy(page_address(sg_page(&st_bp->sg[i])), ptr, cnt);
 		do_count -= cnt;
 		ptr      += cnt;
 	}
@@ -5451,7 +5453,7 @@ static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
 	for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length < do_count ?
 		      st_bp->sg[i].length : do_count ;
-		memcpy(ptr, page_address(st_bp->sg[i].page), cnt);
+		memcpy(ptr, page_address(sg_page(&st_bp->sg[i])), cnt);
 		do_count -= cnt;
 		ptr      += cnt;
 	}
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 190e2a7..26c41b0 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -443,7 +443,7 @@ SYM53C500_intr(int irq, void *dev_id)
 
 			scsi_for_each_sg(curSC, sg, scsi_sg_count(curSC), i) {
 				SYM53C500_pio_write(fast_pio, port_base,
-						    page_address(sg->page) + sg->offset,
+				    page_address(sg_page(sg)) + sg->offset,
 						    sg->length);
 			}
 			REG0(port_base);
@@ -463,8 +463,8 @@ SYM53C500_intr(int irq, void *dev_id)
 
 			scsi_for_each_sg(curSC, sg, scsi_sg_count(curSC), i) {
 				SYM53C500_pio_read(fast_pio, port_base,
-						   page_address(sg->page) + sg->offset,
-						   sg->length);
+					page_address(sg_page(sg)) + sg->offset,
+					sg->length);
 			}
 			REG0(port_base);
 		}
diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
index 67b6d76..07f31e5 100644
--- a/drivers/scsi/ppa.c
+++ b/drivers/scsi/ppa.c
@@ -609,7 +609,7 @@ static int ppa_completion(struct scsi_cmnd *cmd)
 				cmd->SCp.this_residual =
 				    cmd->SCp.buffer->length;
 				cmd->SCp.ptr =
-				    page_address(cmd->SCp.buffer->page) +
+				    page_address(sg_page(cmd->SCp.buffer)) +
 				    cmd->SCp.buffer->offset;
 			}
 		}
@@ -756,7 +756,7 @@ static int ppa_engine(ppa_struct *dev, struct scsi_cmnd *cmd)
 			/* if many buffers are available, start filling the first */
 			cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
 			cmd->SCp.this_residual = cmd->SCp.buffer->length;
-			cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) +
+			cmd->SCp.ptr = page_address(sg_page(cmd->SCp.buffer)) +
 			    cmd->SCp.buffer->offset;
 		} else {
 			/* else fill the only available buffer */
diff --git a/drivers/scsi/qlogicfas408.c b/drivers/scsi/qlogicfas408.c
index 2bfbf26..feff3f7 100644
--- a/drivers/scsi/qlogicfas408.c
+++ b/drivers/scsi/qlogicfas408.c
@@ -317,7 +317,7 @@ static unsigned int ql_pcmd(struct scsi_cmnd *cmd)
 				return ((priv->qabort == 1 ?
 					 DID_ABORT : DID_RESET) << 16);
 			}
-			buf = page_address(sg->page) + sg->offset;
+			buf = page_address(sg_page(sg)) + sg->offset;
 			if (ql_pdma(priv, phase, buf, sg->length))
 				break;
 		}
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 72ee4c9..46cae5a 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -625,7 +625,7 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
 	scsi_for_each_sg(scp, sg, scp->use_sg, k) {
 		if (active) {
 			kaddr = (unsigned char *)
-				kmap_atomic(sg->page, KM_USER0);
+				kmap_atomic(sg_page(sg), KM_USER0);
 			if (NULL == kaddr)
 				return (DID_ERROR << 16);
 			kaddr_off = (unsigned char *)kaddr + sg->offset;
@@ -672,7 +672,7 @@ static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
 	sg = scsi_sglist(scp);
 	req_len = fin = 0;
 	for (k = 0; k < scp->use_sg; ++k, sg = sg_next(sg)) {
-		kaddr = (unsigned char *)kmap_atomic(sg->page, KM_USER0);
+		kaddr = (unsigned char *)kmap_atomic(sg_page(sg), KM_USER0);
 		if (NULL == kaddr)
 			return -1;
 		kaddr_off = (unsigned char *)kaddr + sg->offset;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index aac8a02..61fdaf0 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -295,7 +295,7 @@ static int scsi_req_map_sg(struct request *rq, struct scatterlist *sgl,
 	int i, err, nr_vecs = 0;
 
 	for_each_sg(sgl, sg, nsegs, i) {
-		page = sg->page;
+		page = sg_page(sg);
 		off = sg->offset;
 		len = sg->length;
  		data_len += len;
@@ -764,7 +764,7 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
 		if (unlikely(!sgl))
 			goto enomem;
 
-		memset(sgl, 0, sizeof(*sgl) * sgp->size);
+		sg_init_table(sgl, sgp->size);
 
 		/*
 		 * first loop through, set initial index and return value
@@ -781,6 +781,13 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
 			sg_chain(prev, SCSI_MAX_SG_SEGMENTS, sgl);
 
 		/*
+		 * if we have nothing left, mark the last segment as
+		 * end-of-list
+		 */
+		if (!left)
+			sg_mark_end(sgl, this);
+
+		/*
 		 * don't allow subsequent mempool allocs to sleep, it would
 		 * violate the mempool principle.
 		 */
@@ -2353,7 +2360,7 @@ void *scsi_kmap_atomic_sg(struct scatterlist *sgl, int sg_count,
 	*offset = *offset - len_complete + sg->offset;
 
 	/* Assumption: contiguous pages can be accessed as "page + i" */
-	page = nth_page(sg->page, (*offset >> PAGE_SHIFT));
+	page = nth_page(sg_page(sg), (*offset >> PAGE_SHIFT));
 	*offset &= ~PAGE_MASK;
 
 	/* Bytes in this sg-entry from *offset to the end of the page */
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 7238b2d..cc19710 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1169,7 +1169,7 @@ sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type)
 		len = vma->vm_end - sa;
 		len = (len < sg->length) ? len : sg->length;
 		if (offset < len) {
-			page = virt_to_page(page_address(sg->page) + offset);
+			page = virt_to_page(page_address(sg_page(sg)) + offset);
 			get_page(page);	/* increment page count */
 			break;
 		}
@@ -1717,13 +1717,13 @@ st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,
 		   goto out_unlock; */
         }
 
-	sgl[0].page = pages[0];
+	sg_set_page(sgl, pages[0]);
 	sgl[0].offset = uaddr & ~PAGE_MASK;
 	if (nr_pages > 1) {
 		sgl[0].length = PAGE_SIZE - sgl[0].offset;
 		count -= sgl[0].length;
 		for (i=1; i < nr_pages ; i++) {
-			sgl[i].page = pages[i]; 
+			sg_set_page(&sgl[i], pages[i]);
 			sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
 			count -= PAGE_SIZE;
 		}
@@ -1754,7 +1754,7 @@ st_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_pages,
 	int i;
 
 	for (i=0; i < nr_pages; i++) {
-		struct page *page = sgl[i].page;
+		struct page *page = sg_page(&sgl[i]);
 
 		if (dirtied)
 			SetPageDirty(page);
@@ -1854,7 +1854,7 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
 				scatter_elem_sz_prev = ret_sz;
 			}
 		}
-		sg->page = p;
+		sg_set_page(sg, p);
 		sg->length = (ret_sz > num) ? num : ret_sz;
 
 		SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k=%d, num=%d, "
@@ -1907,14 +1907,14 @@ sg_write_xfer(Sg_request * srp)
 		onum = 1;
 
 	ksglen = sg->length;
-	p = page_address(sg->page);
+	p = page_address(sg_page(sg));
 	for (j = 0, k = 0; j < onum; ++j) {
 		res = sg_u_iovec(hp, iovec_count, j, 1, &usglen, &up);
 		if (res)
 			return res;
 
 		for (; p; sg = sg_next(sg), ksglen = sg->length,
-		     p = page_address(sg->page)) {
+		     p = page_address(sg_page(sg))) {
 			if (usglen <= 0)
 				break;
 			if (ksglen > usglen) {
@@ -1991,12 +1991,12 @@ sg_remove_scat(Sg_scatter_hold * schp)
 		} else {
 			int k;
 
-			for (k = 0; (k < schp->k_use_sg) && sg->page;
+			for (k = 0; (k < schp->k_use_sg) && sg_page(sg);
 			     ++k, sg = sg_next(sg)) {
 				SCSI_LOG_TIMEOUT(5, printk(
 				    "sg_remove_scat: k=%d, pg=0x%p, len=%d\n",
-				    k, sg->page, sg->length));
-				sg_page_free(sg->page, sg->length);
+				    k, sg_page(sg), sg->length));
+				sg_page_free(sg_page(sg), sg->length);
 			}
 		}
 		kfree(schp->buffer);
@@ -2038,7 +2038,7 @@ sg_read_xfer(Sg_request * srp)
 	} else
 		onum = 1;
 
-	p = page_address(sg->page);
+	p = page_address(sg_page(sg));
 	ksglen = sg->length;
 	for (j = 0, k = 0; j < onum; ++j) {
 		res = sg_u_iovec(hp, iovec_count, j, 0, &usglen, &up);
@@ -2046,7 +2046,7 @@ sg_read_xfer(Sg_request * srp)
 			return res;
 
 		for (; p; sg = sg_next(sg), ksglen = sg->length,
-		     p = page_address(sg->page)) {
+		     p = page_address(sg_page(sg))) {
 			if (usglen <= 0)
 				break;
 			if (ksglen > usglen) {
@@ -2092,15 +2092,15 @@ sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer)
 	if ((!outp) || (num_read_xfer <= 0))
 		return 0;
 
-	for (k = 0; (k < schp->k_use_sg) && sg->page; ++k, sg = sg_next(sg)) {
+	for (k = 0; (k < schp->k_use_sg) && sg_page(sg); ++k, sg = sg_next(sg)) {
 		num = sg->length;
 		if (num > num_read_xfer) {
-			if (__copy_to_user(outp, page_address(sg->page),
+			if (__copy_to_user(outp, page_address(sg_page(sg)),
 					   num_read_xfer))
 				return -EFAULT;
 			break;
 		} else {
-			if (__copy_to_user(outp, page_address(sg->page),
+			if (__copy_to_user(outp, page_address(sg_page(sg)),
 					   num))
 				return -EFAULT;
 			num_read_xfer -= num;
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 73c44cb..ce69b9e 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -3797,7 +3797,7 @@ static void buf_to_sg(struct st_buffer *STbp, unsigned int length)
 	sg = &(STbp->sg[0]);
 	frp = STbp->frp;
 	for (i=count=0; count < length; i++) {
-		sg[i].page = frp[i].page;
+		sg_set_page(&sg[i], frp[i].page);
 		if (length - count > frp[i].length)
 			sg[i].length = frp[i].length;
 		else
@@ -4446,14 +4446,14 @@ static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pa
         }
 
 	/* Populate the scatter/gather list */
-	sgl[0].page = pages[0]; 
+	sg_set_page(&sgl[0], pages[0]);
 	sgl[0].offset = uaddr & ~PAGE_MASK;
 	if (nr_pages > 1) {
 		sgl[0].length = PAGE_SIZE - sgl[0].offset;
 		count -= sgl[0].length;
 		for (i=1; i < nr_pages ; i++) {
+			sg_set_page(&sgl[i], pages[i]);;
 			sgl[i].offset = 0;
-			sgl[i].page = pages[i]; 
 			sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
 			count -= PAGE_SIZE;
 		}
@@ -4483,7 +4483,7 @@ static int sgl_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_p
 	int i;
 
 	for (i=0; i < nr_pages; i++) {
-		struct page *page = sgl[i].page;
+		struct page *page = sg_page(&sgl[i]);
 
 		if (dirtied)
 			SetPageDirty(page);
diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c
index 5c72ca3..4419304 100644
--- a/drivers/scsi/tmscsim.c
+++ b/drivers/scsi/tmscsim.c
@@ -430,10 +430,7 @@ static __inline__ void dc390_Going_remove (struct dc390_dcb* pDCB, struct dc390_
 
 static struct scatterlist* dc390_sg_build_single(struct scatterlist *sg, void *addr, unsigned int length)
 {
-	memset(sg, 0, sizeof(struct scatterlist));
-	sg->page	= virt_to_page(addr);
-	sg->length	= length;
-	sg->offset	= (unsigned long)addr & ~PAGE_MASK;
+	sg_init_one(sg, addr, length);
 	return sg;
 }
 
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index c021af3..3577453 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -438,12 +438,12 @@ int usb_sg_init (
 			io->urbs[i]->transfer_buffer = NULL;
 #else
 			io->urbs[i]->transfer_buffer =
-				page_address(sg[i].page) + sg[i].offset;
+				page_address(sg_page(&sg[i])) + sg[i].offset;
 #endif
 		} else {
 			/* hc may use _only_ transfer_buffer */
 			io->urbs [i]->transfer_buffer =
-				page_address (sg [i].page) + sg [i].offset;
+				page_address(sg_page(&sg[i])) + sg [i].offset;
 			len = sg [i].length;
 		}
 
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
index e7d982a..4866baf 100644
--- a/drivers/usb/image/microtek.c
+++ b/drivers/usb/image/microtek.c
@@ -519,7 +519,7 @@ static void mts_do_sg (struct urb* transfer)
 	context->fragment++;
 	mts_int_submit_urb(transfer,
 			   context->data_pipe,
-			   page_address(sg[context->fragment].page) +
+			   page_address(sg_page(&sg[context->fragment])) +
 			   sg[context->fragment].offset,
 			   sg[context->fragment].length,
 			   context->fragment + 1 == scsi_sg_count(context->srb) ?
@@ -557,7 +557,7 @@ mts_build_transfer_context(struct scsi_cmnd *srb, struct mts_desc* desc)
 		return;
 	} else {
 		sg = scsi_sglist(srb);
-		desc->context.data = page_address(sg[0].page) + sg[0].offset;
+		desc->context.data = page_address(sg_page(&sg[0])) + sg[0].offset;
 		desc->context.data_length = sg[0].length;
 	}
 
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index e901d31..ca8cb34 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -360,9 +360,10 @@ static void free_sglist (struct scatterlist *sg, int nents)
 	if (!sg)
 		return;
 	for (i = 0; i < nents; i++) {
-		if (!sg [i].page)
+		struct page *page = sg_page(&sg[i]);
+		if (!page)
 			continue;
-		kfree (page_address (sg [i].page) + sg [i].offset);
+		kfree (page_address (page) + sg [i].offset);
 	}
 	kfree (sg);
 }
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c
index cc8f7c5..889622b 100644
--- a/drivers/usb/storage/protocol.c
+++ b/drivers/usb/storage/protocol.c
@@ -195,7 +195,7 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
 		 * the *offset and *index values for the next loop. */
 		cnt = 0;
 		while (cnt < buflen) {
-			struct page *page = sg->page +
+			struct page *page = sg_page(sg) +
 					((sg->offset + *offset) >> PAGE_SHIFT);
 			unsigned int poff =
 					(sg->offset + *offset) & (PAGE_SIZE-1);
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index 1ae90ef..0a9882e 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -283,7 +283,7 @@ int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg,
 		pg = virt_to_page(addr);
 		offset = offset_in_page(addr);
 		if (sg) {
-			sg[i].page = pg;
+			sg_set_page(&sg[i], pg);
 			sg[i].offset = offset;
 		}
 		remainder_of_page = PAGE_CACHE_SIZE - offset;
@@ -713,10 +713,13 @@ ecryptfs_encrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
 {
 	struct scatterlist src_sg, dst_sg;
 
-	src_sg.page = src_page;
+	sg_init_table(&src_sg, 1);
+	sg_init_table(&dst_sg, 1);
+
+	sg_set_page(&src_sg, src_page);
 	src_sg.offset = src_offset;
 	src_sg.length = size;
-	dst_sg.page = dst_page;
+	sg_set_page(&dst_sg, dst_page);
 	dst_sg.offset = dst_offset;
 	dst_sg.length = size;
 	return encrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
@@ -742,10 +745,13 @@ ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
 {
 	struct scatterlist src_sg, dst_sg;
 
-	src_sg.page = src_page;
+	sg_init_table(&src_sg, 1);
+	sg_init_table(&dst_sg, 1);
+
+	sg_set_page(&src_sg, src_page);
 	src_sg.offset = src_offset;
 	src_sg.length = size;
-	dst_sg.page = dst_page;
+	sg_set_page(&dst_sg, dst_page);
 	dst_sg.offset = dst_offset;
 	dst_sg.length = size;
 	return decrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 89d9710..263fed8 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -1040,6 +1040,9 @@ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
 	};
 	int rc = 0;
 
+	sg_init_table(&dst_sg, 1);
+	sg_init_table(&src_sg, 1);
+
 	if (unlikely(ecryptfs_verbosity > 0)) {
 		ecryptfs_printk(
 			KERN_DEBUG, "Session key encryption key (size [%d]):\n",
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index ebd03cc..6f03918 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -88,7 +88,7 @@ nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname)
 {
 	struct xdr_netobj cksum;
 	struct hash_desc desc;
-	struct scatterlist sg[1];
+	struct scatterlist sg;
 	__be32 status = nfserr_resource;
 
 	dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n",
@@ -102,11 +102,9 @@ nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname)
 	if (cksum.data == NULL)
  		goto out;
 
-	sg[0].page = virt_to_page(clname->data);
-	sg[0].offset = offset_in_page(clname->data);
-	sg[0].length = clname->len;
+	sg_init_one(&sg, clname->data, clname->len);
 
-	if (crypto_hash_digest(&desc, sg, sg->length, cksum.data))
+	if (crypto_hash_digest(&desc, &sg, sg.length, cksum.data))
 		goto out;
 
 	md5_to_hex(dname, cksum.data);
diff --git a/include/asm-sparc64/scatterlist.h b/include/asm-sparc64/scatterlist.h
index 703c5bb..6df23f0 100644
--- a/include/asm-sparc64/scatterlist.h
+++ b/include/asm-sparc64/scatterlist.h
@@ -6,7 +6,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page	*page;
+#ifdef CONFIG_DEBUG_SG
+	unsigned long	sg_magic;
+#endif
+	unsigned long	page_link;
 	unsigned int	offset;
 
 	unsigned int	length;
diff --git a/include/asm-x86/dma-mapping_32.h b/include/asm-x86/dma-mapping_32.h
index 6a2d26c..e0d38d8 100644
--- a/include/asm-x86/dma-mapping_32.h
+++ b/include/asm-x86/dma-mapping_32.h
@@ -45,9 +45,9 @@ dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
 	WARN_ON(nents == 0 || sglist[0].length == 0);
 
 	for_each_sg(sglist, sg, nents, i) {
-		BUG_ON(!sg->page);
+		BUG_ON(!sg_page(sg));
 
-		sg->dma_address = page_to_phys(sg->page) + sg->offset;
+		sg->dma_address = page_to_phys(sg_page(sg)) + sg->offset;
 	}
 
 	flush_write_buffers();
diff --git a/include/asm-x86/scatterlist_32.h b/include/asm-x86/scatterlist_32.h
index bd5164a..0e7d997 100644
--- a/include/asm-x86/scatterlist_32.h
+++ b/include/asm-x86/scatterlist_32.h
@@ -4,7 +4,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page		*page;
+#ifdef CONFIG_DEBUG_SG
+    unsigned long	sg_magic;
+#endif
+    unsigned long	page_link;
     unsigned int	offset;
     dma_addr_t		dma_address;
     unsigned int	length;
diff --git a/include/asm-x86/scatterlist_64.h b/include/asm-x86/scatterlist_64.h
index ef3986b..1847c72 100644
--- a/include/asm-x86/scatterlist_64.h
+++ b/include/asm-x86/scatterlist_64.h
@@ -4,7 +4,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page		*page;
+#ifdef CONFIG_DEBUG_SG
+    unsigned long	sg_magic;
+#endif
+    unsigned long	page_link;
     unsigned int	offset;
     unsigned int	length;
     dma_addr_t		dma_address;
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index 2dc7464..013164b 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -5,29 +5,37 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 
+#define SG_MAGIC	0x87654321
+
+static inline void sg_set_page(struct scatterlist *sg, struct page *page)
+{
+	unsigned long page_link = sg->page_link & 0x3;
+
+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(sg->sg_magic != SG_MAGIC);
+#endif
+	sg->page_link = page_link | (unsigned long) page;
+}
+
+#define sg_page(sg)	((struct page *) ((sg)->page_link & ~0x3))
+
 static inline void sg_set_buf(struct scatterlist *sg, const void *buf,
 			      unsigned int buflen)
 {
-	sg->page = virt_to_page(buf);
+	sg_set_page(sg, virt_to_page(buf));
 	sg->offset = offset_in_page(buf);
 	sg->length = buflen;
 }
 
-static inline void sg_init_one(struct scatterlist *sg, const void *buf,
-			       unsigned int buflen)
-{
-	memset(sg, 0, sizeof(*sg));
-	sg_set_buf(sg, buf, buflen);
-}
-
 /*
  * We overload the LSB of the page pointer to indicate whether it's
  * a valid sg entry, or whether it points to the start of a new scatterlist.
  * Those low bits are there for everyone! (thanks mason :-)
  */
-#define sg_is_chain(sg)		((unsigned long) (sg)->page & 0x01)
+#define sg_is_chain(sg)		((sg)->page_link & 0x01)
+#define sg_is_last(sg)		((sg)->page_link & 0x02)
 #define sg_chain_ptr(sg)	\
-	((struct scatterlist *) ((unsigned long) (sg)->page & ~0x01))
+	((struct scatterlist *) ((sg)->page_link & ~0x03))
 
 /**
  * sg_next - return the next scatterlist entry in a list
@@ -43,10 +51,15 @@ static inline void sg_init_one(struct scatterlist *sg, const void *buf,
  */
 static inline struct scatterlist *sg_next(struct scatterlist *sg)
 {
-	sg++;
-
-	if (unlikely(sg_is_chain(sg)))
+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(sg->sg_magic != SG_MAGIC);
+#endif
+	if (sg_is_last(sg))
+		sg = NULL;
+	else if (sg_is_chain(sg))
 		sg = sg_chain_ptr(sg);
+	else
+		sg++;
 
 	return sg;
 }
@@ -83,6 +96,9 @@ static inline struct scatterlist *sg_last(struct scatterlist *sgl,
 		ret = sg;
 
 #endif
+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(sgl[0].sg_magic != SG_MAGIC);
+#endif
 	return ret;
 }
 
@@ -101,7 +117,45 @@ static inline void sg_chain(struct scatterlist *prv, unsigned int prv_nents,
 #ifndef ARCH_HAS_SG_CHAIN
 	BUG();
 #endif
-	prv[prv_nents - 1].page = (struct page *) ((unsigned long) sgl | 0x01);
+	prv[prv_nents - 1].page_link = (unsigned long) sgl | 0x01;
 }
 
+/**
+ * sg_mark_end - Mark the end of the scatterlist
+ * @sgl:	Scatterlist
+ * @nents:	Number of entries in sgl
+ *
+ * Marks the last entry as the termination point for sg_next()
+ *
+ */
+static inline void sg_mark_end(struct scatterlist *sgl, unsigned int nents)
+{
+	sgl[nents - 1].page_link = 0x02;
+}
+
+static inline void sg_init_one(struct scatterlist *sg, const void *buf,
+			       unsigned int buflen)
+{
+	memset(sg, 0, sizeof(*sg));
+#ifdef CONFIG_DEBUG_SG
+	sg->sg_magic = SG_MAGIC;
+#endif
+	sg_set_buf(sg, buf, buflen);
+	sg_mark_end(sg, 1);
+}
+
+static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents)
+{
+	memset(sgl, 0, sizeof(*sgl) * nents);
+	sg_mark_end(sgl, nents);
+#ifdef CONFIG_DEBUG_SG
+	{
+		int i;
+		for (i = 0; i < nents; i++)
+			sgl[i].sg_magic = SG_MAGIC;
+	}
+#endif
+}
+
+
 #endif /* _LINUX_SCATTERLIST_H */
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 7d16e64..183f42c 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -389,6 +389,16 @@ config DEBUG_LIST
 
 	  If unsure, say N.
 
+config DEBUG_SG
+	bool "Debug SG table operations"
+	depends on DEBUG_KERNEL
+	help
+	  Enable this to turn on checks on scatter-gather tables. This can
+	  help find problems with drivers that do not properly initialize
+	  their sg tables.
+
+	  If unsure, say N.
+
 config FRAME_POINTER
 	bool "Compile the kernel with frame pointers"
 	depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML || S390 || AVR32 || SUPERH || BFIN)
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 752fd95..e58909e 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -35,7 +35,7 @@
 #define OFFSET(val,align) ((unsigned long)	\
 	                   ( (val) & ( (align) - 1)))
 
-#define SG_ENT_VIRT_ADDRESS(sg)	(page_address((sg)->page) + (sg)->offset)
+#define SG_ENT_VIRT_ADDRESS(sg)	(page_address(sg_page((sg)) + (sg)->offset))
 #define SG_ENT_PHYS_ADDRESS(sg)	virt_to_bus(SG_ENT_VIRT_ADDRESS(sg))
 
 /*
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 70d9b5d..4e2c84f 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2045,7 +2045,7 @@ skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
 	if (copy > 0) {
 		if (copy > len)
 			copy = len;
-		sg[elt].page = virt_to_page(skb->data + offset);
+		sg_set_page(&sg[elt], virt_to_page(skb->data + offset));
 		sg[elt].offset = (unsigned long)(skb->data + offset) % PAGE_SIZE;
 		sg[elt].length = copy;
 		elt++;
@@ -2065,7 +2065,7 @@ skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
 
 			if (copy > len)
 				copy = len;
-			sg[elt].page = frag->page;
+			sg_set_page(&sg[elt], frag->page);
 			sg[elt].offset = frag->page_offset+offset-start;
 			sg[elt].length = copy;
 			elt++;
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
index 6cc54ee..34d4c77 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -390,9 +390,7 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	icv[3] = crc >> 24;
 
 	crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = len + 4;
+	sg_init_one(&sg, pos, len + 4);
 	return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
 }
 
@@ -485,9 +483,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	plen = skb->len - hdr_len - 12;
 
 	crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = plen + 4;
+	sg_init_one(&sg, pos, plen + 4);
 	if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG ": TKIP: failed to decrypt "
@@ -539,11 +535,12 @@ static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
 		printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
 		return -1;
 	}
-	sg[0].page = virt_to_page(hdr);
+	sg_init_table(sg, 2);
+	sg_set_page(&sg[0], virt_to_page(hdr));
 	sg[0].offset = offset_in_page(hdr);
 	sg[0].length = 16;
 
-	sg[1].page = virt_to_page(data);
+	sg_set_page(&sg[1], virt_to_page(data));
 	sg[1].offset = offset_in_page(data);
 	sg[1].length = data_len;
 
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
index 8d18245..0af6103 100644
--- a/net/ieee80211/ieee80211_crypt_wep.c
+++ b/net/ieee80211/ieee80211_crypt_wep.c
@@ -170,9 +170,7 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	icv[3] = crc >> 24;
 
 	crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = len + 4;
+	sg_init_one(&sg, pos, len + 4);
 	return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
 }
 
@@ -212,9 +210,7 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	plen = skb->len - hdr_len - 8;
 
 	crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = plen + 4;
+	sg_init_one(&sg, pos, plen + 4);
 	if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
 		return -7;
 
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 6675261..cc806d6 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -138,9 +138,7 @@ void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
 	*icv = cpu_to_le32(~crc32_le(~0, data, data_len));
 
 	crypto_blkcipher_setkey(tfm, rc4key, klen);
-	sg.page = virt_to_page(data);
-	sg.offset = offset_in_page(data);
-	sg.length = data_len + WEP_ICV_LEN;
+	sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
 	crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length);
 }
 
@@ -204,9 +202,7 @@ int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
 	__le32 crc;
 
 	crypto_blkcipher_setkey(tfm, rc4key, klen);
-	sg.page = virt_to_page(data);
-	sg.offset = offset_in_page(data);
-	sg.length = data_len + WEP_ICV_LEN;
+	sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
 	crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length);
 
 	crc = cpu_to_le32(~crc32_le(~0, data, data_len));
diff --git a/net/sctp/auth.c b/net/sctp/auth.c
index 7818107..cbd64b2 100644
--- a/net/sctp/auth.c
+++ b/net/sctp/auth.c
@@ -726,7 +726,8 @@ void sctp_auth_calculate_hmac(const struct sctp_association *asoc,
 
 	/* set up scatter list */
 	end = skb_tail_pointer(skb);
-	sg.page = virt_to_page(auth);
+	sg_init_table(&sg, 1);
+	sg_set_page(&sg, virt_to_page(auth));
 	sg.offset = (unsigned long)(auth) % PAGE_SIZE;
 	sg.length = end - (unsigned char *)auth;
 
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index f983a36..d5a9785 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1513,7 +1513,8 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
 		struct hash_desc desc;
 
 		/* Sign the message.  */
-		sg.page = virt_to_page(&cookie->c);
+		sg_init_table(&sg, 1);
+		sg_set_page(&sg, virt_to_page(&cookie->c));
 		sg.offset = (unsigned long)(&cookie->c) % PAGE_SIZE;
 		sg.length = bodysize;
 		keylen = SCTP_SECRET_SIZE;
@@ -1585,7 +1586,8 @@ struct sctp_association *sctp_unpack_cookie(
 
 	/* Check the signature.  */
 	keylen = SCTP_SECRET_SIZE;
-	sg.page = virt_to_page(bear_cookie);
+	sg_init_table(&sg, 1);
+	sg_set_page(&sg, virt_to_page(bear_cookie));
 	sg.offset = (unsigned long)(bear_cookie) % PAGE_SIZE;
 	sg.length = bodysize;
 	key = (char *)ep->secret_key[ep->current_key];
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index bfb6a29..32be431 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -197,9 +197,9 @@ encryptor(struct scatterlist *sg, void *data)
 		int i = (page_pos + outbuf->page_base) >> PAGE_CACHE_SHIFT;
 		in_page = desc->pages[i];
 	} else {
-		in_page = sg->page;
+		in_page = sg_page(sg);
 	}
-	desc->infrags[desc->fragno].page = in_page;
+	sg_set_page(&desc->infrags[desc->fragno], in_page);
 	desc->fragno++;
 	desc->fraglen += sg->length;
 	desc->pos += sg->length;
@@ -215,11 +215,11 @@ encryptor(struct scatterlist *sg, void *data)
 	if (ret)
 		return ret;
 	if (fraglen) {
-		desc->outfrags[0].page = sg->page;
+		sg_set_page(&desc->outfrags[0], sg_page(sg));
 		desc->outfrags[0].offset = sg->offset + sg->length - fraglen;
 		desc->outfrags[0].length = fraglen;
 		desc->infrags[0] = desc->outfrags[0];
-		desc->infrags[0].page = in_page;
+		sg_set_page(&desc->infrags[0], in_page);
 		desc->fragno = 1;
 		desc->fraglen = fraglen;
 	} else {
@@ -287,7 +287,7 @@ decryptor(struct scatterlist *sg, void *data)
 	if (ret)
 		return ret;
 	if (fraglen) {
-		desc->frags[0].page = sg->page;
+		sg_set_page(&desc->frags[0], sg_page(sg));
 		desc->frags[0].offset = sg->offset + sg->length - fraglen;
 		desc->frags[0].length = fraglen;
 		desc->fragno = 1;
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 6a59180..3d1f7cd 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -1059,7 +1059,7 @@ xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len,
 		do {
 			if (thislen > page_len)
 				thislen = page_len;
-			sg->page = buf->pages[i];
+			sg_set_page(sg, buf->pages[i]);
 			sg->offset = page_offset;
 			sg->length = thislen;
 			ret = actor(sg, data);
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index 5ced62c..fb2220a 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -552,7 +552,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
 		if (copy > len)
 			copy = len;
 
-		sg.page = virt_to_page(skb->data + offset);
+		sg_set_page(&sg, virt_to_page(skb->data + offset));
 		sg.offset = (unsigned long)(skb->data + offset) % PAGE_SIZE;
 		sg.length = copy;
 
@@ -577,7 +577,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
 			if (copy > len)
 				copy = len;
 
-			sg.page = frag->page;
+			sg_set_page(&sg, frag->page);
 			sg.offset = frag->page_offset + offset-start;
 			sg.length = copy;
 

-- 
Jens Axboe


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

* Re: [bug] block subsystem related crash with latest -git
  2007-10-18 12:03                   ` David Miller
@ 2007-10-18 12:28                     ` Jens Axboe
  0 siblings, 0 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-18 12:28 UTC (permalink / raw)
  To: David Miller; +Cc: bhalevy, torvalds, mingo, linux-kernel, akpm

On Thu, Oct 18 2007, David Miller wrote:
> From: Jens Axboe <jens.axboe@oracle.com>
> Date: Thu, 18 Oct 2007 12:55:17 +0200
> 
> > Things have progressed a lot since, see my recent posting based on
> > Davem's proposal. Will post another patch soonish, that is also
> > tested.
> 
> One core issue here is that we need to decide whether this thing to be
> iterated like an array or like a linked list.  It's trying to be both.
> 
> If we decide upon a looping construct for consumers and stick to it,
> we'll be in much better shape than we are now and bugs will be eaiser
> to spot.  It would be so much simpler to audit if all we saw in the
> consumers were things like:
> 
> 	while (sg) {
> 		do_stuff(sg);
> 		sg = sg_next(sg);
> 	}
> 
> I would suggest that we just get it over with and convert the whole
> tree now rather than trying to do this kind of thing in stages.
> Because then we can say that ever scatterlist creator has to set
> the "end" bit and therefore you use well established patterns
> for scatterlist iteration such as "traverse sg_next() until NULL"
> as shown above.

The above should work now, PROVIDED that the end has been marked
properly. I have added some helpers to init an sglist (or sg entry).
You can still use

        for_each_sg()

and pass in the number of entries, that'll work even with an end marker.
So, it does both.

> I also noticed that there is the issue of on-stack and embedded
> scatterlist users.  We'll need some sort of "DECLARE_SCATTERLIST"
> and a "scatterlist_init()" thing so that we can keep DEBUG_SG
> working even in those cases.  But for all I know Jens could be
> working on that already :-)

Heh, got some of it covered! The stack usage is generally just converted
to either use sg_init_one() if we can, or sg_init_table(). Adding some
soft of DECLARE_SCATTERLIST() sounds like a good idea, though. I'll take
patches :-)

> The only other real option if we don't convert the whole tree now to
> the "end" marker stuff, is to enforce that every scatterlist iterator
> only traverse the number of entries there were told are in the one
> given to them.

Driver that do all their own sg management typically still use a manual
loop over the number of entries they know are there. I didn't change
those, and the original sg chaining didn't convert those either. Some
manual labor is required in utilizing chained sg lists, unless you are
part of a subsystem (like SCSI) that allocates and inits themf or you.
So I still think that baby steps are a good idea - only convert things
that matter. Leave the rest to janitors or others willing to dive in.

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 12:15                                                     ` Jens Axboe
@ 2007-10-18 12:36                                                       ` David Miller
  2007-10-18 12:39                                                         ` Jens Axboe
  2007-10-18 12:58                                                       ` Benny Halevy
  2007-10-18 12:58                                                       ` Jens Axboe
  2 siblings, 1 reply; 151+ messages in thread
From: David Miller @ 2007-10-18 12:36 UTC (permalink / raw)
  To: jens.axboe
  Cc: torvalds, fujita.tomonori, mingo, linux-kernel, jgarzik, alan,
	tomof

From: Jens Axboe <jens.axboe@oracle.com>
Date: Thu, 18 Oct 2007 14:15:47 +0200

> On Thu, Oct 18 2007, Jens Axboe wrote:
> > On Thu, Oct 18 2007, David Miller wrote:
> > > From: Jens Axboe <jens.axboe@oracle.com>
> > > Date: Thu, 18 Oct 2007 13:57:02 +0200
> > > 
> > > > Thanks a lot, Dave! The patch is a monster right now, I'll work on
> > > > splitting it into a 3-step process. Any arch help is greatly
> > > > appreciated.
> > > 
> > > I have some other bits that my compile hit, such as some things in the
> > > crypto layer.
> > 
> > Yeah, I have tons of that so far. I hope to have an allyesconfig
> > compiling pretty soonish, will send that out then.
> 
> OK here goes, this compiles with allyesconfig on x86-64. Not too bad,
> the scsi/ drivers were by far the worst.

It build cleanly here on sparc64 too.

It's late and I'm about to hit bed so I'm too chicken to do a test
boot it right now :-)


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 12:36                                                       ` David Miller
@ 2007-10-18 12:39                                                         ` Jens Axboe
  0 siblings, 0 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-18 12:39 UTC (permalink / raw)
  To: David Miller
  Cc: torvalds, fujita.tomonori, mingo, linux-kernel, jgarzik, alan,
	tomof

On Thu, Oct 18 2007, David Miller wrote:
> From: Jens Axboe <jens.axboe@oracle.com>
> Date: Thu, 18 Oct 2007 14:15:47 +0200
> 
> > On Thu, Oct 18 2007, Jens Axboe wrote:
> > > On Thu, Oct 18 2007, David Miller wrote:
> > > > From: Jens Axboe <jens.axboe@oracle.com>
> > > > Date: Thu, 18 Oct 2007 13:57:02 +0200
> > > > 
> > > > > Thanks a lot, Dave! The patch is a monster right now, I'll work on
> > > > > splitting it into a 3-step process. Any arch help is greatly
> > > > > appreciated.
> > > > 
> > > > I have some other bits that my compile hit, such as some things in the
> > > > crypto layer.
> > > 
> > > Yeah, I have tons of that so far. I hope to have an allyesconfig
> > > compiling pretty soonish, will send that out then.
> > 
> > OK here goes, this compiles with allyesconfig on x86-64. Not too bad,
> > the scsi/ drivers were by far the worst.
> 
> It build cleanly here on sparc64 too.

Super

> It's late and I'm about to hit bed so I'm too chicken to do a test
> boot it right now :-)

Don't boot it Dave, odds are that something will break and you'll then
be stuck debugging that since you can't relax and sleep until it's
working :-)

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 12:15                                                     ` Jens Axboe
  2007-10-18 12:36                                                       ` David Miller
@ 2007-10-18 12:58                                                       ` Benny Halevy
  2007-10-18 13:56                                                         ` Jens Axboe
  2007-10-18 12:58                                                       ` Jens Axboe
  2 siblings, 1 reply; 151+ messages in thread
From: Benny Halevy @ 2007-10-18 12:58 UTC (permalink / raw)
  To: Jens Axboe
  Cc: David Miller, torvalds, fujita.tomonori, mingo, linux-kernel,
	jgarzik, alan, tomof

On Oct. 18, 2007, 14:15 +0200, Jens Axboe <jens.axboe@oracle.com> wrote:
<snip>
>  /**
>   * sg_next - return the next scatterlist entry in a list
> @@ -43,10 +51,15 @@ static inline void sg_init_one(struct scatterlist *sg, const void *buf,
>   */
>  static inline struct scatterlist *sg_next(struct scatterlist *sg)
>  {
> -	sg++;
> -
> -	if (unlikely(sg_is_chain(sg)))
> +#ifdef CONFIG_DEBUG_SG
> +	BUG_ON(sg->sg_magic != SG_MAGIC);
> +#endif
> +	if (sg_is_last(sg))
> +		sg = NULL;
> +	else if (sg_is_chain(sg))
>  		sg = sg_chain_ptr(sg);
> +	else
> +		sg++;

Hmm, sg_next is not supposed to return a pointer to the chain entry
itself, but rather skip it.  I think that the fix needs only
check the "last" flag before incrementing sg.

+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(sg->sg_magic != SG_MAGIC);
+#endif
+	if (sg_is_last(sg))
+		return NULL;
+
 	sg++
 
 	if (unlikely(sg_is_chain(sg)))
 		sg = sg_chain_ptr(sg);

>  
>  	return sg;
>  }
> @@ -83,6 +96,9 @@ static inline struct scatterlist *sg_last(struct scatterlist *sgl,
>  		ret = sg;
>  
>  #endif
> +#ifdef CONFIG_DEBUG_SG
> +	BUG_ON(sgl[0].sg_magic != SG_MAGIC);

can it also do BUG_ON(!sg_is_last(sg))?

> +#endif
>  	return ret;
>  }
>  


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 12:15                                                     ` Jens Axboe
  2007-10-18 12:36                                                       ` David Miller
  2007-10-18 12:58                                                       ` Benny Halevy
@ 2007-10-18 12:58                                                       ` Jens Axboe
  2007-10-18 13:32                                                         ` Jens Axboe
  2 siblings, 1 reply; 151+ messages in thread
From: Jens Axboe @ 2007-10-18 12:58 UTC (permalink / raw)
  To: David Miller
  Cc: torvalds, fujita.tomonori, mingo, linux-kernel, jgarzik, alan,
	tomof

On Thu, Oct 18 2007, Jens Axboe wrote:
> On Thu, Oct 18 2007, Jens Axboe wrote:
> > On Thu, Oct 18 2007, David Miller wrote:
> > > From: Jens Axboe <jens.axboe@oracle.com>
> > > Date: Thu, 18 Oct 2007 13:57:02 +0200
> > > 
> > > > Thanks a lot, Dave! The patch is a monster right now, I'll work on
> > > > splitting it into a 3-step process. Any arch help is greatly
> > > > appreciated.
> > > 
> > > I have some other bits that my compile hit, such as some things in the
> > > crypto layer.
> > 
> > Yeah, I have tons of that so far. I hope to have an allyesconfig
> > compiling pretty soonish, will send that out then.
> 
> OK here goes, this compiles with allyesconfig on x86-64. Not too bad,
> the scsi/ drivers were by far the worst.

Alright, small modifications and tested somewhat. It boots on my laptop
just fine (CONFIG_DEBUG_SG is set) without warnings. Also tested with
PAGEALLOC set, that also boots and works fine without issue.

So if this is what we want, the question is how to proceed. Right now
i386 and x86-64 works, sparc64 PROBABLY works but is not tested. Any
other arch will NOT compile, since it's not converted to use page_link.
I'll try and do ppc64 now.


diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c
index 29af777..73852a2 100644
--- a/arch/sparc64/kernel/iommu.c
+++ b/arch/sparc64/kernel/iommu.c
@@ -473,7 +473,7 @@ static void dma_4u_unmap_single(struct device *dev, dma_addr_t bus_addr,
 }
 
 #define SG_ENT_PHYS_ADDRESS(SG)	\
-	(__pa(page_address((SG)->page)) + (SG)->offset)
+	(__pa(page_address(sg_page(SG))) + (SG)->offset)
 
 static void fill_sg(iopte_t *iopte, struct scatterlist *sg,
 		    int nused, int nelems,
@@ -566,7 +566,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
 	if (nelems == 1) {
 		sglist->dma_address =
 			dma_4u_map_single(dev,
-					  (page_address(sglist->page) +
+					  (page_address(sg_page(sglist)) +
 					   sglist->offset),
 					  sglist->length, direction);
 		if (unlikely(sglist->dma_address == DMA_ERROR_CODE))
diff --git a/arch/sparc64/kernel/iommu_common.c b/arch/sparc64/kernel/iommu_common.c
index d7ca900..ec863e0 100644
--- a/arch/sparc64/kernel/iommu_common.c
+++ b/arch/sparc64/kernel/iommu_common.c
@@ -73,7 +73,7 @@ static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg,
 
 	daddr = dma_sg->dma_address;
 	sglen = sg->length;
-	sgaddr = (unsigned long) (page_address(sg->page) + sg->offset);
+	sgaddr = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
 	while (dlen > 0) {
 		unsigned long paddr;
 
@@ -123,7 +123,7 @@ static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg,
 		sg = sg_next(sg);
 		if (--nents <= 0)
 			break;
-		sgaddr = (unsigned long) (page_address(sg->page) + sg->offset);
+		sgaddr = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
 		sglen = sg->length;
 	}
 	if (dlen < 0) {
@@ -191,7 +191,7 @@ void verify_sglist(struct scatterlist *sglist, int nents, iopte_t *iopte, int np
 			printk("sg(%d): page_addr(%p) off(%x) length(%x) "
 			       "dma_address[%016x] dma_length[%016x]\n",
 			       i,
-			       page_address(sg->page), sg->offset,
+			       page_address(sg_page(sg)), sg->offset,
 			       sg->length,
 			       sg->dma_address, sg->dma_length);
 		}
@@ -207,15 +207,15 @@ unsigned long prepare_sg(struct scatterlist *sg, int nents)
 	unsigned long prev;
 	u32 dent_addr, dent_len;
 
-	prev  = (unsigned long) (page_address(sg->page) + sg->offset);
+	prev  = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
 	prev += (unsigned long) (dent_len = sg->length);
-	dent_addr = (u32) ((unsigned long)(page_address(sg->page) + sg->offset)
+	dent_addr = (u32) ((unsigned long)(page_address(sg_page(sg)) + sg->offset)
 			   & (IO_PAGE_SIZE - 1UL));
 	while (--nents) {
 		unsigned long addr;
 
 		sg = sg_next(sg);
-		addr = (unsigned long) (page_address(sg->page) + sg->offset);
+		addr = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
 		if (! VCONTIG(prev, addr)) {
 			dma_sg->dma_address = dent_addr;
 			dma_sg->dma_length = dent_len;
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index fe46ace..5324a34 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -366,7 +366,7 @@ static void dma_4v_unmap_single(struct device *dev, dma_addr_t bus_addr,
 }
 
 #define SG_ENT_PHYS_ADDRESS(SG)	\
-	(__pa(page_address((SG)->page)) + (SG)->offset)
+	(__pa(page_address(sg_page(SG))) + (SG)->offset)
 
 static long fill_sg(long entry, struct device *dev,
 		    struct scatterlist *sg,
@@ -478,7 +478,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
 	if (nelems == 1) {
 		sglist->dma_address =
 			dma_4v_map_single(dev,
-					  (page_address(sglist->page) +
+					  (page_address(sg_page(sglist)) +
 					   sglist->offset),
 					  sglist->length, direction);
 		if (unlikely(sglist->dma_address == DMA_ERROR_CODE))
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 5098f58..c9f0eb0 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -411,8 +411,10 @@ static int calgary_nontranslate_map_sg(struct device* dev,
 	int i;
 
 	for_each_sg(sg, s, nelems, i) {
-		BUG_ON(!s->page);
-		s->dma_address = virt_to_bus(page_address(s->page) +s->offset);
+		struct page *p = sg_page(s);
+
+		BUG_ON(!p);
+		s->dma_address = virt_to_bus(page_address(p) + s->offset);
 		s->dma_length = s->length;
 	}
 	return nelems;
@@ -432,9 +434,11 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
 		return calgary_nontranslate_map_sg(dev, sg, nelems, direction);
 
 	for_each_sg(sg, s, nelems, i) {
-		BUG_ON(!s->page);
+		struct page *p = sg_page(s);
+
+		BUG_ON(!p);
 
-		vaddr = (unsigned long)page_address(s->page) + s->offset;
+		vaddr = (unsigned long)page_address(p) + s->offset;
 		npages = num_dma_pages(vaddr, s->length);
 
 		entry = iommu_range_alloc(tbl, npages);
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index 5cdfab6..daaf636 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -302,7 +302,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
 #endif
 
 	for_each_sg(sg, s, nents, i) {
-		unsigned long addr = page_to_phys(s->page) + s->offset; 
+		unsigned long addr = page_to_phys(sg_page(s)) + s->offset; 
 		if (nonforced_iommu(dev, addr, s->length)) { 
 			addr = dma_map_area(dev, addr, s->length, dir);
 			if (addr == bad_dma_address) { 
@@ -397,7 +397,7 @@ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 	start_sg = sgmap = sg;
 	ps = NULL; /* shut up gcc */
 	for_each_sg(sg, s, nents, i) {
-		dma_addr_t addr = page_to_phys(s->page) + s->offset;
+		dma_addr_t addr = page_to_phys(sg_page(s)) + s->offset;
 		s->dma_address = addr;
 		BUG_ON(s->length == 0); 
 
diff --git a/arch/x86/kernel/pci-nommu_64.c b/arch/x86/kernel/pci-nommu_64.c
index e85d436..d64a4a5 100644
--- a/arch/x86/kernel/pci-nommu_64.c
+++ b/arch/x86/kernel/pci-nommu_64.c
@@ -62,8 +62,8 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
 	int i;
 
 	for_each_sg(sg, s, nents, i) {
-		BUG_ON(!s->page);
-		s->dma_address = virt_to_bus(page_address(s->page) +s->offset);
+		BUG_ON(!sg_page(s));
+		s->dma_address = virt_to_bus(page_address(sg_page(s)) +s->offset);
 		if (!check_addr("map_sg", hwdev, s->dma_address, s->length))
 			return 0;
 		s->dma_length = s->length;
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 3935469..ce9754f 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -1354,8 +1354,9 @@ new_segment:
 			else
 				sg = sg_next(sg);
 
-			memset(sg, 0, sizeof(*sg));
-			sg->page = bvec->bv_page;
+			sg_dma_len(sg) = 0;
+			sg_dma_address(sg) = 0;
+			sg_set_page(sg, bvec->bv_page);
 			sg->length = nbytes;
 			sg->offset = bvec->bv_offset;
 			nsegs++;
diff --git a/crypto/digest.c b/crypto/digest.c
index e56de67..8871dec 100644
--- a/crypto/digest.c
+++ b/crypto/digest.c
@@ -41,7 +41,7 @@ static int update2(struct hash_desc *desc,
 		return 0;
 
 	for (;;) {
-		struct page *pg = sg->page;
+		struct page *pg = sg_page(sg);
 		unsigned int offset = sg->offset;
 		unsigned int l = sg->length;
 
diff --git a/crypto/hmac.c b/crypto/hmac.c
index 8802fb6..e4eb6ac 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -159,7 +159,8 @@ static int hmac_digest(struct hash_desc *pdesc, struct scatterlist *sg,
 	desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP;
 
 	sg_set_buf(sg1, ipad, bs);
-	sg1[1].page = (void *)sg;
+
+	sg_set_page(&sg[1], (void *) sg);
 	sg1[1].length = 0;
 	sg_set_buf(sg2, opad, bs + ds);
 
diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c
index d6852c3..b9bbda0 100644
--- a/crypto/scatterwalk.c
+++ b/crypto/scatterwalk.c
@@ -54,7 +54,7 @@ static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
 	if (out) {
 		struct page *page;
 
-		page = walk->sg->page + ((walk->offset - 1) >> PAGE_SHIFT);
+		page = sg_page(walk->sg) + ((walk->offset - 1) >> PAGE_SHIFT);
 		flush_dcache_page(page);
 	}
 
diff --git a/crypto/scatterwalk.h b/crypto/scatterwalk.h
index 9c73e37..87ed681 100644
--- a/crypto/scatterwalk.h
+++ b/crypto/scatterwalk.h
@@ -22,13 +22,13 @@
 
 static inline struct scatterlist *scatterwalk_sg_next(struct scatterlist *sg)
 {
-	return (++sg)->length ? sg : (void *)sg->page;
+	return (++sg)->length ? sg : (void *) sg_page(sg);
 }
 
 static inline unsigned long scatterwalk_samebuf(struct scatter_walk *walk_in,
 						struct scatter_walk *walk_out)
 {
-	return !(((walk_in->sg->page - walk_out->sg->page) << PAGE_SHIFT) +
+	return !(((sg_page(walk_in->sg) - sg_page(walk_out->sg)) << PAGE_SHIFT) +
 		 (int)(walk_in->offset - walk_out->offset));
 }
 
@@ -60,7 +60,7 @@ static inline unsigned int scatterwalk_aligned(struct scatter_walk *walk,
 
 static inline struct page *scatterwalk_page(struct scatter_walk *walk)
 {
-	return walk->sg->page + (walk->offset >> PAGE_SHIFT);
+	return sg_page(walk->sg) + (walk->offset >> PAGE_SHIFT);
 }
 
 static inline void scatterwalk_unmap(void *vaddr, int out)
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 18d489c..d741c63 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -317,7 +317,7 @@ static void test_cipher(char *algo, int enc,
 				goto out;
 			}
 
-			q = kmap(sg[0].page) + sg[0].offset;
+			q = kmap(sg_page(&sg[0])) + sg[0].offset;
 			hexdump(q, cipher_tv[i].rlen);
 
 			printk("%s\n",
@@ -390,7 +390,7 @@ static void test_cipher(char *algo, int enc,
 			temp = 0;
 			for (k = 0; k < cipher_tv[i].np; k++) {
 				printk("page %u\n", k);
-				q = kmap(sg[k].page) + sg[k].offset;
+				q = kmap(sg_page(&sg[k])) + sg[k].offset;
 				hexdump(q, cipher_tv[i].tap[k]);
 				printk("%s\n",
 					memcmp(q, cipher_tv[i].result + temp,
diff --git a/crypto/xcbc.c b/crypto/xcbc.c
index 9f502b8..ac68f3b 100644
--- a/crypto/xcbc.c
+++ b/crypto/xcbc.c
@@ -120,7 +120,7 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc,
 
 	do {
 
-		struct page *pg = sg[i].page;
+		struct page *pg = sg_page(&sg[i]);
 		unsigned int offset = sg[i].offset;
 		unsigned int slen = sg[i].length;
 
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index bbaa545..b1fa70a 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4296,7 +4296,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
 		sg_last(sg, qc->orig_n_elem)->length += qc->pad_len;
 		if (pad_buf) {
 			struct scatterlist *psg = &qc->pad_sgent;
-			void *addr = kmap_atomic(psg->page, KM_IRQ0);
+			void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
 			memcpy(addr + psg->offset, pad_buf, qc->pad_len);
 			kunmap_atomic(addr, KM_IRQ0);
 		}
@@ -4686,11 +4686,11 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
 		 * data in this function or read data in ata_sg_clean.
 		 */
 		offset = lsg->offset + lsg->length - qc->pad_len;
-		psg->page = nth_page(lsg->page, offset >> PAGE_SHIFT);
+		sg_set_page(psg, nth_page(sg_page(lsg), offset >> PAGE_SHIFT));
 		psg->offset = offset_in_page(offset);
 
 		if (qc->tf.flags & ATA_TFLAG_WRITE) {
-			void *addr = kmap_atomic(psg->page, KM_IRQ0);
+			void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
 			memcpy(pad_buf, addr + psg->offset, qc->pad_len);
 			kunmap_atomic(addr, KM_IRQ0);
 		}
@@ -4836,7 +4836,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
 	if (qc->curbytes == qc->nbytes - qc->sect_size)
 		ap->hsm_task_state = HSM_ST_LAST;
 
-	page = qc->cursg->page;
+	page = sg_page(qc->cursg);
 	offset = qc->cursg->offset + qc->cursg_ofs;
 
 	/* get the current page and offset */
@@ -4988,7 +4988,7 @@ next_sg:
 
 	sg = qc->cursg;
 
-	page = sg->page;
+	page = sg_page(sg);
 	offset = sg->offset + qc->cursg_ofs;
 
 	/* get the current page and offset */
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 9fbb39c..5b758b9 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1544,7 +1544,7 @@ static unsigned int ata_scsi_rbuf_get(struct scsi_cmnd *cmd, u8 **buf_out)
 	struct scatterlist *sg = scsi_sglist(cmd);
 
 	if (sg) {
-		buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+		buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 		buflen = sg->length;
 	} else {
 		buf = NULL;
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 7c2cfde..5a6fe17 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -2610,7 +2610,7 @@ static void do_cciss_request(struct request_queue *q)
 	       (int)creq->nr_sectors);
 #endif				/* CCISS_DEBUG */
 
-	memset(tmp_sg, 0, sizeof(tmp_sg));
+	sg_init_table(tmp_sg, MAXSGENTRIES);
 	seg = blk_rq_map_sg(q, creq, tmp_sg);
 
 	/* get the DMA records for the setup */
@@ -2621,7 +2621,7 @@ static void do_cciss_request(struct request_queue *q)
 
 	for (i = 0; i < seg; i++) {
 		c->SG[i].Len = tmp_sg[i].length;
-		temp64.val = (__u64) pci_map_page(h->pdev, tmp_sg[i].page,
+		temp64.val = (__u64) pci_map_page(h->pdev, sg_page(&tmp_sg[i]),
 						  tmp_sg[i].offset,
 						  tmp_sg[i].length, dir);
 		c->SG[i].Addr.lower = temp64.val32.lower;
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index 568603d..efab27f 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -918,6 +918,7 @@ queue_next:
 DBGPX(
 	printk("sector=%d, nr_sectors=%d\n", creq->sector, creq->nr_sectors);
 );
+	sg_init_table(tmp_sg, SG_MAX);
 	seg = blk_rq_map_sg(q, creq, tmp_sg);
 
 	/* Now do all the DMA Mappings */
@@ -929,7 +930,7 @@ DBGPX(
 	{
 		c->req.sg[i].size = tmp_sg[i].length;
 		c->req.sg[i].addr = (__u32) pci_map_page(h->pci_dev,
-						 tmp_sg[i].page,
+						 sg_page(&tmp_sg[i]),
 						 tmp_sg[i].offset,
 						 tmp_sg[i].length, dir);
 	}
diff --git a/drivers/block/cryptoloop.c b/drivers/block/cryptoloop.c
index 4053503..1b58b01 100644
--- a/drivers/block/cryptoloop.c
+++ b/drivers/block/cryptoloop.c
@@ -26,6 +26,7 @@
 #include <linux/crypto.h>
 #include <linux/blkdev.h>
 #include <linux/loop.h>
+#include <linux/scatterlist.h>
 #include <asm/semaphore.h>
 #include <asm/uaccess.h>
 
@@ -119,14 +120,17 @@ cryptoloop_transfer(struct loop_device *lo, int cmd,
 		.tfm = tfm,
 		.flags = CRYPTO_TFM_REQ_MAY_SLEEP,
 	};
-	struct scatterlist sg_out = { NULL, };
-	struct scatterlist sg_in = { NULL, };
+	struct scatterlist sg_out;
+	struct scatterlist sg_in;
 
 	encdec_cbc_t encdecfunc;
 	struct page *in_page, *out_page;
 	unsigned in_offs, out_offs;
 	int err;
 
+	sg_init_table(&sg_out, 1);
+	sg_init_table(&sg_in, 1);
+
 	if (cmd == READ) {
 		in_page = raw_page;
 		in_offs = raw_off;
@@ -146,11 +150,11 @@ cryptoloop_transfer(struct loop_device *lo, int cmd,
 		u32 iv[4] = { 0, };
 		iv[0] = cpu_to_le32(IV & 0xffffffff);
 
-		sg_in.page = in_page;
+		sg_set_page(&sg_in, in_page);
 		sg_in.offset = in_offs;
 		sg_in.length = sz;
 
-		sg_out.page = out_page;
+		sg_set_page(&sg_out, out_page);
 		sg_out.offset = out_offs;
 		sg_out.length = sz;
 
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index c57dd2b..d6f7b43 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -25,6 +25,7 @@
 #include <linux/usb_usual.h>
 #include <linux/blkdev.h>
 #include <linux/timer.h>
+#include <linux/scatterlist.h>
 #include <scsi/scsi.h>
 
 #define DRV_NAME "ub"
@@ -656,6 +657,7 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq)
 	if ((cmd = ub_get_cmd(lun)) == NULL)
 		return -1;
 	memset(cmd, 0, sizeof(struct ub_scsi_cmd));
+	sg_init_table(cmd->sgv, UB_MAX_REQ_SG);
 
 	blkdev_dequeue_request(rq);
 
@@ -1310,7 +1312,7 @@ static void ub_data_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 		pipe = sc->send_bulk_pipe;
 	sc->last_pipe = pipe;
 	usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe,
-	    page_address(sg->page) + sg->offset, sg->length,
+	    page_address(sg_page(sg)) + sg->offset, sg->length,
 	    ub_urb_complete, sc);
 	sc->work_urb.actual_length = 0;
 	sc->work_urb.error_count = 0;
@@ -1427,7 +1429,7 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 	scmd->state = UB_CMDST_INIT;
 	scmd->nsg = 1;
 	sg = &scmd->sgv[0];
-	sg->page = virt_to_page(sc->top_sense);
+	sg_set_page(sg, virt_to_page(sc->top_sense));
 	sg->offset = (unsigned long)sc->top_sense & (PAGE_SIZE-1);
 	sg->length = UB_SENSE_SIZE;
 	scmd->len = UB_SENSE_SIZE;
@@ -1863,7 +1865,7 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
 	cmd->state = UB_CMDST_INIT;
 	cmd->nsg = 1;
 	sg = &cmd->sgv[0];
-	sg->page = virt_to_page(p);
+	sg_set_page(sg, virt_to_page(p));
 	sg->offset = (unsigned long)p & (PAGE_SIZE-1);
 	sg->length = 8;
 	cmd->len = 8;
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 3c945d6..7c640cd 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -1337,12 +1337,14 @@ static int hwif_init(ide_hwif_t *hwif)
 	if (!hwif->sg_max_nents)
 		hwif->sg_max_nents = PRD_ENTRIES;
 
-	hwif->sg_table = kzalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
+	hwif->sg_table = kmalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
 				 GFP_KERNEL);
 	if (!hwif->sg_table) {
 		printk(KERN_ERR "%s: unable to allocate SG table.\n", hwif->name);
 		goto out;
 	}
+
+	sg_init_table(hwif->sg_table, hwif->sg_max_nents);
 	
 	if (init_irq(hwif) == 0)
 		goto done;
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 2a3c8d4..086157f 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -278,7 +278,7 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
 		hwif->cursg = sg;
 	}
 
-	page = cursg->page;
+	page = sg_page(cursg);
 	offset = cursg->offset + hwif->cursg_ofs * SECTOR_SIZE;
 
 	/* get the current page and offset */
diff --git a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c
index 45d6055..25e113b 100644
--- a/drivers/ieee1394/dma.c
+++ b/drivers/ieee1394/dma.c
@@ -111,7 +111,7 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes,
 		unsigned long va =
 		    (unsigned long)dma->kvirt + (i << PAGE_SHIFT);
 
-		dma->sglist[i].page = vmalloc_to_page((void *)va);
+		sg_set_page(&dma->sglist[i], vmalloc_to_page((void *)va));
 		dma->sglist[i].length = PAGE_SIZE;
 	}
 
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 1b353b9..d5dfe11 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -1466,7 +1466,7 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb,
 		cmd->dma_size = sgpnt[0].length;
 		cmd->dma_type = CMD_DMA_PAGE;
 		cmd->cmd_dma = dma_map_page(hi->host->device.parent,
-					    sgpnt[0].page, sgpnt[0].offset,
+					    sg_page(&sgpnt[0]), sgpnt[0].offset,
 					    cmd->dma_size, cmd->dma_dir);
 
 		orb->data_descriptor_lo = cmd->cmd_dma;
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index 2f54e29..14159ff 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -55,9 +55,11 @@ static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int d
 		ib_dma_unmap_sg(dev, chunk->page_list,
 				chunk->nents, DMA_BIDIRECTIONAL);
 		for (i = 0; i < chunk->nents; ++i) {
+			struct page *page = sg_page(&chunk->page_list[i]);
+
 			if (umem->writable && dirty)
-				set_page_dirty_lock(chunk->page_list[i].page);
-			put_page(chunk->page_list[i].page);
+				set_page_dirty_lock(page);
+			put_page(page);
 		}
 
 		kfree(chunk);
@@ -164,11 +166,12 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
 			}
 
 			chunk->nents = min_t(int, ret, IB_UMEM_MAX_PAGE_CHUNK);
+			sg_init_table(chunk->page_list, chunk->nents);
 			for (i = 0; i < chunk->nents; ++i) {
 				if (vma_list &&
 				    !is_vm_hugetlb_page(vma_list[i + off]))
 					umem->hugetlb = 0;
-				chunk->page_list[i].page   = page_list[i + off];
+				sg_set_page(&chunk->page_list[i], page_list[i + off]);
 				chunk->page_list[i].offset = 0;
 				chunk->page_list[i].length = PAGE_SIZE;
 			}
@@ -179,7 +182,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
 						    DMA_BIDIRECTIONAL);
 			if (chunk->nmap <= 0) {
 				for (i = 0; i < chunk->nents; ++i)
-					put_page(chunk->page_list[i].page);
+					put_page(sg_page(&chunk->page_list[i]));
 				kfree(chunk);
 
 				ret = -ENOMEM;
diff --git a/drivers/infiniband/hw/ipath/ipath_dma.c b/drivers/infiniband/hw/ipath/ipath_dma.c
index 22709a4..e90a0ea 100644
--- a/drivers/infiniband/hw/ipath/ipath_dma.c
+++ b/drivers/infiniband/hw/ipath/ipath_dma.c
@@ -108,7 +108,7 @@ static int ipath_map_sg(struct ib_device *dev, struct scatterlist *sgl,
 	BUG_ON(!valid_dma_direction(direction));
 
 	for_each_sg(sgl, sg, nents, i) {
-		addr = (u64) page_address(sg->page);
+		addr = (u64) page_address(sg_page(sg));
 		/* TODO: handle highmem pages */
 		if (!addr) {
 			ret = 0;
@@ -127,7 +127,7 @@ static void ipath_unmap_sg(struct ib_device *dev,
 
 static u64 ipath_sg_dma_address(struct ib_device *dev, struct scatterlist *sg)
 {
-	u64 addr = (u64) page_address(sg->page);
+	u64 addr = (u64) page_address(sg_page(sg));
 
 	if (addr)
 		addr += sg->offset;
diff --git a/drivers/infiniband/hw/ipath/ipath_mr.c b/drivers/infiniband/hw/ipath/ipath_mr.c
index e442470..db4ba92 100644
--- a/drivers/infiniband/hw/ipath/ipath_mr.c
+++ b/drivers/infiniband/hw/ipath/ipath_mr.c
@@ -225,7 +225,7 @@ struct ib_mr *ipath_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
 		for (i = 0; i < chunk->nents; i++) {
 			void *vaddr;
 
-			vaddr = page_address(chunk->page_list[i].page);
+			vaddr = page_address(sg_page(&chunk->page_list[i]));
 			if (!vaddr) {
 				ret = ERR_PTR(-EINVAL);
 				goto bail;
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
index e61f3e6..007b381 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -71,7 +71,7 @@ static void mthca_free_icm_pages(struct mthca_dev *dev, struct mthca_icm_chunk *
 			     PCI_DMA_BIDIRECTIONAL);
 
 	for (i = 0; i < chunk->npages; ++i)
-		__free_pages(chunk->mem[i].page,
+		__free_pages(sg_page(&chunk->mem[i]),
 			     get_order(chunk->mem[i].length));
 }
 
@@ -81,7 +81,7 @@ static void mthca_free_icm_coherent(struct mthca_dev *dev, struct mthca_icm_chun
 
 	for (i = 0; i < chunk->npages; ++i) {
 		dma_free_coherent(&dev->pdev->dev, chunk->mem[i].length,
-				  lowmem_page_address(chunk->mem[i].page),
+				  lowmem_page_address(sg_page(&chunk->mem[i])),
 				  sg_dma_address(&chunk->mem[i]));
 	}
 }
@@ -107,10 +107,13 @@ void mthca_free_icm(struct mthca_dev *dev, struct mthca_icm *icm, int coherent)
 
 static int mthca_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_mask)
 {
-	mem->page = alloc_pages(gfp_mask, order);
-	if (!mem->page)
+	struct page *page;
+
+	page = alloc_pages(gfp_mask, order);
+	if (!page)
 		return -ENOMEM;
 
+	sg_set_page(mem, page);
 	mem->length = PAGE_SIZE << order;
 	mem->offset = 0;
 	return 0;
@@ -157,6 +160,7 @@ struct mthca_icm *mthca_alloc_icm(struct mthca_dev *dev, int npages,
 			if (!chunk)
 				goto fail;
 
+			sg_init_table(chunk->mem, MTHCA_ICM_CHUNK_LEN);
 			chunk->npages = 0;
 			chunk->nsg    = 0;
 			list_add_tail(&chunk->list, &icm->chunk_list);
@@ -304,7 +308,7 @@ void *mthca_table_find(struct mthca_icm_table *table, int obj, dma_addr_t *dma_h
 			 * so if we found the page, dma_handle has already
 			 * been assigned to. */
 			if (chunk->mem[i].length > offset) {
-				page = chunk->mem[i].page;
+				page = sg_page(&chunk->mem[i]);
 				goto out;
 			}
 			offset -= chunk->mem[i].length;
@@ -445,6 +449,7 @@ static u64 mthca_uarc_virt(struct mthca_dev *dev, struct mthca_uar *uar, int pag
 int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
 		      struct mthca_user_db_table *db_tab, int index, u64 uaddr)
 {
+	struct page *pages[1];
 	int ret = 0;
 	u8 status;
 	int i;
@@ -472,16 +477,17 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
 	}
 
 	ret = get_user_pages(current, current->mm, uaddr & PAGE_MASK, 1, 1, 0,
-			     &db_tab->page[i].mem.page, NULL);
+			     pages, NULL);
 	if (ret < 0)
 		goto out;
 
+	sg_set_page(&db_tab->page[i].mem, pages[0]);
 	db_tab->page[i].mem.length = MTHCA_ICM_PAGE_SIZE;
 	db_tab->page[i].mem.offset = uaddr & ~PAGE_MASK;
 
 	ret = pci_map_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
 	if (ret < 0) {
-		put_page(db_tab->page[i].mem.page);
+		put_page(pages[0]);
 		goto out;
 	}
 
@@ -491,7 +497,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
 		ret = -EINVAL;
 	if (ret) {
 		pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
-		put_page(db_tab->page[i].mem.page);
+		put_page(sg_page(&db_tab->page[i].mem));
 		goto out;
 	}
 
@@ -557,7 +563,7 @@ void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar,
 		if (db_tab->page[i].uvirt) {
 			mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, uar, i), 1, &status);
 			pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
-			put_page(db_tab->page[i].mem.page);
+			put_page(sg_page(&db_tab->page[i].mem));
 		}
 	}
 
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
index f3529b6..29c842e 100644
--- a/drivers/infiniband/ulp/iser/iser_memory.c
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -131,7 +131,7 @@ static int iser_start_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
 
 		p = mem;
 		for_each_sg(sgl, sg, data->size, i) {
-			from = kmap_atomic(sg->page, KM_USER0);
+			from = kmap_atomic(sg_page(sg), KM_USER0);
 			memcpy(p,
 			       from + sg->offset,
 			       sg->length);
@@ -191,7 +191,7 @@ void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
 
 		p = mem;
 		for_each_sg(sgl, sg, sg_size, i) {
-			to = kmap_atomic(sg->page, KM_SOFTIRQ0);
+			to = kmap_atomic(sg_page(sg), KM_SOFTIRQ0);
 			memcpy(to + sg->offset,
 			       p,
 			       sg->length);
@@ -336,7 +336,7 @@ static void iser_data_buf_dump(struct iser_data_buf *data,
 		iser_err("sg[%d] dma_addr:0x%lX page:0x%p "
 			 "off:0x%x sz:0x%x dma_len:0x%x\n",
 			 i, (unsigned long)ib_sg_dma_address(ibdev, sg),
-			 sg->page, sg->offset,
+			 sg_page(sg), sg->offset,
 			 sg->length, ib_sg_dma_len(ibdev, sg));
 }
 
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 64fee90..cde915f 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -346,16 +346,17 @@ static int crypt_convert(struct crypt_config *cc,
 	      ctx->idx_out < ctx->bio_out->bi_vcnt) {
 		struct bio_vec *bv_in = bio_iovec_idx(ctx->bio_in, ctx->idx_in);
 		struct bio_vec *bv_out = bio_iovec_idx(ctx->bio_out, ctx->idx_out);
-		struct scatterlist sg_in = {
-			.page = bv_in->bv_page,
-			.offset = bv_in->bv_offset + ctx->offset_in,
-			.length = 1 << SECTOR_SHIFT
-		};
-		struct scatterlist sg_out = {
-			.page = bv_out->bv_page,
-			.offset = bv_out->bv_offset + ctx->offset_out,
-			.length = 1 << SECTOR_SHIFT
-		};
+		struct scatterlist sg_in, sg_out;
+
+		sg_init_table(&sg_in, 1);
+		sg_set_page(&sg_in, bv_in->bv_page);
+		sg_in.offset = bv_in->bv_offset + ctx->offset_in;
+		sg_in.length = 1 << SECTOR_SHIFT;
+		
+		sg_init_table(&sg_out, 1);
+		sg_set_page(&sg_out, bv_out->bv_page);
+		sg_out.offset = bv_out->bv_offset + ctx->offset_out;
+		sg_out.length = 1 << SECTOR_SHIFT;
 
 		ctx->offset_in += sg_in.length;
 		if (ctx->offset_in >= bv_in->bv_len) {
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c
index 365a221..2b1f8b4 100644
--- a/drivers/media/common/saa7146_core.c
+++ b/drivers/media/common/saa7146_core.c
@@ -112,12 +112,13 @@ static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages)
 	sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL);
 	if (NULL == sglist)
 		return NULL;
+	sg_init_table(sglist, nr_pages);
 	for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
 		pg = vmalloc_to_page(virt);
 		if (NULL == pg)
 			goto err;
 		BUG_ON(PageHighMem(pg));
-		sglist[i].page   = pg;
+		sg_set_page(&sglist[i], pg);
 		sglist[i].length = PAGE_SIZE;
 	}
 	return sglist;
diff --git a/drivers/media/video/ivtv/ivtv-udma.c b/drivers/media/video/ivtv/ivtv-udma.c
index c4626d1..912b424 100644
--- a/drivers/media/video/ivtv/ivtv-udma.c
+++ b/drivers/media/video/ivtv/ivtv-udma.c
@@ -63,10 +63,10 @@ int ivtv_udma_fill_sg_list (struct ivtv_user_dma *dma, struct ivtv_dma_page_info
 			memcpy(page_address(dma->bouncemap[map_offset]) + offset, src, len);
 			kunmap_atomic(src, KM_BOUNCE_READ);
 			local_irq_restore(flags);
-			dma->SGlist[map_offset].page = dma->bouncemap[map_offset];
+			sg_set_page(&dma->SGlist[map_offset], dma->bouncemap[map_offset]);
 		}
 		else {
-			dma->SGlist[map_offset].page = dma->map[map_offset];
+			sg_set_page(&dma->SGlist[map_offset], dma->map[map_offset]);
 		}
 		offset = 0;
 		map_offset++;
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
index 3eb6123..0a18286 100644
--- a/drivers/media/video/videobuf-dma-sg.c
+++ b/drivers/media/video/videobuf-dma-sg.c
@@ -60,12 +60,13 @@ videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages)
 	sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL);
 	if (NULL == sglist)
 		return NULL;
+	sg_init_table(sglist, nr_pages);
 	for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
 		pg = vmalloc_to_page(virt);
 		if (NULL == pg)
 			goto err;
 		BUG_ON(PageHighMem(pg));
-		sglist[i].page   = pg;
+		sg_set_page(&sglist[i], pg);
 		sglist[i].length = PAGE_SIZE;
 	}
 	return sglist;
@@ -86,13 +87,14 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
 	sglist = kcalloc(nr_pages, sizeof(*sglist), GFP_KERNEL);
 	if (NULL == sglist)
 		return NULL;
+	sg_init_table(sglist, nr_pages);
 
 	if (NULL == pages[0])
 		goto nopage;
 	if (PageHighMem(pages[0]))
 		/* DMA to highmem pages might not work */
 		goto highmem;
-	sglist[0].page   = pages[0];
+	sg_set_page(&sglist[0], pages[0]);
 	sglist[0].offset = offset;
 	sglist[0].length = PAGE_SIZE - offset;
 	for (i = 1; i < nr_pages; i++) {
@@ -100,7 +102,7 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
 			goto nopage;
 		if (PageHighMem(pages[i]))
 			goto highmem;
-		sglist[i].page   = pages[i];
+		sg_set_page(&sglist[i], pages[i]);
 		sglist[i].length = PAGE_SIZE;
 	}
 	return sglist;
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index a5d0354..68c1fe9 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -13,6 +13,7 @@
 #include <linux/blkdev.h>
 #include <linux/freezer.h>
 #include <linux/kthread.h>
+#include <linux/scatterlist.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
@@ -153,19 +154,21 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
 			blk_queue_max_hw_segments(mq->queue, bouncesz / 512);
 			blk_queue_max_segment_size(mq->queue, bouncesz);
 
-			mq->sg = kzalloc(sizeof(struct scatterlist),
+			mq->sg = kmalloc(sizeof(struct scatterlist),
 				GFP_KERNEL);
 			if (!mq->sg) {
 				ret = -ENOMEM;
 				goto cleanup_queue;
 			}
+			sg_init_table(mq->sg, 1);
 
-			mq->bounce_sg = kzalloc(sizeof(struct scatterlist) *
+			mq->bounce_sg = kmalloc(sizeof(struct scatterlist) *
 				bouncesz / 512, GFP_KERNEL);
 			if (!mq->bounce_sg) {
 				ret = -ENOMEM;
 				goto cleanup_queue;
 			}
+			sg_init_table(mq->bounce_sg, bouncesz / 512);
 		}
 	}
 #endif
@@ -302,12 +305,12 @@ static void copy_sg(struct scatterlist *dst, unsigned int dst_len,
 		BUG_ON(dst_len == 0);
 
 		if (dst_size == 0) {
-			dst_buf = page_address(dst->page) + dst->offset;
+			dst_buf = page_address(sg_page(dst)) + dst->offset;
 			dst_size = dst->length;
 		}
 
 		if (src_size == 0) {
-			src_buf = page_address(src->page) + src->offset;
+			src_buf = page_address(sg_page(src)) + src->offset;
 			src_size = src->length;
 		}
 
@@ -353,9 +356,7 @@ unsigned int mmc_queue_map_sg(struct mmc_queue *mq)
 		return 1;
 	}
 
-	mq->sg[0].page = virt_to_page(mq->bounce_buf);
-	mq->sg[0].offset = offset_in_page(mq->bounce_buf);
-	mq->sg[0].length = 0;
+	sg_init_one(mq->sg, mq->bounce_buf, 0);
 
 	while (sg_len) {
 		mq->sg[0].length += mq->bounce_sg[sg_len - 1].length;
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 7ae18ea..12c2d80 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -813,7 +813,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
 					&& dir == DMA_FROM_DEVICE)
 				dir = DMA_BIDIRECTIONAL;
 
-			dma_addr = dma_map_page(dma_dev, sg->page, 0,
+			dma_addr = dma_map_page(dma_dev, sg_page(sg), 0,
 						PAGE_SIZE, dir);
 			if (direction == DMA_TO_DEVICE)
 				t->tx_dma = dma_addr + sg->offset;
@@ -822,7 +822,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
 		}
 
 		/* allow pio too; we don't allow highmem */
-		kmap_addr = kmap(sg->page);
+		kmap_addr = kmap(sg_page(sg));
 		if (direction == DMA_TO_DEVICE)
 			t->tx_buf = kmap_addr + sg->offset;
 		else
@@ -855,8 +855,8 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
 
 		/* discard mappings */
 		if (direction == DMA_FROM_DEVICE)
-			flush_kernel_dcache_page(sg->page);
-		kunmap(sg->page);
+			flush_kernel_dcache_page(sg_page(sg));
+		kunmap(sg_page(sg));
 		if (dma_dev)
 			dma_unmap_page(dma_dev, dma_addr, PAGE_SIZE, dir);
 
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index b397121..b6500e9 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -231,7 +231,7 @@ static void sdhci_deactivate_led(struct sdhci_host *host)
 
 static inline char* sdhci_sg_to_buffer(struct sdhci_host* host)
 {
-	return page_address(host->cur_sg->page) + host->cur_sg->offset;
+	return page_address(sg_page(host->cur_sg)) + host->cur_sg->offset;
 }
 
 static inline int sdhci_next_sg(struct sdhci_host* host)
diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c
index 9b90479..c11a3d2 100644
--- a/drivers/mmc/host/tifm_sd.c
+++ b/drivers/mmc/host/tifm_sd.c
@@ -192,7 +192,7 @@ static void tifm_sd_transfer_data(struct tifm_sd *host)
 		}
 		off = sg[host->sg_pos].offset + host->block_pos;
 
-		pg = nth_page(sg[host->sg_pos].page, off >> PAGE_SHIFT);
+		pg = nth_page(sg_page(&sg[host->sg_pos]), off >> PAGE_SHIFT);
 		p_off = offset_in_page(off);
 		p_cnt = PAGE_SIZE - p_off;
 		p_cnt = min(p_cnt, cnt);
@@ -241,18 +241,18 @@ static void tifm_sd_bounce_block(struct tifm_sd *host, struct mmc_data *r_data)
 		}
 		off = sg[host->sg_pos].offset + host->block_pos;
 
-		pg = nth_page(sg[host->sg_pos].page, off >> PAGE_SHIFT);
+		pg = nth_page(sg_page(&sg[host->sg_pos]), off >> PAGE_SHIFT);
 		p_off = offset_in_page(off);
 		p_cnt = PAGE_SIZE - p_off;
 		p_cnt = min(p_cnt, cnt);
 		p_cnt = min(p_cnt, t_size);
 
 		if (r_data->flags & MMC_DATA_WRITE)
-			tifm_sd_copy_page(host->bounce_buf.page,
+			tifm_sd_copy_page(sg_page(&host->bounce_buf),
 					  r_data->blksz - t_size,
 					  pg, p_off, p_cnt);
 		else if (r_data->flags & MMC_DATA_READ)
-			tifm_sd_copy_page(pg, p_off, host->bounce_buf.page,
+			tifm_sd_copy_page(pg, p_off, sg_page(&host->bounce_buf),
 					  r_data->blksz - t_size, p_cnt);
 
 		t_size -= p_cnt;
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c
index 80db11c..971ca0f 100644
--- a/drivers/mmc/host/wbsd.c
+++ b/drivers/mmc/host/wbsd.c
@@ -269,7 +269,7 @@ static inline int wbsd_next_sg(struct wbsd_host *host)
 
 static inline char *wbsd_sg_to_buffer(struct wbsd_host *host)
 {
-	return page_address(host->cur_sg->page) + host->cur_sg->offset;
+	return page_address(sg_page(host->cur_sg)) + host->cur_sg->offset;
 }
 
 static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data)
@@ -283,7 +283,7 @@ static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data)
 	len = data->sg_len;
 
 	for (i = 0; i < len; i++) {
-		sgbuf = page_address(sg[i].page) + sg[i].offset;
+		sgbuf = page_address(sg_page(&sg[i])) + sg[i].offset;
 		memcpy(dmabuf, sgbuf, sg[i].length);
 		dmabuf += sg[i].length;
 	}
@@ -300,7 +300,7 @@ static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data)
 	len = data->sg_len;
 
 	for (i = 0; i < len; i++) {
-		sgbuf = page_address(sg[i].page) + sg[i].offset;
+		sgbuf = page_address(sg_page(&sg[i])) + sg[i].offset;
 		memcpy(sgbuf, dmabuf, sg[i].length);
 		dmabuf += sg[i].length;
 	}
diff --git a/drivers/net/mlx4/icm.c b/drivers/net/mlx4/icm.c
index 4b3c109..887633b 100644
--- a/drivers/net/mlx4/icm.c
+++ b/drivers/net/mlx4/icm.c
@@ -60,7 +60,7 @@ static void mlx4_free_icm_pages(struct mlx4_dev *dev, struct mlx4_icm_chunk *chu
 			     PCI_DMA_BIDIRECTIONAL);
 
 	for (i = 0; i < chunk->npages; ++i)
-		__free_pages(chunk->mem[i].page,
+		__free_pages(sg_page(&chunk->mem[i]),
 			     get_order(chunk->mem[i].length));
 }
 
@@ -70,7 +70,7 @@ static void mlx4_free_icm_coherent(struct mlx4_dev *dev, struct mlx4_icm_chunk *
 
 	for (i = 0; i < chunk->npages; ++i)
 		dma_free_coherent(&dev->pdev->dev, chunk->mem[i].length,
-				  lowmem_page_address(chunk->mem[i].page),
+				  lowmem_page_address(sg_page(&chunk->mem[i])),
 				  sg_dma_address(&chunk->mem[i]));
 }
 
@@ -95,10 +95,13 @@ void mlx4_free_icm(struct mlx4_dev *dev, struct mlx4_icm *icm, int coherent)
 
 static int mlx4_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_mask)
 {
-	mem->page = alloc_pages(gfp_mask, order);
-	if (!mem->page)
+	struct page *page;
+
+	page = alloc_pages(gfp_mask, order);
+	if (!page)
 		return -ENOMEM;
 
+	sg_set_page(mem, page);
 	mem->length = PAGE_SIZE << order;
 	mem->offset = 0;
 	return 0;
@@ -145,6 +148,7 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
 			if (!chunk)
 				goto fail;
 
+			sg_init_table(chunk->mem, MLX4_ICM_CHUNK_LEN);
 			chunk->npages = 0;
 			chunk->nsg    = 0;
 			list_add_tail(&chunk->list, &icm->chunk_list);
@@ -334,7 +338,7 @@ void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_han
 			 * been assigned to.
 			 */
 			if (chunk->mem[i].length > offset) {
-				page = chunk->mem[i].page;
+				page = sg_page(&chunk->mem[i]);
 				goto out;
 			}
 			offset -= chunk->mem[i].length;
diff --git a/drivers/net/ppp_mppe.c b/drivers/net/ppp_mppe.c
index c0b6d19..bcb0885 100644
--- a/drivers/net/ppp_mppe.c
+++ b/drivers/net/ppp_mppe.c
@@ -55,7 +55,7 @@
 #include <linux/mm.h>
 #include <linux/ppp_defs.h>
 #include <linux/ppp-comp.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 
 #include "ppp_mppe.h"
 
@@ -68,9 +68,7 @@ MODULE_VERSION("1.0.2");
 static unsigned int
 setup_sg(struct scatterlist *sg, const void *address, unsigned int length)
 {
-	sg[0].page = virt_to_page(address);
-	sg[0].offset = offset_in_page(address);
-	sg[0].length = length;
+	sg_init_one(sg, address, length);
 	return length;
 }
 
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index fb14014..afb262b 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -1840,7 +1840,7 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
 			    (scsi_bufflen(srb) < TW_MIN_SGL_LENGTH)) {
 				if (srb->sc_data_direction == DMA_TO_DEVICE || srb->sc_data_direction == DMA_BIDIRECTIONAL) {
 					struct scatterlist *sg = scsi_sglist(srb);
-					char *buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+					char *buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 					memcpy(tw_dev->generic_buffer_virt[request_id], buf, sg->length);
 					kunmap_atomic(buf - sg->offset, KM_IRQ0);
 				}
@@ -1919,7 +1919,7 @@ static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int re
 			char *buf;
 			unsigned long flags = 0;
 			local_irq_save(flags);
-			buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+			buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 			memcpy(buf, tw_dev->generic_buffer_virt[request_id], sg->length);
 			kunmap_atomic(buf - sg->offset, KM_IRQ0);
 			local_irq_restore(flags);
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index a64153b..59716eb 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -1469,7 +1469,7 @@ static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id,
 	struct scatterlist *sg = scsi_sglist(cmd);
 
 	local_irq_save(flags);
-	buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+	buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 	transfer_len = min(sg->length, len);
 
 	memcpy(buf, data, transfer_len);
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index 988f0bc..7a76b4b 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -298,7 +298,7 @@ static __inline__ void initialize_SCp(Scsi_Cmnd * cmd)
 	if (cmd->use_sg) {
 		cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
 		cmd->SCp.buffers_residual = cmd->use_sg - 1;
-		cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+
+		cmd->SCp.ptr = page_address(sg_page(cmd->SCp.buffer))+
 			       cmd->SCp.buffer->offset;
 		cmd->SCp.this_residual = cmd->SCp.buffer->length;
 	} else {
@@ -2143,7 +2143,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
 					++cmd->SCp.buffer;
 					--cmd->SCp.buffers_residual;
 					cmd->SCp.this_residual = cmd->SCp.buffer->length;
-					cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+
+					cmd->SCp.ptr = page_address(sg_page(cmd->SCp.buffer))+
 						       cmd->SCp.buffer->offset;
 					dprintk(NDEBUG_INFORMATION, ("scsi%d : %d bytes and %d buffers left\n", instance->host_no, cmd->SCp.this_residual, cmd->SCp.buffers_residual));
 				}
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 80e448d..a77ab8d 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -356,7 +356,7 @@ static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigne
 	int transfer_len;
 	struct scatterlist *sg = scsi_sglist(scsicmd);
 
-	buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+	buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 	transfer_len = min(sg->length, len + offset);
 
 	transfer_len -= offset;
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index f817775..f7a2528 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -1343,7 +1343,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \
 						/* 4 bytes: Areca io control code */
 
 	sg = scsi_sglist(cmd);
-	buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+	buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 	if (scsi_sg_count(cmd) > 1) {
 		retvalue = ARCMSR_MESSAGE_FAIL;
 		goto message_out;
@@ -1593,7 +1593,7 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,
 		strncpy(&inqdata[32], "R001", 4); /* Product Revision */
 
 		sg = scsi_sglist(cmd);
-		buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+		buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 
 		memcpy(buffer, inqdata, sizeof(inqdata));
 		sg = scsi_sglist(cmd);
diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
index 5d282e6..dc4e463 100644
--- a/drivers/scsi/fdomain.c
+++ b/drivers/scsi/fdomain.c
@@ -1321,7 +1321,7 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id)
 	    if (current_SC->SCp.buffers_residual) {
 	       --current_SC->SCp.buffers_residual;
 	       ++current_SC->SCp.buffer;
-	       current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
+	       current_SC->SCp.ptr = page_address(sg_page(current_SC->SCp.buffer)) + current_SC->SCp.buffer->offset;
 	       current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
 	    } else
 		  break;
@@ -1354,7 +1354,7 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id)
 	     && current_SC->SCp.buffers_residual) {
 	    --current_SC->SCp.buffers_residual;
 	    ++current_SC->SCp.buffer;
-	    current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
+	    current_SC->SCp.ptr = page_address(sg_page(current_SC->SCp.buffer)) + current_SC->SCp.buffer->offset;
 	    current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
 	 }
       }
@@ -1439,7 +1439,7 @@ static int fdomain_16x0_queue(struct scsi_cmnd *SCpnt,
 
    if (scsi_sg_count(current_SC)) {
 	   current_SC->SCp.buffer = scsi_sglist(current_SC);
-	   current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page)
+	   current_SC->SCp.ptr = page_address(sg_page(current_SC->SCp.buffer))
 		   + current_SC->SCp.buffer->offset;
 	   current_SC->SCp.this_residual    = current_SC->SCp.buffer->length;
 	   current_SC->SCp.buffers_residual = scsi_sg_count(current_SC) - 1;
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 3ac080e..ac6c57a 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -2374,13 +2374,13 @@ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
             if (cpsum+cpnow > cpcount) 
                 cpnow = cpcount - cpsum;
             cpsum += cpnow;
-            if (!sl->page) {
+            if (!sg_page(sl)) {
                 printk("GDT-HA %d: invalid sc/gt element in gdth_copy_internal_data()\n",
                        ha->hanum);
                 return;
             }
             local_irq_save(flags);
-            address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset;
+            address = kmap_atomic(sg_page(sl), KM_BIO_SRC_IRQ) + sl->offset;
             if (to_buffer)
                 memcpy(buffer, address, cpnow);
             else
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index fa7ba64..7eb415d 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -179,14 +179,14 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
 			unsigned long flags;
 
 			local_irq_save(flags);
-			buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
+			buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) +
 					pc->sg->offset;
 			drive->hwif->atapi_input_bytes(drive,
 						buf + pc->b_count, count);
 			kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
 			local_irq_restore(flags);
 		} else {
-			buf = page_address(pc->sg->page) + pc->sg->offset;
+			buf = page_address(sg_page(pc->sg)) + pc->sg->offset;
 			drive->hwif->atapi_input_bytes(drive,
 						buf + pc->b_count, count);
 		}
@@ -216,14 +216,14 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
 			unsigned long flags;
 
 			local_irq_save(flags);
-			buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
+			buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) +
 						pc->sg->offset;
 			drive->hwif->atapi_output_bytes(drive,
 						buf + pc->b_count, count);
 			kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
 			local_irq_restore(flags);
 		} else {
-			buf = page_address(pc->sg->page) + pc->sg->offset;
+			buf = page_address(sg_page(pc->sg)) + pc->sg->offset;
 			drive->hwif->atapi_output_bytes(drive,
 						buf + pc->b_count, count);
 		}
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c
index 74cdc1f..da9b0ba 100644
--- a/drivers/scsi/imm.c
+++ b/drivers/scsi/imm.c
@@ -706,7 +706,7 @@ static int imm_completion(struct scsi_cmnd *cmd)
 				cmd->SCp.this_residual =
 				    cmd->SCp.buffer->length;
 				cmd->SCp.ptr =
-				    page_address(cmd->SCp.buffer->page) +
+				    page_address(sg_page(cmd->SCp.buffer)) +
 				    cmd->SCp.buffer->offset;
 
 				/*
@@ -845,7 +845,7 @@ static int imm_engine(imm_struct *dev, struct scsi_cmnd *cmd)
 			    (struct scatterlist *) cmd->request_buffer;
 			cmd->SCp.this_residual = cmd->SCp.buffer->length;
 			cmd->SCp.ptr =
-			    page_address(cmd->SCp.buffer->page) +
+			    page_address(sg_page(cmd->SCp.buffer)) +
 			    cmd->SCp.buffer->offset;
 		} else {
 			/* else fill the only available buffer */
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index b41dfb5..dc98a85 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -2872,6 +2872,7 @@ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len)
 	}
 
 	scatterlist = sglist->scatterlist;
+	sg_init_table(scatterlist, num_elem);
 
 	sglist->order = order;
 	sglist->num_sg = num_elem;
@@ -2884,12 +2885,12 @@ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len)
 
 			/* Free up what we already allocated */
 			for (j = i - 1; j >= 0; j--)
-				__free_pages(scatterlist[j].page, order);
+				__free_pages(sg_page(&scatterlist[j]), order);
 			kfree(sglist);
 			return NULL;
 		}
 
-		scatterlist[i].page = page;
+		sg_set_page(&scatterlist[i], page);
 	}
 
 	return sglist;
@@ -2910,7 +2911,7 @@ static void ipr_free_ucode_buffer(struct ipr_sglist *sglist)
 	int i;
 
 	for (i = 0; i < sglist->num_sg; i++)
-		__free_pages(sglist->scatterlist[i].page, sglist->order);
+		__free_pages(sg_page(&sglist->scatterlist[i]), sglist->order);
 
 	kfree(sglist);
 }
@@ -2940,9 +2941,11 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist,
 	scatterlist = sglist->scatterlist;
 
 	for (i = 0; i < (len / bsize_elem); i++, buffer += bsize_elem) {
-		kaddr = kmap(scatterlist[i].page);
+		struct page *page = sg_page(&scatterlist[i]);
+
+		kaddr = kmap(page);
 		memcpy(kaddr, buffer, bsize_elem);
-		kunmap(scatterlist[i].page);
+		kunmap(page);
 
 		scatterlist[i].length = bsize_elem;
 
@@ -2953,9 +2956,11 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist,
 	}
 
 	if (len % bsize_elem) {
-		kaddr = kmap(scatterlist[i].page);
+		struct page *page = sg_page(&scatterlist[i]);
+
+		kaddr = kmap(page);
 		memcpy(kaddr, buffer, len % bsize_elem);
-		kunmap(scatterlist[i].page);
+		kunmap(page);
 
 		scatterlist[i].length = len % bsize_elem;
 	}
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index edaac27..5c5a9b2 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -1515,7 +1515,7 @@ static int ips_is_passthru(struct scsi_cmnd *SC)
                 /* kmap_atomic() ensures addressability of the user buffer.*/
                 /* local_irq_save() protects the KM_IRQ0 address slot.     */
                 local_irq_save(flags);
-                buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+                buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
                 if (buffer && buffer[0] == 'C' && buffer[1] == 'O' &&
                     buffer[2] == 'P' && buffer[3] == 'P') {
                         kunmap_atomic(buffer - sg->offset, KM_IRQ0);
@@ -3523,7 +3523,7 @@ ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count)
                 /* kmap_atomic() ensures addressability of the data buffer.*/
                 /* local_irq_save() protects the KM_IRQ0 address slot.     */
                 local_irq_save(flags);
-                buffer = kmap_atomic(sg[i].page, KM_IRQ0) + sg[i].offset;
+                buffer = kmap_atomic(sg_page(&sg[i]), KM_IRQ0) + sg[i].offset;
                 memcpy(buffer, &cdata[xfer_cnt], min_cnt);
                 kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
                 local_irq_restore(flags);
@@ -3556,7 +3556,7 @@ ips_scmd_buf_read(struct scsi_cmnd *scmd, void *data, unsigned int count)
                 /* kmap_atomic() ensures addressability of the data buffer.*/
                 /* local_irq_save() protects the KM_IRQ0 address slot.     */
                 local_irq_save(flags);
-                buffer = kmap_atomic(sg[i].page, KM_IRQ0) + sg[i].offset;
+                buffer = kmap_atomic(sg_page(&sg[i]), KM_IRQ0) + sg[i].offset;
                 memcpy(&cdata[xfer_cnt], buffer, min_cnt);
                 kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
                 local_irq_restore(flags);
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index a21455d..6ce4109 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -70,9 +70,7 @@ module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);
 static inline void
 iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size)
 {
-	ibuf->sg.page = virt_to_page(vbuf);
-	ibuf->sg.offset = offset_in_page(vbuf);
-	ibuf->sg.length = size;
+	sg_init_one(&ibuf->sg, vbuf, size);
 	ibuf->sent = 0;
 	ibuf->use_sendmsg = 1;
 }
@@ -80,13 +78,14 @@ iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size)
 static inline void
 iscsi_buf_init_sg(struct iscsi_buf *ibuf, struct scatterlist *sg)
 {
-	ibuf->sg.page = sg->page;
+	sg_init_table(&ibuf->sg, 1);
+	sg_set_page(&ibuf->sg, sg_page(sg));
 	ibuf->sg.offset = sg->offset;
 	ibuf->sg.length = sg->length;
 	/*
 	 * Fastpath: sg element fits into single page
 	 */
-	if (sg->length + sg->offset <= PAGE_SIZE && !PageSlab(sg->page))
+	if (sg->length + sg->offset <= PAGE_SIZE && !PageSlab(sg_page(sg)))
 		ibuf->use_sendmsg = 0;
 	else
 		ibuf->use_sendmsg = 1;
@@ -716,7 +715,7 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn)
 	for (i = tcp_ctask->sg_count; i < scsi_sg_count(sc); i++) {
 		char *dest;
 
-		dest = kmap_atomic(sg[i].page, KM_SOFTIRQ0);
+		dest = kmap_atomic(sg_page(&sg[i]), KM_SOFTIRQ0);
 		rc = iscsi_ctask_copy(tcp_conn, ctask, dest + sg[i].offset,
 				      sg[i].length, offset);
 		kunmap_atomic(dest, KM_SOFTIRQ0);
@@ -1103,9 +1102,9 @@ iscsi_send(struct iscsi_conn *conn, struct iscsi_buf *buf, int size, int flags)
 	 * slab case.
 	 */
 	if (buf->use_sendmsg)
-		res = sock_no_sendpage(sk, buf->sg.page, offset, size, flags);
+		res = sock_no_sendpage(sk, sg_page(&buf->sg), offset, size, flags);
 	else
-		res = tcp_conn->sendpage(sk, buf->sg.page, offset, size, flags);
+		res = tcp_conn->sendpage(sk, sg_page(&buf->sg), offset, size, flags);
 
 	if (res >= 0) {
 		conn->txdata_octets += res;
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 10d1aff..0a848e8 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -658,7 +658,7 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
 			struct scatterlist *sg;
 
 			sg = scsi_sglist(cmd);
-			buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+			buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 
 			memset(buf, 0, cmd->cmnd[4]);
 			kunmap_atomic(buf - sg->offset, KM_IRQ0);
@@ -1542,9 +1542,9 @@ mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status)
 		if( cmd->cmnd[0] == INQUIRY && !islogical ) {
 
 			sgl = scsi_sglist(cmd);
-			if( sgl->page ) {
+			if( sg_page(sgl) ) {
 				c = *(unsigned char *)
-					page_address((&sgl[0])->page) +
+					page_address((sg_page(&sgl[0]))) +
 					(&sgl[0])->offset; 
 			} else {
 				printk(KERN_WARNING
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index e4e4c6a..376263c 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -1584,9 +1584,9 @@ megaraid_mbox_build_cmd(adapter_t *adapter, struct scsi_cmnd *scp, int *busy)
 			caddr_t			vaddr;
 
 			sgl = scsi_sglist(scp);
-			if (sgl->page) {
+			if (sg_page(sgl)) {
 				vaddr = (caddr_t)
-					(page_address((&sgl[0])->page)
+					(page_address(sg_page(&sgl[0]))
 					 + (&sgl[0])->offset);
 
 				memset(vaddr, 0, scp->cmnd[4]);
@@ -2328,9 +2328,9 @@ megaraid_mbox_dpc(unsigned long devp)
 				&& IS_RAID_CH(raid_dev, scb->dev_channel)) {
 
 			sgl = scsi_sglist(scp);
-			if (sgl->page) {
+			if (sg_page(sgl)) {
 				c = *(unsigned char *)
-					(page_address((&sgl[0])->page) +
+					(page_address(sg_page(&sgl[0])) +
 					 (&sgl[0])->offset);
 			} else {
 				con_log(CL_ANN, (KERN_WARNING
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 331b789..1c5c4b6 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -542,7 +542,7 @@ static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int q
 	if (STp->raw) {
 		if (STp->buffer->syscall_result) {
 			for (i=0; i < STp->buffer->sg_segs; i++)
-				memset(page_address(STp->buffer->sg[i].page),
+				memset(page_address(sg_page(&STp->buffer->sg[i])),
 				       0, STp->buffer->sg[i].length);
 			strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");
                 } else
@@ -4437,7 +4437,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp)
 		for (i = 0, b_size = 0; 
 		     (i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE); 
 		     b_size += STp->buffer->sg[i++].length);
-		STp->buffer->aux = (os_aux_t *) (page_address(STp->buffer->sg[i].page) + OS_DATA_SIZE - b_size);
+		STp->buffer->aux = (os_aux_t *) (page_address(sg_page(&STp->buffer->sg[i])) + OS_DATA_SIZE - b_size);
 #if DEBUG
 		printk(OSST_DEB_MSG "%s:D: b_data points to %p in segment 0 at %p\n", name,
 			STp->buffer->b_data, page_address(STp->buffer->sg[0].page));
@@ -5252,25 +5252,26 @@ static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
 	/* Try to allocate the first segment up to OS_DATA_SIZE and the others
 	   big enough to reach the goal (code assumes no segments in place) */
 	for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) {
-		STbuffer->sg[0].page = alloc_pages(priority, order);
+		struct page *page = alloc_pages(priority, order);
+
 		STbuffer->sg[0].offset = 0;
-		if (STbuffer->sg[0].page != NULL) {
+		if (page != NULL) {
+		    sg_set_page(&STbuffer->sg[0], page);
 		    STbuffer->sg[0].length = b_size;
-		    STbuffer->b_data = page_address(STbuffer->sg[0].page);
+		    STbuffer->b_data = page_address(page);
 		    break;
 		}
 	}
-	if (STbuffer->sg[0].page == NULL) {
+	if (sg_page(&STbuffer->sg[0]) == NULL) {
 		printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n");
 		return 0;
 	}
 	/* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */
 	for (segs=STbuffer->sg_segs=1, got=b_size;
 	     segs < max_segs && got < OS_FRAME_SIZE; ) {
-		STbuffer->sg[segs].page =
-				alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
+		struct page *page = alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
 		STbuffer->sg[segs].offset = 0;
-		if (STbuffer->sg[segs].page == NULL) {
+		if (page == NULL) {
 			if (OS_FRAME_SIZE - got <= (max_segs - segs) * b_size / 2 && order) {
 				b_size /= 2;  /* Large enough for the rest of the buffers */
 				order--;
@@ -5284,6 +5285,7 @@ static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
 			normalize_buffer(STbuffer);
 			return 0;
 		}
+		sg_set_page(&STbuffer->sg[segs], page);
 		STbuffer->sg[segs].length = (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size;
 		got += STbuffer->sg[segs].length;
 		STbuffer->buffer_size = got;
@@ -5316,7 +5318,7 @@ static void normalize_buffer(struct osst_buffer *STbuffer)
 		     b_size < STbuffer->sg[i].length;
 		     b_size *= 2, order++);
 
-		__free_pages(STbuffer->sg[i].page, order);
+		__free_pages(sg_page(&STbuffer->sg[i]), order);
 		STbuffer->buffer_size -= STbuffer->sg[i].length;
 	}
 #if DEBUG
@@ -5344,7 +5346,7 @@ static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, i
 	for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length - offset < do_count ?
 		      st_bp->sg[i].length - offset : do_count;
-		res = copy_from_user(page_address(st_bp->sg[i].page) + offset, ubp, cnt);
+		res = copy_from_user(page_address(sg_page(&st_bp->sg[i])) + offset, ubp, cnt);
 		if (res)
 			return (-EFAULT);
 		do_count -= cnt;
@@ -5377,7 +5379,7 @@ static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count
 	for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length - offset < do_count ?
 		      st_bp->sg[i].length - offset : do_count;
-		res = copy_to_user(ubp, page_address(st_bp->sg[i].page) + offset, cnt);
+		res = copy_to_user(ubp, page_address(sg_page(&st_bp->sg[i])) + offset, cnt);
 		if (res)
 			return (-EFAULT);
 		do_count -= cnt;
@@ -5410,7 +5412,7 @@ static int osst_zero_buffer_tail(struct osst_buffer *st_bp)
 	     i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length - offset < do_count ?
 		      st_bp->sg[i].length - offset : do_count ;
-		memset(page_address(st_bp->sg[i].page) + offset, 0, cnt);
+		memset(page_address(sg_page(&st_bp->sg[i])) + offset, 0, cnt);
 		do_count -= cnt;
 		offset = 0;
 	}
@@ -5430,7 +5432,7 @@ static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
 	for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length < do_count ?
 		      st_bp->sg[i].length : do_count ;
-		memcpy(page_address(st_bp->sg[i].page), ptr, cnt);
+		memcpy(page_address(sg_page(&st_bp->sg[i])), ptr, cnt);
 		do_count -= cnt;
 		ptr      += cnt;
 	}
@@ -5451,7 +5453,7 @@ static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
 	for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length < do_count ?
 		      st_bp->sg[i].length : do_count ;
-		memcpy(ptr, page_address(st_bp->sg[i].page), cnt);
+		memcpy(ptr, page_address(sg_page(&st_bp->sg[i])), cnt);
 		do_count -= cnt;
 		ptr      += cnt;
 	}
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 190e2a7..26c41b0 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -443,7 +443,7 @@ SYM53C500_intr(int irq, void *dev_id)
 
 			scsi_for_each_sg(curSC, sg, scsi_sg_count(curSC), i) {
 				SYM53C500_pio_write(fast_pio, port_base,
-						    page_address(sg->page) + sg->offset,
+				    page_address(sg_page(sg)) + sg->offset,
 						    sg->length);
 			}
 			REG0(port_base);
@@ -463,8 +463,8 @@ SYM53C500_intr(int irq, void *dev_id)
 
 			scsi_for_each_sg(curSC, sg, scsi_sg_count(curSC), i) {
 				SYM53C500_pio_read(fast_pio, port_base,
-						   page_address(sg->page) + sg->offset,
-						   sg->length);
+					page_address(sg_page(sg)) + sg->offset,
+					sg->length);
 			}
 			REG0(port_base);
 		}
diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
index 67b6d76..07f31e5 100644
--- a/drivers/scsi/ppa.c
+++ b/drivers/scsi/ppa.c
@@ -609,7 +609,7 @@ static int ppa_completion(struct scsi_cmnd *cmd)
 				cmd->SCp.this_residual =
 				    cmd->SCp.buffer->length;
 				cmd->SCp.ptr =
-				    page_address(cmd->SCp.buffer->page) +
+				    page_address(sg_page(cmd->SCp.buffer)) +
 				    cmd->SCp.buffer->offset;
 			}
 		}
@@ -756,7 +756,7 @@ static int ppa_engine(ppa_struct *dev, struct scsi_cmnd *cmd)
 			/* if many buffers are available, start filling the first */
 			cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
 			cmd->SCp.this_residual = cmd->SCp.buffer->length;
-			cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) +
+			cmd->SCp.ptr = page_address(sg_page(cmd->SCp.buffer)) +
 			    cmd->SCp.buffer->offset;
 		} else {
 			/* else fill the only available buffer */
diff --git a/drivers/scsi/qlogicfas408.c b/drivers/scsi/qlogicfas408.c
index 2bfbf26..feff3f7 100644
--- a/drivers/scsi/qlogicfas408.c
+++ b/drivers/scsi/qlogicfas408.c
@@ -317,7 +317,7 @@ static unsigned int ql_pcmd(struct scsi_cmnd *cmd)
 				return ((priv->qabort == 1 ?
 					 DID_ABORT : DID_RESET) << 16);
 			}
-			buf = page_address(sg->page) + sg->offset;
+			buf = page_address(sg_page(sg)) + sg->offset;
 			if (ql_pdma(priv, phase, buf, sg->length))
 				break;
 		}
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 72ee4c9..46cae5a 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -625,7 +625,7 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
 	scsi_for_each_sg(scp, sg, scp->use_sg, k) {
 		if (active) {
 			kaddr = (unsigned char *)
-				kmap_atomic(sg->page, KM_USER0);
+				kmap_atomic(sg_page(sg), KM_USER0);
 			if (NULL == kaddr)
 				return (DID_ERROR << 16);
 			kaddr_off = (unsigned char *)kaddr + sg->offset;
@@ -672,7 +672,7 @@ static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
 	sg = scsi_sglist(scp);
 	req_len = fin = 0;
 	for (k = 0; k < scp->use_sg; ++k, sg = sg_next(sg)) {
-		kaddr = (unsigned char *)kmap_atomic(sg->page, KM_USER0);
+		kaddr = (unsigned char *)kmap_atomic(sg_page(sg), KM_USER0);
 		if (NULL == kaddr)
 			return -1;
 		kaddr_off = (unsigned char *)kaddr + sg->offset;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index aac8a02..61fdaf0 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -295,7 +295,7 @@ static int scsi_req_map_sg(struct request *rq, struct scatterlist *sgl,
 	int i, err, nr_vecs = 0;
 
 	for_each_sg(sgl, sg, nsegs, i) {
-		page = sg->page;
+		page = sg_page(sg);
 		off = sg->offset;
 		len = sg->length;
  		data_len += len;
@@ -764,7 +764,7 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
 		if (unlikely(!sgl))
 			goto enomem;
 
-		memset(sgl, 0, sizeof(*sgl) * sgp->size);
+		sg_init_table(sgl, sgp->size);
 
 		/*
 		 * first loop through, set initial index and return value
@@ -781,6 +781,13 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
 			sg_chain(prev, SCSI_MAX_SG_SEGMENTS, sgl);
 
 		/*
+		 * if we have nothing left, mark the last segment as
+		 * end-of-list
+		 */
+		if (!left)
+			sg_mark_end(sgl, this);
+
+		/*
 		 * don't allow subsequent mempool allocs to sleep, it would
 		 * violate the mempool principle.
 		 */
@@ -2353,7 +2360,7 @@ void *scsi_kmap_atomic_sg(struct scatterlist *sgl, int sg_count,
 	*offset = *offset - len_complete + sg->offset;
 
 	/* Assumption: contiguous pages can be accessed as "page + i" */
-	page = nth_page(sg->page, (*offset >> PAGE_SHIFT));
+	page = nth_page(sg_page(sg), (*offset >> PAGE_SHIFT));
 	*offset &= ~PAGE_MASK;
 
 	/* Bytes in this sg-entry from *offset to the end of the page */
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 7238b2d..cc19710 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1169,7 +1169,7 @@ sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type)
 		len = vma->vm_end - sa;
 		len = (len < sg->length) ? len : sg->length;
 		if (offset < len) {
-			page = virt_to_page(page_address(sg->page) + offset);
+			page = virt_to_page(page_address(sg_page(sg)) + offset);
 			get_page(page);	/* increment page count */
 			break;
 		}
@@ -1717,13 +1717,13 @@ st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,
 		   goto out_unlock; */
         }
 
-	sgl[0].page = pages[0];
+	sg_set_page(sgl, pages[0]);
 	sgl[0].offset = uaddr & ~PAGE_MASK;
 	if (nr_pages > 1) {
 		sgl[0].length = PAGE_SIZE - sgl[0].offset;
 		count -= sgl[0].length;
 		for (i=1; i < nr_pages ; i++) {
-			sgl[i].page = pages[i]; 
+			sg_set_page(&sgl[i], pages[i]);
 			sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
 			count -= PAGE_SIZE;
 		}
@@ -1754,7 +1754,7 @@ st_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_pages,
 	int i;
 
 	for (i=0; i < nr_pages; i++) {
-		struct page *page = sgl[i].page;
+		struct page *page = sg_page(&sgl[i]);
 
 		if (dirtied)
 			SetPageDirty(page);
@@ -1854,7 +1854,7 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
 				scatter_elem_sz_prev = ret_sz;
 			}
 		}
-		sg->page = p;
+		sg_set_page(sg, p);
 		sg->length = (ret_sz > num) ? num : ret_sz;
 
 		SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k=%d, num=%d, "
@@ -1907,14 +1907,14 @@ sg_write_xfer(Sg_request * srp)
 		onum = 1;
 
 	ksglen = sg->length;
-	p = page_address(sg->page);
+	p = page_address(sg_page(sg));
 	for (j = 0, k = 0; j < onum; ++j) {
 		res = sg_u_iovec(hp, iovec_count, j, 1, &usglen, &up);
 		if (res)
 			return res;
 
 		for (; p; sg = sg_next(sg), ksglen = sg->length,
-		     p = page_address(sg->page)) {
+		     p = page_address(sg_page(sg))) {
 			if (usglen <= 0)
 				break;
 			if (ksglen > usglen) {
@@ -1991,12 +1991,12 @@ sg_remove_scat(Sg_scatter_hold * schp)
 		} else {
 			int k;
 
-			for (k = 0; (k < schp->k_use_sg) && sg->page;
+			for (k = 0; (k < schp->k_use_sg) && sg_page(sg);
 			     ++k, sg = sg_next(sg)) {
 				SCSI_LOG_TIMEOUT(5, printk(
 				    "sg_remove_scat: k=%d, pg=0x%p, len=%d\n",
-				    k, sg->page, sg->length));
-				sg_page_free(sg->page, sg->length);
+				    k, sg_page(sg), sg->length));
+				sg_page_free(sg_page(sg), sg->length);
 			}
 		}
 		kfree(schp->buffer);
@@ -2038,7 +2038,7 @@ sg_read_xfer(Sg_request * srp)
 	} else
 		onum = 1;
 
-	p = page_address(sg->page);
+	p = page_address(sg_page(sg));
 	ksglen = sg->length;
 	for (j = 0, k = 0; j < onum; ++j) {
 		res = sg_u_iovec(hp, iovec_count, j, 0, &usglen, &up);
@@ -2046,7 +2046,7 @@ sg_read_xfer(Sg_request * srp)
 			return res;
 
 		for (; p; sg = sg_next(sg), ksglen = sg->length,
-		     p = page_address(sg->page)) {
+		     p = page_address(sg_page(sg))) {
 			if (usglen <= 0)
 				break;
 			if (ksglen > usglen) {
@@ -2092,15 +2092,15 @@ sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer)
 	if ((!outp) || (num_read_xfer <= 0))
 		return 0;
 
-	for (k = 0; (k < schp->k_use_sg) && sg->page; ++k, sg = sg_next(sg)) {
+	for (k = 0; (k < schp->k_use_sg) && sg_page(sg); ++k, sg = sg_next(sg)) {
 		num = sg->length;
 		if (num > num_read_xfer) {
-			if (__copy_to_user(outp, page_address(sg->page),
+			if (__copy_to_user(outp, page_address(sg_page(sg)),
 					   num_read_xfer))
 				return -EFAULT;
 			break;
 		} else {
-			if (__copy_to_user(outp, page_address(sg->page),
+			if (__copy_to_user(outp, page_address(sg_page(sg)),
 					   num))
 				return -EFAULT;
 			num_read_xfer -= num;
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 73c44cb..ce69b9e 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -3797,7 +3797,7 @@ static void buf_to_sg(struct st_buffer *STbp, unsigned int length)
 	sg = &(STbp->sg[0]);
 	frp = STbp->frp;
 	for (i=count=0; count < length; i++) {
-		sg[i].page = frp[i].page;
+		sg_set_page(&sg[i], frp[i].page);
 		if (length - count > frp[i].length)
 			sg[i].length = frp[i].length;
 		else
@@ -4446,14 +4446,14 @@ static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pa
         }
 
 	/* Populate the scatter/gather list */
-	sgl[0].page = pages[0]; 
+	sg_set_page(&sgl[0], pages[0]);
 	sgl[0].offset = uaddr & ~PAGE_MASK;
 	if (nr_pages > 1) {
 		sgl[0].length = PAGE_SIZE - sgl[0].offset;
 		count -= sgl[0].length;
 		for (i=1; i < nr_pages ; i++) {
+			sg_set_page(&sgl[i], pages[i]);;
 			sgl[i].offset = 0;
-			sgl[i].page = pages[i]; 
 			sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
 			count -= PAGE_SIZE;
 		}
@@ -4483,7 +4483,7 @@ static int sgl_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_p
 	int i;
 
 	for (i=0; i < nr_pages; i++) {
-		struct page *page = sgl[i].page;
+		struct page *page = sg_page(&sgl[i]);
 
 		if (dirtied)
 			SetPageDirty(page);
diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c
index 5c72ca3..4419304 100644
--- a/drivers/scsi/tmscsim.c
+++ b/drivers/scsi/tmscsim.c
@@ -430,10 +430,7 @@ static __inline__ void dc390_Going_remove (struct dc390_dcb* pDCB, struct dc390_
 
 static struct scatterlist* dc390_sg_build_single(struct scatterlist *sg, void *addr, unsigned int length)
 {
-	memset(sg, 0, sizeof(struct scatterlist));
-	sg->page	= virt_to_page(addr);
-	sg->length	= length;
-	sg->offset	= (unsigned long)addr & ~PAGE_MASK;
+	sg_init_one(sg, addr, length);
 	return sg;
 }
 
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index c021af3..3577453 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -438,12 +438,12 @@ int usb_sg_init (
 			io->urbs[i]->transfer_buffer = NULL;
 #else
 			io->urbs[i]->transfer_buffer =
-				page_address(sg[i].page) + sg[i].offset;
+				page_address(sg_page(&sg[i])) + sg[i].offset;
 #endif
 		} else {
 			/* hc may use _only_ transfer_buffer */
 			io->urbs [i]->transfer_buffer =
-				page_address (sg [i].page) + sg [i].offset;
+				page_address(sg_page(&sg[i])) + sg [i].offset;
 			len = sg [i].length;
 		}
 
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
index e7d982a..4866baf 100644
--- a/drivers/usb/image/microtek.c
+++ b/drivers/usb/image/microtek.c
@@ -519,7 +519,7 @@ static void mts_do_sg (struct urb* transfer)
 	context->fragment++;
 	mts_int_submit_urb(transfer,
 			   context->data_pipe,
-			   page_address(sg[context->fragment].page) +
+			   page_address(sg_page(&sg[context->fragment])) +
 			   sg[context->fragment].offset,
 			   sg[context->fragment].length,
 			   context->fragment + 1 == scsi_sg_count(context->srb) ?
@@ -557,7 +557,7 @@ mts_build_transfer_context(struct scsi_cmnd *srb, struct mts_desc* desc)
 		return;
 	} else {
 		sg = scsi_sglist(srb);
-		desc->context.data = page_address(sg[0].page) + sg[0].offset;
+		desc->context.data = page_address(sg_page(&sg[0])) + sg[0].offset;
 		desc->context.data_length = sg[0].length;
 	}
 
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index e901d31..ca8cb34 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -360,9 +360,10 @@ static void free_sglist (struct scatterlist *sg, int nents)
 	if (!sg)
 		return;
 	for (i = 0; i < nents; i++) {
-		if (!sg [i].page)
+		struct page *page = sg_page(&sg[i]);
+		if (!page)
 			continue;
-		kfree (page_address (sg [i].page) + sg [i].offset);
+		kfree (page_address (page) + sg [i].offset);
 	}
 	kfree (sg);
 }
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c
index cc8f7c5..889622b 100644
--- a/drivers/usb/storage/protocol.c
+++ b/drivers/usb/storage/protocol.c
@@ -195,7 +195,7 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
 		 * the *offset and *index values for the next loop. */
 		cnt = 0;
 		while (cnt < buflen) {
-			struct page *page = sg->page +
+			struct page *page = sg_page(sg) +
 					((sg->offset + *offset) >> PAGE_SHIFT);
 			unsigned int poff =
 					(sg->offset + *offset) & (PAGE_SIZE-1);
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index 1ae90ef..0a9882e 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -283,7 +283,7 @@ int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg,
 		pg = virt_to_page(addr);
 		offset = offset_in_page(addr);
 		if (sg) {
-			sg[i].page = pg;
+			sg_set_page(&sg[i], pg);
 			sg[i].offset = offset;
 		}
 		remainder_of_page = PAGE_CACHE_SIZE - offset;
@@ -713,10 +713,13 @@ ecryptfs_encrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
 {
 	struct scatterlist src_sg, dst_sg;
 
-	src_sg.page = src_page;
+	sg_init_table(&src_sg, 1);
+	sg_init_table(&dst_sg, 1);
+
+	sg_set_page(&src_sg, src_page);
 	src_sg.offset = src_offset;
 	src_sg.length = size;
-	dst_sg.page = dst_page;
+	sg_set_page(&dst_sg, dst_page);
 	dst_sg.offset = dst_offset;
 	dst_sg.length = size;
 	return encrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
@@ -742,10 +745,13 @@ ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
 {
 	struct scatterlist src_sg, dst_sg;
 
-	src_sg.page = src_page;
+	sg_init_table(&src_sg, 1);
+	sg_init_table(&dst_sg, 1);
+
+	sg_set_page(&src_sg, src_page);
 	src_sg.offset = src_offset;
 	src_sg.length = size;
-	dst_sg.page = dst_page;
+	sg_set_page(&dst_sg, dst_page);
 	dst_sg.offset = dst_offset;
 	dst_sg.length = size;
 	return decrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 89d9710..263fed8 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -1040,6 +1040,9 @@ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
 	};
 	int rc = 0;
 
+	sg_init_table(&dst_sg, 1);
+	sg_init_table(&src_sg, 1);
+
 	if (unlikely(ecryptfs_verbosity > 0)) {
 		ecryptfs_printk(
 			KERN_DEBUG, "Session key encryption key (size [%d]):\n",
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index ebd03cc..6f03918 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -88,7 +88,7 @@ nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname)
 {
 	struct xdr_netobj cksum;
 	struct hash_desc desc;
-	struct scatterlist sg[1];
+	struct scatterlist sg;
 	__be32 status = nfserr_resource;
 
 	dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n",
@@ -102,11 +102,9 @@ nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname)
 	if (cksum.data == NULL)
  		goto out;
 
-	sg[0].page = virt_to_page(clname->data);
-	sg[0].offset = offset_in_page(clname->data);
-	sg[0].length = clname->len;
+	sg_init_one(&sg, clname->data, clname->len);
 
-	if (crypto_hash_digest(&desc, sg, sg->length, cksum.data))
+	if (crypto_hash_digest(&desc, &sg, sg.length, cksum.data))
 		goto out;
 
 	md5_to_hex(dname, cksum.data);
diff --git a/include/asm-sparc64/scatterlist.h b/include/asm-sparc64/scatterlist.h
index 703c5bb..6df23f0 100644
--- a/include/asm-sparc64/scatterlist.h
+++ b/include/asm-sparc64/scatterlist.h
@@ -6,7 +6,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page	*page;
+#ifdef CONFIG_DEBUG_SG
+	unsigned long	sg_magic;
+#endif
+	unsigned long	page_link;
 	unsigned int	offset;
 
 	unsigned int	length;
diff --git a/include/asm-x86/dma-mapping_32.h b/include/asm-x86/dma-mapping_32.h
index 6a2d26c..e0d38d8 100644
--- a/include/asm-x86/dma-mapping_32.h
+++ b/include/asm-x86/dma-mapping_32.h
@@ -45,9 +45,9 @@ dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
 	WARN_ON(nents == 0 || sglist[0].length == 0);
 
 	for_each_sg(sglist, sg, nents, i) {
-		BUG_ON(!sg->page);
+		BUG_ON(!sg_page(sg));
 
-		sg->dma_address = page_to_phys(sg->page) + sg->offset;
+		sg->dma_address = page_to_phys(sg_page(sg)) + sg->offset;
 	}
 
 	flush_write_buffers();
diff --git a/include/asm-x86/scatterlist_32.h b/include/asm-x86/scatterlist_32.h
index bd5164a..0e7d997 100644
--- a/include/asm-x86/scatterlist_32.h
+++ b/include/asm-x86/scatterlist_32.h
@@ -4,7 +4,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page		*page;
+#ifdef CONFIG_DEBUG_SG
+    unsigned long	sg_magic;
+#endif
+    unsigned long	page_link;
     unsigned int	offset;
     dma_addr_t		dma_address;
     unsigned int	length;
diff --git a/include/asm-x86/scatterlist_64.h b/include/asm-x86/scatterlist_64.h
index ef3986b..1847c72 100644
--- a/include/asm-x86/scatterlist_64.h
+++ b/include/asm-x86/scatterlist_64.h
@@ -4,7 +4,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page		*page;
+#ifdef CONFIG_DEBUG_SG
+    unsigned long	sg_magic;
+#endif
+    unsigned long	page_link;
     unsigned int	offset;
     unsigned int	length;
     dma_addr_t		dma_address;
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index 2dc7464..b4d6a64 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -5,29 +5,72 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 
+/*
+ * Notes on SG table design.
+ *
+ * Architectures must provide an unsigned long page_link field in the
+ * scatterlist struct. We use that to place the page pointer AND encode
+ * information about the sg table as well. The two lower bits are reserved
+ * for this information.
+ *
+ * If bit 0 is set, then the page_link contains a pointer to the next sg
+ * table list. Otherwise the next entry is at sg + 1.
+ *
+ * If bit 1 is set, then this sg entry is the last element in a list.
+ *
+ * See sg_next().
+ *
+ */
+
+#define SG_MAGIC	0x87654321
+
+/**
+ * sg_set_page - Set sg entry to point at given page
+ * @sg:		 SG entry
+ * @page:	 The page
+ *
+ * Use this function to set an sg entry pointing at a page, never assign
+ * the page directly. We encode sg table information in the lower bits
+ * of the page pointer. See sg_page() for looking up the page belonging
+ * to an sg entry.
+ *
+ */
+static inline void sg_set_page(struct scatterlist *sg, struct page *page)
+{
+	unsigned long page_link = sg->page_link & 0x3;
+
+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(sg->sg_magic != SG_MAGIC);
+#endif
+	sg->page_link = page_link | (unsigned long) page;
+}
+
+#define sg_page(sg)	((struct page *) ((sg)->page_link & ~0x3))
+
+/**
+ * sg_set_buf - Set sg entry to point at given data
+ * @sg:		 SG entry
+ * @buf:	 Data
+ * @buflen:	 Data length
+ * 
+*/
 static inline void sg_set_buf(struct scatterlist *sg, const void *buf,
 			      unsigned int buflen)
 {
-	sg->page = virt_to_page(buf);
+	sg_set_page(sg, virt_to_page(buf));
 	sg->offset = offset_in_page(buf);
 	sg->length = buflen;
 }
 
-static inline void sg_init_one(struct scatterlist *sg, const void *buf,
-			       unsigned int buflen)
-{
-	memset(sg, 0, sizeof(*sg));
-	sg_set_buf(sg, buf, buflen);
-}
-
 /*
  * We overload the LSB of the page pointer to indicate whether it's
  * a valid sg entry, or whether it points to the start of a new scatterlist.
  * Those low bits are there for everyone! (thanks mason :-)
  */
-#define sg_is_chain(sg)		((unsigned long) (sg)->page & 0x01)
+#define sg_is_chain(sg)		((sg)->page_link & 0x01)
+#define sg_is_last(sg)		((sg)->page_link & 0x02)
 #define sg_chain_ptr(sg)	\
-	((struct scatterlist *) ((unsigned long) (sg)->page & ~0x01))
+	((struct scatterlist *) ((sg)->page_link & ~0x03))
 
 /**
  * sg_next - return the next scatterlist entry in a list
@@ -37,16 +80,18 @@ static inline void sg_init_one(struct scatterlist *sg, const void *buf,
  * of a chained scatterlist, it could jump to the start of a new
  * scatterlist array.
  *
- * Note that the caller must ensure that there are further entries after
- * the current entry, this function will NOT return NULL for an end-of-list.
- *
  */
 static inline struct scatterlist *sg_next(struct scatterlist *sg)
 {
-	sg++;
-
-	if (unlikely(sg_is_chain(sg)))
+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(sg->sg_magic != SG_MAGIC);
+#endif
+	if (sg_is_last(sg))
+		sg = NULL;
+	else if (sg_is_chain(sg))
 		sg = sg_chain_ptr(sg);
+	else
+		sg++;
 
 	return sg;
 }
@@ -83,6 +128,9 @@ static inline struct scatterlist *sg_last(struct scatterlist *sgl,
 		ret = sg;
 
 #endif
+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(sgl[0].sg_magic != SG_MAGIC);
+#endif
 	return ret;
 }
 
@@ -101,7 +149,63 @@ static inline void sg_chain(struct scatterlist *prv, unsigned int prv_nents,
 #ifndef ARCH_HAS_SG_CHAIN
 	BUG();
 #endif
-	prv[prv_nents - 1].page = (struct page *) ((unsigned long) sgl | 0x01);
+	prv[prv_nents - 1].page_link = (unsigned long) sgl | 0x01;
+}
+
+/**
+ * sg_mark_end - Mark the end of the scatterlist
+ * @sgl:	Scatterlist
+ * @nents:	Number of entries in sgl
+ *
+ * Marks the last entry as the termination point for sg_next()
+ *
+ */
+static inline void sg_mark_end(struct scatterlist *sgl, unsigned int nents)
+{
+	sgl[nents - 1].page_link = 0x02;
+}
+
+/**
+ * sg_init_one - Initialize a single entry sg list
+ * @sg:		 SG entry
+ * @buf:	 Virtual address for IO
+ * @buflen:	 IO length
+ *
+ * Note: this should not be used on a single entry that is part of a larger
+ * table. Use sg_init_table() for that.
+ *
+ */
+static inline void sg_init_one(struct scatterlist *sg, const void *buf,
+			       unsigned int buflen)
+{
+	memset(sg, 0, sizeof(*sg));
+#ifdef CONFIG_DEBUG_SG
+	sg->sg_magic = SG_MAGIC;
+#endif
+	sg_mark_end(sg, 1);
+	sg_set_buf(sg, buf, buflen);
+}
+
+/**
+ * sg_init_table - Initialize SG table
+ * @sgl:	   The SG table
+ * @nents:	   Number of entries in table
+ *
+ * Note: If this is part of a chained sg table, sg_mark_end() should be
+ * used only on the last table part.
+ *
+ */
+static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents)
+{
+	memset(sgl, 0, sizeof(*sgl) * nents);
+	sg_mark_end(sgl, nents);
+#ifdef CONFIG_DEBUG_SG
+	{
+		int i;
+		for (i = 0; i < nents; i++)
+			sgl[i].sg_magic = SG_MAGIC;
+	}
+#endif
 }
 
 #endif /* _LINUX_SCATTERLIST_H */
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 7d16e64..183f42c 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -389,6 +389,16 @@ config DEBUG_LIST
 
 	  If unsure, say N.
 
+config DEBUG_SG
+	bool "Debug SG table operations"
+	depends on DEBUG_KERNEL
+	help
+	  Enable this to turn on checks on scatter-gather tables. This can
+	  help find problems with drivers that do not properly initialize
+	  their sg tables.
+
+	  If unsure, say N.
+
 config FRAME_POINTER
 	bool "Compile the kernel with frame pointers"
 	depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML || S390 || AVR32 || SUPERH || BFIN)
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 752fd95..e58909e 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -35,7 +35,7 @@
 #define OFFSET(val,align) ((unsigned long)	\
 	                   ( (val) & ( (align) - 1)))
 
-#define SG_ENT_VIRT_ADDRESS(sg)	(page_address((sg)->page) + (sg)->offset)
+#define SG_ENT_VIRT_ADDRESS(sg)	(page_address(sg_page((sg)) + (sg)->offset))
 #define SG_ENT_PHYS_ADDRESS(sg)	virt_to_bus(SG_ENT_VIRT_ADDRESS(sg))
 
 /*
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 70d9b5d..4e2c84f 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2045,7 +2045,7 @@ skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
 	if (copy > 0) {
 		if (copy > len)
 			copy = len;
-		sg[elt].page = virt_to_page(skb->data + offset);
+		sg_set_page(&sg[elt], virt_to_page(skb->data + offset));
 		sg[elt].offset = (unsigned long)(skb->data + offset) % PAGE_SIZE;
 		sg[elt].length = copy;
 		elt++;
@@ -2065,7 +2065,7 @@ skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
 
 			if (copy > len)
 				copy = len;
-			sg[elt].page = frag->page;
+			sg_set_page(&sg[elt], frag->page);
 			sg[elt].offset = frag->page_offset+offset-start;
 			sg[elt].length = copy;
 			elt++;
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
index 6cc54ee..34d4c77 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -390,9 +390,7 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	icv[3] = crc >> 24;
 
 	crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = len + 4;
+	sg_init_one(&sg, pos, len + 4);
 	return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
 }
 
@@ -485,9 +483,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	plen = skb->len - hdr_len - 12;
 
 	crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = plen + 4;
+	sg_init_one(&sg, pos, plen + 4);
 	if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG ": TKIP: failed to decrypt "
@@ -539,11 +535,12 @@ static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
 		printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
 		return -1;
 	}
-	sg[0].page = virt_to_page(hdr);
+	sg_init_table(sg, 2);
+	sg_set_page(&sg[0], virt_to_page(hdr));
 	sg[0].offset = offset_in_page(hdr);
 	sg[0].length = 16;
 
-	sg[1].page = virt_to_page(data);
+	sg_set_page(&sg[1], virt_to_page(data));
 	sg[1].offset = offset_in_page(data);
 	sg[1].length = data_len;
 
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
index 8d18245..0af6103 100644
--- a/net/ieee80211/ieee80211_crypt_wep.c
+++ b/net/ieee80211/ieee80211_crypt_wep.c
@@ -170,9 +170,7 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	icv[3] = crc >> 24;
 
 	crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = len + 4;
+	sg_init_one(&sg, pos, len + 4);
 	return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
 }
 
@@ -212,9 +210,7 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	plen = skb->len - hdr_len - 8;
 
 	crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = plen + 4;
+	sg_init_one(&sg, pos, plen + 4);
 	if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
 		return -7;
 
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 6675261..cc806d6 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -138,9 +138,7 @@ void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
 	*icv = cpu_to_le32(~crc32_le(~0, data, data_len));
 
 	crypto_blkcipher_setkey(tfm, rc4key, klen);
-	sg.page = virt_to_page(data);
-	sg.offset = offset_in_page(data);
-	sg.length = data_len + WEP_ICV_LEN;
+	sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
 	crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length);
 }
 
@@ -204,9 +202,7 @@ int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
 	__le32 crc;
 
 	crypto_blkcipher_setkey(tfm, rc4key, klen);
-	sg.page = virt_to_page(data);
-	sg.offset = offset_in_page(data);
-	sg.length = data_len + WEP_ICV_LEN;
+	sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
 	crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length);
 
 	crc = cpu_to_le32(~crc32_le(~0, data, data_len));
diff --git a/net/sctp/auth.c b/net/sctp/auth.c
index 7818107..cbd64b2 100644
--- a/net/sctp/auth.c
+++ b/net/sctp/auth.c
@@ -726,7 +726,8 @@ void sctp_auth_calculate_hmac(const struct sctp_association *asoc,
 
 	/* set up scatter list */
 	end = skb_tail_pointer(skb);
-	sg.page = virt_to_page(auth);
+	sg_init_table(&sg, 1);
+	sg_set_page(&sg, virt_to_page(auth));
 	sg.offset = (unsigned long)(auth) % PAGE_SIZE;
 	sg.length = end - (unsigned char *)auth;
 
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index f983a36..d5a9785 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1513,7 +1513,8 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
 		struct hash_desc desc;
 
 		/* Sign the message.  */
-		sg.page = virt_to_page(&cookie->c);
+		sg_init_table(&sg, 1);
+		sg_set_page(&sg, virt_to_page(&cookie->c));
 		sg.offset = (unsigned long)(&cookie->c) % PAGE_SIZE;
 		sg.length = bodysize;
 		keylen = SCTP_SECRET_SIZE;
@@ -1585,7 +1586,8 @@ struct sctp_association *sctp_unpack_cookie(
 
 	/* Check the signature.  */
 	keylen = SCTP_SECRET_SIZE;
-	sg.page = virt_to_page(bear_cookie);
+	sg_init_table(&sg, 1);
+	sg_set_page(&sg, virt_to_page(bear_cookie));
 	sg.offset = (unsigned long)(bear_cookie) % PAGE_SIZE;
 	sg.length = bodysize;
 	key = (char *)ep->secret_key[ep->current_key];
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index bfb6a29..32be431 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -197,9 +197,9 @@ encryptor(struct scatterlist *sg, void *data)
 		int i = (page_pos + outbuf->page_base) >> PAGE_CACHE_SHIFT;
 		in_page = desc->pages[i];
 	} else {
-		in_page = sg->page;
+		in_page = sg_page(sg);
 	}
-	desc->infrags[desc->fragno].page = in_page;
+	sg_set_page(&desc->infrags[desc->fragno], in_page);
 	desc->fragno++;
 	desc->fraglen += sg->length;
 	desc->pos += sg->length;
@@ -215,11 +215,11 @@ encryptor(struct scatterlist *sg, void *data)
 	if (ret)
 		return ret;
 	if (fraglen) {
-		desc->outfrags[0].page = sg->page;
+		sg_set_page(&desc->outfrags[0], sg_page(sg));
 		desc->outfrags[0].offset = sg->offset + sg->length - fraglen;
 		desc->outfrags[0].length = fraglen;
 		desc->infrags[0] = desc->outfrags[0];
-		desc->infrags[0].page = in_page;
+		sg_set_page(&desc->infrags[0], in_page);
 		desc->fragno = 1;
 		desc->fraglen = fraglen;
 	} else {
@@ -287,7 +287,7 @@ decryptor(struct scatterlist *sg, void *data)
 	if (ret)
 		return ret;
 	if (fraglen) {
-		desc->frags[0].page = sg->page;
+		sg_set_page(&desc->frags[0], sg_page(sg));
 		desc->frags[0].offset = sg->offset + sg->length - fraglen;
 		desc->frags[0].length = fraglen;
 		desc->fragno = 1;
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 6a59180..3d1f7cd 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -1059,7 +1059,7 @@ xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len,
 		do {
 			if (thislen > page_len)
 				thislen = page_len;
-			sg->page = buf->pages[i];
+			sg_set_page(sg, buf->pages[i]);
 			sg->offset = page_offset;
 			sg->length = thislen;
 			ret = actor(sg, data);
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index 5ced62c..fb2220a 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -552,7 +552,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
 		if (copy > len)
 			copy = len;
 
-		sg.page = virt_to_page(skb->data + offset);
+		sg_set_page(&sg, virt_to_page(skb->data + offset));
 		sg.offset = (unsigned long)(skb->data + offset) % PAGE_SIZE;
 		sg.length = copy;
 
@@ -577,7 +577,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
 			if (copy > len)
 				copy = len;
 
-			sg.page = frag->page;
+			sg_set_page(&sg, frag->page);
 			sg.offset = frag->page_offset + offset-start;
 			sg.length = copy;
 

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  7:05                                                       ` Jens Axboe
@ 2007-10-18 13:13                                                         ` Mark Lord
  2007-10-18 13:23                                                           ` Jens Axboe
  0 siblings, 1 reply; 151+ messages in thread
From: Mark Lord @ 2007-10-18 13:13 UTC (permalink / raw)
  To: Jens Axboe
  Cc: Jeff Garzik, Linus Torvalds, David Miller, fujita.tomonori, mingo,
	linux-kernel, alan, tomof

Jens Axboe wrote:
> On Thu, Oct 18 2007, Jeff Garzik wrote:
>> Mark Lord wrote:
>>> Okay, mine is dying with EIP at blk_rq_map_sg+0xcb/0x160.
>>> Screen photo is at http://rtr.ca/recent/2.6.23-git12-crash.jpg,
>>> but the top was cut off (isn't there a new config option or patch
>>> to do double-columns or scrollback or something ???.
>> Is this a sata_mv box?  If so, could you try this patch?
> 
> If anything, that shrinks the size of the resulting request. Did this
> patch make any difference to you?

Not a sata_mv box, so no point here.

ata_piix.

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 13:13                                                         ` Mark Lord
@ 2007-10-18 13:23                                                           ` Jens Axboe
  2007-10-18 13:32                                                             ` Mark Lord
  0 siblings, 1 reply; 151+ messages in thread
From: Jens Axboe @ 2007-10-18 13:23 UTC (permalink / raw)
  To: Mark Lord
  Cc: Jeff Garzik, Linus Torvalds, David Miller, fujita.tomonori, mingo,
	linux-kernel, alan, tomof

On Thu, Oct 18 2007, Mark Lord wrote:
> Jens Axboe wrote:
>> On Thu, Oct 18 2007, Jeff Garzik wrote:
>>> Mark Lord wrote:
>>>> Okay, mine is dying with EIP at blk_rq_map_sg+0xcb/0x160.
>>>> Screen photo is at http://rtr.ca/recent/2.6.23-git12-crash.jpg,
>>>> but the top was cut off (isn't there a new config option or patch
>>>> to do double-columns or scrollback or something ???.
>>> Is this a sata_mv box?  If so, could you try this patch?
>> If anything, that shrinks the size of the resulting request. Did this
>> patch make any difference to you?
>
> Not a sata_mv box, so no point here.

Can you try the big patch I just posted?

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 12:58                                                       ` Jens Axboe
@ 2007-10-18 13:32                                                         ` Jens Axboe
  2007-10-18 13:49                                                           ` Benny Halevy
  2007-10-18 13:51                                                           ` Mark Lord
  0 siblings, 2 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-18 13:32 UTC (permalink / raw)
  To: David Miller
  Cc: torvalds, fujita.tomonori, mingo, linux-kernel, jgarzik, alan,
	tomof

On Thu, Oct 18 2007, Jens Axboe wrote:
> On Thu, Oct 18 2007, Jens Axboe wrote:
> > On Thu, Oct 18 2007, Jens Axboe wrote:
> > > On Thu, Oct 18 2007, David Miller wrote:
> > > > From: Jens Axboe <jens.axboe@oracle.com>
> > > > Date: Thu, 18 Oct 2007 13:57:02 +0200
> > > > 
> > > > > Thanks a lot, Dave! The patch is a monster right now, I'll work on
> > > > > splitting it into a 3-step process. Any arch help is greatly
> > > > > appreciated.
> > > > 
> > > > I have some other bits that my compile hit, such as some things in the
> > > > crypto layer.
> > > 
> > > Yeah, I have tons of that so far. I hope to have an allyesconfig
> > > compiling pretty soonish, will send that out then.
> > 
> > OK here goes, this compiles with allyesconfig on x86-64. Not too bad,
> > the scsi/ drivers were by far the worst.
> 
> Alright, small modifications and tested somewhat. It boots on my laptop
> just fine (CONFIG_DEBUG_SG is set) without warnings. Also tested with
> PAGEALLOC set, that also boots and works fine without issue.
> 
> So if this is what we want, the question is how to proceed. Right now
> i386 and x86-64 works, sparc64 PROBABLY works but is not tested. Any
> other arch will NOT compile, since it's not converted to use page_link.
> I'll try and do ppc64 now.

OK, I think that covers every arch out there. I haven't been able to
compile any of them, but it's mostly search'n replace operations. I hope
nothing is missing linux/scatterlist.h includes...

 arch/alpha/kernel/pci_iommu.c               |    2 
 arch/arm/common/dmabounce.c                 |    2 
 arch/blackfin/kernel/dma-mapping.c          |    2 
 arch/ia64/hp/common/sba_iommu.c             |    2 
 arch/ia64/hp/sim/simscsi.c                  |    4 
 arch/ia64/sn/pci/pci_dma.c                  |    2 
 arch/m68k/kernel/dma.c                      |    2 
 arch/mips/mm/dma-default.c                  |    8 -
 arch/powerpc/kernel/dma_64.c                |    2 
 arch/powerpc/kernel/ibmebus.c               |    2 
 arch/powerpc/kernel/iommu.c                 |    2 
 arch/powerpc/platforms/ps3/system-bus.c     |    2 
 arch/sparc/kernel/ioport.c                  |   16 +-
 arch/sparc/mm/io-unit.c                     |    2 
 arch/sparc/mm/iommu.c                       |    8 -
 arch/sparc/mm/sun4c.c                       |    2 
 arch/sparc64/kernel/iommu.c                 |    4 
 arch/sparc64/kernel/iommu_common.c          |   12 -
 arch/sparc64/kernel/ldc.c                   |    2 
 arch/sparc64/kernel/pci_sun4v.c             |    4 
 arch/um/drivers/ubd_kern.c                  |    2 
 arch/x86/kernel/pci-calgary_64.c            |   12 +
 arch/x86/kernel/pci-gart_64.c               |    4 
 arch/x86/kernel/pci-nommu_64.c              |    4 
 block/ll_rw_blk.c                           |    5 
 crypto/digest.c                             |    2 
 crypto/hmac.c                               |    3 
 crypto/scatterwalk.c                        |    2 
 crypto/scatterwalk.h                        |    6 
 crypto/tcrypt.c                             |    4 
 crypto/xcbc.c                               |    2 
 drivers/ata/libata-core.c                   |   10 -
 drivers/ata/libata-scsi.c                   |    2 
 drivers/block/cciss.c                       |    4 
 drivers/block/cpqarray.c                    |    3 
 drivers/block/cryptoloop.c                  |   12 +
 drivers/block/ub.c                          |    8 -
 drivers/ide/cris/ide-cris.c                 |    4 
 drivers/ide/ide-probe.c                     |    4 
 drivers/ide/ide-taskfile.c                  |    2 
 drivers/ide/mips/au1xxx-ide.c               |    4 
 drivers/ieee1394/dma.c                      |    2 
 drivers/ieee1394/sbp2.c                     |    2 
 drivers/infiniband/core/umem.c              |   11 +
 drivers/infiniband/hw/ipath/ipath_dma.c     |    4 
 drivers/infiniband/hw/ipath/ipath_mr.c      |    2 
 drivers/infiniband/hw/mthca/mthca_memfree.c |   24 ++-
 drivers/infiniband/ulp/iser/iser_memory.c   |    8 -
 drivers/md/dm-crypt.c                       |   21 +--
 drivers/media/common/saa7146_core.c         |    3 
 drivers/media/video/ivtv/ivtv-udma.c        |    4 
 drivers/media/video/videobuf-dma-sg.c       |    8 -
 drivers/mmc/card/queue.c                    |   15 +-
 drivers/mmc/host/at91_mci.c                 |    8 -
 drivers/mmc/host/au1xmmc.c                  |    8 -
 drivers/mmc/host/imxmmc.c                   |    2 
 drivers/mmc/host/mmc_spi.c                  |    8 -
 drivers/mmc/host/omap.c                     |    4 
 drivers/mmc/host/sdhci.c                    |    2 
 drivers/mmc/host/tifm_sd.c                  |    8 -
 drivers/mmc/host/wbsd.c                     |    6 
 drivers/net/mlx4/icm.c                      |   14 +-
 drivers/net/ppp_mppe.c                      |    6 
 drivers/scsi/3w-9xxx.c                      |    4 
 drivers/scsi/3w-xxxx.c                      |    2 
 drivers/scsi/NCR5380.c                      |    4 
 drivers/scsi/NCR53c406a.c                   |    4 
 drivers/scsi/aacraid/aachba.c               |    2 
 drivers/scsi/aha1542.c                      |    6 
 drivers/scsi/arcmsr/arcmsr_hba.c            |    4 
 drivers/scsi/fdomain.c                      |    6 
 drivers/scsi/gdth.c                         |    4 
 drivers/scsi/ibmmca.c                       |    2 
 drivers/scsi/ide-scsi.c                     |   12 -
 drivers/scsi/imm.c                          |    4 
 drivers/scsi/ipr.c                          |   19 +-
 drivers/scsi/ips.c                          |    6 
 drivers/scsi/iscsi_tcp.c                    |   15 +-
 drivers/scsi/megaraid.c                     |    6 
 drivers/scsi/megaraid/megaraid_mbox.c       |    8 -
 drivers/scsi/osst.c                         |   32 ++--
 drivers/scsi/pcmcia/sym53c500_cs.c          |    6 
 drivers/scsi/ppa.c                          |    4 
 drivers/scsi/qlogicfas408.c                 |    2 
 drivers/scsi/scsi_debug.c                   |    4 
 drivers/scsi/scsi_lib.c                     |   13 +
 drivers/scsi/sg.c                           |   30 ++--
 drivers/scsi/st.c                           |    8 -
 drivers/scsi/tmscsim.c                      |    5 
 drivers/scsi/ultrastor.c                    |    2 
 drivers/scsi/wd7000.c                       |    2 
 drivers/usb/core/message.c                  |    4 
 drivers/usb/image/microtek.c                |    4 
 drivers/usb/misc/usbtest.c                  |    5 
 drivers/usb/storage/protocol.c              |    2 
 fs/ecryptfs/crypto.c                        |   16 +-
 fs/ecryptfs/keystore.c                      |    3 
 fs/nfsd/nfs4recover.c                       |    8 -
 include/asm-alpha/scatterlist.h             |    2 
 include/asm-arm/scatterlist.h               |    2 
 include/asm-avr32/scatterlist.h             |    2 
 include/asm-blackfin/scatterlist.h          |    2 
 include/asm-cris/scatterlist.h              |    2 
 include/asm-frv/scatterlist.h               |    2 
 include/asm-h8300/scatterlist.h             |    2 
 include/asm-ia64/scatterlist.h              |    2 
 include/asm-m32r/scatterlist.h              |    2 
 include/asm-m68k/scatterlist.h              |    2 
 include/asm-m68knommu/scatterlist.h         |    2 
 include/asm-mips/scatterlist.h              |    2 
 include/asm-parisc/scatterlist.h            |    2 
 include/asm-powerpc/scatterlist.h           |    2 
 include/asm-s390/scatterlist.h              |    2 
 include/asm-sh/scatterlist.h                |    2 
 include/asm-sh64/scatterlist.h              |    2 
 include/asm-sparc/scatterlist.h             |    2 
 include/asm-sparc64/scatterlist.h           |    5 
 include/asm-v850/scatterlist.h              |    2 
 include/asm-x86/dma-mapping_32.h            |    4 
 include/asm-x86/scatterlist_32.h            |    5 
 include/asm-x86/scatterlist_64.h            |    5 
 include/asm-xtensa/scatterlist.h            |    2 
 include/linux/scatterlist.h                 |  138 +++++++++++++++++---
 lib/Kconfig.debug                           |   10 +
 lib/swiotlb.c                               |    2 
 net/core/skbuff.c                           |    4 
 net/ieee80211/ieee80211_crypt_tkip.c        |   13 -
 net/ieee80211/ieee80211_crypt_wep.c         |    8 -
 net/mac80211/wep.c                          |    8 -
 net/sctp/auth.c                             |    3 
 net/sctp/sm_make_chunk.c                    |    6 
 net/sunrpc/auth_gss/gss_krb5_crypto.c       |   10 -
 net/sunrpc/xdr.c                            |    2 
 net/xfrm/xfrm_algo.c                        |    4 
 134 files changed, 520 insertions(+), 356 deletions(-)


diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index e1c4707..094a95e 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -465,7 +465,7 @@ EXPORT_SYMBOL(pci_free_consistent);
    Write dma_length of each leader with the combined lengths of
    the mergable followers.  */
 
-#define SG_ENT_VIRT_ADDRESS(SG) (page_address((SG)->page) + (SG)->offset)
+#define SG_ENT_VIRT_ADDRESS(SG) (page_address(sg_page((SG)) + (SG)->offset))
 #define SG_ENT_PHYS_ADDRESS(SG) __pa(SG_ENT_VIRT_ADDRESS(SG))
 
 static void
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 44ab0da..9d371e4 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -442,7 +442,7 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 	BUG_ON(dir == DMA_NONE);
 
 	for (i = 0; i < nents; i++, sg++) {
-		struct page *page = sg->page;
+		struct page *page = sg_page(sg);
 		unsigned int offset = sg->offset;
 		unsigned int length = sg->length;
 		void *ptr = page_address(page) + offset;
diff --git a/arch/blackfin/kernel/dma-mapping.c b/arch/blackfin/kernel/dma-mapping.c
index 94d7b11..dbf7222 100644
--- a/arch/blackfin/kernel/dma-mapping.c
+++ b/arch/blackfin/kernel/dma-mapping.c
@@ -160,7 +160,7 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 	BUG_ON(direction == DMA_NONE);
 
 	for (i = 0; i < nents; i++, sg++) {
-		sg->dma_address = (dma_addr_t)(page_address(sg->page) +
+		sg->dma_address = (dma_addr_t)(page_address(sg_page(sg)) +
 					sg->offset);
 
 		invalidate_dcache_range(sg_dma_address(sg),
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index 3c95f41..0b74c63 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -246,7 +246,7 @@ static int reserve_sba_gart = 1;
 static SBA_INLINE void sba_mark_invalid(struct ioc *, dma_addr_t, size_t);
 static SBA_INLINE void sba_free_range(struct ioc *, dma_addr_t, size_t);
 
-#define sba_sg_address(sg)	(page_address((sg)->page) + (sg)->offset)
+#define sba_sg_address(sg)	(page_address(sg_page((sg)) + (sg)->offset))
 
 #ifdef FULL_VALID_PDIR
 static u64 prefetch_spill_page;
diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c
index a3a558a..7f1794f 100644
--- a/arch/ia64/hp/sim/simscsi.c
+++ b/arch/ia64/hp/sim/simscsi.c
@@ -131,7 +131,7 @@ simscsi_sg_readwrite (struct scsi_cmnd *sc, int mode, unsigned long offset)
 	stat.fd = desc[sc->device->id];
 
 	scsi_for_each_sg(sc, sl, scsi_sg_count(sc), i) {
-		req.addr = __pa(page_address(sl->page) + sl->offset);
+		req.addr = __pa(page_address(sg_page(sl)) + sl->offset);
 		req.len  = sl->length;
 		if (DBG)
 			printk("simscsi_sg_%s @ %lx (off %lx) use_sg=%d len=%d\n",
@@ -212,7 +212,7 @@ static void simscsi_fillresult(struct scsi_cmnd *sc, char *buf, unsigned len)
 		if (!len)
 			break;
 		thislen = min(len, slp->length);
-		memcpy(page_address(slp->page) + slp->offset, buf, thislen);
+		memcpy(page_address(sg_page(slp)) + slp->offset, buf, thislen);
 		len -= thislen;
 	}
 }
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index ecd8a52..6048eaf 100644
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -16,7 +16,7 @@
 #include <asm/sn/pcidev.h>
 #include <asm/sn/sn_sal.h>
 
-#define SG_ENT_VIRT_ADDRESS(sg)	(page_address((sg)->page) + (sg)->offset)
+#define SG_ENT_VIRT_ADDRESS(sg)	(page_address(sg_page((sg)) + (sg)->offset))
 #define SG_ENT_PHYS_ADDRESS(SG)	virt_to_phys(SG_ENT_VIRT_ADDRESS(SG))
 
 /**
diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c
index 9d4e4b5..b2d620b 100644
--- a/arch/m68k/kernel/dma.c
+++ b/arch/m68k/kernel/dma.c
@@ -121,7 +121,7 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 	int i;
 
 	for (i = 0; i < nents; sg++, i++) {
-		sg->dma_address = page_to_phys(sg->page) + sg->offset;
+		sg->dma_address = page_to_phys(sg_page(sg)) + sg->offset;
 		dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);
 	}
 	return nents;
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 98b5e5b..4aa143b 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -165,7 +165,7 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 	for (i = 0; i < nents; i++, sg++) {
 		unsigned long addr;
 
-		addr = (unsigned long) page_address(sg->page);
+		addr = (unsigned long) page_address(sg_page(sg));
 		if (!plat_device_is_coherent(dev) && addr)
 			__dma_sync(addr + sg->offset, sg->length, direction);
 		sg->dma_address = plat_map_dma_mem(dev,
@@ -223,7 +223,7 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
 	for (i = 0; i < nhwentries; i++, sg++) {
 		if (!plat_device_is_coherent(dev) &&
 		    direction != DMA_TO_DEVICE) {
-			addr = (unsigned long) page_address(sg->page);
+			addr = (unsigned long) page_address(sg_page(sg));
 			if (addr)
 				__dma_sync(addr + sg->offset, sg->length,
 				           direction);
@@ -304,7 +304,7 @@ void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
 	/* Make sure that gcc doesn't leave the empty loop body.  */
 	for (i = 0; i < nelems; i++, sg++) {
 		if (cpu_is_noncoherent_r10000(dev))
-			__dma_sync((unsigned long)page_address(sg->page),
+			__dma_sync((unsigned long)page_address(sg_page(sg)),
 			           sg->length, direction);
 		plat_unmap_dma_mem(sg->dma_address);
 	}
@@ -322,7 +322,7 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nele
 	/* Make sure that gcc doesn't leave the empty loop body.  */
 	for (i = 0; i < nelems; i++, sg++) {
 		if (!plat_device_is_coherent(dev))
-			__dma_sync((unsigned long)page_address(sg->page),
+			__dma_sync((unsigned long)page_address(sg_page(sg)),
 			           sg->length, direction);
 		plat_unmap_dma_mem(sg->dma_address);
 	}
diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
index 9001104..5d0aa90 100644
--- a/arch/powerpc/kernel/dma_64.c
+++ b/arch/powerpc/kernel/dma_64.c
@@ -161,7 +161,7 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
 	int i;
 
 	for_each_sg(sgl, sg, nents, i) {
-		sg->dma_address = (page_to_phys(sg->page) + sg->offset) |
+		sg->dma_address = (page_to_phys(sg_page(sg)) + sg->offset) |
 			dma_direct_offset;
 		sg->dma_length = sg->length;
 	}
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index 289d7e9..3d0e71b 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -102,7 +102,7 @@ static int ibmebus_map_sg(struct device *dev,
 	int i;
 
 	for_each_sg(sgl, sg, nents, i) {
-		sg->dma_address = (dma_addr_t)page_address(sg->page)
+		sg->dma_address = (dma_addr_t)page_address(sg_page(sg))
 			+ sg->offset;
 		sg->dma_length = sg->length;
 	}
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 306a6f7..47d745a 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -307,7 +307,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
 			continue;
 		}
 		/* Allocate iommu entries for that segment */
-		vaddr = (unsigned long)page_address(s->page) + s->offset;
+		vaddr = (unsigned long)page_address(sg_page(s)) + s->offset;
 		npages = iommu_num_pages(vaddr, slen);
 		entry = iommu_range_alloc(tbl, npages, &handle, mask >> IOMMU_PAGE_SHIFT, 0);
 
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 07e64b4..e8202b6 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -629,7 +629,7 @@ static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sgl,
 
 	for_each_sg(sgl, sg, nents, i) {
 		int result = ps3_dma_map(dev->d_region,
-			page_to_phys(sg->page) + sg->offset, sg->length,
+			page_to_phys(sg_page(sg)) + sg->offset, sg->length,
 					 &sg->dma_address, 0);
 
 		if (result) {
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 9c3ed88..abc4470 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -727,9 +727,9 @@ int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents,
 	BUG_ON(direction == PCI_DMA_NONE);
 	/* IIep is write-through, not flushing. */
 	for_each_sg(sgl, sg, nents, n) {
-		BUG_ON(page_address(sg->page) == NULL);
+		BUG_ON(page_address(sg_page(sg)) == NULL);
 		sg->dvma_address =
-			virt_to_phys(page_address(sg->page)) + sg->offset;
+			virt_to_phys(page_address(sg_page(sg))) + sg->offset;
 		sg->dvma_length = sg->length;
 	}
 	return nents;
@@ -748,9 +748,9 @@ void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents,
 	BUG_ON(direction == PCI_DMA_NONE);
 	if (direction != PCI_DMA_TODEVICE) {
 		for_each_sg(sgl, sg, nents, n) {
-			BUG_ON(page_address(sg->page) == NULL);
+			BUG_ON(page_address(sg_page(sg)) == NULL);
 			mmu_inval_dma_area(
-			    (unsigned long) page_address(sg->page),
+			    (unsigned long) page_address(sg_page(sg)),
 			    (sg->length + PAGE_SIZE-1) & PAGE_MASK);
 		}
 	}
@@ -798,9 +798,9 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sgl, int
 	BUG_ON(direction == PCI_DMA_NONE);
 	if (direction != PCI_DMA_TODEVICE) {
 		for_each_sg(sgl, sg, nents, n) {
-			BUG_ON(page_address(sg->page) == NULL);
+			BUG_ON(page_address(sg_page(sg)) == NULL);
 			mmu_inval_dma_area(
-			    (unsigned long) page_address(sg->page),
+			    (unsigned long) page_address(sg_page(sg)),
 			    (sg->length + PAGE_SIZE-1) & PAGE_MASK);
 		}
 	}
@@ -814,9 +814,9 @@ void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sgl,
 	BUG_ON(direction == PCI_DMA_NONE);
 	if (direction != PCI_DMA_TODEVICE) {
 		for_each_sg(sgl, sg, nents, n) {
-			BUG_ON(page_address(sg->page) == NULL);
+			BUG_ON(page_address(sg_page(sg)) == NULL);
 			mmu_inval_dma_area(
-			    (unsigned long) page_address(sg->page),
+			    (unsigned long) page_address(sg_page(sg)),
 			    (sg->length + PAGE_SIZE-1) & PAGE_MASK);
 		}
 	}
diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c
index 375b4db..0f2ad57 100644
--- a/arch/sparc/mm/io-unit.c
+++ b/arch/sparc/mm/io-unit.c
@@ -144,7 +144,7 @@ static void iounit_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus
 	spin_lock_irqsave(&iounit->lock, flags);
 	while (sz != 0) {
 		--sz;
-		sg->dvma_address = iounit_get_area(iounit, (unsigned long)page_address(sg->page) + sg->offset, sg->length);
+		sg->dvma_address = iounit_get_area(iounit, (unsigned long)page_address(sg_page(sg)) + sg->offset, sg->length);
 		sg->dvma_length = sg->length;
 		sg = sg_next(sg);
 	}
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
index 283656d..4b93427 100644
--- a/arch/sparc/mm/iommu.c
+++ b/arch/sparc/mm/iommu.c
@@ -238,7 +238,7 @@ static void iommu_get_scsi_sgl_noflush(struct scatterlist *sg, int sz, struct sb
 	while (sz != 0) {
 		--sz;
 		n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
-		sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset;
+		sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset;
 		sg->dvma_length = (__u32) sg->length;
 		sg = sg_next(sg);
 	}
@@ -252,7 +252,7 @@ static void iommu_get_scsi_sgl_gflush(struct scatterlist *sg, int sz, struct sbu
 	while (sz != 0) {
 		--sz;
 		n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
-		sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset;
+		sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset;
 		sg->dvma_length = (__u32) sg->length;
 		sg = sg_next(sg);
 	}
@@ -273,7 +273,7 @@ static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbu
 		 * XXX Is this a good assumption?
 		 * XXX What if someone else unmaps it here and races us?
 		 */
-		if ((page = (unsigned long) page_address(sg->page)) != 0) {
+		if ((page = (unsigned long) page_address(sg_page(sg))) != 0) {
 			for (i = 0; i < n; i++) {
 				if (page != oldpage) {	/* Already flushed? */
 					flush_page_for_dma(page);
@@ -283,7 +283,7 @@ static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbu
 			}
 		}
 
-		sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset;
+		sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset;
 		sg->dvma_length = (__u32) sg->length;
 		sg = sg_next(sg);
 	}
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
index ee6708f..f172dbe 100644
--- a/arch/sparc/mm/sun4c.c
+++ b/arch/sparc/mm/sun4c.c
@@ -1228,7 +1228,7 @@ static void sun4c_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *
 {
 	while (sz != 0) {
 		--sz;
-		sg->dvma_address = (__u32)sun4c_lockarea(page_address(sg->page) + sg->offset, sg->length);
+		sg->dvma_address = (__u32)sun4c_lockarea(page_address(sg_page(sg)) + sg->offset, sg->length);
 		sg->dvma_length = sg->length;
 		sg = sg_next(sg);
 	}
diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c
index 29af777..73852a2 100644
--- a/arch/sparc64/kernel/iommu.c
+++ b/arch/sparc64/kernel/iommu.c
@@ -473,7 +473,7 @@ static void dma_4u_unmap_single(struct device *dev, dma_addr_t bus_addr,
 }
 
 #define SG_ENT_PHYS_ADDRESS(SG)	\
-	(__pa(page_address((SG)->page)) + (SG)->offset)
+	(__pa(page_address(sg_page(SG))) + (SG)->offset)
 
 static void fill_sg(iopte_t *iopte, struct scatterlist *sg,
 		    int nused, int nelems,
@@ -566,7 +566,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
 	if (nelems == 1) {
 		sglist->dma_address =
 			dma_4u_map_single(dev,
-					  (page_address(sglist->page) +
+					  (page_address(sg_page(sglist)) +
 					   sglist->offset),
 					  sglist->length, direction);
 		if (unlikely(sglist->dma_address == DMA_ERROR_CODE))
diff --git a/arch/sparc64/kernel/iommu_common.c b/arch/sparc64/kernel/iommu_common.c
index d7ca900..ec863e0 100644
--- a/arch/sparc64/kernel/iommu_common.c
+++ b/arch/sparc64/kernel/iommu_common.c
@@ -73,7 +73,7 @@ static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg,
 
 	daddr = dma_sg->dma_address;
 	sglen = sg->length;
-	sgaddr = (unsigned long) (page_address(sg->page) + sg->offset);
+	sgaddr = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
 	while (dlen > 0) {
 		unsigned long paddr;
 
@@ -123,7 +123,7 @@ static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg,
 		sg = sg_next(sg);
 		if (--nents <= 0)
 			break;
-		sgaddr = (unsigned long) (page_address(sg->page) + sg->offset);
+		sgaddr = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
 		sglen = sg->length;
 	}
 	if (dlen < 0) {
@@ -191,7 +191,7 @@ void verify_sglist(struct scatterlist *sglist, int nents, iopte_t *iopte, int np
 			printk("sg(%d): page_addr(%p) off(%x) length(%x) "
 			       "dma_address[%016x] dma_length[%016x]\n",
 			       i,
-			       page_address(sg->page), sg->offset,
+			       page_address(sg_page(sg)), sg->offset,
 			       sg->length,
 			       sg->dma_address, sg->dma_length);
 		}
@@ -207,15 +207,15 @@ unsigned long prepare_sg(struct scatterlist *sg, int nents)
 	unsigned long prev;
 	u32 dent_addr, dent_len;
 
-	prev  = (unsigned long) (page_address(sg->page) + sg->offset);
+	prev  = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
 	prev += (unsigned long) (dent_len = sg->length);
-	dent_addr = (u32) ((unsigned long)(page_address(sg->page) + sg->offset)
+	dent_addr = (u32) ((unsigned long)(page_address(sg_page(sg)) + sg->offset)
 			   & (IO_PAGE_SIZE - 1UL));
 	while (--nents) {
 		unsigned long addr;
 
 		sg = sg_next(sg);
-		addr = (unsigned long) (page_address(sg->page) + sg->offset);
+		addr = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
 		if (! VCONTIG(prev, addr)) {
 			dma_sg->dma_address = dent_addr;
 			dma_sg->dma_length = dent_len;
diff --git a/arch/sparc64/kernel/ldc.c b/arch/sparc64/kernel/ldc.c
index 85a2be0..c8313cb 100644
--- a/arch/sparc64/kernel/ldc.c
+++ b/arch/sparc64/kernel/ldc.c
@@ -2057,7 +2057,7 @@ static void fill_cookies(struct cookie_state *sp, unsigned long pa,
 
 static int sg_count_one(struct scatterlist *sg)
 {
-	unsigned long base = page_to_pfn(sg->page) << PAGE_SHIFT;
+	unsigned long base = page_to_pfn(sg_page(sg)) << PAGE_SHIFT;
 	long len = sg->length;
 
 	if ((sg->offset | len) & (8UL - 1))
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index fe46ace..5324a34 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -366,7 +366,7 @@ static void dma_4v_unmap_single(struct device *dev, dma_addr_t bus_addr,
 }
 
 #define SG_ENT_PHYS_ADDRESS(SG)	\
-	(__pa(page_address((SG)->page)) + (SG)->offset)
+	(__pa(page_address(sg_page(SG))) + (SG)->offset)
 
 static long fill_sg(long entry, struct device *dev,
 		    struct scatterlist *sg,
@@ -478,7 +478,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
 	if (nelems == 1) {
 		sglist->dma_address =
 			dma_4v_map_single(dev,
-					  (page_address(sglist->page) +
+					  (page_address(sg_page(sglist)) +
 					   sglist->offset),
 					  sglist->length, direction);
 		if (unlikely(sglist->dma_address == DMA_ERROR_CODE))
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 25b248a..3a8cd3d 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -1115,7 +1115,7 @@ static void do_ubd_request(struct request_queue *q)
 			}
 			prepare_request(req, io_req,
 					(unsigned long long) req->sector << 9,
-					sg->offset, sg->length, sg->page);
+					sg->offset, sg->length, sg_page(sg));
 
 			last_sectors = sg->length >> 9;
 			n = os_write_file(thread_fd, &io_req,
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 5098f58..c9f0eb0 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -411,8 +411,10 @@ static int calgary_nontranslate_map_sg(struct device* dev,
 	int i;
 
 	for_each_sg(sg, s, nelems, i) {
-		BUG_ON(!s->page);
-		s->dma_address = virt_to_bus(page_address(s->page) +s->offset);
+		struct page *p = sg_page(s);
+
+		BUG_ON(!p);
+		s->dma_address = virt_to_bus(page_address(p) + s->offset);
 		s->dma_length = s->length;
 	}
 	return nelems;
@@ -432,9 +434,11 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
 		return calgary_nontranslate_map_sg(dev, sg, nelems, direction);
 
 	for_each_sg(sg, s, nelems, i) {
-		BUG_ON(!s->page);
+		struct page *p = sg_page(s);
+
+		BUG_ON(!p);
 
-		vaddr = (unsigned long)page_address(s->page) + s->offset;
+		vaddr = (unsigned long)page_address(p) + s->offset;
 		npages = num_dma_pages(vaddr, s->length);
 
 		entry = iommu_range_alloc(tbl, npages);
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index 5cdfab6..daaf636 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -302,7 +302,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
 #endif
 
 	for_each_sg(sg, s, nents, i) {
-		unsigned long addr = page_to_phys(s->page) + s->offset; 
+		unsigned long addr = page_to_phys(sg_page(s)) + s->offset; 
 		if (nonforced_iommu(dev, addr, s->length)) { 
 			addr = dma_map_area(dev, addr, s->length, dir);
 			if (addr == bad_dma_address) { 
@@ -397,7 +397,7 @@ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 	start_sg = sgmap = sg;
 	ps = NULL; /* shut up gcc */
 	for_each_sg(sg, s, nents, i) {
-		dma_addr_t addr = page_to_phys(s->page) + s->offset;
+		dma_addr_t addr = page_to_phys(sg_page(s)) + s->offset;
 		s->dma_address = addr;
 		BUG_ON(s->length == 0); 
 
diff --git a/arch/x86/kernel/pci-nommu_64.c b/arch/x86/kernel/pci-nommu_64.c
index e85d436..d64a4a5 100644
--- a/arch/x86/kernel/pci-nommu_64.c
+++ b/arch/x86/kernel/pci-nommu_64.c
@@ -62,8 +62,8 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
 	int i;
 
 	for_each_sg(sg, s, nents, i) {
-		BUG_ON(!s->page);
-		s->dma_address = virt_to_bus(page_address(s->page) +s->offset);
+		BUG_ON(!sg_page(s));
+		s->dma_address = virt_to_bus(page_address(sg_page(s)) +s->offset);
 		if (!check_addr("map_sg", hwdev, s->dma_address, s->length))
 			return 0;
 		s->dma_length = s->length;
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 3935469..ce9754f 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -1354,8 +1354,9 @@ new_segment:
 			else
 				sg = sg_next(sg);
 
-			memset(sg, 0, sizeof(*sg));
-			sg->page = bvec->bv_page;
+			sg_dma_len(sg) = 0;
+			sg_dma_address(sg) = 0;
+			sg_set_page(sg, bvec->bv_page);
 			sg->length = nbytes;
 			sg->offset = bvec->bv_offset;
 			nsegs++;
diff --git a/crypto/digest.c b/crypto/digest.c
index e56de67..8871dec 100644
--- a/crypto/digest.c
+++ b/crypto/digest.c
@@ -41,7 +41,7 @@ static int update2(struct hash_desc *desc,
 		return 0;
 
 	for (;;) {
-		struct page *pg = sg->page;
+		struct page *pg = sg_page(sg);
 		unsigned int offset = sg->offset;
 		unsigned int l = sg->length;
 
diff --git a/crypto/hmac.c b/crypto/hmac.c
index 8802fb6..e4eb6ac 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -159,7 +159,8 @@ static int hmac_digest(struct hash_desc *pdesc, struct scatterlist *sg,
 	desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP;
 
 	sg_set_buf(sg1, ipad, bs);
-	sg1[1].page = (void *)sg;
+
+	sg_set_page(&sg[1], (void *) sg);
 	sg1[1].length = 0;
 	sg_set_buf(sg2, opad, bs + ds);
 
diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c
index d6852c3..b9bbda0 100644
--- a/crypto/scatterwalk.c
+++ b/crypto/scatterwalk.c
@@ -54,7 +54,7 @@ static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
 	if (out) {
 		struct page *page;
 
-		page = walk->sg->page + ((walk->offset - 1) >> PAGE_SHIFT);
+		page = sg_page(walk->sg) + ((walk->offset - 1) >> PAGE_SHIFT);
 		flush_dcache_page(page);
 	}
 
diff --git a/crypto/scatterwalk.h b/crypto/scatterwalk.h
index 9c73e37..87ed681 100644
--- a/crypto/scatterwalk.h
+++ b/crypto/scatterwalk.h
@@ -22,13 +22,13 @@
 
 static inline struct scatterlist *scatterwalk_sg_next(struct scatterlist *sg)
 {
-	return (++sg)->length ? sg : (void *)sg->page;
+	return (++sg)->length ? sg : (void *) sg_page(sg);
 }
 
 static inline unsigned long scatterwalk_samebuf(struct scatter_walk *walk_in,
 						struct scatter_walk *walk_out)
 {
-	return !(((walk_in->sg->page - walk_out->sg->page) << PAGE_SHIFT) +
+	return !(((sg_page(walk_in->sg) - sg_page(walk_out->sg)) << PAGE_SHIFT) +
 		 (int)(walk_in->offset - walk_out->offset));
 }
 
@@ -60,7 +60,7 @@ static inline unsigned int scatterwalk_aligned(struct scatter_walk *walk,
 
 static inline struct page *scatterwalk_page(struct scatter_walk *walk)
 {
-	return walk->sg->page + (walk->offset >> PAGE_SHIFT);
+	return sg_page(walk->sg) + (walk->offset >> PAGE_SHIFT);
 }
 
 static inline void scatterwalk_unmap(void *vaddr, int out)
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 18d489c..d741c63 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -317,7 +317,7 @@ static void test_cipher(char *algo, int enc,
 				goto out;
 			}
 
-			q = kmap(sg[0].page) + sg[0].offset;
+			q = kmap(sg_page(&sg[0])) + sg[0].offset;
 			hexdump(q, cipher_tv[i].rlen);
 
 			printk("%s\n",
@@ -390,7 +390,7 @@ static void test_cipher(char *algo, int enc,
 			temp = 0;
 			for (k = 0; k < cipher_tv[i].np; k++) {
 				printk("page %u\n", k);
-				q = kmap(sg[k].page) + sg[k].offset;
+				q = kmap(sg_page(&sg[k])) + sg[k].offset;
 				hexdump(q, cipher_tv[i].tap[k]);
 				printk("%s\n",
 					memcmp(q, cipher_tv[i].result + temp,
diff --git a/crypto/xcbc.c b/crypto/xcbc.c
index 9f502b8..ac68f3b 100644
--- a/crypto/xcbc.c
+++ b/crypto/xcbc.c
@@ -120,7 +120,7 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc,
 
 	do {
 
-		struct page *pg = sg[i].page;
+		struct page *pg = sg_page(&sg[i]);
 		unsigned int offset = sg[i].offset;
 		unsigned int slen = sg[i].length;
 
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index bbaa545..b1fa70a 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4296,7 +4296,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
 		sg_last(sg, qc->orig_n_elem)->length += qc->pad_len;
 		if (pad_buf) {
 			struct scatterlist *psg = &qc->pad_sgent;
-			void *addr = kmap_atomic(psg->page, KM_IRQ0);
+			void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
 			memcpy(addr + psg->offset, pad_buf, qc->pad_len);
 			kunmap_atomic(addr, KM_IRQ0);
 		}
@@ -4686,11 +4686,11 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
 		 * data in this function or read data in ata_sg_clean.
 		 */
 		offset = lsg->offset + lsg->length - qc->pad_len;
-		psg->page = nth_page(lsg->page, offset >> PAGE_SHIFT);
+		sg_set_page(psg, nth_page(sg_page(lsg), offset >> PAGE_SHIFT));
 		psg->offset = offset_in_page(offset);
 
 		if (qc->tf.flags & ATA_TFLAG_WRITE) {
-			void *addr = kmap_atomic(psg->page, KM_IRQ0);
+			void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
 			memcpy(pad_buf, addr + psg->offset, qc->pad_len);
 			kunmap_atomic(addr, KM_IRQ0);
 		}
@@ -4836,7 +4836,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
 	if (qc->curbytes == qc->nbytes - qc->sect_size)
 		ap->hsm_task_state = HSM_ST_LAST;
 
-	page = qc->cursg->page;
+	page = sg_page(qc->cursg);
 	offset = qc->cursg->offset + qc->cursg_ofs;
 
 	/* get the current page and offset */
@@ -4988,7 +4988,7 @@ next_sg:
 
 	sg = qc->cursg;
 
-	page = sg->page;
+	page = sg_page(sg);
 	offset = sg->offset + qc->cursg_ofs;
 
 	/* get the current page and offset */
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 9fbb39c..5b758b9 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1544,7 +1544,7 @@ static unsigned int ata_scsi_rbuf_get(struct scsi_cmnd *cmd, u8 **buf_out)
 	struct scatterlist *sg = scsi_sglist(cmd);
 
 	if (sg) {
-		buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+		buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 		buflen = sg->length;
 	} else {
 		buf = NULL;
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 7c2cfde..5a6fe17 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -2610,7 +2610,7 @@ static void do_cciss_request(struct request_queue *q)
 	       (int)creq->nr_sectors);
 #endif				/* CCISS_DEBUG */
 
-	memset(tmp_sg, 0, sizeof(tmp_sg));
+	sg_init_table(tmp_sg, MAXSGENTRIES);
 	seg = blk_rq_map_sg(q, creq, tmp_sg);
 
 	/* get the DMA records for the setup */
@@ -2621,7 +2621,7 @@ static void do_cciss_request(struct request_queue *q)
 
 	for (i = 0; i < seg; i++) {
 		c->SG[i].Len = tmp_sg[i].length;
-		temp64.val = (__u64) pci_map_page(h->pdev, tmp_sg[i].page,
+		temp64.val = (__u64) pci_map_page(h->pdev, sg_page(&tmp_sg[i]),
 						  tmp_sg[i].offset,
 						  tmp_sg[i].length, dir);
 		c->SG[i].Addr.lower = temp64.val32.lower;
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index 568603d..efab27f 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -918,6 +918,7 @@ queue_next:
 DBGPX(
 	printk("sector=%d, nr_sectors=%d\n", creq->sector, creq->nr_sectors);
 );
+	sg_init_table(tmp_sg, SG_MAX);
 	seg = blk_rq_map_sg(q, creq, tmp_sg);
 
 	/* Now do all the DMA Mappings */
@@ -929,7 +930,7 @@ DBGPX(
 	{
 		c->req.sg[i].size = tmp_sg[i].length;
 		c->req.sg[i].addr = (__u32) pci_map_page(h->pci_dev,
-						 tmp_sg[i].page,
+						 sg_page(&tmp_sg[i]),
 						 tmp_sg[i].offset,
 						 tmp_sg[i].length, dir);
 	}
diff --git a/drivers/block/cryptoloop.c b/drivers/block/cryptoloop.c
index 4053503..1b58b01 100644
--- a/drivers/block/cryptoloop.c
+++ b/drivers/block/cryptoloop.c
@@ -26,6 +26,7 @@
 #include <linux/crypto.h>
 #include <linux/blkdev.h>
 #include <linux/loop.h>
+#include <linux/scatterlist.h>
 #include <asm/semaphore.h>
 #include <asm/uaccess.h>
 
@@ -119,14 +120,17 @@ cryptoloop_transfer(struct loop_device *lo, int cmd,
 		.tfm = tfm,
 		.flags = CRYPTO_TFM_REQ_MAY_SLEEP,
 	};
-	struct scatterlist sg_out = { NULL, };
-	struct scatterlist sg_in = { NULL, };
+	struct scatterlist sg_out;
+	struct scatterlist sg_in;
 
 	encdec_cbc_t encdecfunc;
 	struct page *in_page, *out_page;
 	unsigned in_offs, out_offs;
 	int err;
 
+	sg_init_table(&sg_out, 1);
+	sg_init_table(&sg_in, 1);
+
 	if (cmd == READ) {
 		in_page = raw_page;
 		in_offs = raw_off;
@@ -146,11 +150,11 @@ cryptoloop_transfer(struct loop_device *lo, int cmd,
 		u32 iv[4] = { 0, };
 		iv[0] = cpu_to_le32(IV & 0xffffffff);
 
-		sg_in.page = in_page;
+		sg_set_page(&sg_in, in_page);
 		sg_in.offset = in_offs;
 		sg_in.length = sz;
 
-		sg_out.page = out_page;
+		sg_set_page(&sg_out, out_page);
 		sg_out.offset = out_offs;
 		sg_out.length = sz;
 
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index c57dd2b..d6f7b43 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -25,6 +25,7 @@
 #include <linux/usb_usual.h>
 #include <linux/blkdev.h>
 #include <linux/timer.h>
+#include <linux/scatterlist.h>
 #include <scsi/scsi.h>
 
 #define DRV_NAME "ub"
@@ -656,6 +657,7 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq)
 	if ((cmd = ub_get_cmd(lun)) == NULL)
 		return -1;
 	memset(cmd, 0, sizeof(struct ub_scsi_cmd));
+	sg_init_table(cmd->sgv, UB_MAX_REQ_SG);
 
 	blkdev_dequeue_request(rq);
 
@@ -1310,7 +1312,7 @@ static void ub_data_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 		pipe = sc->send_bulk_pipe;
 	sc->last_pipe = pipe;
 	usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe,
-	    page_address(sg->page) + sg->offset, sg->length,
+	    page_address(sg_page(sg)) + sg->offset, sg->length,
 	    ub_urb_complete, sc);
 	sc->work_urb.actual_length = 0;
 	sc->work_urb.error_count = 0;
@@ -1427,7 +1429,7 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 	scmd->state = UB_CMDST_INIT;
 	scmd->nsg = 1;
 	sg = &scmd->sgv[0];
-	sg->page = virt_to_page(sc->top_sense);
+	sg_set_page(sg, virt_to_page(sc->top_sense));
 	sg->offset = (unsigned long)sc->top_sense & (PAGE_SIZE-1);
 	sg->length = UB_SENSE_SIZE;
 	scmd->len = UB_SENSE_SIZE;
@@ -1863,7 +1865,7 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
 	cmd->state = UB_CMDST_INIT;
 	cmd->nsg = 1;
 	sg = &cmd->sgv[0];
-	sg->page = virt_to_page(p);
+	sg_set_page(sg, virt_to_page(p));
 	sg->offset = (unsigned long)p & (PAGE_SIZE-1);
 	sg->length = 8;
 	cmd->len = 8;
diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c
index 06c75f1..3979bf4 100644
--- a/drivers/ide/cris/ide-cris.c
+++ b/drivers/ide/cris/ide-cris.c
@@ -934,11 +934,11 @@ static int cris_ide_build_dmatable (ide_drive_t *drive)
 		 * than two possibly non-adjacent physical 4kB pages.
 		 */
 		/* group sequential buffers into one large buffer */
-		addr = page_to_phys(sg->page) + sg->offset;
+		addr = page_to_phys(sg_page(sg)) + sg->offset;
 		size = sg_dma_len(sg);
 		while (--i) {
 			sg = sg_next(sg);
-			if ((addr + size) != page_to_phys(sg->page) + sg->offset)
+			if ((addr + size) != page_to_phys(sg_page(sg)) + sg->offset)
 				break;
 			size += sg_dma_len(sg);
 		}
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 3c945d6..7c640cd 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -1337,12 +1337,14 @@ static int hwif_init(ide_hwif_t *hwif)
 	if (!hwif->sg_max_nents)
 		hwif->sg_max_nents = PRD_ENTRIES;
 
-	hwif->sg_table = kzalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
+	hwif->sg_table = kmalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
 				 GFP_KERNEL);
 	if (!hwif->sg_table) {
 		printk(KERN_ERR "%s: unable to allocate SG table.\n", hwif->name);
 		goto out;
 	}
+
+	sg_init_table(hwif->sg_table, hwif->sg_max_nents);
 	
 	if (init_irq(hwif) == 0)
 		goto done;
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 2a3c8d4..086157f 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -278,7 +278,7 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
 		hwif->cursg = sg;
 	}
 
-	page = cursg->page;
+	page = sg_page(cursg);
 	offset = cursg->offset + hwif->cursg_ofs * SECTOR_SIZE;
 
 	/* get the current page and offset */
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
index 47c035a..1b22ab7 100644
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -276,7 +276,7 @@ static int auide_build_dmatable(ide_drive_t *drive)
 
 			if (iswrite) {
 				if(!put_source_flags(ahwif->tx_chan, 
-						     (void*)(page_address(sg->page) 
+						     (void*)(page_address(sg_page(sg)) 
 							     + sg->offset), 
 						     tc, flags)) { 
 					printk(KERN_ERR "%s failed %d\n", 
@@ -285,7 +285,7 @@ static int auide_build_dmatable(ide_drive_t *drive)
 			} else 
 			{
 				if(!put_dest_flags(ahwif->rx_chan, 
-						   (void*)(page_address(sg->page) 
+						   (void*)(page_address(sg_page(sg)) 
 							   + sg->offset), 
 						   tc, flags)) { 
 					printk(KERN_ERR "%s failed %d\n", 
diff --git a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c
index 45d6055..25e113b 100644
--- a/drivers/ieee1394/dma.c
+++ b/drivers/ieee1394/dma.c
@@ -111,7 +111,7 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes,
 		unsigned long va =
 		    (unsigned long)dma->kvirt + (i << PAGE_SHIFT);
 
-		dma->sglist[i].page = vmalloc_to_page((void *)va);
+		sg_set_page(&dma->sglist[i], vmalloc_to_page((void *)va));
 		dma->sglist[i].length = PAGE_SIZE;
 	}
 
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 1b353b9..d5dfe11 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -1466,7 +1466,7 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb,
 		cmd->dma_size = sgpnt[0].length;
 		cmd->dma_type = CMD_DMA_PAGE;
 		cmd->cmd_dma = dma_map_page(hi->host->device.parent,
-					    sgpnt[0].page, sgpnt[0].offset,
+					    sg_page(&sgpnt[0]), sgpnt[0].offset,
 					    cmd->dma_size, cmd->dma_dir);
 
 		orb->data_descriptor_lo = cmd->cmd_dma;
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index 2f54e29..14159ff 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -55,9 +55,11 @@ static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int d
 		ib_dma_unmap_sg(dev, chunk->page_list,
 				chunk->nents, DMA_BIDIRECTIONAL);
 		for (i = 0; i < chunk->nents; ++i) {
+			struct page *page = sg_page(&chunk->page_list[i]);
+
 			if (umem->writable && dirty)
-				set_page_dirty_lock(chunk->page_list[i].page);
-			put_page(chunk->page_list[i].page);
+				set_page_dirty_lock(page);
+			put_page(page);
 		}
 
 		kfree(chunk);
@@ -164,11 +166,12 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
 			}
 
 			chunk->nents = min_t(int, ret, IB_UMEM_MAX_PAGE_CHUNK);
+			sg_init_table(chunk->page_list, chunk->nents);
 			for (i = 0; i < chunk->nents; ++i) {
 				if (vma_list &&
 				    !is_vm_hugetlb_page(vma_list[i + off]))
 					umem->hugetlb = 0;
-				chunk->page_list[i].page   = page_list[i + off];
+				sg_set_page(&chunk->page_list[i], page_list[i + off]);
 				chunk->page_list[i].offset = 0;
 				chunk->page_list[i].length = PAGE_SIZE;
 			}
@@ -179,7 +182,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
 						    DMA_BIDIRECTIONAL);
 			if (chunk->nmap <= 0) {
 				for (i = 0; i < chunk->nents; ++i)
-					put_page(chunk->page_list[i].page);
+					put_page(sg_page(&chunk->page_list[i]));
 				kfree(chunk);
 
 				ret = -ENOMEM;
diff --git a/drivers/infiniband/hw/ipath/ipath_dma.c b/drivers/infiniband/hw/ipath/ipath_dma.c
index 22709a4..e90a0ea 100644
--- a/drivers/infiniband/hw/ipath/ipath_dma.c
+++ b/drivers/infiniband/hw/ipath/ipath_dma.c
@@ -108,7 +108,7 @@ static int ipath_map_sg(struct ib_device *dev, struct scatterlist *sgl,
 	BUG_ON(!valid_dma_direction(direction));
 
 	for_each_sg(sgl, sg, nents, i) {
-		addr = (u64) page_address(sg->page);
+		addr = (u64) page_address(sg_page(sg));
 		/* TODO: handle highmem pages */
 		if (!addr) {
 			ret = 0;
@@ -127,7 +127,7 @@ static void ipath_unmap_sg(struct ib_device *dev,
 
 static u64 ipath_sg_dma_address(struct ib_device *dev, struct scatterlist *sg)
 {
-	u64 addr = (u64) page_address(sg->page);
+	u64 addr = (u64) page_address(sg_page(sg));
 
 	if (addr)
 		addr += sg->offset;
diff --git a/drivers/infiniband/hw/ipath/ipath_mr.c b/drivers/infiniband/hw/ipath/ipath_mr.c
index e442470..db4ba92 100644
--- a/drivers/infiniband/hw/ipath/ipath_mr.c
+++ b/drivers/infiniband/hw/ipath/ipath_mr.c
@@ -225,7 +225,7 @@ struct ib_mr *ipath_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
 		for (i = 0; i < chunk->nents; i++) {
 			void *vaddr;
 
-			vaddr = page_address(chunk->page_list[i].page);
+			vaddr = page_address(sg_page(&chunk->page_list[i]));
 			if (!vaddr) {
 				ret = ERR_PTR(-EINVAL);
 				goto bail;
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
index e61f3e6..007b381 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -71,7 +71,7 @@ static void mthca_free_icm_pages(struct mthca_dev *dev, struct mthca_icm_chunk *
 			     PCI_DMA_BIDIRECTIONAL);
 
 	for (i = 0; i < chunk->npages; ++i)
-		__free_pages(chunk->mem[i].page,
+		__free_pages(sg_page(&chunk->mem[i]),
 			     get_order(chunk->mem[i].length));
 }
 
@@ -81,7 +81,7 @@ static void mthca_free_icm_coherent(struct mthca_dev *dev, struct mthca_icm_chun
 
 	for (i = 0; i < chunk->npages; ++i) {
 		dma_free_coherent(&dev->pdev->dev, chunk->mem[i].length,
-				  lowmem_page_address(chunk->mem[i].page),
+				  lowmem_page_address(sg_page(&chunk->mem[i])),
 				  sg_dma_address(&chunk->mem[i]));
 	}
 }
@@ -107,10 +107,13 @@ void mthca_free_icm(struct mthca_dev *dev, struct mthca_icm *icm, int coherent)
 
 static int mthca_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_mask)
 {
-	mem->page = alloc_pages(gfp_mask, order);
-	if (!mem->page)
+	struct page *page;
+
+	page = alloc_pages(gfp_mask, order);
+	if (!page)
 		return -ENOMEM;
 
+	sg_set_page(mem, page);
 	mem->length = PAGE_SIZE << order;
 	mem->offset = 0;
 	return 0;
@@ -157,6 +160,7 @@ struct mthca_icm *mthca_alloc_icm(struct mthca_dev *dev, int npages,
 			if (!chunk)
 				goto fail;
 
+			sg_init_table(chunk->mem, MTHCA_ICM_CHUNK_LEN);
 			chunk->npages = 0;
 			chunk->nsg    = 0;
 			list_add_tail(&chunk->list, &icm->chunk_list);
@@ -304,7 +308,7 @@ void *mthca_table_find(struct mthca_icm_table *table, int obj, dma_addr_t *dma_h
 			 * so if we found the page, dma_handle has already
 			 * been assigned to. */
 			if (chunk->mem[i].length > offset) {
-				page = chunk->mem[i].page;
+				page = sg_page(&chunk->mem[i]);
 				goto out;
 			}
 			offset -= chunk->mem[i].length;
@@ -445,6 +449,7 @@ static u64 mthca_uarc_virt(struct mthca_dev *dev, struct mthca_uar *uar, int pag
 int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
 		      struct mthca_user_db_table *db_tab, int index, u64 uaddr)
 {
+	struct page *pages[1];
 	int ret = 0;
 	u8 status;
 	int i;
@@ -472,16 +477,17 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
 	}
 
 	ret = get_user_pages(current, current->mm, uaddr & PAGE_MASK, 1, 1, 0,
-			     &db_tab->page[i].mem.page, NULL);
+			     pages, NULL);
 	if (ret < 0)
 		goto out;
 
+	sg_set_page(&db_tab->page[i].mem, pages[0]);
 	db_tab->page[i].mem.length = MTHCA_ICM_PAGE_SIZE;
 	db_tab->page[i].mem.offset = uaddr & ~PAGE_MASK;
 
 	ret = pci_map_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
 	if (ret < 0) {
-		put_page(db_tab->page[i].mem.page);
+		put_page(pages[0]);
 		goto out;
 	}
 
@@ -491,7 +497,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
 		ret = -EINVAL;
 	if (ret) {
 		pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
-		put_page(db_tab->page[i].mem.page);
+		put_page(sg_page(&db_tab->page[i].mem));
 		goto out;
 	}
 
@@ -557,7 +563,7 @@ void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar,
 		if (db_tab->page[i].uvirt) {
 			mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, uar, i), 1, &status);
 			pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
-			put_page(db_tab->page[i].mem.page);
+			put_page(sg_page(&db_tab->page[i].mem));
 		}
 	}
 
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
index f3529b6..813b96b 100644
--- a/drivers/infiniband/ulp/iser/iser_memory.c
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -131,7 +131,7 @@ static int iser_start_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
 
 		p = mem;
 		for_each_sg(sgl, sg, data->size, i) {
-			from = kmap_atomic(sg->page, KM_USER0);
+			from = kmap_atomic(sg_page(sg), KM_USER0);
 			memcpy(p,
 			       from + sg->offset,
 			       sg->length);
@@ -191,7 +191,7 @@ void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
 
 		p = mem;
 		for_each_sg(sgl, sg, sg_size, i) {
-			to = kmap_atomic(sg->page, KM_SOFTIRQ0);
+			to = kmap_atomic(sg_page(sg), KM_SOFTIRQ0);
 			memcpy(to + sg->offset,
 			       p,
 			       sg->length);
@@ -300,7 +300,7 @@ static unsigned int iser_data_buf_aligned_len(struct iser_data_buf *data,
 	for_each_sg(sgl, sg, data->dma_nents, i) {
 		/* iser_dbg("Checking sg iobuf [%d]: phys=0x%08lX "
 		   "offset: %ld sz: %ld\n", i,
-		   (unsigned long)page_to_phys(sg->page),
+		   (unsigned long)page_to_phys(sg_page(sg)),
 		   (unsigned long)sg->offset,
 		   (unsigned long)sg->length); */
 		end_addr = ib_sg_dma_address(ibdev, sg) +
@@ -336,7 +336,7 @@ static void iser_data_buf_dump(struct iser_data_buf *data,
 		iser_err("sg[%d] dma_addr:0x%lX page:0x%p "
 			 "off:0x%x sz:0x%x dma_len:0x%x\n",
 			 i, (unsigned long)ib_sg_dma_address(ibdev, sg),
-			 sg->page, sg->offset,
+			 sg_page(sg), sg->offset,
 			 sg->length, ib_sg_dma_len(ibdev, sg));
 }
 
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 64fee90..cde915f 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -346,16 +346,17 @@ static int crypt_convert(struct crypt_config *cc,
 	      ctx->idx_out < ctx->bio_out->bi_vcnt) {
 		struct bio_vec *bv_in = bio_iovec_idx(ctx->bio_in, ctx->idx_in);
 		struct bio_vec *bv_out = bio_iovec_idx(ctx->bio_out, ctx->idx_out);
-		struct scatterlist sg_in = {
-			.page = bv_in->bv_page,
-			.offset = bv_in->bv_offset + ctx->offset_in,
-			.length = 1 << SECTOR_SHIFT
-		};
-		struct scatterlist sg_out = {
-			.page = bv_out->bv_page,
-			.offset = bv_out->bv_offset + ctx->offset_out,
-			.length = 1 << SECTOR_SHIFT
-		};
+		struct scatterlist sg_in, sg_out;
+
+		sg_init_table(&sg_in, 1);
+		sg_set_page(&sg_in, bv_in->bv_page);
+		sg_in.offset = bv_in->bv_offset + ctx->offset_in;
+		sg_in.length = 1 << SECTOR_SHIFT;
+		
+		sg_init_table(&sg_out, 1);
+		sg_set_page(&sg_out, bv_out->bv_page);
+		sg_out.offset = bv_out->bv_offset + ctx->offset_out;
+		sg_out.length = 1 << SECTOR_SHIFT;
 
 		ctx->offset_in += sg_in.length;
 		if (ctx->offset_in >= bv_in->bv_len) {
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c
index 365a221..2b1f8b4 100644
--- a/drivers/media/common/saa7146_core.c
+++ b/drivers/media/common/saa7146_core.c
@@ -112,12 +112,13 @@ static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages)
 	sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL);
 	if (NULL == sglist)
 		return NULL;
+	sg_init_table(sglist, nr_pages);
 	for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
 		pg = vmalloc_to_page(virt);
 		if (NULL == pg)
 			goto err;
 		BUG_ON(PageHighMem(pg));
-		sglist[i].page   = pg;
+		sg_set_page(&sglist[i], pg);
 		sglist[i].length = PAGE_SIZE;
 	}
 	return sglist;
diff --git a/drivers/media/video/ivtv/ivtv-udma.c b/drivers/media/video/ivtv/ivtv-udma.c
index c4626d1..912b424 100644
--- a/drivers/media/video/ivtv/ivtv-udma.c
+++ b/drivers/media/video/ivtv/ivtv-udma.c
@@ -63,10 +63,10 @@ int ivtv_udma_fill_sg_list (struct ivtv_user_dma *dma, struct ivtv_dma_page_info
 			memcpy(page_address(dma->bouncemap[map_offset]) + offset, src, len);
 			kunmap_atomic(src, KM_BOUNCE_READ);
 			local_irq_restore(flags);
-			dma->SGlist[map_offset].page = dma->bouncemap[map_offset];
+			sg_set_page(&dma->SGlist[map_offset], dma->bouncemap[map_offset]);
 		}
 		else {
-			dma->SGlist[map_offset].page = dma->map[map_offset];
+			sg_set_page(&dma->SGlist[map_offset], dma->map[map_offset]);
 		}
 		offset = 0;
 		map_offset++;
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
index 3eb6123..0a18286 100644
--- a/drivers/media/video/videobuf-dma-sg.c
+++ b/drivers/media/video/videobuf-dma-sg.c
@@ -60,12 +60,13 @@ videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages)
 	sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL);
 	if (NULL == sglist)
 		return NULL;
+	sg_init_table(sglist, nr_pages);
 	for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
 		pg = vmalloc_to_page(virt);
 		if (NULL == pg)
 			goto err;
 		BUG_ON(PageHighMem(pg));
-		sglist[i].page   = pg;
+		sg_set_page(&sglist[i], pg);
 		sglist[i].length = PAGE_SIZE;
 	}
 	return sglist;
@@ -86,13 +87,14 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
 	sglist = kcalloc(nr_pages, sizeof(*sglist), GFP_KERNEL);
 	if (NULL == sglist)
 		return NULL;
+	sg_init_table(sglist, nr_pages);
 
 	if (NULL == pages[0])
 		goto nopage;
 	if (PageHighMem(pages[0]))
 		/* DMA to highmem pages might not work */
 		goto highmem;
-	sglist[0].page   = pages[0];
+	sg_set_page(&sglist[0], pages[0]);
 	sglist[0].offset = offset;
 	sglist[0].length = PAGE_SIZE - offset;
 	for (i = 1; i < nr_pages; i++) {
@@ -100,7 +102,7 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
 			goto nopage;
 		if (PageHighMem(pages[i]))
 			goto highmem;
-		sglist[i].page   = pages[i];
+		sg_set_page(&sglist[i], pages[i]);
 		sglist[i].length = PAGE_SIZE;
 	}
 	return sglist;
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index a5d0354..68c1fe9 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -13,6 +13,7 @@
 #include <linux/blkdev.h>
 #include <linux/freezer.h>
 #include <linux/kthread.h>
+#include <linux/scatterlist.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
@@ -153,19 +154,21 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
 			blk_queue_max_hw_segments(mq->queue, bouncesz / 512);
 			blk_queue_max_segment_size(mq->queue, bouncesz);
 
-			mq->sg = kzalloc(sizeof(struct scatterlist),
+			mq->sg = kmalloc(sizeof(struct scatterlist),
 				GFP_KERNEL);
 			if (!mq->sg) {
 				ret = -ENOMEM;
 				goto cleanup_queue;
 			}
+			sg_init_table(mq->sg, 1);
 
-			mq->bounce_sg = kzalloc(sizeof(struct scatterlist) *
+			mq->bounce_sg = kmalloc(sizeof(struct scatterlist) *
 				bouncesz / 512, GFP_KERNEL);
 			if (!mq->bounce_sg) {
 				ret = -ENOMEM;
 				goto cleanup_queue;
 			}
+			sg_init_table(mq->bounce_sg, bouncesz / 512);
 		}
 	}
 #endif
@@ -302,12 +305,12 @@ static void copy_sg(struct scatterlist *dst, unsigned int dst_len,
 		BUG_ON(dst_len == 0);
 
 		if (dst_size == 0) {
-			dst_buf = page_address(dst->page) + dst->offset;
+			dst_buf = page_address(sg_page(dst)) + dst->offset;
 			dst_size = dst->length;
 		}
 
 		if (src_size == 0) {
-			src_buf = page_address(src->page) + src->offset;
+			src_buf = page_address(sg_page(src)) + src->offset;
 			src_size = src->length;
 		}
 
@@ -353,9 +356,7 @@ unsigned int mmc_queue_map_sg(struct mmc_queue *mq)
 		return 1;
 	}
 
-	mq->sg[0].page = virt_to_page(mq->bounce_buf);
-	mq->sg[0].offset = offset_in_page(mq->bounce_buf);
-	mq->sg[0].length = 0;
+	sg_init_one(mq->sg, mq->bounce_buf, 0);
 
 	while (sg_len) {
 		mq->sg[0].length += mq->bounce_sg[sg_len - 1].length;
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index 7a452c2..b1edcef 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -149,7 +149,7 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data
 
 		sg = &data->sg[i];
 
-		sgbuffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
+		sgbuffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
 		amount = min(size, sg->length);
 		size -= amount;
 
@@ -226,7 +226,7 @@ static void at91_mci_pre_dma_read(struct at91mci_host *host)
 		sg = &data->sg[host->transfer_index++];
 		pr_debug("sg = %p\n", sg);
 
-		sg->dma_address = dma_map_page(NULL, sg->page, sg->offset, sg->length, DMA_FROM_DEVICE);
+		sg->dma_address = dma_map_page(NULL, sg_page(sg), sg->offset, sg->length, DMA_FROM_DEVICE);
 
 		pr_debug("dma address = %08X, length = %d\n", sg->dma_address, sg->length);
 
@@ -283,7 +283,7 @@ static void at91_mci_post_dma_read(struct at91mci_host *host)
 			int index;
 
 			/* Swap the contents of the buffer */
-			buffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
+			buffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
 			pr_debug("buffer = %p, length = %d\n", buffer, sg->length);
 
 			for (index = 0; index < (sg->length / 4); index++)
@@ -292,7 +292,7 @@ static void at91_mci_post_dma_read(struct at91mci_host *host)
 			kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
 		}
 
-		flush_dcache_page(sg->page);
+		flush_dcache_page(sg_page(sg));
 	}
 
 	/* Is there another transfer to trigger? */
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c
index 92c4d0d..0632f4d 100644
--- a/drivers/mmc/host/au1xmmc.c
+++ b/drivers/mmc/host/au1xmmc.c
@@ -340,7 +340,7 @@ static void au1xmmc_send_pio(struct au1xmmc_host *host)
 
 	/* This is the pointer to the data buffer */
 	sg = &data->sg[host->pio.index];
-	sg_ptr = page_address(sg->page) + sg->offset + host->pio.offset;
+	sg_ptr = page_address(sg_page(sg)) + sg->offset + host->pio.offset;
 
 	/* This is the space left inside the buffer */
 	sg_len = data->sg[host->pio.index].length - host->pio.offset;
@@ -400,7 +400,7 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host)
 
 	if (host->pio.index < host->dma.len) {
 		sg = &data->sg[host->pio.index];
-		sg_ptr = page_address(sg->page) + sg->offset + host->pio.offset;
+		sg_ptr = page_address(sg_page(sg)) + sg->offset + host->pio.offset;
 
 		/* This is the space left inside the buffer */
 		sg_len = sg_dma_len(&data->sg[host->pio.index]) - host->pio.offset;
@@ -613,13 +613,13 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data)
 
     			if (host->flags & HOST_F_XMIT){
       				ret = au1xxx_dbdma_put_source_flags(channel,
-					(void *) (page_address(sg->page) +
+					(void *) (page_address(sg_page(sg)) +
 						  sg->offset),
 					len, flags);
 			}
     			else {
       				ret = au1xxx_dbdma_put_dest_flags(channel,
-					(void *) (page_address(sg->page) +
+					(void *) (page_address(sg_page(sg)) +
 						  sg->offset),
 					len, flags);
 			}
diff --git a/drivers/mmc/host/imxmmc.c b/drivers/mmc/host/imxmmc.c
index 6ebc41e..581bb8f 100644
--- a/drivers/mmc/host/imxmmc.c
+++ b/drivers/mmc/host/imxmmc.c
@@ -262,7 +262,7 @@ static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data)
 		}
 
 		/* Convert back to virtual address */
-		host->data_ptr = (u16*)(page_address(data->sg->page) + data->sg->offset);
+		host->data_ptr = (u16*)(page_address(sg_page(data->sg)) + data->sg->offset);
 		host->data_cnt = 0;
 
 		clear_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events);
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 7ae18ea..12c2d80 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -813,7 +813,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
 					&& dir == DMA_FROM_DEVICE)
 				dir = DMA_BIDIRECTIONAL;
 
-			dma_addr = dma_map_page(dma_dev, sg->page, 0,
+			dma_addr = dma_map_page(dma_dev, sg_page(sg), 0,
 						PAGE_SIZE, dir);
 			if (direction == DMA_TO_DEVICE)
 				t->tx_dma = dma_addr + sg->offset;
@@ -822,7 +822,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
 		}
 
 		/* allow pio too; we don't allow highmem */
-		kmap_addr = kmap(sg->page);
+		kmap_addr = kmap(sg_page(sg));
 		if (direction == DMA_TO_DEVICE)
 			t->tx_buf = kmap_addr + sg->offset;
 		else
@@ -855,8 +855,8 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
 
 		/* discard mappings */
 		if (direction == DMA_FROM_DEVICE)
-			flush_kernel_dcache_page(sg->page);
-		kunmap(sg->page);
+			flush_kernel_dcache_page(sg_page(sg));
+		kunmap(sg_page(sg));
 		if (dma_dev)
 			dma_unmap_page(dma_dev, dma_addr, PAGE_SIZE, dir);
 
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 60a67df..649f647 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -24,10 +24,10 @@
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
 #include <linux/clk.h>
+#include <linux/scatterlist.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/scatterlist.h>
 #include <asm/mach-types.h>
 
 #include <asm/arch/board.h>
@@ -383,7 +383,7 @@ mmc_omap_sg_to_buf(struct mmc_omap_host *host)
 
 	sg = host->data->sg + host->sg_idx;
 	host->buffer_bytes_left = sg->length;
-	host->buffer = page_address(sg->page) + sg->offset;
+	host->buffer = page_address(sg_page(sg)) + sg->offset;
 	if (host->buffer_bytes_left > host->total_bytes_left)
 		host->buffer_bytes_left = host->total_bytes_left;
 }
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index b397121..b6500e9 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -231,7 +231,7 @@ static void sdhci_deactivate_led(struct sdhci_host *host)
 
 static inline char* sdhci_sg_to_buffer(struct sdhci_host* host)
 {
-	return page_address(host->cur_sg->page) + host->cur_sg->offset;
+	return page_address(sg_page(host->cur_sg)) + host->cur_sg->offset;
 }
 
 static inline int sdhci_next_sg(struct sdhci_host* host)
diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c
index 9b90479..c11a3d2 100644
--- a/drivers/mmc/host/tifm_sd.c
+++ b/drivers/mmc/host/tifm_sd.c
@@ -192,7 +192,7 @@ static void tifm_sd_transfer_data(struct tifm_sd *host)
 		}
 		off = sg[host->sg_pos].offset + host->block_pos;
 
-		pg = nth_page(sg[host->sg_pos].page, off >> PAGE_SHIFT);
+		pg = nth_page(sg_page(&sg[host->sg_pos]), off >> PAGE_SHIFT);
 		p_off = offset_in_page(off);
 		p_cnt = PAGE_SIZE - p_off;
 		p_cnt = min(p_cnt, cnt);
@@ -241,18 +241,18 @@ static void tifm_sd_bounce_block(struct tifm_sd *host, struct mmc_data *r_data)
 		}
 		off = sg[host->sg_pos].offset + host->block_pos;
 
-		pg = nth_page(sg[host->sg_pos].page, off >> PAGE_SHIFT);
+		pg = nth_page(sg_page(&sg[host->sg_pos]), off >> PAGE_SHIFT);
 		p_off = offset_in_page(off);
 		p_cnt = PAGE_SIZE - p_off;
 		p_cnt = min(p_cnt, cnt);
 		p_cnt = min(p_cnt, t_size);
 
 		if (r_data->flags & MMC_DATA_WRITE)
-			tifm_sd_copy_page(host->bounce_buf.page,
+			tifm_sd_copy_page(sg_page(&host->bounce_buf),
 					  r_data->blksz - t_size,
 					  pg, p_off, p_cnt);
 		else if (r_data->flags & MMC_DATA_READ)
-			tifm_sd_copy_page(pg, p_off, host->bounce_buf.page,
+			tifm_sd_copy_page(pg, p_off, sg_page(&host->bounce_buf),
 					  r_data->blksz - t_size, p_cnt);
 
 		t_size -= p_cnt;
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c
index 80db11c..971ca0f 100644
--- a/drivers/mmc/host/wbsd.c
+++ b/drivers/mmc/host/wbsd.c
@@ -269,7 +269,7 @@ static inline int wbsd_next_sg(struct wbsd_host *host)
 
 static inline char *wbsd_sg_to_buffer(struct wbsd_host *host)
 {
-	return page_address(host->cur_sg->page) + host->cur_sg->offset;
+	return page_address(sg_page(host->cur_sg)) + host->cur_sg->offset;
 }
 
 static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data)
@@ -283,7 +283,7 @@ static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data)
 	len = data->sg_len;
 
 	for (i = 0; i < len; i++) {
-		sgbuf = page_address(sg[i].page) + sg[i].offset;
+		sgbuf = page_address(sg_page(&sg[i])) + sg[i].offset;
 		memcpy(dmabuf, sgbuf, sg[i].length);
 		dmabuf += sg[i].length;
 	}
@@ -300,7 +300,7 @@ static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data)
 	len = data->sg_len;
 
 	for (i = 0; i < len; i++) {
-		sgbuf = page_address(sg[i].page) + sg[i].offset;
+		sgbuf = page_address(sg_page(&sg[i])) + sg[i].offset;
 		memcpy(sgbuf, dmabuf, sg[i].length);
 		dmabuf += sg[i].length;
 	}
diff --git a/drivers/net/mlx4/icm.c b/drivers/net/mlx4/icm.c
index 4b3c109..887633b 100644
--- a/drivers/net/mlx4/icm.c
+++ b/drivers/net/mlx4/icm.c
@@ -60,7 +60,7 @@ static void mlx4_free_icm_pages(struct mlx4_dev *dev, struct mlx4_icm_chunk *chu
 			     PCI_DMA_BIDIRECTIONAL);
 
 	for (i = 0; i < chunk->npages; ++i)
-		__free_pages(chunk->mem[i].page,
+		__free_pages(sg_page(&chunk->mem[i]),
 			     get_order(chunk->mem[i].length));
 }
 
@@ -70,7 +70,7 @@ static void mlx4_free_icm_coherent(struct mlx4_dev *dev, struct mlx4_icm_chunk *
 
 	for (i = 0; i < chunk->npages; ++i)
 		dma_free_coherent(&dev->pdev->dev, chunk->mem[i].length,
-				  lowmem_page_address(chunk->mem[i].page),
+				  lowmem_page_address(sg_page(&chunk->mem[i])),
 				  sg_dma_address(&chunk->mem[i]));
 }
 
@@ -95,10 +95,13 @@ void mlx4_free_icm(struct mlx4_dev *dev, struct mlx4_icm *icm, int coherent)
 
 static int mlx4_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_mask)
 {
-	mem->page = alloc_pages(gfp_mask, order);
-	if (!mem->page)
+	struct page *page;
+
+	page = alloc_pages(gfp_mask, order);
+	if (!page)
 		return -ENOMEM;
 
+	sg_set_page(mem, page);
 	mem->length = PAGE_SIZE << order;
 	mem->offset = 0;
 	return 0;
@@ -145,6 +148,7 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
 			if (!chunk)
 				goto fail;
 
+			sg_init_table(chunk->mem, MLX4_ICM_CHUNK_LEN);
 			chunk->npages = 0;
 			chunk->nsg    = 0;
 			list_add_tail(&chunk->list, &icm->chunk_list);
@@ -334,7 +338,7 @@ void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_han
 			 * been assigned to.
 			 */
 			if (chunk->mem[i].length > offset) {
-				page = chunk->mem[i].page;
+				page = sg_page(&chunk->mem[i]);
 				goto out;
 			}
 			offset -= chunk->mem[i].length;
diff --git a/drivers/net/ppp_mppe.c b/drivers/net/ppp_mppe.c
index c0b6d19..bcb0885 100644
--- a/drivers/net/ppp_mppe.c
+++ b/drivers/net/ppp_mppe.c
@@ -55,7 +55,7 @@
 #include <linux/mm.h>
 #include <linux/ppp_defs.h>
 #include <linux/ppp-comp.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 
 #include "ppp_mppe.h"
 
@@ -68,9 +68,7 @@ MODULE_VERSION("1.0.2");
 static unsigned int
 setup_sg(struct scatterlist *sg, const void *address, unsigned int length)
 {
-	sg[0].page = virt_to_page(address);
-	sg[0].offset = offset_in_page(address);
-	sg[0].length = length;
+	sg_init_one(sg, address, length);
 	return length;
 }
 
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index fb14014..afb262b 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -1840,7 +1840,7 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
 			    (scsi_bufflen(srb) < TW_MIN_SGL_LENGTH)) {
 				if (srb->sc_data_direction == DMA_TO_DEVICE || srb->sc_data_direction == DMA_BIDIRECTIONAL) {
 					struct scatterlist *sg = scsi_sglist(srb);
-					char *buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+					char *buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 					memcpy(tw_dev->generic_buffer_virt[request_id], buf, sg->length);
 					kunmap_atomic(buf - sg->offset, KM_IRQ0);
 				}
@@ -1919,7 +1919,7 @@ static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int re
 			char *buf;
 			unsigned long flags = 0;
 			local_irq_save(flags);
-			buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+			buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 			memcpy(buf, tw_dev->generic_buffer_virt[request_id], sg->length);
 			kunmap_atomic(buf - sg->offset, KM_IRQ0);
 			local_irq_restore(flags);
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index a64153b..59716eb 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -1469,7 +1469,7 @@ static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id,
 	struct scatterlist *sg = scsi_sglist(cmd);
 
 	local_irq_save(flags);
-	buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+	buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 	transfer_len = min(sg->length, len);
 
 	memcpy(buf, data, transfer_len);
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index 988f0bc..7a76b4b 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -298,7 +298,7 @@ static __inline__ void initialize_SCp(Scsi_Cmnd * cmd)
 	if (cmd->use_sg) {
 		cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
 		cmd->SCp.buffers_residual = cmd->use_sg - 1;
-		cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+
+		cmd->SCp.ptr = page_address(sg_page(cmd->SCp.buffer))+
 			       cmd->SCp.buffer->offset;
 		cmd->SCp.this_residual = cmd->SCp.buffer->length;
 	} else {
@@ -2143,7 +2143,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
 					++cmd->SCp.buffer;
 					--cmd->SCp.buffers_residual;
 					cmd->SCp.this_residual = cmd->SCp.buffer->length;
-					cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+
+					cmd->SCp.ptr = page_address(sg_page(cmd->SCp.buffer))+
 						       cmd->SCp.buffer->offset;
 					dprintk(NDEBUG_INFORMATION, ("scsi%d : %d bytes and %d buffers left\n", instance->host_no, cmd->SCp.this_residual, cmd->SCp.buffers_residual));
 				}
diff --git a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c
index 3168a17..db1a8bc 100644
--- a/drivers/scsi/NCR53c406a.c
+++ b/drivers/scsi/NCR53c406a.c
@@ -875,7 +875,7 @@ static void NCR53c406a_intr(void *dev_id)
 			outb(TRANSFER_INFO | DMA_OP, CMD_REG);
 #if USE_PIO
                         scsi_for_each_sg(current_SC, sg, scsi_sg_count(current_SC), i) {
-                                NCR53c406a_pio_write(page_address(sg->page) + sg->offset,
+                                NCR53c406a_pio_write(page_address(sg_page(sg)) + sg->offset,
                                                      sg->length);
                         }
 			REG0;
@@ -897,7 +897,7 @@ static void NCR53c406a_intr(void *dev_id)
 			outb(TRANSFER_INFO | DMA_OP, CMD_REG);
 #if USE_PIO
                         scsi_for_each_sg(current_SC, sg, scsi_sg_count(current_SC), i) {
-                                NCR53c406a_pio_read(page_address(sg->page) + sg->offset,
+                                NCR53c406a_pio_read(page_address(sg_page(sg)) + sg->offset,
                                                     sg->length);
                         }
 			REG0;
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 80e448d..a77ab8d 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -356,7 +356,7 @@ static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigne
 	int transfer_len;
 	struct scatterlist *sg = scsi_sglist(scsicmd);
 
-	buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+	buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 	transfer_len = min(sg->length, len + offset);
 
 	transfer_len -= offset;
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
index 961a188..50da0a3 100644
--- a/drivers/scsi/aha1542.c
+++ b/drivers/scsi/aha1542.c
@@ -49,7 +49,7 @@
 #include "aha1542.h"
 
 #define SCSI_BUF_PA(address)	isa_virt_to_bus(address)
-#define SCSI_SG_PA(sgent)	(isa_page_to_bus((sgent)->page) + (sgent)->offset)
+#define SCSI_SG_PA(sgent)	(isa_page_to_bus(sg_page((sgent))) + (sgent)->offset)
 
 static void BAD_DMA(void *address, unsigned int length)
 {
@@ -67,7 +67,7 @@ static void BAD_SG_DMA(Scsi_Cmnd * SCpnt,
 {
 	printk(KERN_CRIT "sgpnt[%d:%d] page %p/0x%llx length %u\n",
 	       badseg, nseg,
-	       page_address(sgp->page) + sgp->offset,
+	       page_address(sg_page(sgp)) + sgp->offset,
 	       (unsigned long long)SCSI_SG_PA(sgp),
 	       sgp->length);
 
@@ -712,7 +712,7 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 				printk(KERN_CRIT "Bad segment list supplied to aha1542.c (%d, %d)\n", SCpnt->use_sg, i);
 				scsi_for_each_sg(SCpnt, sg, SCpnt->use_sg, i) {
 					printk(KERN_CRIT "%d: %p %d\n", i,
-					       (page_address(sg->page) +
+					       (page_address(sg_page(sg)) +
 						sg->offset), sg->length);
 				};
 				printk(KERN_CRIT "cptr %x: ", (unsigned int) cptr);
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index f817775..f7a2528 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -1343,7 +1343,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \
 						/* 4 bytes: Areca io control code */
 
 	sg = scsi_sglist(cmd);
-	buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+	buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 	if (scsi_sg_count(cmd) > 1) {
 		retvalue = ARCMSR_MESSAGE_FAIL;
 		goto message_out;
@@ -1593,7 +1593,7 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,
 		strncpy(&inqdata[32], "R001", 4); /* Product Revision */
 
 		sg = scsi_sglist(cmd);
-		buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+		buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 
 		memcpy(buffer, inqdata, sizeof(inqdata));
 		sg = scsi_sglist(cmd);
diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
index 5d282e6..dc4e463 100644
--- a/drivers/scsi/fdomain.c
+++ b/drivers/scsi/fdomain.c
@@ -1321,7 +1321,7 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id)
 	    if (current_SC->SCp.buffers_residual) {
 	       --current_SC->SCp.buffers_residual;
 	       ++current_SC->SCp.buffer;
-	       current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
+	       current_SC->SCp.ptr = page_address(sg_page(current_SC->SCp.buffer)) + current_SC->SCp.buffer->offset;
 	       current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
 	    } else
 		  break;
@@ -1354,7 +1354,7 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id)
 	     && current_SC->SCp.buffers_residual) {
 	    --current_SC->SCp.buffers_residual;
 	    ++current_SC->SCp.buffer;
-	    current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
+	    current_SC->SCp.ptr = page_address(sg_page(current_SC->SCp.buffer)) + current_SC->SCp.buffer->offset;
 	    current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
 	 }
       }
@@ -1439,7 +1439,7 @@ static int fdomain_16x0_queue(struct scsi_cmnd *SCpnt,
 
    if (scsi_sg_count(current_SC)) {
 	   current_SC->SCp.buffer = scsi_sglist(current_SC);
-	   current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page)
+	   current_SC->SCp.ptr = page_address(sg_page(current_SC->SCp.buffer))
 		   + current_SC->SCp.buffer->offset;
 	   current_SC->SCp.this_residual    = current_SC->SCp.buffer->length;
 	   current_SC->SCp.buffers_residual = scsi_sg_count(current_SC) - 1;
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 3ac080e..ac6c57a 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -2374,13 +2374,13 @@ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
             if (cpsum+cpnow > cpcount) 
                 cpnow = cpcount - cpsum;
             cpsum += cpnow;
-            if (!sl->page) {
+            if (!sg_page(sl)) {
                 printk("GDT-HA %d: invalid sc/gt element in gdth_copy_internal_data()\n",
                        ha->hanum);
                 return;
             }
             local_irq_save(flags);
-            address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset;
+            address = kmap_atomic(sg_page(sl), KM_BIO_SRC_IRQ) + sl->offset;
             if (to_buffer)
                 memcpy(buffer, address, cpnow);
             else
diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
index 714e627..db004a4 100644
--- a/drivers/scsi/ibmmca.c
+++ b/drivers/scsi/ibmmca.c
@@ -1828,7 +1828,7 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 		BUG_ON(scsi_sg_count(cmd) > 16);
 
 		scsi_for_each_sg(cmd, sg, scsi_sg_count(cmd), i) {
-			ld(shpnt)[ldn].sge[i].address = (void *) (isa_page_to_bus(sg->page) + sg->offset);
+			ld(shpnt)[ldn].sge[i].address = (void *) (isa_page_to_bus(sg_page(sg)) + sg->offset);
 			ld(shpnt)[ldn].sge[i].byte_length = sg->length;
 		}
 		scb->enable |= IM_POINTER_TO_LIST;
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index fa7ba64..2c7dd8b 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -175,18 +175,18 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
 
 	while (bcount) {
 		count = min(pc->sg->length - pc->b_count, bcount);
-		if (PageHighMem(pc->sg->page)) {
+		if (PageHighMem(sg_page(pc->sg))) {
 			unsigned long flags;
 
 			local_irq_save(flags);
-			buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
+			buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) +
 					pc->sg->offset;
 			drive->hwif->atapi_input_bytes(drive,
 						buf + pc->b_count, count);
 			kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
 			local_irq_restore(flags);
 		} else {
-			buf = page_address(pc->sg->page) + pc->sg->offset;
+			buf = page_address(sg_page(pc->sg)) + pc->sg->offset;
 			drive->hwif->atapi_input_bytes(drive,
 						buf + pc->b_count, count);
 		}
@@ -212,18 +212,18 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
 
 	while (bcount) {
 		count = min(pc->sg->length - pc->b_count, bcount);
-		if (PageHighMem(pc->sg->page)) {
+		if (PageHighMem(sg_page(pc->sg))) {
 			unsigned long flags;
 
 			local_irq_save(flags);
-			buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
+			buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) +
 						pc->sg->offset;
 			drive->hwif->atapi_output_bytes(drive,
 						buf + pc->b_count, count);
 			kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
 			local_irq_restore(flags);
 		} else {
-			buf = page_address(pc->sg->page) + pc->sg->offset;
+			buf = page_address(sg_page(pc->sg)) + pc->sg->offset;
 			drive->hwif->atapi_output_bytes(drive,
 						buf + pc->b_count, count);
 		}
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c
index 74cdc1f..da9b0ba 100644
--- a/drivers/scsi/imm.c
+++ b/drivers/scsi/imm.c
@@ -706,7 +706,7 @@ static int imm_completion(struct scsi_cmnd *cmd)
 				cmd->SCp.this_residual =
 				    cmd->SCp.buffer->length;
 				cmd->SCp.ptr =
-				    page_address(cmd->SCp.buffer->page) +
+				    page_address(sg_page(cmd->SCp.buffer)) +
 				    cmd->SCp.buffer->offset;
 
 				/*
@@ -845,7 +845,7 @@ static int imm_engine(imm_struct *dev, struct scsi_cmnd *cmd)
 			    (struct scatterlist *) cmd->request_buffer;
 			cmd->SCp.this_residual = cmd->SCp.buffer->length;
 			cmd->SCp.ptr =
-			    page_address(cmd->SCp.buffer->page) +
+			    page_address(sg_page(cmd->SCp.buffer)) +
 			    cmd->SCp.buffer->offset;
 		} else {
 			/* else fill the only available buffer */
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index b41dfb5..dc98a85 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -2872,6 +2872,7 @@ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len)
 	}
 
 	scatterlist = sglist->scatterlist;
+	sg_init_table(scatterlist, num_elem);
 
 	sglist->order = order;
 	sglist->num_sg = num_elem;
@@ -2884,12 +2885,12 @@ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len)
 
 			/* Free up what we already allocated */
 			for (j = i - 1; j >= 0; j--)
-				__free_pages(scatterlist[j].page, order);
+				__free_pages(sg_page(&scatterlist[j]), order);
 			kfree(sglist);
 			return NULL;
 		}
 
-		scatterlist[i].page = page;
+		sg_set_page(&scatterlist[i], page);
 	}
 
 	return sglist;
@@ -2910,7 +2911,7 @@ static void ipr_free_ucode_buffer(struct ipr_sglist *sglist)
 	int i;
 
 	for (i = 0; i < sglist->num_sg; i++)
-		__free_pages(sglist->scatterlist[i].page, sglist->order);
+		__free_pages(sg_page(&sglist->scatterlist[i]), sglist->order);
 
 	kfree(sglist);
 }
@@ -2940,9 +2941,11 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist,
 	scatterlist = sglist->scatterlist;
 
 	for (i = 0; i < (len / bsize_elem); i++, buffer += bsize_elem) {
-		kaddr = kmap(scatterlist[i].page);
+		struct page *page = sg_page(&scatterlist[i]);
+
+		kaddr = kmap(page);
 		memcpy(kaddr, buffer, bsize_elem);
-		kunmap(scatterlist[i].page);
+		kunmap(page);
 
 		scatterlist[i].length = bsize_elem;
 
@@ -2953,9 +2956,11 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist,
 	}
 
 	if (len % bsize_elem) {
-		kaddr = kmap(scatterlist[i].page);
+		struct page *page = sg_page(&scatterlist[i]);
+
+		kaddr = kmap(page);
 		memcpy(kaddr, buffer, len % bsize_elem);
-		kunmap(scatterlist[i].page);
+		kunmap(page);
 
 		scatterlist[i].length = len % bsize_elem;
 	}
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index edaac27..5c5a9b2 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -1515,7 +1515,7 @@ static int ips_is_passthru(struct scsi_cmnd *SC)
                 /* kmap_atomic() ensures addressability of the user buffer.*/
                 /* local_irq_save() protects the KM_IRQ0 address slot.     */
                 local_irq_save(flags);
-                buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+                buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
                 if (buffer && buffer[0] == 'C' && buffer[1] == 'O' &&
                     buffer[2] == 'P' && buffer[3] == 'P') {
                         kunmap_atomic(buffer - sg->offset, KM_IRQ0);
@@ -3523,7 +3523,7 @@ ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count)
                 /* kmap_atomic() ensures addressability of the data buffer.*/
                 /* local_irq_save() protects the KM_IRQ0 address slot.     */
                 local_irq_save(flags);
-                buffer = kmap_atomic(sg[i].page, KM_IRQ0) + sg[i].offset;
+                buffer = kmap_atomic(sg_page(&sg[i]), KM_IRQ0) + sg[i].offset;
                 memcpy(buffer, &cdata[xfer_cnt], min_cnt);
                 kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
                 local_irq_restore(flags);
@@ -3556,7 +3556,7 @@ ips_scmd_buf_read(struct scsi_cmnd *scmd, void *data, unsigned int count)
                 /* kmap_atomic() ensures addressability of the data buffer.*/
                 /* local_irq_save() protects the KM_IRQ0 address slot.     */
                 local_irq_save(flags);
-                buffer = kmap_atomic(sg[i].page, KM_IRQ0) + sg[i].offset;
+                buffer = kmap_atomic(sg_page(&sg[i]), KM_IRQ0) + sg[i].offset;
                 memcpy(&cdata[xfer_cnt], buffer, min_cnt);
                 kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
                 local_irq_restore(flags);
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index a21455d..6ce4109 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -70,9 +70,7 @@ module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);
 static inline void
 iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size)
 {
-	ibuf->sg.page = virt_to_page(vbuf);
-	ibuf->sg.offset = offset_in_page(vbuf);
-	ibuf->sg.length = size;
+	sg_init_one(&ibuf->sg, vbuf, size);
 	ibuf->sent = 0;
 	ibuf->use_sendmsg = 1;
 }
@@ -80,13 +78,14 @@ iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size)
 static inline void
 iscsi_buf_init_sg(struct iscsi_buf *ibuf, struct scatterlist *sg)
 {
-	ibuf->sg.page = sg->page;
+	sg_init_table(&ibuf->sg, 1);
+	sg_set_page(&ibuf->sg, sg_page(sg));
 	ibuf->sg.offset = sg->offset;
 	ibuf->sg.length = sg->length;
 	/*
 	 * Fastpath: sg element fits into single page
 	 */
-	if (sg->length + sg->offset <= PAGE_SIZE && !PageSlab(sg->page))
+	if (sg->length + sg->offset <= PAGE_SIZE && !PageSlab(sg_page(sg)))
 		ibuf->use_sendmsg = 0;
 	else
 		ibuf->use_sendmsg = 1;
@@ -716,7 +715,7 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn)
 	for (i = tcp_ctask->sg_count; i < scsi_sg_count(sc); i++) {
 		char *dest;
 
-		dest = kmap_atomic(sg[i].page, KM_SOFTIRQ0);
+		dest = kmap_atomic(sg_page(&sg[i]), KM_SOFTIRQ0);
 		rc = iscsi_ctask_copy(tcp_conn, ctask, dest + sg[i].offset,
 				      sg[i].length, offset);
 		kunmap_atomic(dest, KM_SOFTIRQ0);
@@ -1103,9 +1102,9 @@ iscsi_send(struct iscsi_conn *conn, struct iscsi_buf *buf, int size, int flags)
 	 * slab case.
 	 */
 	if (buf->use_sendmsg)
-		res = sock_no_sendpage(sk, buf->sg.page, offset, size, flags);
+		res = sock_no_sendpage(sk, sg_page(&buf->sg), offset, size, flags);
 	else
-		res = tcp_conn->sendpage(sk, buf->sg.page, offset, size, flags);
+		res = tcp_conn->sendpage(sk, sg_page(&buf->sg), offset, size, flags);
 
 	if (res >= 0) {
 		conn->txdata_octets += res;
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 10d1aff..0a848e8 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -658,7 +658,7 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
 			struct scatterlist *sg;
 
 			sg = scsi_sglist(cmd);
-			buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+			buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 
 			memset(buf, 0, cmd->cmnd[4]);
 			kunmap_atomic(buf - sg->offset, KM_IRQ0);
@@ -1542,9 +1542,9 @@ mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status)
 		if( cmd->cmnd[0] == INQUIRY && !islogical ) {
 
 			sgl = scsi_sglist(cmd);
-			if( sgl->page ) {
+			if( sg_page(sgl) ) {
 				c = *(unsigned char *)
-					page_address((&sgl[0])->page) +
+					page_address((sg_page(&sgl[0]))) +
 					(&sgl[0])->offset; 
 			} else {
 				printk(KERN_WARNING
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index e4e4c6a..376263c 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -1584,9 +1584,9 @@ megaraid_mbox_build_cmd(adapter_t *adapter, struct scsi_cmnd *scp, int *busy)
 			caddr_t			vaddr;
 
 			sgl = scsi_sglist(scp);
-			if (sgl->page) {
+			if (sg_page(sgl)) {
 				vaddr = (caddr_t)
-					(page_address((&sgl[0])->page)
+					(page_address(sg_page(&sgl[0]))
 					 + (&sgl[0])->offset);
 
 				memset(vaddr, 0, scp->cmnd[4]);
@@ -2328,9 +2328,9 @@ megaraid_mbox_dpc(unsigned long devp)
 				&& IS_RAID_CH(raid_dev, scb->dev_channel)) {
 
 			sgl = scsi_sglist(scp);
-			if (sgl->page) {
+			if (sg_page(sgl)) {
 				c = *(unsigned char *)
-					(page_address((&sgl[0])->page) +
+					(page_address(sg_page(&sgl[0])) +
 					 (&sgl[0])->offset);
 			} else {
 				con_log(CL_ANN, (KERN_WARNING
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 331b789..1c5c4b6 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -542,7 +542,7 @@ static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int q
 	if (STp->raw) {
 		if (STp->buffer->syscall_result) {
 			for (i=0; i < STp->buffer->sg_segs; i++)
-				memset(page_address(STp->buffer->sg[i].page),
+				memset(page_address(sg_page(&STp->buffer->sg[i])),
 				       0, STp->buffer->sg[i].length);
 			strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");
                 } else
@@ -4437,7 +4437,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp)
 		for (i = 0, b_size = 0; 
 		     (i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE); 
 		     b_size += STp->buffer->sg[i++].length);
-		STp->buffer->aux = (os_aux_t *) (page_address(STp->buffer->sg[i].page) + OS_DATA_SIZE - b_size);
+		STp->buffer->aux = (os_aux_t *) (page_address(sg_page(&STp->buffer->sg[i])) + OS_DATA_SIZE - b_size);
 #if DEBUG
 		printk(OSST_DEB_MSG "%s:D: b_data points to %p in segment 0 at %p\n", name,
 			STp->buffer->b_data, page_address(STp->buffer->sg[0].page));
@@ -5252,25 +5252,26 @@ static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
 	/* Try to allocate the first segment up to OS_DATA_SIZE and the others
 	   big enough to reach the goal (code assumes no segments in place) */
 	for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) {
-		STbuffer->sg[0].page = alloc_pages(priority, order);
+		struct page *page = alloc_pages(priority, order);
+
 		STbuffer->sg[0].offset = 0;
-		if (STbuffer->sg[0].page != NULL) {
+		if (page != NULL) {
+		    sg_set_page(&STbuffer->sg[0], page);
 		    STbuffer->sg[0].length = b_size;
-		    STbuffer->b_data = page_address(STbuffer->sg[0].page);
+		    STbuffer->b_data = page_address(page);
 		    break;
 		}
 	}
-	if (STbuffer->sg[0].page == NULL) {
+	if (sg_page(&STbuffer->sg[0]) == NULL) {
 		printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n");
 		return 0;
 	}
 	/* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */
 	for (segs=STbuffer->sg_segs=1, got=b_size;
 	     segs < max_segs && got < OS_FRAME_SIZE; ) {
-		STbuffer->sg[segs].page =
-				alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
+		struct page *page = alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
 		STbuffer->sg[segs].offset = 0;
-		if (STbuffer->sg[segs].page == NULL) {
+		if (page == NULL) {
 			if (OS_FRAME_SIZE - got <= (max_segs - segs) * b_size / 2 && order) {
 				b_size /= 2;  /* Large enough for the rest of the buffers */
 				order--;
@@ -5284,6 +5285,7 @@ static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
 			normalize_buffer(STbuffer);
 			return 0;
 		}
+		sg_set_page(&STbuffer->sg[segs], page);
 		STbuffer->sg[segs].length = (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size;
 		got += STbuffer->sg[segs].length;
 		STbuffer->buffer_size = got;
@@ -5316,7 +5318,7 @@ static void normalize_buffer(struct osst_buffer *STbuffer)
 		     b_size < STbuffer->sg[i].length;
 		     b_size *= 2, order++);
 
-		__free_pages(STbuffer->sg[i].page, order);
+		__free_pages(sg_page(&STbuffer->sg[i]), order);
 		STbuffer->buffer_size -= STbuffer->sg[i].length;
 	}
 #if DEBUG
@@ -5344,7 +5346,7 @@ static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, i
 	for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length - offset < do_count ?
 		      st_bp->sg[i].length - offset : do_count;
-		res = copy_from_user(page_address(st_bp->sg[i].page) + offset, ubp, cnt);
+		res = copy_from_user(page_address(sg_page(&st_bp->sg[i])) + offset, ubp, cnt);
 		if (res)
 			return (-EFAULT);
 		do_count -= cnt;
@@ -5377,7 +5379,7 @@ static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count
 	for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length - offset < do_count ?
 		      st_bp->sg[i].length - offset : do_count;
-		res = copy_to_user(ubp, page_address(st_bp->sg[i].page) + offset, cnt);
+		res = copy_to_user(ubp, page_address(sg_page(&st_bp->sg[i])) + offset, cnt);
 		if (res)
 			return (-EFAULT);
 		do_count -= cnt;
@@ -5410,7 +5412,7 @@ static int osst_zero_buffer_tail(struct osst_buffer *st_bp)
 	     i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length - offset < do_count ?
 		      st_bp->sg[i].length - offset : do_count ;
-		memset(page_address(st_bp->sg[i].page) + offset, 0, cnt);
+		memset(page_address(sg_page(&st_bp->sg[i])) + offset, 0, cnt);
 		do_count -= cnt;
 		offset = 0;
 	}
@@ -5430,7 +5432,7 @@ static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
 	for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length < do_count ?
 		      st_bp->sg[i].length : do_count ;
-		memcpy(page_address(st_bp->sg[i].page), ptr, cnt);
+		memcpy(page_address(sg_page(&st_bp->sg[i])), ptr, cnt);
 		do_count -= cnt;
 		ptr      += cnt;
 	}
@@ -5451,7 +5453,7 @@ static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
 	for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length < do_count ?
 		      st_bp->sg[i].length : do_count ;
-		memcpy(ptr, page_address(st_bp->sg[i].page), cnt);
+		memcpy(ptr, page_address(sg_page(&st_bp->sg[i])), cnt);
 		do_count -= cnt;
 		ptr      += cnt;
 	}
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 190e2a7..26c41b0 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -443,7 +443,7 @@ SYM53C500_intr(int irq, void *dev_id)
 
 			scsi_for_each_sg(curSC, sg, scsi_sg_count(curSC), i) {
 				SYM53C500_pio_write(fast_pio, port_base,
-						    page_address(sg->page) + sg->offset,
+				    page_address(sg_page(sg)) + sg->offset,
 						    sg->length);
 			}
 			REG0(port_base);
@@ -463,8 +463,8 @@ SYM53C500_intr(int irq, void *dev_id)
 
 			scsi_for_each_sg(curSC, sg, scsi_sg_count(curSC), i) {
 				SYM53C500_pio_read(fast_pio, port_base,
-						   page_address(sg->page) + sg->offset,
-						   sg->length);
+					page_address(sg_page(sg)) + sg->offset,
+					sg->length);
 			}
 			REG0(port_base);
 		}
diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
index 67b6d76..07f31e5 100644
--- a/drivers/scsi/ppa.c
+++ b/drivers/scsi/ppa.c
@@ -609,7 +609,7 @@ static int ppa_completion(struct scsi_cmnd *cmd)
 				cmd->SCp.this_residual =
 				    cmd->SCp.buffer->length;
 				cmd->SCp.ptr =
-				    page_address(cmd->SCp.buffer->page) +
+				    page_address(sg_page(cmd->SCp.buffer)) +
 				    cmd->SCp.buffer->offset;
 			}
 		}
@@ -756,7 +756,7 @@ static int ppa_engine(ppa_struct *dev, struct scsi_cmnd *cmd)
 			/* if many buffers are available, start filling the first */
 			cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
 			cmd->SCp.this_residual = cmd->SCp.buffer->length;
-			cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) +
+			cmd->SCp.ptr = page_address(sg_page(cmd->SCp.buffer)) +
 			    cmd->SCp.buffer->offset;
 		} else {
 			/* else fill the only available buffer */
diff --git a/drivers/scsi/qlogicfas408.c b/drivers/scsi/qlogicfas408.c
index 2bfbf26..feff3f7 100644
--- a/drivers/scsi/qlogicfas408.c
+++ b/drivers/scsi/qlogicfas408.c
@@ -317,7 +317,7 @@ static unsigned int ql_pcmd(struct scsi_cmnd *cmd)
 				return ((priv->qabort == 1 ?
 					 DID_ABORT : DID_RESET) << 16);
 			}
-			buf = page_address(sg->page) + sg->offset;
+			buf = page_address(sg_page(sg)) + sg->offset;
 			if (ql_pdma(priv, phase, buf, sg->length))
 				break;
 		}
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 72ee4c9..46cae5a 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -625,7 +625,7 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
 	scsi_for_each_sg(scp, sg, scp->use_sg, k) {
 		if (active) {
 			kaddr = (unsigned char *)
-				kmap_atomic(sg->page, KM_USER0);
+				kmap_atomic(sg_page(sg), KM_USER0);
 			if (NULL == kaddr)
 				return (DID_ERROR << 16);
 			kaddr_off = (unsigned char *)kaddr + sg->offset;
@@ -672,7 +672,7 @@ static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
 	sg = scsi_sglist(scp);
 	req_len = fin = 0;
 	for (k = 0; k < scp->use_sg; ++k, sg = sg_next(sg)) {
-		kaddr = (unsigned char *)kmap_atomic(sg->page, KM_USER0);
+		kaddr = (unsigned char *)kmap_atomic(sg_page(sg), KM_USER0);
 		if (NULL == kaddr)
 			return -1;
 		kaddr_off = (unsigned char *)kaddr + sg->offset;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index aac8a02..61fdaf0 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -295,7 +295,7 @@ static int scsi_req_map_sg(struct request *rq, struct scatterlist *sgl,
 	int i, err, nr_vecs = 0;
 
 	for_each_sg(sgl, sg, nsegs, i) {
-		page = sg->page;
+		page = sg_page(sg);
 		off = sg->offset;
 		len = sg->length;
  		data_len += len;
@@ -764,7 +764,7 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
 		if (unlikely(!sgl))
 			goto enomem;
 
-		memset(sgl, 0, sizeof(*sgl) * sgp->size);
+		sg_init_table(sgl, sgp->size);
 
 		/*
 		 * first loop through, set initial index and return value
@@ -781,6 +781,13 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
 			sg_chain(prev, SCSI_MAX_SG_SEGMENTS, sgl);
 
 		/*
+		 * if we have nothing left, mark the last segment as
+		 * end-of-list
+		 */
+		if (!left)
+			sg_mark_end(sgl, this);
+
+		/*
 		 * don't allow subsequent mempool allocs to sleep, it would
 		 * violate the mempool principle.
 		 */
@@ -2353,7 +2360,7 @@ void *scsi_kmap_atomic_sg(struct scatterlist *sgl, int sg_count,
 	*offset = *offset - len_complete + sg->offset;
 
 	/* Assumption: contiguous pages can be accessed as "page + i" */
-	page = nth_page(sg->page, (*offset >> PAGE_SHIFT));
+	page = nth_page(sg_page(sg), (*offset >> PAGE_SHIFT));
 	*offset &= ~PAGE_MASK;
 
 	/* Bytes in this sg-entry from *offset to the end of the page */
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 7238b2d..cc19710 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1169,7 +1169,7 @@ sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type)
 		len = vma->vm_end - sa;
 		len = (len < sg->length) ? len : sg->length;
 		if (offset < len) {
-			page = virt_to_page(page_address(sg->page) + offset);
+			page = virt_to_page(page_address(sg_page(sg)) + offset);
 			get_page(page);	/* increment page count */
 			break;
 		}
@@ -1717,13 +1717,13 @@ st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,
 		   goto out_unlock; */
         }
 
-	sgl[0].page = pages[0];
+	sg_set_page(sgl, pages[0]);
 	sgl[0].offset = uaddr & ~PAGE_MASK;
 	if (nr_pages > 1) {
 		sgl[0].length = PAGE_SIZE - sgl[0].offset;
 		count -= sgl[0].length;
 		for (i=1; i < nr_pages ; i++) {
-			sgl[i].page = pages[i]; 
+			sg_set_page(&sgl[i], pages[i]);
 			sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
 			count -= PAGE_SIZE;
 		}
@@ -1754,7 +1754,7 @@ st_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_pages,
 	int i;
 
 	for (i=0; i < nr_pages; i++) {
-		struct page *page = sgl[i].page;
+		struct page *page = sg_page(&sgl[i]);
 
 		if (dirtied)
 			SetPageDirty(page);
@@ -1854,7 +1854,7 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
 				scatter_elem_sz_prev = ret_sz;
 			}
 		}
-		sg->page = p;
+		sg_set_page(sg, p);
 		sg->length = (ret_sz > num) ? num : ret_sz;
 
 		SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k=%d, num=%d, "
@@ -1907,14 +1907,14 @@ sg_write_xfer(Sg_request * srp)
 		onum = 1;
 
 	ksglen = sg->length;
-	p = page_address(sg->page);
+	p = page_address(sg_page(sg));
 	for (j = 0, k = 0; j < onum; ++j) {
 		res = sg_u_iovec(hp, iovec_count, j, 1, &usglen, &up);
 		if (res)
 			return res;
 
 		for (; p; sg = sg_next(sg), ksglen = sg->length,
-		     p = page_address(sg->page)) {
+		     p = page_address(sg_page(sg))) {
 			if (usglen <= 0)
 				break;
 			if (ksglen > usglen) {
@@ -1991,12 +1991,12 @@ sg_remove_scat(Sg_scatter_hold * schp)
 		} else {
 			int k;
 
-			for (k = 0; (k < schp->k_use_sg) && sg->page;
+			for (k = 0; (k < schp->k_use_sg) && sg_page(sg);
 			     ++k, sg = sg_next(sg)) {
 				SCSI_LOG_TIMEOUT(5, printk(
 				    "sg_remove_scat: k=%d, pg=0x%p, len=%d\n",
-				    k, sg->page, sg->length));
-				sg_page_free(sg->page, sg->length);
+				    k, sg_page(sg), sg->length));
+				sg_page_free(sg_page(sg), sg->length);
 			}
 		}
 		kfree(schp->buffer);
@@ -2038,7 +2038,7 @@ sg_read_xfer(Sg_request * srp)
 	} else
 		onum = 1;
 
-	p = page_address(sg->page);
+	p = page_address(sg_page(sg));
 	ksglen = sg->length;
 	for (j = 0, k = 0; j < onum; ++j) {
 		res = sg_u_iovec(hp, iovec_count, j, 0, &usglen, &up);
@@ -2046,7 +2046,7 @@ sg_read_xfer(Sg_request * srp)
 			return res;
 
 		for (; p; sg = sg_next(sg), ksglen = sg->length,
-		     p = page_address(sg->page)) {
+		     p = page_address(sg_page(sg))) {
 			if (usglen <= 0)
 				break;
 			if (ksglen > usglen) {
@@ -2092,15 +2092,15 @@ sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer)
 	if ((!outp) || (num_read_xfer <= 0))
 		return 0;
 
-	for (k = 0; (k < schp->k_use_sg) && sg->page; ++k, sg = sg_next(sg)) {
+	for (k = 0; (k < schp->k_use_sg) && sg_page(sg); ++k, sg = sg_next(sg)) {
 		num = sg->length;
 		if (num > num_read_xfer) {
-			if (__copy_to_user(outp, page_address(sg->page),
+			if (__copy_to_user(outp, page_address(sg_page(sg)),
 					   num_read_xfer))
 				return -EFAULT;
 			break;
 		} else {
-			if (__copy_to_user(outp, page_address(sg->page),
+			if (__copy_to_user(outp, page_address(sg_page(sg)),
 					   num))
 				return -EFAULT;
 			num_read_xfer -= num;
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 73c44cb..ce69b9e 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -3797,7 +3797,7 @@ static void buf_to_sg(struct st_buffer *STbp, unsigned int length)
 	sg = &(STbp->sg[0]);
 	frp = STbp->frp;
 	for (i=count=0; count < length; i++) {
-		sg[i].page = frp[i].page;
+		sg_set_page(&sg[i], frp[i].page);
 		if (length - count > frp[i].length)
 			sg[i].length = frp[i].length;
 		else
@@ -4446,14 +4446,14 @@ static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pa
         }
 
 	/* Populate the scatter/gather list */
-	sgl[0].page = pages[0]; 
+	sg_set_page(&sgl[0], pages[0]);
 	sgl[0].offset = uaddr & ~PAGE_MASK;
 	if (nr_pages > 1) {
 		sgl[0].length = PAGE_SIZE - sgl[0].offset;
 		count -= sgl[0].length;
 		for (i=1; i < nr_pages ; i++) {
+			sg_set_page(&sgl[i], pages[i]);;
 			sgl[i].offset = 0;
-			sgl[i].page = pages[i]; 
 			sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
 			count -= PAGE_SIZE;
 		}
@@ -4483,7 +4483,7 @@ static int sgl_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_p
 	int i;
 
 	for (i=0; i < nr_pages; i++) {
-		struct page *page = sgl[i].page;
+		struct page *page = sg_page(&sgl[i]);
 
 		if (dirtied)
 			SetPageDirty(page);
diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c
index 5c72ca3..4419304 100644
--- a/drivers/scsi/tmscsim.c
+++ b/drivers/scsi/tmscsim.c
@@ -430,10 +430,7 @@ static __inline__ void dc390_Going_remove (struct dc390_dcb* pDCB, struct dc390_
 
 static struct scatterlist* dc390_sg_build_single(struct scatterlist *sg, void *addr, unsigned int length)
 {
-	memset(sg, 0, sizeof(struct scatterlist));
-	sg->page	= virt_to_page(addr);
-	sg->length	= length;
-	sg->offset	= (unsigned long)addr & ~PAGE_MASK;
+	sg_init_one(sg, addr, length);
 	return sg;
 }
 
diff --git a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c
index ea72bbe..6d1f0ed 100644
--- a/drivers/scsi/ultrastor.c
+++ b/drivers/scsi/ultrastor.c
@@ -681,7 +681,7 @@ static inline void build_sg_list(struct mscp *mscp, struct scsi_cmnd *SCpnt)
 
 	max = scsi_sg_count(SCpnt);
 	scsi_for_each_sg(SCpnt, sg, max, i) {
-		mscp->sglist[i].address = isa_page_to_bus(sg->page) + sg->offset;
+		mscp->sglist[i].address = isa_page_to_bus(sg_page(sg)) + sg->offset;
 		mscp->sglist[i].num_bytes = sg->length;
 		transfer_length += sg->length;
 	}
diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c
index 255c611..03cd44f 100644
--- a/drivers/scsi/wd7000.c
+++ b/drivers/scsi/wd7000.c
@@ -1123,7 +1123,7 @@ static int wd7000_queuecommand(struct scsi_cmnd *SCpnt,
 		any2scsi(scb->maxlen, nseg * sizeof(Sgb));
 
 		scsi_for_each_sg(SCpnt, sg, nseg, i) {
-			any2scsi(sgb[i].ptr, isa_page_to_bus(sg->page) + sg->offset);
+			any2scsi(sgb[i].ptr, isa_page_to_bus(sg_page(sg)) + sg->offset);
 			any2scsi(sgb[i].len, sg->length);
 		}
 	} else {
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index c021af3..3577453 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -438,12 +438,12 @@ int usb_sg_init (
 			io->urbs[i]->transfer_buffer = NULL;
 #else
 			io->urbs[i]->transfer_buffer =
-				page_address(sg[i].page) + sg[i].offset;
+				page_address(sg_page(&sg[i])) + sg[i].offset;
 #endif
 		} else {
 			/* hc may use _only_ transfer_buffer */
 			io->urbs [i]->transfer_buffer =
-				page_address (sg [i].page) + sg [i].offset;
+				page_address(sg_page(&sg[i])) + sg [i].offset;
 			len = sg [i].length;
 		}
 
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
index e7d982a..4866baf 100644
--- a/drivers/usb/image/microtek.c
+++ b/drivers/usb/image/microtek.c
@@ -519,7 +519,7 @@ static void mts_do_sg (struct urb* transfer)
 	context->fragment++;
 	mts_int_submit_urb(transfer,
 			   context->data_pipe,
-			   page_address(sg[context->fragment].page) +
+			   page_address(sg_page(&sg[context->fragment])) +
 			   sg[context->fragment].offset,
 			   sg[context->fragment].length,
 			   context->fragment + 1 == scsi_sg_count(context->srb) ?
@@ -557,7 +557,7 @@ mts_build_transfer_context(struct scsi_cmnd *srb, struct mts_desc* desc)
 		return;
 	} else {
 		sg = scsi_sglist(srb);
-		desc->context.data = page_address(sg[0].page) + sg[0].offset;
+		desc->context.data = page_address(sg_page(&sg[0])) + sg[0].offset;
 		desc->context.data_length = sg[0].length;
 	}
 
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index e901d31..ca8cb34 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -360,9 +360,10 @@ static void free_sglist (struct scatterlist *sg, int nents)
 	if (!sg)
 		return;
 	for (i = 0; i < nents; i++) {
-		if (!sg [i].page)
+		struct page *page = sg_page(&sg[i]);
+		if (!page)
 			continue;
-		kfree (page_address (sg [i].page) + sg [i].offset);
+		kfree (page_address (page) + sg [i].offset);
 	}
 	kfree (sg);
 }
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c
index cc8f7c5..889622b 100644
--- a/drivers/usb/storage/protocol.c
+++ b/drivers/usb/storage/protocol.c
@@ -195,7 +195,7 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
 		 * the *offset and *index values for the next loop. */
 		cnt = 0;
 		while (cnt < buflen) {
-			struct page *page = sg->page +
+			struct page *page = sg_page(sg) +
 					((sg->offset + *offset) >> PAGE_SHIFT);
 			unsigned int poff =
 					(sg->offset + *offset) & (PAGE_SIZE-1);
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index 1ae90ef..0a9882e 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -283,7 +283,7 @@ int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg,
 		pg = virt_to_page(addr);
 		offset = offset_in_page(addr);
 		if (sg) {
-			sg[i].page = pg;
+			sg_set_page(&sg[i], pg);
 			sg[i].offset = offset;
 		}
 		remainder_of_page = PAGE_CACHE_SIZE - offset;
@@ -713,10 +713,13 @@ ecryptfs_encrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
 {
 	struct scatterlist src_sg, dst_sg;
 
-	src_sg.page = src_page;
+	sg_init_table(&src_sg, 1);
+	sg_init_table(&dst_sg, 1);
+
+	sg_set_page(&src_sg, src_page);
 	src_sg.offset = src_offset;
 	src_sg.length = size;
-	dst_sg.page = dst_page;
+	sg_set_page(&dst_sg, dst_page);
 	dst_sg.offset = dst_offset;
 	dst_sg.length = size;
 	return encrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
@@ -742,10 +745,13 @@ ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
 {
 	struct scatterlist src_sg, dst_sg;
 
-	src_sg.page = src_page;
+	sg_init_table(&src_sg, 1);
+	sg_init_table(&dst_sg, 1);
+
+	sg_set_page(&src_sg, src_page);
 	src_sg.offset = src_offset;
 	src_sg.length = size;
-	dst_sg.page = dst_page;
+	sg_set_page(&dst_sg, dst_page);
 	dst_sg.offset = dst_offset;
 	dst_sg.length = size;
 	return decrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 89d9710..263fed8 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -1040,6 +1040,9 @@ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
 	};
 	int rc = 0;
 
+	sg_init_table(&dst_sg, 1);
+	sg_init_table(&src_sg, 1);
+
 	if (unlikely(ecryptfs_verbosity > 0)) {
 		ecryptfs_printk(
 			KERN_DEBUG, "Session key encryption key (size [%d]):\n",
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index ebd03cc..6f03918 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -88,7 +88,7 @@ nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname)
 {
 	struct xdr_netobj cksum;
 	struct hash_desc desc;
-	struct scatterlist sg[1];
+	struct scatterlist sg;
 	__be32 status = nfserr_resource;
 
 	dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n",
@@ -102,11 +102,9 @@ nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname)
 	if (cksum.data == NULL)
  		goto out;
 
-	sg[0].page = virt_to_page(clname->data);
-	sg[0].offset = offset_in_page(clname->data);
-	sg[0].length = clname->len;
+	sg_init_one(&sg, clname->data, clname->len);
 
-	if (crypto_hash_digest(&desc, sg, sg->length, cksum.data))
+	if (crypto_hash_digest(&desc, &sg, sg.length, cksum.data))
 		goto out;
 
 	md5_to_hex(dname, cksum.data);
diff --git a/include/asm-alpha/scatterlist.h b/include/asm-alpha/scatterlist.h
index 9173654..b764706 100644
--- a/include/asm-alpha/scatterlist.h
+++ b/include/asm-alpha/scatterlist.h
@@ -5,7 +5,7 @@
 #include <asm/types.h>
   
 struct scatterlist {
-	struct page *page;
+	unsigned long page_link;
 	unsigned int offset;
 
 	unsigned int length;
diff --git a/include/asm-arm/scatterlist.h b/include/asm-arm/scatterlist.h
index de2f65e..ab1d85d 100644
--- a/include/asm-arm/scatterlist.h
+++ b/include/asm-arm/scatterlist.h
@@ -5,7 +5,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page	*page;		/* buffer page			 */
+	unsigned long	page_link;
 	unsigned int	offset;		/* buffer offset		 */
 	dma_addr_t	dma_address;	/* dma address			 */
 	unsigned int	length;		/* length			 */
diff --git a/include/asm-avr32/scatterlist.h b/include/asm-avr32/scatterlist.h
index c6d5ce3..1356f29 100644
--- a/include/asm-avr32/scatterlist.h
+++ b/include/asm-avr32/scatterlist.h
@@ -4,7 +4,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page		*page;
+    unsigned long	page_link;
     unsigned int	offset;
     dma_addr_t		dma_address;
     unsigned int	length;
diff --git a/include/asm-blackfin/scatterlist.h b/include/asm-blackfin/scatterlist.h
index 60e07b9..384af54 100644
--- a/include/asm-blackfin/scatterlist.h
+++ b/include/asm-blackfin/scatterlist.h
@@ -4,7 +4,7 @@
 #include <linux/mm.h>
 
 struct scatterlist {
-	struct page *page;
+	unsigned long page_link;
 	unsigned int offset;
 	dma_addr_t dma_address;
 	unsigned int length;
diff --git a/include/asm-cris/scatterlist.h b/include/asm-cris/scatterlist.h
index 4bdc44c..5a8a834 100644
--- a/include/asm-cris/scatterlist.h
+++ b/include/asm-cris/scatterlist.h
@@ -6,7 +6,7 @@ struct scatterlist {
 	unsigned int length;
 
 	/* The following is i386 highmem junk - not used by us */
-	struct page * page; /* Location for highmem page, if any */
+	unsigned long page_link;
 	unsigned int offset;/* for highmem, page offset */
 
 };
diff --git a/include/asm-frv/scatterlist.h b/include/asm-frv/scatterlist.h
index 8e827fa..53dade7 100644
--- a/include/asm-frv/scatterlist.h
+++ b/include/asm-frv/scatterlist.h
@@ -22,7 +22,7 @@
  * and that's it. There's no excuse for not highmem enabling YOUR driver. /jens
  */
 struct scatterlist {
-	struct page	*page;		/* Location for highmem page, if any */
+	unsigned long	page_link;
 	unsigned int	offset;		/* for highmem, page offset */
 
 	dma_addr_t	dma_address;
diff --git a/include/asm-h8300/scatterlist.h b/include/asm-h8300/scatterlist.h
index 985fdf5..7e41983 100644
--- a/include/asm-h8300/scatterlist.h
+++ b/include/asm-h8300/scatterlist.h
@@ -4,7 +4,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page	*page;
+	unsigned long	page_link;
 	unsigned int	offset;
 	dma_addr_t	dma_address;
 	unsigned int	length;
diff --git a/include/asm-ia64/scatterlist.h b/include/asm-ia64/scatterlist.h
index 7d5234d..2f76ce3 100644
--- a/include/asm-ia64/scatterlist.h
+++ b/include/asm-ia64/scatterlist.h
@@ -9,7 +9,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page *page;
+	unsigned long page_link;
 	unsigned int offset;
 	unsigned int length;	/* buffer length */
 
diff --git a/include/asm-m32r/scatterlist.h b/include/asm-m32r/scatterlist.h
index 352415f..33b4b4d 100644
--- a/include/asm-m32r/scatterlist.h
+++ b/include/asm-m32r/scatterlist.h
@@ -6,7 +6,7 @@
 struct scatterlist {
     char *  address;    /* Location data is to be transferred to, NULL for
                          * highmem page */
-    struct page * page; /* Location for highmem page, if any */
+    unsigned long page_link;
     unsigned int offset;/* for highmem, page offset */
 
     dma_addr_t dma_address;
diff --git a/include/asm-m68k/scatterlist.h b/include/asm-m68k/scatterlist.h
index 24887a2..e06bb89 100644
--- a/include/asm-m68k/scatterlist.h
+++ b/include/asm-m68k/scatterlist.h
@@ -4,7 +4,7 @@
 #include <linux/types.h>
 
 struct scatterlist {
-	struct page *page;
+	unsigned long page_link;
 	unsigned int offset;
 	unsigned int length;
 
diff --git a/include/asm-m68knommu/scatterlist.h b/include/asm-m68knommu/scatterlist.h
index 4da79d3..28bed41 100644
--- a/include/asm-m68knommu/scatterlist.h
+++ b/include/asm-m68knommu/scatterlist.h
@@ -5,7 +5,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page	*page;
+	unsigned long	page_link;
 	unsigned int	offset;
 	dma_addr_t	dma_address;
 	unsigned int	length;
diff --git a/include/asm-mips/scatterlist.h b/include/asm-mips/scatterlist.h
index 7af104c..787797c 100644
--- a/include/asm-mips/scatterlist.h
+++ b/include/asm-mips/scatterlist.h
@@ -4,7 +4,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page *	page;
+	unsigned long	page_link;
 	unsigned int	offset;
 	dma_addr_t	dma_address;
 	unsigned int	length;
diff --git a/include/asm-parisc/scatterlist.h b/include/asm-parisc/scatterlist.h
index e7211c7..26da914 100644
--- a/include/asm-parisc/scatterlist.h
+++ b/include/asm-parisc/scatterlist.h
@@ -5,7 +5,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page *page;
+	unsigned long page_link;
 	unsigned int offset;
 
 	unsigned int length;
diff --git a/include/asm-powerpc/scatterlist.h b/include/asm-powerpc/scatterlist.h
index b075f61..b9f1dbc 100644
--- a/include/asm-powerpc/scatterlist.h
+++ b/include/asm-powerpc/scatterlist.h
@@ -14,7 +14,7 @@
 #include <asm/dma.h>
 
 struct scatterlist {
-	struct page *page;
+	unsigned long page_link;
 	unsigned int offset;
 	unsigned int length;
 
diff --git a/include/asm-s390/scatterlist.h b/include/asm-s390/scatterlist.h
index a43b3af..eb39486 100644
--- a/include/asm-s390/scatterlist.h
+++ b/include/asm-s390/scatterlist.h
@@ -2,7 +2,7 @@
 #define _ASMS390_SCATTERLIST_H
 
 struct scatterlist {
-    struct page *page;
+    unsigned long page_link;
     unsigned int offset;
     unsigned int length;
 };
diff --git a/include/asm-sh/scatterlist.h b/include/asm-sh/scatterlist.h
index b9ae53c..bc7c809 100644
--- a/include/asm-sh/scatterlist.h
+++ b/include/asm-sh/scatterlist.h
@@ -4,7 +4,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page * page; /* Location for highmem page, if any */
+    unsigned long page_link;
     unsigned int offset;/* for highmem, page offset */
     dma_addr_t dma_address;
     unsigned int length;
diff --git a/include/asm-sh64/scatterlist.h b/include/asm-sh64/scatterlist.h
index 1c723f2..0afd856 100644
--- a/include/asm-sh64/scatterlist.h
+++ b/include/asm-sh64/scatterlist.h
@@ -14,7 +14,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page * page; /* Location for highmem page, if any */
+    unsigned long page_link;
     unsigned int offset;/* for highmem, page offset */
     dma_addr_t dma_address;
     unsigned int length;
diff --git a/include/asm-sparc/scatterlist.h b/include/asm-sparc/scatterlist.h
index 4055af9..45b16f1 100644
--- a/include/asm-sparc/scatterlist.h
+++ b/include/asm-sparc/scatterlist.h
@@ -5,7 +5,7 @@
 #include <linux/types.h>
 
 struct scatterlist {
-	struct page *page;
+	unsigned long page_link;
 	unsigned int offset;
 
 	unsigned int length;
diff --git a/include/asm-sparc64/scatterlist.h b/include/asm-sparc64/scatterlist.h
index 703c5bb..6df23f0 100644
--- a/include/asm-sparc64/scatterlist.h
+++ b/include/asm-sparc64/scatterlist.h
@@ -6,7 +6,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page	*page;
+#ifdef CONFIG_DEBUG_SG
+	unsigned long	sg_magic;
+#endif
+	unsigned long	page_link;
 	unsigned int	offset;
 
 	unsigned int	length;
diff --git a/include/asm-v850/scatterlist.h b/include/asm-v850/scatterlist.h
index 56f4029..db91feb 100644
--- a/include/asm-v850/scatterlist.h
+++ b/include/asm-v850/scatterlist.h
@@ -17,7 +17,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page	*page;
+	unsigned long	page_link;
 	unsigned	offset;
 	dma_addr_t	dma_address;
 	unsigned	length;
diff --git a/include/asm-x86/dma-mapping_32.h b/include/asm-x86/dma-mapping_32.h
index 6a2d26c..e0d38d8 100644
--- a/include/asm-x86/dma-mapping_32.h
+++ b/include/asm-x86/dma-mapping_32.h
@@ -45,9 +45,9 @@ dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
 	WARN_ON(nents == 0 || sglist[0].length == 0);
 
 	for_each_sg(sglist, sg, nents, i) {
-		BUG_ON(!sg->page);
+		BUG_ON(!sg_page(sg));
 
-		sg->dma_address = page_to_phys(sg->page) + sg->offset;
+		sg->dma_address = page_to_phys(sg_page(sg)) + sg->offset;
 	}
 
 	flush_write_buffers();
diff --git a/include/asm-x86/scatterlist_32.h b/include/asm-x86/scatterlist_32.h
index bd5164a..0e7d997 100644
--- a/include/asm-x86/scatterlist_32.h
+++ b/include/asm-x86/scatterlist_32.h
@@ -4,7 +4,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page		*page;
+#ifdef CONFIG_DEBUG_SG
+    unsigned long	sg_magic;
+#endif
+    unsigned long	page_link;
     unsigned int	offset;
     dma_addr_t		dma_address;
     unsigned int	length;
diff --git a/include/asm-x86/scatterlist_64.h b/include/asm-x86/scatterlist_64.h
index ef3986b..1847c72 100644
--- a/include/asm-x86/scatterlist_64.h
+++ b/include/asm-x86/scatterlist_64.h
@@ -4,7 +4,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page		*page;
+#ifdef CONFIG_DEBUG_SG
+    unsigned long	sg_magic;
+#endif
+    unsigned long	page_link;
     unsigned int	offset;
     unsigned int	length;
     dma_addr_t		dma_address;
diff --git a/include/asm-xtensa/scatterlist.h b/include/asm-xtensa/scatterlist.h
index ca337a2..3b8aba5 100644
--- a/include/asm-xtensa/scatterlist.h
+++ b/include/asm-xtensa/scatterlist.h
@@ -14,7 +14,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page 	*page;
+	unsigned long	page_link;
 	unsigned int	offset;
 	dma_addr_t	dma_address;
 	unsigned int	length;
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index 2dc7464..b4d6a64 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -5,29 +5,72 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 
+/*
+ * Notes on SG table design.
+ *
+ * Architectures must provide an unsigned long page_link field in the
+ * scatterlist struct. We use that to place the page pointer AND encode
+ * information about the sg table as well. The two lower bits are reserved
+ * for this information.
+ *
+ * If bit 0 is set, then the page_link contains a pointer to the next sg
+ * table list. Otherwise the next entry is at sg + 1.
+ *
+ * If bit 1 is set, then this sg entry is the last element in a list.
+ *
+ * See sg_next().
+ *
+ */
+
+#define SG_MAGIC	0x87654321
+
+/**
+ * sg_set_page - Set sg entry to point at given page
+ * @sg:		 SG entry
+ * @page:	 The page
+ *
+ * Use this function to set an sg entry pointing at a page, never assign
+ * the page directly. We encode sg table information in the lower bits
+ * of the page pointer. See sg_page() for looking up the page belonging
+ * to an sg entry.
+ *
+ */
+static inline void sg_set_page(struct scatterlist *sg, struct page *page)
+{
+	unsigned long page_link = sg->page_link & 0x3;
+
+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(sg->sg_magic != SG_MAGIC);
+#endif
+	sg->page_link = page_link | (unsigned long) page;
+}
+
+#define sg_page(sg)	((struct page *) ((sg)->page_link & ~0x3))
+
+/**
+ * sg_set_buf - Set sg entry to point at given data
+ * @sg:		 SG entry
+ * @buf:	 Data
+ * @buflen:	 Data length
+ * 
+*/
 static inline void sg_set_buf(struct scatterlist *sg, const void *buf,
 			      unsigned int buflen)
 {
-	sg->page = virt_to_page(buf);
+	sg_set_page(sg, virt_to_page(buf));
 	sg->offset = offset_in_page(buf);
 	sg->length = buflen;
 }
 
-static inline void sg_init_one(struct scatterlist *sg, const void *buf,
-			       unsigned int buflen)
-{
-	memset(sg, 0, sizeof(*sg));
-	sg_set_buf(sg, buf, buflen);
-}
-
 /*
  * We overload the LSB of the page pointer to indicate whether it's
  * a valid sg entry, or whether it points to the start of a new scatterlist.
  * Those low bits are there for everyone! (thanks mason :-)
  */
-#define sg_is_chain(sg)		((unsigned long) (sg)->page & 0x01)
+#define sg_is_chain(sg)		((sg)->page_link & 0x01)
+#define sg_is_last(sg)		((sg)->page_link & 0x02)
 #define sg_chain_ptr(sg)	\
-	((struct scatterlist *) ((unsigned long) (sg)->page & ~0x01))
+	((struct scatterlist *) ((sg)->page_link & ~0x03))
 
 /**
  * sg_next - return the next scatterlist entry in a list
@@ -37,16 +80,18 @@ static inline void sg_init_one(struct scatterlist *sg, const void *buf,
  * of a chained scatterlist, it could jump to the start of a new
  * scatterlist array.
  *
- * Note that the caller must ensure that there are further entries after
- * the current entry, this function will NOT return NULL for an end-of-list.
- *
  */
 static inline struct scatterlist *sg_next(struct scatterlist *sg)
 {
-	sg++;
-
-	if (unlikely(sg_is_chain(sg)))
+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(sg->sg_magic != SG_MAGIC);
+#endif
+	if (sg_is_last(sg))
+		sg = NULL;
+	else if (sg_is_chain(sg))
 		sg = sg_chain_ptr(sg);
+	else
+		sg++;
 
 	return sg;
 }
@@ -83,6 +128,9 @@ static inline struct scatterlist *sg_last(struct scatterlist *sgl,
 		ret = sg;
 
 #endif
+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(sgl[0].sg_magic != SG_MAGIC);
+#endif
 	return ret;
 }
 
@@ -101,7 +149,63 @@ static inline void sg_chain(struct scatterlist *prv, unsigned int prv_nents,
 #ifndef ARCH_HAS_SG_CHAIN
 	BUG();
 #endif
-	prv[prv_nents - 1].page = (struct page *) ((unsigned long) sgl | 0x01);
+	prv[prv_nents - 1].page_link = (unsigned long) sgl | 0x01;
+}
+
+/**
+ * sg_mark_end - Mark the end of the scatterlist
+ * @sgl:	Scatterlist
+ * @nents:	Number of entries in sgl
+ *
+ * Marks the last entry as the termination point for sg_next()
+ *
+ */
+static inline void sg_mark_end(struct scatterlist *sgl, unsigned int nents)
+{
+	sgl[nents - 1].page_link = 0x02;
+}
+
+/**
+ * sg_init_one - Initialize a single entry sg list
+ * @sg:		 SG entry
+ * @buf:	 Virtual address for IO
+ * @buflen:	 IO length
+ *
+ * Note: this should not be used on a single entry that is part of a larger
+ * table. Use sg_init_table() for that.
+ *
+ */
+static inline void sg_init_one(struct scatterlist *sg, const void *buf,
+			       unsigned int buflen)
+{
+	memset(sg, 0, sizeof(*sg));
+#ifdef CONFIG_DEBUG_SG
+	sg->sg_magic = SG_MAGIC;
+#endif
+	sg_mark_end(sg, 1);
+	sg_set_buf(sg, buf, buflen);
+}
+
+/**
+ * sg_init_table - Initialize SG table
+ * @sgl:	   The SG table
+ * @nents:	   Number of entries in table
+ *
+ * Note: If this is part of a chained sg table, sg_mark_end() should be
+ * used only on the last table part.
+ *
+ */
+static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents)
+{
+	memset(sgl, 0, sizeof(*sgl) * nents);
+	sg_mark_end(sgl, nents);
+#ifdef CONFIG_DEBUG_SG
+	{
+		int i;
+		for (i = 0; i < nents; i++)
+			sgl[i].sg_magic = SG_MAGIC;
+	}
+#endif
 }
 
 #endif /* _LINUX_SCATTERLIST_H */
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 7d16e64..183f42c 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -389,6 +389,16 @@ config DEBUG_LIST
 
 	  If unsure, say N.
 
+config DEBUG_SG
+	bool "Debug SG table operations"
+	depends on DEBUG_KERNEL
+	help
+	  Enable this to turn on checks on scatter-gather tables. This can
+	  help find problems with drivers that do not properly initialize
+	  their sg tables.
+
+	  If unsure, say N.
+
 config FRAME_POINTER
 	bool "Compile the kernel with frame pointers"
 	depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML || S390 || AVR32 || SUPERH || BFIN)
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 752fd95..e58909e 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -35,7 +35,7 @@
 #define OFFSET(val,align) ((unsigned long)	\
 	                   ( (val) & ( (align) - 1)))
 
-#define SG_ENT_VIRT_ADDRESS(sg)	(page_address((sg)->page) + (sg)->offset)
+#define SG_ENT_VIRT_ADDRESS(sg)	(page_address(sg_page((sg)) + (sg)->offset))
 #define SG_ENT_PHYS_ADDRESS(sg)	virt_to_bus(SG_ENT_VIRT_ADDRESS(sg))
 
 /*
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 70d9b5d..4e2c84f 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2045,7 +2045,7 @@ skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
 	if (copy > 0) {
 		if (copy > len)
 			copy = len;
-		sg[elt].page = virt_to_page(skb->data + offset);
+		sg_set_page(&sg[elt], virt_to_page(skb->data + offset));
 		sg[elt].offset = (unsigned long)(skb->data + offset) % PAGE_SIZE;
 		sg[elt].length = copy;
 		elt++;
@@ -2065,7 +2065,7 @@ skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
 
 			if (copy > len)
 				copy = len;
-			sg[elt].page = frag->page;
+			sg_set_page(&sg[elt], frag->page);
 			sg[elt].offset = frag->page_offset+offset-start;
 			sg[elt].length = copy;
 			elt++;
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
index 6cc54ee..34d4c77 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -390,9 +390,7 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	icv[3] = crc >> 24;
 
 	crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = len + 4;
+	sg_init_one(&sg, pos, len + 4);
 	return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
 }
 
@@ -485,9 +483,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	plen = skb->len - hdr_len - 12;
 
 	crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = plen + 4;
+	sg_init_one(&sg, pos, plen + 4);
 	if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG ": TKIP: failed to decrypt "
@@ -539,11 +535,12 @@ static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
 		printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
 		return -1;
 	}
-	sg[0].page = virt_to_page(hdr);
+	sg_init_table(sg, 2);
+	sg_set_page(&sg[0], virt_to_page(hdr));
 	sg[0].offset = offset_in_page(hdr);
 	sg[0].length = 16;
 
-	sg[1].page = virt_to_page(data);
+	sg_set_page(&sg[1], virt_to_page(data));
 	sg[1].offset = offset_in_page(data);
 	sg[1].length = data_len;
 
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
index 8d18245..0af6103 100644
--- a/net/ieee80211/ieee80211_crypt_wep.c
+++ b/net/ieee80211/ieee80211_crypt_wep.c
@@ -170,9 +170,7 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	icv[3] = crc >> 24;
 
 	crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = len + 4;
+	sg_init_one(&sg, pos, len + 4);
 	return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
 }
 
@@ -212,9 +210,7 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	plen = skb->len - hdr_len - 8;
 
 	crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = plen + 4;
+	sg_init_one(&sg, pos, plen + 4);
 	if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
 		return -7;
 
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 6675261..cc806d6 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -138,9 +138,7 @@ void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
 	*icv = cpu_to_le32(~crc32_le(~0, data, data_len));
 
 	crypto_blkcipher_setkey(tfm, rc4key, klen);
-	sg.page = virt_to_page(data);
-	sg.offset = offset_in_page(data);
-	sg.length = data_len + WEP_ICV_LEN;
+	sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
 	crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length);
 }
 
@@ -204,9 +202,7 @@ int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
 	__le32 crc;
 
 	crypto_blkcipher_setkey(tfm, rc4key, klen);
-	sg.page = virt_to_page(data);
-	sg.offset = offset_in_page(data);
-	sg.length = data_len + WEP_ICV_LEN;
+	sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
 	crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length);
 
 	crc = cpu_to_le32(~crc32_le(~0, data, data_len));
diff --git a/net/sctp/auth.c b/net/sctp/auth.c
index 7818107..cbd64b2 100644
--- a/net/sctp/auth.c
+++ b/net/sctp/auth.c
@@ -726,7 +726,8 @@ void sctp_auth_calculate_hmac(const struct sctp_association *asoc,
 
 	/* set up scatter list */
 	end = skb_tail_pointer(skb);
-	sg.page = virt_to_page(auth);
+	sg_init_table(&sg, 1);
+	sg_set_page(&sg, virt_to_page(auth));
 	sg.offset = (unsigned long)(auth) % PAGE_SIZE;
 	sg.length = end - (unsigned char *)auth;
 
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index f983a36..d5a9785 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1513,7 +1513,8 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
 		struct hash_desc desc;
 
 		/* Sign the message.  */
-		sg.page = virt_to_page(&cookie->c);
+		sg_init_table(&sg, 1);
+		sg_set_page(&sg, virt_to_page(&cookie->c));
 		sg.offset = (unsigned long)(&cookie->c) % PAGE_SIZE;
 		sg.length = bodysize;
 		keylen = SCTP_SECRET_SIZE;
@@ -1585,7 +1586,8 @@ struct sctp_association *sctp_unpack_cookie(
 
 	/* Check the signature.  */
 	keylen = SCTP_SECRET_SIZE;
-	sg.page = virt_to_page(bear_cookie);
+	sg_init_table(&sg, 1);
+	sg_set_page(&sg, virt_to_page(bear_cookie));
 	sg.offset = (unsigned long)(bear_cookie) % PAGE_SIZE;
 	sg.length = bodysize;
 	key = (char *)ep->secret_key[ep->current_key];
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index bfb6a29..32be431 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -197,9 +197,9 @@ encryptor(struct scatterlist *sg, void *data)
 		int i = (page_pos + outbuf->page_base) >> PAGE_CACHE_SHIFT;
 		in_page = desc->pages[i];
 	} else {
-		in_page = sg->page;
+		in_page = sg_page(sg);
 	}
-	desc->infrags[desc->fragno].page = in_page;
+	sg_set_page(&desc->infrags[desc->fragno], in_page);
 	desc->fragno++;
 	desc->fraglen += sg->length;
 	desc->pos += sg->length;
@@ -215,11 +215,11 @@ encryptor(struct scatterlist *sg, void *data)
 	if (ret)
 		return ret;
 	if (fraglen) {
-		desc->outfrags[0].page = sg->page;
+		sg_set_page(&desc->outfrags[0], sg_page(sg));
 		desc->outfrags[0].offset = sg->offset + sg->length - fraglen;
 		desc->outfrags[0].length = fraglen;
 		desc->infrags[0] = desc->outfrags[0];
-		desc->infrags[0].page = in_page;
+		sg_set_page(&desc->infrags[0], in_page);
 		desc->fragno = 1;
 		desc->fraglen = fraglen;
 	} else {
@@ -287,7 +287,7 @@ decryptor(struct scatterlist *sg, void *data)
 	if (ret)
 		return ret;
 	if (fraglen) {
-		desc->frags[0].page = sg->page;
+		sg_set_page(&desc->frags[0], sg_page(sg));
 		desc->frags[0].offset = sg->offset + sg->length - fraglen;
 		desc->frags[0].length = fraglen;
 		desc->fragno = 1;
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 6a59180..3d1f7cd 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -1059,7 +1059,7 @@ xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len,
 		do {
 			if (thislen > page_len)
 				thislen = page_len;
-			sg->page = buf->pages[i];
+			sg_set_page(sg, buf->pages[i]);
 			sg->offset = page_offset;
 			sg->length = thislen;
 			ret = actor(sg, data);
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index 5ced62c..fb2220a 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -552,7 +552,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
 		if (copy > len)
 			copy = len;
 
-		sg.page = virt_to_page(skb->data + offset);
+		sg_set_page(&sg, virt_to_page(skb->data + offset));
 		sg.offset = (unsigned long)(skb->data + offset) % PAGE_SIZE;
 		sg.length = copy;
 
@@ -577,7 +577,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
 			if (copy > len)
 				copy = len;
 
-			sg.page = frag->page;
+			sg_set_page(&sg, frag->page);
 			sg.offset = frag->page_offset + offset-start;
 			sg.length = copy;
 

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 13:23                                                           ` Jens Axboe
@ 2007-10-18 13:32                                                             ` Mark Lord
  2007-10-18 13:34                                                               ` Jens Axboe
  0 siblings, 1 reply; 151+ messages in thread
From: Mark Lord @ 2007-10-18 13:32 UTC (permalink / raw)
  To: Jens Axboe
  Cc: Jeff Garzik, Linus Torvalds, David Miller, fujita.tomonori, mingo,
	linux-kernel, alan, tomof

Jens Axboe wrote:
> On Thu, Oct 18 2007, Mark Lord wrote:
>> Jens Axboe wrote:
>>> On Thu, Oct 18 2007, Jeff Garzik wrote:
>>>> Mark Lord wrote:
>>>>> Okay, mine is dying with EIP at blk_rq_map_sg+0xcb/0x160.
>>>>> Screen photo is at http://rtr.ca/recent/2.6.23-git12-crash.jpg,
>>>>> but the top was cut off (isn't there a new config option or patch
>>>>> to do double-columns or scrollback or something ???.
>>>> Is this a sata_mv box?  If so, could you try this patch?
>>> If anything, that shrinks the size of the resulting request. Did this
>>> patch make any difference to you?
>> Not a sata_mv box, so no point here.
> 
> Can you try the big patch I just posted?

I'll hunt for it and try it, but your earlier little patch already works fine.

Cheers


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 13:32                                                             ` Mark Lord
@ 2007-10-18 13:34                                                               ` Jens Axboe
  2007-10-18 13:59                                                                 ` Mark Lord
  0 siblings, 1 reply; 151+ messages in thread
From: Jens Axboe @ 2007-10-18 13:34 UTC (permalink / raw)
  To: Mark Lord
  Cc: Jeff Garzik, Linus Torvalds, David Miller, fujita.tomonori, mingo,
	linux-kernel, alan, tomof

On Thu, Oct 18 2007, Mark Lord wrote:
> Jens Axboe wrote:
>> On Thu, Oct 18 2007, Mark Lord wrote:
>>> Jens Axboe wrote:
>>>> On Thu, Oct 18 2007, Jeff Garzik wrote:
>>>>> Mark Lord wrote:
>>>>>> Okay, mine is dying with EIP at blk_rq_map_sg+0xcb/0x160.
>>>>>> Screen photo is at http://rtr.ca/recent/2.6.23-git12-crash.jpg,
>>>>>> but the top was cut off (isn't there a new config option or patch
>>>>>> to do double-columns or scrollback or something ???.
>>>>> Is this a sata_mv box?  If so, could you try this patch?
>>>> If anything, that shrinks the size of the resulting request. Did this
>>>> patch make any difference to you?
>>> Not a sata_mv box, so no point here.
>> Can you try the big patch I just posted?
>
> I'll hunt for it and try it, but your earlier little patch already works 
> fine.

I'll send it privately.

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 13:32                                                         ` Jens Axboe
@ 2007-10-18 13:49                                                           ` Benny Halevy
  2007-10-18 13:55                                                             ` Jens Axboe
  2007-10-18 13:51                                                           ` Mark Lord
  1 sibling, 1 reply; 151+ messages in thread
From: Benny Halevy @ 2007-10-18 13:49 UTC (permalink / raw)
  To: Jens Axboe
  Cc: David Miller, torvalds, fujita.tomonori, mingo, linux-kernel,
	jgarzik, alan, tomof

On Oct. 18, 2007, 15:32 +0200, Jens Axboe <jens.axboe@oracle.com> wrote:
>  static inline struct scatterlist *sg_next(struct scatterlist *sg)
>  {
> -	sg++;
> -
> -	if (unlikely(sg_is_chain(sg)))
> +#ifdef CONFIG_DEBUG_SG
> +	BUG_ON(sg->sg_magic != SG_MAGIC);
> +#endif
> +	if (sg_is_last(sg))
> +		sg = NULL;
> +	else if (sg_is_chain(sg))
>  		sg = sg_chain_ptr(sg);
> +	else
> +		sg++;
>  

Jens, again, please correct me if I'm wrong, but when sg points at the
entry right before a chain entry this implementation of sg_next will
return a pointer to the chain entry here, which I believe it must not.

>  	return sg;
>  }
> 

here's how I think sg_next should be implemented:

  */
 static inline struct scatterlist *sg_next(struct scatterlist *sg)
 {
+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(sg->sg_magic != SG_MAGIC);
+#endif
+	if (sg_is_last(sg))
+		return NULL;
+
 	sg++;
 
 	if (unlikely(sg_is_chain(sg)))
 		sg = sg_chain_ptr(sg);
 
 	return sg;
 }

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 13:32                                                         ` Jens Axboe
  2007-10-18 13:49                                                           ` Benny Halevy
@ 2007-10-18 13:51                                                           ` Mark Lord
  2007-10-18 13:58                                                             ` Jens Axboe
  1 sibling, 1 reply; 151+ messages in thread
From: Mark Lord @ 2007-10-18 13:51 UTC (permalink / raw)
  To: Jens Axboe
  Cc: David Miller, torvalds, fujita.tomonori, mingo, linux-kernel,
	jgarzik, alan, tomof

Jens wrote:
> OK, I think that covers every arch out there. I haven't been able to
> compile any of them, but it's mostly search'n replace operations. I hope
> nothing is missing linux/scatterlist.h includes...

Patch fails on drivers/scsi/scsi_lib.c.

I replaced that part of the patch with this updated portion instead:



--- a/drivers/scsi/scsi_lib.c	2007-10-18 09:35:28.000000000 -0400
+++ b/drivers/scsi/scsi_lib.c	2007-10-18 09:46:47.000000000 -0400
@@ -295,7 +295,7 @@
 	int i, err, nr_vecs = 0;
 
 	for_each_sg(sgl, sg, nsegs, i) {
-		page = sg->page;
+		page = sg_page(sg);
 		off = sg->offset;
 		len = sg->length;
  		data_len += len;
@@ -764,6 +764,8 @@
 		if (unlikely(!sgl))
 			goto enomem;
 
+		sg_init_table(sgl, sgp->size);
+
 		/*
 		 * first loop through, set initial index and return value
 		 */
@@ -779,6 +781,13 @@
 			sg_chain(prev, SCSI_MAX_SG_SEGMENTS, sgl);
 
 		/*
+		 * if we have nothing left, mark the last segment as
+		 * end-of-list
+		 */
+		if (!left)
+			sg_mark_end(sgl, this);
+
+		/*
 		 * don't allow subsequent mempool allocs to sleep, it would
 		 * violate the mempool principle.
 		 */
@@ -2351,7 +2360,7 @@
 	*offset = *offset - len_complete + sg->offset;
 
 	/* Assumption: contiguous pages can be accessed as "page + i" */
-	page = nth_page(sg->page, (*offset >> PAGE_SHIFT));
+	page = nth_page(sg_page(sg), (*offset >> PAGE_SHIFT));
 	*offset &= ~PAGE_MASK;
 
 	/* Bytes in this sg-entry from *offset to the end of the page */

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 13:49                                                           ` Benny Halevy
@ 2007-10-18 13:55                                                             ` Jens Axboe
  0 siblings, 0 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-18 13:55 UTC (permalink / raw)
  To: Benny Halevy
  Cc: David Miller, torvalds, fujita.tomonori, mingo, linux-kernel,
	jgarzik, alan, tomof

On Thu, Oct 18 2007, Benny Halevy wrote:
> On Oct. 18, 2007, 15:32 +0200, Jens Axboe <jens.axboe@oracle.com> wrote:
> >  static inline struct scatterlist *sg_next(struct scatterlist *sg)
> >  {
> > -	sg++;
> > -
> > -	if (unlikely(sg_is_chain(sg)))
> > +#ifdef CONFIG_DEBUG_SG
> > +	BUG_ON(sg->sg_magic != SG_MAGIC);
> > +#endif
> > +	if (sg_is_last(sg))
> > +		sg = NULL;
> > +	else if (sg_is_chain(sg))
> >  		sg = sg_chain_ptr(sg);
> > +	else
> > +		sg++;
> >  
> 
> Jens, again, please correct me if I'm wrong, but when sg points at the
> entry right before a chain entry this implementation of sg_next will
> return a pointer to the chain entry here, which I believe it must not.
> 
> >  	return sg;
> >  }
> > 
> 
> here's how I think sg_next should be implemented:
> 
>   */
>  static inline struct scatterlist *sg_next(struct scatterlist *sg)
>  {
> +#ifdef CONFIG_DEBUG_SG
> +	BUG_ON(sg->sg_magic != SG_MAGIC);
> +#endif
> +	if (sg_is_last(sg))
> +		return NULL;
> +
>  	sg++;
>  
>  	if (unlikely(sg_is_chain(sg)))
>  		sg = sg_chain_ptr(sg);
>  
>  	return sg;
>  }

Yep, thanks for catching that!

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 12:58                                                       ` Benny Halevy
@ 2007-10-18 13:56                                                         ` Jens Axboe
  2007-10-18 14:05                                                           ` Jens Axboe
  0 siblings, 1 reply; 151+ messages in thread
From: Jens Axboe @ 2007-10-18 13:56 UTC (permalink / raw)
  To: Benny Halevy
  Cc: David Miller, torvalds, fujita.tomonori, mingo, linux-kernel,
	jgarzik, alan, tomof

On Thu, Oct 18 2007, Benny Halevy wrote:
> >  	return sg;
> >  }
> > @@ -83,6 +96,9 @@ static inline struct scatterlist *sg_last(struct scatterlist *sgl,
> >  		ret = sg;
> >  
> >  #endif
> > +#ifdef CONFIG_DEBUG_SG
> > +	BUG_ON(sgl[0].sg_magic != SG_MAGIC);
> 
> can it also do BUG_ON(!sg_is_last(sg))?

That would make sense, definitely. I'll add that.

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 13:51                                                           ` Mark Lord
@ 2007-10-18 13:58                                                             ` Jens Axboe
  2007-10-18 14:03                                                               ` Mark Lord
  2007-10-18 14:10                                                               ` Mark Lord
  0 siblings, 2 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-18 13:58 UTC (permalink / raw)
  To: Mark Lord
  Cc: David Miller, torvalds, fujita.tomonori, mingo, linux-kernel,
	jgarzik, alan, tomof

On Thu, Oct 18 2007, Mark Lord wrote:
> Jens wrote:
>> OK, I think that covers every arch out there. I haven't been able to
>> compile any of them, but it's mostly search'n replace operations. I hope
>> nothing is missing linux/scatterlist.h includes...
>
> Patch fails on drivers/scsi/scsi_lib.c.
>
> I replaced that part of the patch with this updated portion instead:

Hmm, what are you applying against? Must be a clean tree, throw away any
patches that you already applied in this thread.

Updated below.

diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index e1c4707..094a95e 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -465,7 +465,7 @@ EXPORT_SYMBOL(pci_free_consistent);
    Write dma_length of each leader with the combined lengths of
    the mergable followers.  */
 
-#define SG_ENT_VIRT_ADDRESS(SG) (page_address((SG)->page) + (SG)->offset)
+#define SG_ENT_VIRT_ADDRESS(SG) (page_address(sg_page((SG)) + (SG)->offset))
 #define SG_ENT_PHYS_ADDRESS(SG) __pa(SG_ENT_VIRT_ADDRESS(SG))
 
 static void
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 44ab0da..9d371e4 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -442,7 +442,7 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 	BUG_ON(dir == DMA_NONE);
 
 	for (i = 0; i < nents; i++, sg++) {
-		struct page *page = sg->page;
+		struct page *page = sg_page(sg);
 		unsigned int offset = sg->offset;
 		unsigned int length = sg->length;
 		void *ptr = page_address(page) + offset;
diff --git a/arch/blackfin/kernel/dma-mapping.c b/arch/blackfin/kernel/dma-mapping.c
index 94d7b11..dbf7222 100644
--- a/arch/blackfin/kernel/dma-mapping.c
+++ b/arch/blackfin/kernel/dma-mapping.c
@@ -160,7 +160,7 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 	BUG_ON(direction == DMA_NONE);
 
 	for (i = 0; i < nents; i++, sg++) {
-		sg->dma_address = (dma_addr_t)(page_address(sg->page) +
+		sg->dma_address = (dma_addr_t)(page_address(sg_page(sg)) +
 					sg->offset);
 
 		invalidate_dcache_range(sg_dma_address(sg),
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index 3c95f41..0b74c63 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -246,7 +246,7 @@ static int reserve_sba_gart = 1;
 static SBA_INLINE void sba_mark_invalid(struct ioc *, dma_addr_t, size_t);
 static SBA_INLINE void sba_free_range(struct ioc *, dma_addr_t, size_t);
 
-#define sba_sg_address(sg)	(page_address((sg)->page) + (sg)->offset)
+#define sba_sg_address(sg)	(page_address(sg_page((sg)) + (sg)->offset))
 
 #ifdef FULL_VALID_PDIR
 static u64 prefetch_spill_page;
diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c
index a3a558a..7f1794f 100644
--- a/arch/ia64/hp/sim/simscsi.c
+++ b/arch/ia64/hp/sim/simscsi.c
@@ -131,7 +131,7 @@ simscsi_sg_readwrite (struct scsi_cmnd *sc, int mode, unsigned long offset)
 	stat.fd = desc[sc->device->id];
 
 	scsi_for_each_sg(sc, sl, scsi_sg_count(sc), i) {
-		req.addr = __pa(page_address(sl->page) + sl->offset);
+		req.addr = __pa(page_address(sg_page(sl)) + sl->offset);
 		req.len  = sl->length;
 		if (DBG)
 			printk("simscsi_sg_%s @ %lx (off %lx) use_sg=%d len=%d\n",
@@ -212,7 +212,7 @@ static void simscsi_fillresult(struct scsi_cmnd *sc, char *buf, unsigned len)
 		if (!len)
 			break;
 		thislen = min(len, slp->length);
-		memcpy(page_address(slp->page) + slp->offset, buf, thislen);
+		memcpy(page_address(sg_page(slp)) + slp->offset, buf, thislen);
 		len -= thislen;
 	}
 }
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index ecd8a52..6048eaf 100644
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -16,7 +16,7 @@
 #include <asm/sn/pcidev.h>
 #include <asm/sn/sn_sal.h>
 
-#define SG_ENT_VIRT_ADDRESS(sg)	(page_address((sg)->page) + (sg)->offset)
+#define SG_ENT_VIRT_ADDRESS(sg)	(page_address(sg_page((sg)) + (sg)->offset))
 #define SG_ENT_PHYS_ADDRESS(SG)	virt_to_phys(SG_ENT_VIRT_ADDRESS(SG))
 
 /**
diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c
index 9d4e4b5..b2d620b 100644
--- a/arch/m68k/kernel/dma.c
+++ b/arch/m68k/kernel/dma.c
@@ -121,7 +121,7 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 	int i;
 
 	for (i = 0; i < nents; sg++, i++) {
-		sg->dma_address = page_to_phys(sg->page) + sg->offset;
+		sg->dma_address = page_to_phys(sg_page(sg)) + sg->offset;
 		dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);
 	}
 	return nents;
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 98b5e5b..4aa143b 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -165,7 +165,7 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 	for (i = 0; i < nents; i++, sg++) {
 		unsigned long addr;
 
-		addr = (unsigned long) page_address(sg->page);
+		addr = (unsigned long) page_address(sg_page(sg));
 		if (!plat_device_is_coherent(dev) && addr)
 			__dma_sync(addr + sg->offset, sg->length, direction);
 		sg->dma_address = plat_map_dma_mem(dev,
@@ -223,7 +223,7 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
 	for (i = 0; i < nhwentries; i++, sg++) {
 		if (!plat_device_is_coherent(dev) &&
 		    direction != DMA_TO_DEVICE) {
-			addr = (unsigned long) page_address(sg->page);
+			addr = (unsigned long) page_address(sg_page(sg));
 			if (addr)
 				__dma_sync(addr + sg->offset, sg->length,
 				           direction);
@@ -304,7 +304,7 @@ void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
 	/* Make sure that gcc doesn't leave the empty loop body.  */
 	for (i = 0; i < nelems; i++, sg++) {
 		if (cpu_is_noncoherent_r10000(dev))
-			__dma_sync((unsigned long)page_address(sg->page),
+			__dma_sync((unsigned long)page_address(sg_page(sg)),
 			           sg->length, direction);
 		plat_unmap_dma_mem(sg->dma_address);
 	}
@@ -322,7 +322,7 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nele
 	/* Make sure that gcc doesn't leave the empty loop body.  */
 	for (i = 0; i < nelems; i++, sg++) {
 		if (!plat_device_is_coherent(dev))
-			__dma_sync((unsigned long)page_address(sg->page),
+			__dma_sync((unsigned long)page_address(sg_page(sg)),
 			           sg->length, direction);
 		plat_unmap_dma_mem(sg->dma_address);
 	}
diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
index 9001104..5d0aa90 100644
--- a/arch/powerpc/kernel/dma_64.c
+++ b/arch/powerpc/kernel/dma_64.c
@@ -161,7 +161,7 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
 	int i;
 
 	for_each_sg(sgl, sg, nents, i) {
-		sg->dma_address = (page_to_phys(sg->page) + sg->offset) |
+		sg->dma_address = (page_to_phys(sg_page(sg)) + sg->offset) |
 			dma_direct_offset;
 		sg->dma_length = sg->length;
 	}
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index 289d7e9..3d0e71b 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -102,7 +102,7 @@ static int ibmebus_map_sg(struct device *dev,
 	int i;
 
 	for_each_sg(sgl, sg, nents, i) {
-		sg->dma_address = (dma_addr_t)page_address(sg->page)
+		sg->dma_address = (dma_addr_t)page_address(sg_page(sg))
 			+ sg->offset;
 		sg->dma_length = sg->length;
 	}
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 306a6f7..47d745a 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -307,7 +307,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
 			continue;
 		}
 		/* Allocate iommu entries for that segment */
-		vaddr = (unsigned long)page_address(s->page) + s->offset;
+		vaddr = (unsigned long)page_address(sg_page(s)) + s->offset;
 		npages = iommu_num_pages(vaddr, slen);
 		entry = iommu_range_alloc(tbl, npages, &handle, mask >> IOMMU_PAGE_SHIFT, 0);
 
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 07e64b4..e8202b6 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -629,7 +629,7 @@ static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sgl,
 
 	for_each_sg(sgl, sg, nents, i) {
 		int result = ps3_dma_map(dev->d_region,
-			page_to_phys(sg->page) + sg->offset, sg->length,
+			page_to_phys(sg_page(sg)) + sg->offset, sg->length,
 					 &sg->dma_address, 0);
 
 		if (result) {
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 9c3ed88..abc4470 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -727,9 +727,9 @@ int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents,
 	BUG_ON(direction == PCI_DMA_NONE);
 	/* IIep is write-through, not flushing. */
 	for_each_sg(sgl, sg, nents, n) {
-		BUG_ON(page_address(sg->page) == NULL);
+		BUG_ON(page_address(sg_page(sg)) == NULL);
 		sg->dvma_address =
-			virt_to_phys(page_address(sg->page)) + sg->offset;
+			virt_to_phys(page_address(sg_page(sg))) + sg->offset;
 		sg->dvma_length = sg->length;
 	}
 	return nents;
@@ -748,9 +748,9 @@ void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents,
 	BUG_ON(direction == PCI_DMA_NONE);
 	if (direction != PCI_DMA_TODEVICE) {
 		for_each_sg(sgl, sg, nents, n) {
-			BUG_ON(page_address(sg->page) == NULL);
+			BUG_ON(page_address(sg_page(sg)) == NULL);
 			mmu_inval_dma_area(
-			    (unsigned long) page_address(sg->page),
+			    (unsigned long) page_address(sg_page(sg)),
 			    (sg->length + PAGE_SIZE-1) & PAGE_MASK);
 		}
 	}
@@ -798,9 +798,9 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sgl, int
 	BUG_ON(direction == PCI_DMA_NONE);
 	if (direction != PCI_DMA_TODEVICE) {
 		for_each_sg(sgl, sg, nents, n) {
-			BUG_ON(page_address(sg->page) == NULL);
+			BUG_ON(page_address(sg_page(sg)) == NULL);
 			mmu_inval_dma_area(
-			    (unsigned long) page_address(sg->page),
+			    (unsigned long) page_address(sg_page(sg)),
 			    (sg->length + PAGE_SIZE-1) & PAGE_MASK);
 		}
 	}
@@ -814,9 +814,9 @@ void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sgl,
 	BUG_ON(direction == PCI_DMA_NONE);
 	if (direction != PCI_DMA_TODEVICE) {
 		for_each_sg(sgl, sg, nents, n) {
-			BUG_ON(page_address(sg->page) == NULL);
+			BUG_ON(page_address(sg_page(sg)) == NULL);
 			mmu_inval_dma_area(
-			    (unsigned long) page_address(sg->page),
+			    (unsigned long) page_address(sg_page(sg)),
 			    (sg->length + PAGE_SIZE-1) & PAGE_MASK);
 		}
 	}
diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c
index 375b4db..0f2ad57 100644
--- a/arch/sparc/mm/io-unit.c
+++ b/arch/sparc/mm/io-unit.c
@@ -144,7 +144,7 @@ static void iounit_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus
 	spin_lock_irqsave(&iounit->lock, flags);
 	while (sz != 0) {
 		--sz;
-		sg->dvma_address = iounit_get_area(iounit, (unsigned long)page_address(sg->page) + sg->offset, sg->length);
+		sg->dvma_address = iounit_get_area(iounit, (unsigned long)page_address(sg_page(sg)) + sg->offset, sg->length);
 		sg->dvma_length = sg->length;
 		sg = sg_next(sg);
 	}
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
index 283656d..4b93427 100644
--- a/arch/sparc/mm/iommu.c
+++ b/arch/sparc/mm/iommu.c
@@ -238,7 +238,7 @@ static void iommu_get_scsi_sgl_noflush(struct scatterlist *sg, int sz, struct sb
 	while (sz != 0) {
 		--sz;
 		n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
-		sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset;
+		sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset;
 		sg->dvma_length = (__u32) sg->length;
 		sg = sg_next(sg);
 	}
@@ -252,7 +252,7 @@ static void iommu_get_scsi_sgl_gflush(struct scatterlist *sg, int sz, struct sbu
 	while (sz != 0) {
 		--sz;
 		n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
-		sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset;
+		sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset;
 		sg->dvma_length = (__u32) sg->length;
 		sg = sg_next(sg);
 	}
@@ -273,7 +273,7 @@ static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbu
 		 * XXX Is this a good assumption?
 		 * XXX What if someone else unmaps it here and races us?
 		 */
-		if ((page = (unsigned long) page_address(sg->page)) != 0) {
+		if ((page = (unsigned long) page_address(sg_page(sg))) != 0) {
 			for (i = 0; i < n; i++) {
 				if (page != oldpage) {	/* Already flushed? */
 					flush_page_for_dma(page);
@@ -283,7 +283,7 @@ static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbu
 			}
 		}
 
-		sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset;
+		sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset;
 		sg->dvma_length = (__u32) sg->length;
 		sg = sg_next(sg);
 	}
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
index ee6708f..f172dbe 100644
--- a/arch/sparc/mm/sun4c.c
+++ b/arch/sparc/mm/sun4c.c
@@ -1228,7 +1228,7 @@ static void sun4c_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *
 {
 	while (sz != 0) {
 		--sz;
-		sg->dvma_address = (__u32)sun4c_lockarea(page_address(sg->page) + sg->offset, sg->length);
+		sg->dvma_address = (__u32)sun4c_lockarea(page_address(sg_page(sg)) + sg->offset, sg->length);
 		sg->dvma_length = sg->length;
 		sg = sg_next(sg);
 	}
diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c
index 29af777..73852a2 100644
--- a/arch/sparc64/kernel/iommu.c
+++ b/arch/sparc64/kernel/iommu.c
@@ -473,7 +473,7 @@ static void dma_4u_unmap_single(struct device *dev, dma_addr_t bus_addr,
 }
 
 #define SG_ENT_PHYS_ADDRESS(SG)	\
-	(__pa(page_address((SG)->page)) + (SG)->offset)
+	(__pa(page_address(sg_page(SG))) + (SG)->offset)
 
 static void fill_sg(iopte_t *iopte, struct scatterlist *sg,
 		    int nused, int nelems,
@@ -566,7 +566,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
 	if (nelems == 1) {
 		sglist->dma_address =
 			dma_4u_map_single(dev,
-					  (page_address(sglist->page) +
+					  (page_address(sg_page(sglist)) +
 					   sglist->offset),
 					  sglist->length, direction);
 		if (unlikely(sglist->dma_address == DMA_ERROR_CODE))
diff --git a/arch/sparc64/kernel/iommu_common.c b/arch/sparc64/kernel/iommu_common.c
index d7ca900..ec863e0 100644
--- a/arch/sparc64/kernel/iommu_common.c
+++ b/arch/sparc64/kernel/iommu_common.c
@@ -73,7 +73,7 @@ static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg,
 
 	daddr = dma_sg->dma_address;
 	sglen = sg->length;
-	sgaddr = (unsigned long) (page_address(sg->page) + sg->offset);
+	sgaddr = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
 	while (dlen > 0) {
 		unsigned long paddr;
 
@@ -123,7 +123,7 @@ static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg,
 		sg = sg_next(sg);
 		if (--nents <= 0)
 			break;
-		sgaddr = (unsigned long) (page_address(sg->page) + sg->offset);
+		sgaddr = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
 		sglen = sg->length;
 	}
 	if (dlen < 0) {
@@ -191,7 +191,7 @@ void verify_sglist(struct scatterlist *sglist, int nents, iopte_t *iopte, int np
 			printk("sg(%d): page_addr(%p) off(%x) length(%x) "
 			       "dma_address[%016x] dma_length[%016x]\n",
 			       i,
-			       page_address(sg->page), sg->offset,
+			       page_address(sg_page(sg)), sg->offset,
 			       sg->length,
 			       sg->dma_address, sg->dma_length);
 		}
@@ -207,15 +207,15 @@ unsigned long prepare_sg(struct scatterlist *sg, int nents)
 	unsigned long prev;
 	u32 dent_addr, dent_len;
 
-	prev  = (unsigned long) (page_address(sg->page) + sg->offset);
+	prev  = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
 	prev += (unsigned long) (dent_len = sg->length);
-	dent_addr = (u32) ((unsigned long)(page_address(sg->page) + sg->offset)
+	dent_addr = (u32) ((unsigned long)(page_address(sg_page(sg)) + sg->offset)
 			   & (IO_PAGE_SIZE - 1UL));
 	while (--nents) {
 		unsigned long addr;
 
 		sg = sg_next(sg);
-		addr = (unsigned long) (page_address(sg->page) + sg->offset);
+		addr = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
 		if (! VCONTIG(prev, addr)) {
 			dma_sg->dma_address = dent_addr;
 			dma_sg->dma_length = dent_len;
diff --git a/arch/sparc64/kernel/ldc.c b/arch/sparc64/kernel/ldc.c
index 85a2be0..c8313cb 100644
--- a/arch/sparc64/kernel/ldc.c
+++ b/arch/sparc64/kernel/ldc.c
@@ -2057,7 +2057,7 @@ static void fill_cookies(struct cookie_state *sp, unsigned long pa,
 
 static int sg_count_one(struct scatterlist *sg)
 {
-	unsigned long base = page_to_pfn(sg->page) << PAGE_SHIFT;
+	unsigned long base = page_to_pfn(sg_page(sg)) << PAGE_SHIFT;
 	long len = sg->length;
 
 	if ((sg->offset | len) & (8UL - 1))
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index fe46ace..5324a34 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -366,7 +366,7 @@ static void dma_4v_unmap_single(struct device *dev, dma_addr_t bus_addr,
 }
 
 #define SG_ENT_PHYS_ADDRESS(SG)	\
-	(__pa(page_address((SG)->page)) + (SG)->offset)
+	(__pa(page_address(sg_page(SG))) + (SG)->offset)
 
 static long fill_sg(long entry, struct device *dev,
 		    struct scatterlist *sg,
@@ -478,7 +478,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
 	if (nelems == 1) {
 		sglist->dma_address =
 			dma_4v_map_single(dev,
-					  (page_address(sglist->page) +
+					  (page_address(sg_page(sglist)) +
 					   sglist->offset),
 					  sglist->length, direction);
 		if (unlikely(sglist->dma_address == DMA_ERROR_CODE))
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 25b248a..3a8cd3d 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -1115,7 +1115,7 @@ static void do_ubd_request(struct request_queue *q)
 			}
 			prepare_request(req, io_req,
 					(unsigned long long) req->sector << 9,
-					sg->offset, sg->length, sg->page);
+					sg->offset, sg->length, sg_page(sg));
 
 			last_sectors = sg->length >> 9;
 			n = os_write_file(thread_fd, &io_req,
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 5098f58..c9f0eb0 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -411,8 +411,10 @@ static int calgary_nontranslate_map_sg(struct device* dev,
 	int i;
 
 	for_each_sg(sg, s, nelems, i) {
-		BUG_ON(!s->page);
-		s->dma_address = virt_to_bus(page_address(s->page) +s->offset);
+		struct page *p = sg_page(s);
+
+		BUG_ON(!p);
+		s->dma_address = virt_to_bus(page_address(p) + s->offset);
 		s->dma_length = s->length;
 	}
 	return nelems;
@@ -432,9 +434,11 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
 		return calgary_nontranslate_map_sg(dev, sg, nelems, direction);
 
 	for_each_sg(sg, s, nelems, i) {
-		BUG_ON(!s->page);
+		struct page *p = sg_page(s);
+
+		BUG_ON(!p);
 
-		vaddr = (unsigned long)page_address(s->page) + s->offset;
+		vaddr = (unsigned long)page_address(p) + s->offset;
 		npages = num_dma_pages(vaddr, s->length);
 
 		entry = iommu_range_alloc(tbl, npages);
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index 5cdfab6..daaf636 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -302,7 +302,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
 #endif
 
 	for_each_sg(sg, s, nents, i) {
-		unsigned long addr = page_to_phys(s->page) + s->offset; 
+		unsigned long addr = page_to_phys(sg_page(s)) + s->offset; 
 		if (nonforced_iommu(dev, addr, s->length)) { 
 			addr = dma_map_area(dev, addr, s->length, dir);
 			if (addr == bad_dma_address) { 
@@ -397,7 +397,7 @@ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 	start_sg = sgmap = sg;
 	ps = NULL; /* shut up gcc */
 	for_each_sg(sg, s, nents, i) {
-		dma_addr_t addr = page_to_phys(s->page) + s->offset;
+		dma_addr_t addr = page_to_phys(sg_page(s)) + s->offset;
 		s->dma_address = addr;
 		BUG_ON(s->length == 0); 
 
diff --git a/arch/x86/kernel/pci-nommu_64.c b/arch/x86/kernel/pci-nommu_64.c
index e85d436..d64a4a5 100644
--- a/arch/x86/kernel/pci-nommu_64.c
+++ b/arch/x86/kernel/pci-nommu_64.c
@@ -62,8 +62,8 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
 	int i;
 
 	for_each_sg(sg, s, nents, i) {
-		BUG_ON(!s->page);
-		s->dma_address = virt_to_bus(page_address(s->page) +s->offset);
+		BUG_ON(!sg_page(s));
+		s->dma_address = virt_to_bus(page_address(sg_page(s)) +s->offset);
 		if (!check_addr("map_sg", hwdev, s->dma_address, s->length))
 			return 0;
 		s->dma_length = s->length;
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 3935469..ce9754f 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -1354,8 +1354,9 @@ new_segment:
 			else
 				sg = sg_next(sg);
 
-			memset(sg, 0, sizeof(*sg));
-			sg->page = bvec->bv_page;
+			sg_dma_len(sg) = 0;
+			sg_dma_address(sg) = 0;
+			sg_set_page(sg, bvec->bv_page);
 			sg->length = nbytes;
 			sg->offset = bvec->bv_offset;
 			nsegs++;
diff --git a/crypto/digest.c b/crypto/digest.c
index e56de67..8871dec 100644
--- a/crypto/digest.c
+++ b/crypto/digest.c
@@ -41,7 +41,7 @@ static int update2(struct hash_desc *desc,
 		return 0;
 
 	for (;;) {
-		struct page *pg = sg->page;
+		struct page *pg = sg_page(sg);
 		unsigned int offset = sg->offset;
 		unsigned int l = sg->length;
 
diff --git a/crypto/hmac.c b/crypto/hmac.c
index 8802fb6..e4eb6ac 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -159,7 +159,8 @@ static int hmac_digest(struct hash_desc *pdesc, struct scatterlist *sg,
 	desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP;
 
 	sg_set_buf(sg1, ipad, bs);
-	sg1[1].page = (void *)sg;
+
+	sg_set_page(&sg[1], (void *) sg);
 	sg1[1].length = 0;
 	sg_set_buf(sg2, opad, bs + ds);
 
diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c
index d6852c3..b9bbda0 100644
--- a/crypto/scatterwalk.c
+++ b/crypto/scatterwalk.c
@@ -54,7 +54,7 @@ static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
 	if (out) {
 		struct page *page;
 
-		page = walk->sg->page + ((walk->offset - 1) >> PAGE_SHIFT);
+		page = sg_page(walk->sg) + ((walk->offset - 1) >> PAGE_SHIFT);
 		flush_dcache_page(page);
 	}
 
diff --git a/crypto/scatterwalk.h b/crypto/scatterwalk.h
index 9c73e37..87ed681 100644
--- a/crypto/scatterwalk.h
+++ b/crypto/scatterwalk.h
@@ -22,13 +22,13 @@
 
 static inline struct scatterlist *scatterwalk_sg_next(struct scatterlist *sg)
 {
-	return (++sg)->length ? sg : (void *)sg->page;
+	return (++sg)->length ? sg : (void *) sg_page(sg);
 }
 
 static inline unsigned long scatterwalk_samebuf(struct scatter_walk *walk_in,
 						struct scatter_walk *walk_out)
 {
-	return !(((walk_in->sg->page - walk_out->sg->page) << PAGE_SHIFT) +
+	return !(((sg_page(walk_in->sg) - sg_page(walk_out->sg)) << PAGE_SHIFT) +
 		 (int)(walk_in->offset - walk_out->offset));
 }
 
@@ -60,7 +60,7 @@ static inline unsigned int scatterwalk_aligned(struct scatter_walk *walk,
 
 static inline struct page *scatterwalk_page(struct scatter_walk *walk)
 {
-	return walk->sg->page + (walk->offset >> PAGE_SHIFT);
+	return sg_page(walk->sg) + (walk->offset >> PAGE_SHIFT);
 }
 
 static inline void scatterwalk_unmap(void *vaddr, int out)
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 18d489c..d741c63 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -317,7 +317,7 @@ static void test_cipher(char *algo, int enc,
 				goto out;
 			}
 
-			q = kmap(sg[0].page) + sg[0].offset;
+			q = kmap(sg_page(&sg[0])) + sg[0].offset;
 			hexdump(q, cipher_tv[i].rlen);
 
 			printk("%s\n",
@@ -390,7 +390,7 @@ static void test_cipher(char *algo, int enc,
 			temp = 0;
 			for (k = 0; k < cipher_tv[i].np; k++) {
 				printk("page %u\n", k);
-				q = kmap(sg[k].page) + sg[k].offset;
+				q = kmap(sg_page(&sg[k])) + sg[k].offset;
 				hexdump(q, cipher_tv[i].tap[k]);
 				printk("%s\n",
 					memcmp(q, cipher_tv[i].result + temp,
diff --git a/crypto/xcbc.c b/crypto/xcbc.c
index 9f502b8..ac68f3b 100644
--- a/crypto/xcbc.c
+++ b/crypto/xcbc.c
@@ -120,7 +120,7 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc,
 
 	do {
 
-		struct page *pg = sg[i].page;
+		struct page *pg = sg_page(&sg[i]);
 		unsigned int offset = sg[i].offset;
 		unsigned int slen = sg[i].length;
 
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index bbaa545..b1fa70a 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4296,7 +4296,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
 		sg_last(sg, qc->orig_n_elem)->length += qc->pad_len;
 		if (pad_buf) {
 			struct scatterlist *psg = &qc->pad_sgent;
-			void *addr = kmap_atomic(psg->page, KM_IRQ0);
+			void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
 			memcpy(addr + psg->offset, pad_buf, qc->pad_len);
 			kunmap_atomic(addr, KM_IRQ0);
 		}
@@ -4686,11 +4686,11 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
 		 * data in this function or read data in ata_sg_clean.
 		 */
 		offset = lsg->offset + lsg->length - qc->pad_len;
-		psg->page = nth_page(lsg->page, offset >> PAGE_SHIFT);
+		sg_set_page(psg, nth_page(sg_page(lsg), offset >> PAGE_SHIFT));
 		psg->offset = offset_in_page(offset);
 
 		if (qc->tf.flags & ATA_TFLAG_WRITE) {
-			void *addr = kmap_atomic(psg->page, KM_IRQ0);
+			void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
 			memcpy(pad_buf, addr + psg->offset, qc->pad_len);
 			kunmap_atomic(addr, KM_IRQ0);
 		}
@@ -4836,7 +4836,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
 	if (qc->curbytes == qc->nbytes - qc->sect_size)
 		ap->hsm_task_state = HSM_ST_LAST;
 
-	page = qc->cursg->page;
+	page = sg_page(qc->cursg);
 	offset = qc->cursg->offset + qc->cursg_ofs;
 
 	/* get the current page and offset */
@@ -4988,7 +4988,7 @@ next_sg:
 
 	sg = qc->cursg;
 
-	page = sg->page;
+	page = sg_page(sg);
 	offset = sg->offset + qc->cursg_ofs;
 
 	/* get the current page and offset */
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 9fbb39c..5b758b9 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1544,7 +1544,7 @@ static unsigned int ata_scsi_rbuf_get(struct scsi_cmnd *cmd, u8 **buf_out)
 	struct scatterlist *sg = scsi_sglist(cmd);
 
 	if (sg) {
-		buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+		buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 		buflen = sg->length;
 	} else {
 		buf = NULL;
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 7c2cfde..5a6fe17 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -2610,7 +2610,7 @@ static void do_cciss_request(struct request_queue *q)
 	       (int)creq->nr_sectors);
 #endif				/* CCISS_DEBUG */
 
-	memset(tmp_sg, 0, sizeof(tmp_sg));
+	sg_init_table(tmp_sg, MAXSGENTRIES);
 	seg = blk_rq_map_sg(q, creq, tmp_sg);
 
 	/* get the DMA records for the setup */
@@ -2621,7 +2621,7 @@ static void do_cciss_request(struct request_queue *q)
 
 	for (i = 0; i < seg; i++) {
 		c->SG[i].Len = tmp_sg[i].length;
-		temp64.val = (__u64) pci_map_page(h->pdev, tmp_sg[i].page,
+		temp64.val = (__u64) pci_map_page(h->pdev, sg_page(&tmp_sg[i]),
 						  tmp_sg[i].offset,
 						  tmp_sg[i].length, dir);
 		c->SG[i].Addr.lower = temp64.val32.lower;
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index 568603d..efab27f 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -918,6 +918,7 @@ queue_next:
 DBGPX(
 	printk("sector=%d, nr_sectors=%d\n", creq->sector, creq->nr_sectors);
 );
+	sg_init_table(tmp_sg, SG_MAX);
 	seg = blk_rq_map_sg(q, creq, tmp_sg);
 
 	/* Now do all the DMA Mappings */
@@ -929,7 +930,7 @@ DBGPX(
 	{
 		c->req.sg[i].size = tmp_sg[i].length;
 		c->req.sg[i].addr = (__u32) pci_map_page(h->pci_dev,
-						 tmp_sg[i].page,
+						 sg_page(&tmp_sg[i]),
 						 tmp_sg[i].offset,
 						 tmp_sg[i].length, dir);
 	}
diff --git a/drivers/block/cryptoloop.c b/drivers/block/cryptoloop.c
index 4053503..1b58b01 100644
--- a/drivers/block/cryptoloop.c
+++ b/drivers/block/cryptoloop.c
@@ -26,6 +26,7 @@
 #include <linux/crypto.h>
 #include <linux/blkdev.h>
 #include <linux/loop.h>
+#include <linux/scatterlist.h>
 #include <asm/semaphore.h>
 #include <asm/uaccess.h>
 
@@ -119,14 +120,17 @@ cryptoloop_transfer(struct loop_device *lo, int cmd,
 		.tfm = tfm,
 		.flags = CRYPTO_TFM_REQ_MAY_SLEEP,
 	};
-	struct scatterlist sg_out = { NULL, };
-	struct scatterlist sg_in = { NULL, };
+	struct scatterlist sg_out;
+	struct scatterlist sg_in;
 
 	encdec_cbc_t encdecfunc;
 	struct page *in_page, *out_page;
 	unsigned in_offs, out_offs;
 	int err;
 
+	sg_init_table(&sg_out, 1);
+	sg_init_table(&sg_in, 1);
+
 	if (cmd == READ) {
 		in_page = raw_page;
 		in_offs = raw_off;
@@ -146,11 +150,11 @@ cryptoloop_transfer(struct loop_device *lo, int cmd,
 		u32 iv[4] = { 0, };
 		iv[0] = cpu_to_le32(IV & 0xffffffff);
 
-		sg_in.page = in_page;
+		sg_set_page(&sg_in, in_page);
 		sg_in.offset = in_offs;
 		sg_in.length = sz;
 
-		sg_out.page = out_page;
+		sg_set_page(&sg_out, out_page);
 		sg_out.offset = out_offs;
 		sg_out.length = sz;
 
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index c57dd2b..d6f7b43 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -25,6 +25,7 @@
 #include <linux/usb_usual.h>
 #include <linux/blkdev.h>
 #include <linux/timer.h>
+#include <linux/scatterlist.h>
 #include <scsi/scsi.h>
 
 #define DRV_NAME "ub"
@@ -656,6 +657,7 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq)
 	if ((cmd = ub_get_cmd(lun)) == NULL)
 		return -1;
 	memset(cmd, 0, sizeof(struct ub_scsi_cmd));
+	sg_init_table(cmd->sgv, UB_MAX_REQ_SG);
 
 	blkdev_dequeue_request(rq);
 
@@ -1310,7 +1312,7 @@ static void ub_data_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 		pipe = sc->send_bulk_pipe;
 	sc->last_pipe = pipe;
 	usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe,
-	    page_address(sg->page) + sg->offset, sg->length,
+	    page_address(sg_page(sg)) + sg->offset, sg->length,
 	    ub_urb_complete, sc);
 	sc->work_urb.actual_length = 0;
 	sc->work_urb.error_count = 0;
@@ -1427,7 +1429,7 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 	scmd->state = UB_CMDST_INIT;
 	scmd->nsg = 1;
 	sg = &scmd->sgv[0];
-	sg->page = virt_to_page(sc->top_sense);
+	sg_set_page(sg, virt_to_page(sc->top_sense));
 	sg->offset = (unsigned long)sc->top_sense & (PAGE_SIZE-1);
 	sg->length = UB_SENSE_SIZE;
 	scmd->len = UB_SENSE_SIZE;
@@ -1863,7 +1865,7 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
 	cmd->state = UB_CMDST_INIT;
 	cmd->nsg = 1;
 	sg = &cmd->sgv[0];
-	sg->page = virt_to_page(p);
+	sg_set_page(sg, virt_to_page(p));
 	sg->offset = (unsigned long)p & (PAGE_SIZE-1);
 	sg->length = 8;
 	cmd->len = 8;
diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c
index 06c75f1..3979bf4 100644
--- a/drivers/ide/cris/ide-cris.c
+++ b/drivers/ide/cris/ide-cris.c
@@ -934,11 +934,11 @@ static int cris_ide_build_dmatable (ide_drive_t *drive)
 		 * than two possibly non-adjacent physical 4kB pages.
 		 */
 		/* group sequential buffers into one large buffer */
-		addr = page_to_phys(sg->page) + sg->offset;
+		addr = page_to_phys(sg_page(sg)) + sg->offset;
 		size = sg_dma_len(sg);
 		while (--i) {
 			sg = sg_next(sg);
-			if ((addr + size) != page_to_phys(sg->page) + sg->offset)
+			if ((addr + size) != page_to_phys(sg_page(sg)) + sg->offset)
 				break;
 			size += sg_dma_len(sg);
 		}
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 3c945d6..7c640cd 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -1337,12 +1337,14 @@ static int hwif_init(ide_hwif_t *hwif)
 	if (!hwif->sg_max_nents)
 		hwif->sg_max_nents = PRD_ENTRIES;
 
-	hwif->sg_table = kzalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
+	hwif->sg_table = kmalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
 				 GFP_KERNEL);
 	if (!hwif->sg_table) {
 		printk(KERN_ERR "%s: unable to allocate SG table.\n", hwif->name);
 		goto out;
 	}
+
+	sg_init_table(hwif->sg_table, hwif->sg_max_nents);
 	
 	if (init_irq(hwif) == 0)
 		goto done;
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 2a3c8d4..086157f 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -278,7 +278,7 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
 		hwif->cursg = sg;
 	}
 
-	page = cursg->page;
+	page = sg_page(cursg);
 	offset = cursg->offset + hwif->cursg_ofs * SECTOR_SIZE;
 
 	/* get the current page and offset */
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
index 47c035a..1b22ab7 100644
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -276,7 +276,7 @@ static int auide_build_dmatable(ide_drive_t *drive)
 
 			if (iswrite) {
 				if(!put_source_flags(ahwif->tx_chan, 
-						     (void*)(page_address(sg->page) 
+						     (void*)(page_address(sg_page(sg)) 
 							     + sg->offset), 
 						     tc, flags)) { 
 					printk(KERN_ERR "%s failed %d\n", 
@@ -285,7 +285,7 @@ static int auide_build_dmatable(ide_drive_t *drive)
 			} else 
 			{
 				if(!put_dest_flags(ahwif->rx_chan, 
-						   (void*)(page_address(sg->page) 
+						   (void*)(page_address(sg_page(sg)) 
 							   + sg->offset), 
 						   tc, flags)) { 
 					printk(KERN_ERR "%s failed %d\n", 
diff --git a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c
index 45d6055..25e113b 100644
--- a/drivers/ieee1394/dma.c
+++ b/drivers/ieee1394/dma.c
@@ -111,7 +111,7 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes,
 		unsigned long va =
 		    (unsigned long)dma->kvirt + (i << PAGE_SHIFT);
 
-		dma->sglist[i].page = vmalloc_to_page((void *)va);
+		sg_set_page(&dma->sglist[i], vmalloc_to_page((void *)va));
 		dma->sglist[i].length = PAGE_SIZE;
 	}
 
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 1b353b9..d5dfe11 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -1466,7 +1466,7 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb,
 		cmd->dma_size = sgpnt[0].length;
 		cmd->dma_type = CMD_DMA_PAGE;
 		cmd->cmd_dma = dma_map_page(hi->host->device.parent,
-					    sgpnt[0].page, sgpnt[0].offset,
+					    sg_page(&sgpnt[0]), sgpnt[0].offset,
 					    cmd->dma_size, cmd->dma_dir);
 
 		orb->data_descriptor_lo = cmd->cmd_dma;
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index 2f54e29..14159ff 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -55,9 +55,11 @@ static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int d
 		ib_dma_unmap_sg(dev, chunk->page_list,
 				chunk->nents, DMA_BIDIRECTIONAL);
 		for (i = 0; i < chunk->nents; ++i) {
+			struct page *page = sg_page(&chunk->page_list[i]);
+
 			if (umem->writable && dirty)
-				set_page_dirty_lock(chunk->page_list[i].page);
-			put_page(chunk->page_list[i].page);
+				set_page_dirty_lock(page);
+			put_page(page);
 		}
 
 		kfree(chunk);
@@ -164,11 +166,12 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
 			}
 
 			chunk->nents = min_t(int, ret, IB_UMEM_MAX_PAGE_CHUNK);
+			sg_init_table(chunk->page_list, chunk->nents);
 			for (i = 0; i < chunk->nents; ++i) {
 				if (vma_list &&
 				    !is_vm_hugetlb_page(vma_list[i + off]))
 					umem->hugetlb = 0;
-				chunk->page_list[i].page   = page_list[i + off];
+				sg_set_page(&chunk->page_list[i], page_list[i + off]);
 				chunk->page_list[i].offset = 0;
 				chunk->page_list[i].length = PAGE_SIZE;
 			}
@@ -179,7 +182,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
 						    DMA_BIDIRECTIONAL);
 			if (chunk->nmap <= 0) {
 				for (i = 0; i < chunk->nents; ++i)
-					put_page(chunk->page_list[i].page);
+					put_page(sg_page(&chunk->page_list[i]));
 				kfree(chunk);
 
 				ret = -ENOMEM;
diff --git a/drivers/infiniband/hw/ipath/ipath_dma.c b/drivers/infiniband/hw/ipath/ipath_dma.c
index 22709a4..e90a0ea 100644
--- a/drivers/infiniband/hw/ipath/ipath_dma.c
+++ b/drivers/infiniband/hw/ipath/ipath_dma.c
@@ -108,7 +108,7 @@ static int ipath_map_sg(struct ib_device *dev, struct scatterlist *sgl,
 	BUG_ON(!valid_dma_direction(direction));
 
 	for_each_sg(sgl, sg, nents, i) {
-		addr = (u64) page_address(sg->page);
+		addr = (u64) page_address(sg_page(sg));
 		/* TODO: handle highmem pages */
 		if (!addr) {
 			ret = 0;
@@ -127,7 +127,7 @@ static void ipath_unmap_sg(struct ib_device *dev,
 
 static u64 ipath_sg_dma_address(struct ib_device *dev, struct scatterlist *sg)
 {
-	u64 addr = (u64) page_address(sg->page);
+	u64 addr = (u64) page_address(sg_page(sg));
 
 	if (addr)
 		addr += sg->offset;
diff --git a/drivers/infiniband/hw/ipath/ipath_mr.c b/drivers/infiniband/hw/ipath/ipath_mr.c
index e442470..db4ba92 100644
--- a/drivers/infiniband/hw/ipath/ipath_mr.c
+++ b/drivers/infiniband/hw/ipath/ipath_mr.c
@@ -225,7 +225,7 @@ struct ib_mr *ipath_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
 		for (i = 0; i < chunk->nents; i++) {
 			void *vaddr;
 
-			vaddr = page_address(chunk->page_list[i].page);
+			vaddr = page_address(sg_page(&chunk->page_list[i]));
 			if (!vaddr) {
 				ret = ERR_PTR(-EINVAL);
 				goto bail;
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
index e61f3e6..007b381 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -71,7 +71,7 @@ static void mthca_free_icm_pages(struct mthca_dev *dev, struct mthca_icm_chunk *
 			     PCI_DMA_BIDIRECTIONAL);
 
 	for (i = 0; i < chunk->npages; ++i)
-		__free_pages(chunk->mem[i].page,
+		__free_pages(sg_page(&chunk->mem[i]),
 			     get_order(chunk->mem[i].length));
 }
 
@@ -81,7 +81,7 @@ static void mthca_free_icm_coherent(struct mthca_dev *dev, struct mthca_icm_chun
 
 	for (i = 0; i < chunk->npages; ++i) {
 		dma_free_coherent(&dev->pdev->dev, chunk->mem[i].length,
-				  lowmem_page_address(chunk->mem[i].page),
+				  lowmem_page_address(sg_page(&chunk->mem[i])),
 				  sg_dma_address(&chunk->mem[i]));
 	}
 }
@@ -107,10 +107,13 @@ void mthca_free_icm(struct mthca_dev *dev, struct mthca_icm *icm, int coherent)
 
 static int mthca_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_mask)
 {
-	mem->page = alloc_pages(gfp_mask, order);
-	if (!mem->page)
+	struct page *page;
+
+	page = alloc_pages(gfp_mask, order);
+	if (!page)
 		return -ENOMEM;
 
+	sg_set_page(mem, page);
 	mem->length = PAGE_SIZE << order;
 	mem->offset = 0;
 	return 0;
@@ -157,6 +160,7 @@ struct mthca_icm *mthca_alloc_icm(struct mthca_dev *dev, int npages,
 			if (!chunk)
 				goto fail;
 
+			sg_init_table(chunk->mem, MTHCA_ICM_CHUNK_LEN);
 			chunk->npages = 0;
 			chunk->nsg    = 0;
 			list_add_tail(&chunk->list, &icm->chunk_list);
@@ -304,7 +308,7 @@ void *mthca_table_find(struct mthca_icm_table *table, int obj, dma_addr_t *dma_h
 			 * so if we found the page, dma_handle has already
 			 * been assigned to. */
 			if (chunk->mem[i].length > offset) {
-				page = chunk->mem[i].page;
+				page = sg_page(&chunk->mem[i]);
 				goto out;
 			}
 			offset -= chunk->mem[i].length;
@@ -445,6 +449,7 @@ static u64 mthca_uarc_virt(struct mthca_dev *dev, struct mthca_uar *uar, int pag
 int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
 		      struct mthca_user_db_table *db_tab, int index, u64 uaddr)
 {
+	struct page *pages[1];
 	int ret = 0;
 	u8 status;
 	int i;
@@ -472,16 +477,17 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
 	}
 
 	ret = get_user_pages(current, current->mm, uaddr & PAGE_MASK, 1, 1, 0,
-			     &db_tab->page[i].mem.page, NULL);
+			     pages, NULL);
 	if (ret < 0)
 		goto out;
 
+	sg_set_page(&db_tab->page[i].mem, pages[0]);
 	db_tab->page[i].mem.length = MTHCA_ICM_PAGE_SIZE;
 	db_tab->page[i].mem.offset = uaddr & ~PAGE_MASK;
 
 	ret = pci_map_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
 	if (ret < 0) {
-		put_page(db_tab->page[i].mem.page);
+		put_page(pages[0]);
 		goto out;
 	}
 
@@ -491,7 +497,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
 		ret = -EINVAL;
 	if (ret) {
 		pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
-		put_page(db_tab->page[i].mem.page);
+		put_page(sg_page(&db_tab->page[i].mem));
 		goto out;
 	}
 
@@ -557,7 +563,7 @@ void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar,
 		if (db_tab->page[i].uvirt) {
 			mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, uar, i), 1, &status);
 			pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
-			put_page(db_tab->page[i].mem.page);
+			put_page(sg_page(&db_tab->page[i].mem));
 		}
 	}
 
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
index f3529b6..813b96b 100644
--- a/drivers/infiniband/ulp/iser/iser_memory.c
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -131,7 +131,7 @@ static int iser_start_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
 
 		p = mem;
 		for_each_sg(sgl, sg, data->size, i) {
-			from = kmap_atomic(sg->page, KM_USER0);
+			from = kmap_atomic(sg_page(sg), KM_USER0);
 			memcpy(p,
 			       from + sg->offset,
 			       sg->length);
@@ -191,7 +191,7 @@ void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
 
 		p = mem;
 		for_each_sg(sgl, sg, sg_size, i) {
-			to = kmap_atomic(sg->page, KM_SOFTIRQ0);
+			to = kmap_atomic(sg_page(sg), KM_SOFTIRQ0);
 			memcpy(to + sg->offset,
 			       p,
 			       sg->length);
@@ -300,7 +300,7 @@ static unsigned int iser_data_buf_aligned_len(struct iser_data_buf *data,
 	for_each_sg(sgl, sg, data->dma_nents, i) {
 		/* iser_dbg("Checking sg iobuf [%d]: phys=0x%08lX "
 		   "offset: %ld sz: %ld\n", i,
-		   (unsigned long)page_to_phys(sg->page),
+		   (unsigned long)page_to_phys(sg_page(sg)),
 		   (unsigned long)sg->offset,
 		   (unsigned long)sg->length); */
 		end_addr = ib_sg_dma_address(ibdev, sg) +
@@ -336,7 +336,7 @@ static void iser_data_buf_dump(struct iser_data_buf *data,
 		iser_err("sg[%d] dma_addr:0x%lX page:0x%p "
 			 "off:0x%x sz:0x%x dma_len:0x%x\n",
 			 i, (unsigned long)ib_sg_dma_address(ibdev, sg),
-			 sg->page, sg->offset,
+			 sg_page(sg), sg->offset,
 			 sg->length, ib_sg_dma_len(ibdev, sg));
 }
 
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 64fee90..cde915f 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -346,16 +346,17 @@ static int crypt_convert(struct crypt_config *cc,
 	      ctx->idx_out < ctx->bio_out->bi_vcnt) {
 		struct bio_vec *bv_in = bio_iovec_idx(ctx->bio_in, ctx->idx_in);
 		struct bio_vec *bv_out = bio_iovec_idx(ctx->bio_out, ctx->idx_out);
-		struct scatterlist sg_in = {
-			.page = bv_in->bv_page,
-			.offset = bv_in->bv_offset + ctx->offset_in,
-			.length = 1 << SECTOR_SHIFT
-		};
-		struct scatterlist sg_out = {
-			.page = bv_out->bv_page,
-			.offset = bv_out->bv_offset + ctx->offset_out,
-			.length = 1 << SECTOR_SHIFT
-		};
+		struct scatterlist sg_in, sg_out;
+
+		sg_init_table(&sg_in, 1);
+		sg_set_page(&sg_in, bv_in->bv_page);
+		sg_in.offset = bv_in->bv_offset + ctx->offset_in;
+		sg_in.length = 1 << SECTOR_SHIFT;
+		
+		sg_init_table(&sg_out, 1);
+		sg_set_page(&sg_out, bv_out->bv_page);
+		sg_out.offset = bv_out->bv_offset + ctx->offset_out;
+		sg_out.length = 1 << SECTOR_SHIFT;
 
 		ctx->offset_in += sg_in.length;
 		if (ctx->offset_in >= bv_in->bv_len) {
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c
index 365a221..2b1f8b4 100644
--- a/drivers/media/common/saa7146_core.c
+++ b/drivers/media/common/saa7146_core.c
@@ -112,12 +112,13 @@ static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages)
 	sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL);
 	if (NULL == sglist)
 		return NULL;
+	sg_init_table(sglist, nr_pages);
 	for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
 		pg = vmalloc_to_page(virt);
 		if (NULL == pg)
 			goto err;
 		BUG_ON(PageHighMem(pg));
-		sglist[i].page   = pg;
+		sg_set_page(&sglist[i], pg);
 		sglist[i].length = PAGE_SIZE;
 	}
 	return sglist;
diff --git a/drivers/media/video/ivtv/ivtv-udma.c b/drivers/media/video/ivtv/ivtv-udma.c
index c4626d1..912b424 100644
--- a/drivers/media/video/ivtv/ivtv-udma.c
+++ b/drivers/media/video/ivtv/ivtv-udma.c
@@ -63,10 +63,10 @@ int ivtv_udma_fill_sg_list (struct ivtv_user_dma *dma, struct ivtv_dma_page_info
 			memcpy(page_address(dma->bouncemap[map_offset]) + offset, src, len);
 			kunmap_atomic(src, KM_BOUNCE_READ);
 			local_irq_restore(flags);
-			dma->SGlist[map_offset].page = dma->bouncemap[map_offset];
+			sg_set_page(&dma->SGlist[map_offset], dma->bouncemap[map_offset]);
 		}
 		else {
-			dma->SGlist[map_offset].page = dma->map[map_offset];
+			sg_set_page(&dma->SGlist[map_offset], dma->map[map_offset]);
 		}
 		offset = 0;
 		map_offset++;
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
index 3eb6123..0a18286 100644
--- a/drivers/media/video/videobuf-dma-sg.c
+++ b/drivers/media/video/videobuf-dma-sg.c
@@ -60,12 +60,13 @@ videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages)
 	sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL);
 	if (NULL == sglist)
 		return NULL;
+	sg_init_table(sglist, nr_pages);
 	for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
 		pg = vmalloc_to_page(virt);
 		if (NULL == pg)
 			goto err;
 		BUG_ON(PageHighMem(pg));
-		sglist[i].page   = pg;
+		sg_set_page(&sglist[i], pg);
 		sglist[i].length = PAGE_SIZE;
 	}
 	return sglist;
@@ -86,13 +87,14 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
 	sglist = kcalloc(nr_pages, sizeof(*sglist), GFP_KERNEL);
 	if (NULL == sglist)
 		return NULL;
+	sg_init_table(sglist, nr_pages);
 
 	if (NULL == pages[0])
 		goto nopage;
 	if (PageHighMem(pages[0]))
 		/* DMA to highmem pages might not work */
 		goto highmem;
-	sglist[0].page   = pages[0];
+	sg_set_page(&sglist[0], pages[0]);
 	sglist[0].offset = offset;
 	sglist[0].length = PAGE_SIZE - offset;
 	for (i = 1; i < nr_pages; i++) {
@@ -100,7 +102,7 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
 			goto nopage;
 		if (PageHighMem(pages[i]))
 			goto highmem;
-		sglist[i].page   = pages[i];
+		sg_set_page(&sglist[i], pages[i]);
 		sglist[i].length = PAGE_SIZE;
 	}
 	return sglist;
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index a5d0354..68c1fe9 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -13,6 +13,7 @@
 #include <linux/blkdev.h>
 #include <linux/freezer.h>
 #include <linux/kthread.h>
+#include <linux/scatterlist.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
@@ -153,19 +154,21 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
 			blk_queue_max_hw_segments(mq->queue, bouncesz / 512);
 			blk_queue_max_segment_size(mq->queue, bouncesz);
 
-			mq->sg = kzalloc(sizeof(struct scatterlist),
+			mq->sg = kmalloc(sizeof(struct scatterlist),
 				GFP_KERNEL);
 			if (!mq->sg) {
 				ret = -ENOMEM;
 				goto cleanup_queue;
 			}
+			sg_init_table(mq->sg, 1);
 
-			mq->bounce_sg = kzalloc(sizeof(struct scatterlist) *
+			mq->bounce_sg = kmalloc(sizeof(struct scatterlist) *
 				bouncesz / 512, GFP_KERNEL);
 			if (!mq->bounce_sg) {
 				ret = -ENOMEM;
 				goto cleanup_queue;
 			}
+			sg_init_table(mq->bounce_sg, bouncesz / 512);
 		}
 	}
 #endif
@@ -302,12 +305,12 @@ static void copy_sg(struct scatterlist *dst, unsigned int dst_len,
 		BUG_ON(dst_len == 0);
 
 		if (dst_size == 0) {
-			dst_buf = page_address(dst->page) + dst->offset;
+			dst_buf = page_address(sg_page(dst)) + dst->offset;
 			dst_size = dst->length;
 		}
 
 		if (src_size == 0) {
-			src_buf = page_address(src->page) + src->offset;
+			src_buf = page_address(sg_page(src)) + src->offset;
 			src_size = src->length;
 		}
 
@@ -353,9 +356,7 @@ unsigned int mmc_queue_map_sg(struct mmc_queue *mq)
 		return 1;
 	}
 
-	mq->sg[0].page = virt_to_page(mq->bounce_buf);
-	mq->sg[0].offset = offset_in_page(mq->bounce_buf);
-	mq->sg[0].length = 0;
+	sg_init_one(mq->sg, mq->bounce_buf, 0);
 
 	while (sg_len) {
 		mq->sg[0].length += mq->bounce_sg[sg_len - 1].length;
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index 7a452c2..b1edcef 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -149,7 +149,7 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data
 
 		sg = &data->sg[i];
 
-		sgbuffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
+		sgbuffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
 		amount = min(size, sg->length);
 		size -= amount;
 
@@ -226,7 +226,7 @@ static void at91_mci_pre_dma_read(struct at91mci_host *host)
 		sg = &data->sg[host->transfer_index++];
 		pr_debug("sg = %p\n", sg);
 
-		sg->dma_address = dma_map_page(NULL, sg->page, sg->offset, sg->length, DMA_FROM_DEVICE);
+		sg->dma_address = dma_map_page(NULL, sg_page(sg), sg->offset, sg->length, DMA_FROM_DEVICE);
 
 		pr_debug("dma address = %08X, length = %d\n", sg->dma_address, sg->length);
 
@@ -283,7 +283,7 @@ static void at91_mci_post_dma_read(struct at91mci_host *host)
 			int index;
 
 			/* Swap the contents of the buffer */
-			buffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
+			buffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
 			pr_debug("buffer = %p, length = %d\n", buffer, sg->length);
 
 			for (index = 0; index < (sg->length / 4); index++)
@@ -292,7 +292,7 @@ static void at91_mci_post_dma_read(struct at91mci_host *host)
 			kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
 		}
 
-		flush_dcache_page(sg->page);
+		flush_dcache_page(sg_page(sg));
 	}
 
 	/* Is there another transfer to trigger? */
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c
index 92c4d0d..0632f4d 100644
--- a/drivers/mmc/host/au1xmmc.c
+++ b/drivers/mmc/host/au1xmmc.c
@@ -340,7 +340,7 @@ static void au1xmmc_send_pio(struct au1xmmc_host *host)
 
 	/* This is the pointer to the data buffer */
 	sg = &data->sg[host->pio.index];
-	sg_ptr = page_address(sg->page) + sg->offset + host->pio.offset;
+	sg_ptr = page_address(sg_page(sg)) + sg->offset + host->pio.offset;
 
 	/* This is the space left inside the buffer */
 	sg_len = data->sg[host->pio.index].length - host->pio.offset;
@@ -400,7 +400,7 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host)
 
 	if (host->pio.index < host->dma.len) {
 		sg = &data->sg[host->pio.index];
-		sg_ptr = page_address(sg->page) + sg->offset + host->pio.offset;
+		sg_ptr = page_address(sg_page(sg)) + sg->offset + host->pio.offset;
 
 		/* This is the space left inside the buffer */
 		sg_len = sg_dma_len(&data->sg[host->pio.index]) - host->pio.offset;
@@ -613,13 +613,13 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data)
 
     			if (host->flags & HOST_F_XMIT){
       				ret = au1xxx_dbdma_put_source_flags(channel,
-					(void *) (page_address(sg->page) +
+					(void *) (page_address(sg_page(sg)) +
 						  sg->offset),
 					len, flags);
 			}
     			else {
       				ret = au1xxx_dbdma_put_dest_flags(channel,
-					(void *) (page_address(sg->page) +
+					(void *) (page_address(sg_page(sg)) +
 						  sg->offset),
 					len, flags);
 			}
diff --git a/drivers/mmc/host/imxmmc.c b/drivers/mmc/host/imxmmc.c
index 6ebc41e..581bb8f 100644
--- a/drivers/mmc/host/imxmmc.c
+++ b/drivers/mmc/host/imxmmc.c
@@ -262,7 +262,7 @@ static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data)
 		}
 
 		/* Convert back to virtual address */
-		host->data_ptr = (u16*)(page_address(data->sg->page) + data->sg->offset);
+		host->data_ptr = (u16*)(page_address(sg_page(data->sg)) + data->sg->offset);
 		host->data_cnt = 0;
 
 		clear_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events);
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 7ae18ea..12c2d80 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -813,7 +813,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
 					&& dir == DMA_FROM_DEVICE)
 				dir = DMA_BIDIRECTIONAL;
 
-			dma_addr = dma_map_page(dma_dev, sg->page, 0,
+			dma_addr = dma_map_page(dma_dev, sg_page(sg), 0,
 						PAGE_SIZE, dir);
 			if (direction == DMA_TO_DEVICE)
 				t->tx_dma = dma_addr + sg->offset;
@@ -822,7 +822,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
 		}
 
 		/* allow pio too; we don't allow highmem */
-		kmap_addr = kmap(sg->page);
+		kmap_addr = kmap(sg_page(sg));
 		if (direction == DMA_TO_DEVICE)
 			t->tx_buf = kmap_addr + sg->offset;
 		else
@@ -855,8 +855,8 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
 
 		/* discard mappings */
 		if (direction == DMA_FROM_DEVICE)
-			flush_kernel_dcache_page(sg->page);
-		kunmap(sg->page);
+			flush_kernel_dcache_page(sg_page(sg));
+		kunmap(sg_page(sg));
 		if (dma_dev)
 			dma_unmap_page(dma_dev, dma_addr, PAGE_SIZE, dir);
 
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 60a67df..649f647 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -24,10 +24,10 @@
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
 #include <linux/clk.h>
+#include <linux/scatterlist.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/scatterlist.h>
 #include <asm/mach-types.h>
 
 #include <asm/arch/board.h>
@@ -383,7 +383,7 @@ mmc_omap_sg_to_buf(struct mmc_omap_host *host)
 
 	sg = host->data->sg + host->sg_idx;
 	host->buffer_bytes_left = sg->length;
-	host->buffer = page_address(sg->page) + sg->offset;
+	host->buffer = page_address(sg_page(sg)) + sg->offset;
 	if (host->buffer_bytes_left > host->total_bytes_left)
 		host->buffer_bytes_left = host->total_bytes_left;
 }
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index b397121..b6500e9 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -231,7 +231,7 @@ static void sdhci_deactivate_led(struct sdhci_host *host)
 
 static inline char* sdhci_sg_to_buffer(struct sdhci_host* host)
 {
-	return page_address(host->cur_sg->page) + host->cur_sg->offset;
+	return page_address(sg_page(host->cur_sg)) + host->cur_sg->offset;
 }
 
 static inline int sdhci_next_sg(struct sdhci_host* host)
diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c
index 9b90479..c11a3d2 100644
--- a/drivers/mmc/host/tifm_sd.c
+++ b/drivers/mmc/host/tifm_sd.c
@@ -192,7 +192,7 @@ static void tifm_sd_transfer_data(struct tifm_sd *host)
 		}
 		off = sg[host->sg_pos].offset + host->block_pos;
 
-		pg = nth_page(sg[host->sg_pos].page, off >> PAGE_SHIFT);
+		pg = nth_page(sg_page(&sg[host->sg_pos]), off >> PAGE_SHIFT);
 		p_off = offset_in_page(off);
 		p_cnt = PAGE_SIZE - p_off;
 		p_cnt = min(p_cnt, cnt);
@@ -241,18 +241,18 @@ static void tifm_sd_bounce_block(struct tifm_sd *host, struct mmc_data *r_data)
 		}
 		off = sg[host->sg_pos].offset + host->block_pos;
 
-		pg = nth_page(sg[host->sg_pos].page, off >> PAGE_SHIFT);
+		pg = nth_page(sg_page(&sg[host->sg_pos]), off >> PAGE_SHIFT);
 		p_off = offset_in_page(off);
 		p_cnt = PAGE_SIZE - p_off;
 		p_cnt = min(p_cnt, cnt);
 		p_cnt = min(p_cnt, t_size);
 
 		if (r_data->flags & MMC_DATA_WRITE)
-			tifm_sd_copy_page(host->bounce_buf.page,
+			tifm_sd_copy_page(sg_page(&host->bounce_buf),
 					  r_data->blksz - t_size,
 					  pg, p_off, p_cnt);
 		else if (r_data->flags & MMC_DATA_READ)
-			tifm_sd_copy_page(pg, p_off, host->bounce_buf.page,
+			tifm_sd_copy_page(pg, p_off, sg_page(&host->bounce_buf),
 					  r_data->blksz - t_size, p_cnt);
 
 		t_size -= p_cnt;
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c
index 80db11c..971ca0f 100644
--- a/drivers/mmc/host/wbsd.c
+++ b/drivers/mmc/host/wbsd.c
@@ -269,7 +269,7 @@ static inline int wbsd_next_sg(struct wbsd_host *host)
 
 static inline char *wbsd_sg_to_buffer(struct wbsd_host *host)
 {
-	return page_address(host->cur_sg->page) + host->cur_sg->offset;
+	return page_address(sg_page(host->cur_sg)) + host->cur_sg->offset;
 }
 
 static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data)
@@ -283,7 +283,7 @@ static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data)
 	len = data->sg_len;
 
 	for (i = 0; i < len; i++) {
-		sgbuf = page_address(sg[i].page) + sg[i].offset;
+		sgbuf = page_address(sg_page(&sg[i])) + sg[i].offset;
 		memcpy(dmabuf, sgbuf, sg[i].length);
 		dmabuf += sg[i].length;
 	}
@@ -300,7 +300,7 @@ static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data)
 	len = data->sg_len;
 
 	for (i = 0; i < len; i++) {
-		sgbuf = page_address(sg[i].page) + sg[i].offset;
+		sgbuf = page_address(sg_page(&sg[i])) + sg[i].offset;
 		memcpy(sgbuf, dmabuf, sg[i].length);
 		dmabuf += sg[i].length;
 	}
diff --git a/drivers/net/mlx4/icm.c b/drivers/net/mlx4/icm.c
index 4b3c109..887633b 100644
--- a/drivers/net/mlx4/icm.c
+++ b/drivers/net/mlx4/icm.c
@@ -60,7 +60,7 @@ static void mlx4_free_icm_pages(struct mlx4_dev *dev, struct mlx4_icm_chunk *chu
 			     PCI_DMA_BIDIRECTIONAL);
 
 	for (i = 0; i < chunk->npages; ++i)
-		__free_pages(chunk->mem[i].page,
+		__free_pages(sg_page(&chunk->mem[i]),
 			     get_order(chunk->mem[i].length));
 }
 
@@ -70,7 +70,7 @@ static void mlx4_free_icm_coherent(struct mlx4_dev *dev, struct mlx4_icm_chunk *
 
 	for (i = 0; i < chunk->npages; ++i)
 		dma_free_coherent(&dev->pdev->dev, chunk->mem[i].length,
-				  lowmem_page_address(chunk->mem[i].page),
+				  lowmem_page_address(sg_page(&chunk->mem[i])),
 				  sg_dma_address(&chunk->mem[i]));
 }
 
@@ -95,10 +95,13 @@ void mlx4_free_icm(struct mlx4_dev *dev, struct mlx4_icm *icm, int coherent)
 
 static int mlx4_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_mask)
 {
-	mem->page = alloc_pages(gfp_mask, order);
-	if (!mem->page)
+	struct page *page;
+
+	page = alloc_pages(gfp_mask, order);
+	if (!page)
 		return -ENOMEM;
 
+	sg_set_page(mem, page);
 	mem->length = PAGE_SIZE << order;
 	mem->offset = 0;
 	return 0;
@@ -145,6 +148,7 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
 			if (!chunk)
 				goto fail;
 
+			sg_init_table(chunk->mem, MLX4_ICM_CHUNK_LEN);
 			chunk->npages = 0;
 			chunk->nsg    = 0;
 			list_add_tail(&chunk->list, &icm->chunk_list);
@@ -334,7 +338,7 @@ void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_han
 			 * been assigned to.
 			 */
 			if (chunk->mem[i].length > offset) {
-				page = chunk->mem[i].page;
+				page = sg_page(&chunk->mem[i]);
 				goto out;
 			}
 			offset -= chunk->mem[i].length;
diff --git a/drivers/net/ppp_mppe.c b/drivers/net/ppp_mppe.c
index c0b6d19..bcb0885 100644
--- a/drivers/net/ppp_mppe.c
+++ b/drivers/net/ppp_mppe.c
@@ -55,7 +55,7 @@
 #include <linux/mm.h>
 #include <linux/ppp_defs.h>
 #include <linux/ppp-comp.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 
 #include "ppp_mppe.h"
 
@@ -68,9 +68,7 @@ MODULE_VERSION("1.0.2");
 static unsigned int
 setup_sg(struct scatterlist *sg, const void *address, unsigned int length)
 {
-	sg[0].page = virt_to_page(address);
-	sg[0].offset = offset_in_page(address);
-	sg[0].length = length;
+	sg_init_one(sg, address, length);
 	return length;
 }
 
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index fb14014..afb262b 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -1840,7 +1840,7 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
 			    (scsi_bufflen(srb) < TW_MIN_SGL_LENGTH)) {
 				if (srb->sc_data_direction == DMA_TO_DEVICE || srb->sc_data_direction == DMA_BIDIRECTIONAL) {
 					struct scatterlist *sg = scsi_sglist(srb);
-					char *buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+					char *buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 					memcpy(tw_dev->generic_buffer_virt[request_id], buf, sg->length);
 					kunmap_atomic(buf - sg->offset, KM_IRQ0);
 				}
@@ -1919,7 +1919,7 @@ static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int re
 			char *buf;
 			unsigned long flags = 0;
 			local_irq_save(flags);
-			buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+			buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 			memcpy(buf, tw_dev->generic_buffer_virt[request_id], sg->length);
 			kunmap_atomic(buf - sg->offset, KM_IRQ0);
 			local_irq_restore(flags);
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index a64153b..59716eb 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -1469,7 +1469,7 @@ static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id,
 	struct scatterlist *sg = scsi_sglist(cmd);
 
 	local_irq_save(flags);
-	buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+	buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 	transfer_len = min(sg->length, len);
 
 	memcpy(buf, data, transfer_len);
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index 988f0bc..7a76b4b 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -298,7 +298,7 @@ static __inline__ void initialize_SCp(Scsi_Cmnd * cmd)
 	if (cmd->use_sg) {
 		cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
 		cmd->SCp.buffers_residual = cmd->use_sg - 1;
-		cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+
+		cmd->SCp.ptr = page_address(sg_page(cmd->SCp.buffer))+
 			       cmd->SCp.buffer->offset;
 		cmd->SCp.this_residual = cmd->SCp.buffer->length;
 	} else {
@@ -2143,7 +2143,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
 					++cmd->SCp.buffer;
 					--cmd->SCp.buffers_residual;
 					cmd->SCp.this_residual = cmd->SCp.buffer->length;
-					cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+
+					cmd->SCp.ptr = page_address(sg_page(cmd->SCp.buffer))+
 						       cmd->SCp.buffer->offset;
 					dprintk(NDEBUG_INFORMATION, ("scsi%d : %d bytes and %d buffers left\n", instance->host_no, cmd->SCp.this_residual, cmd->SCp.buffers_residual));
 				}
diff --git a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c
index 3168a17..db1a8bc 100644
--- a/drivers/scsi/NCR53c406a.c
+++ b/drivers/scsi/NCR53c406a.c
@@ -875,7 +875,7 @@ static void NCR53c406a_intr(void *dev_id)
 			outb(TRANSFER_INFO | DMA_OP, CMD_REG);
 #if USE_PIO
                         scsi_for_each_sg(current_SC, sg, scsi_sg_count(current_SC), i) {
-                                NCR53c406a_pio_write(page_address(sg->page) + sg->offset,
+                                NCR53c406a_pio_write(page_address(sg_page(sg)) + sg->offset,
                                                      sg->length);
                         }
 			REG0;
@@ -897,7 +897,7 @@ static void NCR53c406a_intr(void *dev_id)
 			outb(TRANSFER_INFO | DMA_OP, CMD_REG);
 #if USE_PIO
                         scsi_for_each_sg(current_SC, sg, scsi_sg_count(current_SC), i) {
-                                NCR53c406a_pio_read(page_address(sg->page) + sg->offset,
+                                NCR53c406a_pio_read(page_address(sg_page(sg)) + sg->offset,
                                                     sg->length);
                         }
 			REG0;
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 80e448d..a77ab8d 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -356,7 +356,7 @@ static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigne
 	int transfer_len;
 	struct scatterlist *sg = scsi_sglist(scsicmd);
 
-	buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+	buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 	transfer_len = min(sg->length, len + offset);
 
 	transfer_len -= offset;
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
index 961a188..50da0a3 100644
--- a/drivers/scsi/aha1542.c
+++ b/drivers/scsi/aha1542.c
@@ -49,7 +49,7 @@
 #include "aha1542.h"
 
 #define SCSI_BUF_PA(address)	isa_virt_to_bus(address)
-#define SCSI_SG_PA(sgent)	(isa_page_to_bus((sgent)->page) + (sgent)->offset)
+#define SCSI_SG_PA(sgent)	(isa_page_to_bus(sg_page((sgent))) + (sgent)->offset)
 
 static void BAD_DMA(void *address, unsigned int length)
 {
@@ -67,7 +67,7 @@ static void BAD_SG_DMA(Scsi_Cmnd * SCpnt,
 {
 	printk(KERN_CRIT "sgpnt[%d:%d] page %p/0x%llx length %u\n",
 	       badseg, nseg,
-	       page_address(sgp->page) + sgp->offset,
+	       page_address(sg_page(sgp)) + sgp->offset,
 	       (unsigned long long)SCSI_SG_PA(sgp),
 	       sgp->length);
 
@@ -712,7 +712,7 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 				printk(KERN_CRIT "Bad segment list supplied to aha1542.c (%d, %d)\n", SCpnt->use_sg, i);
 				scsi_for_each_sg(SCpnt, sg, SCpnt->use_sg, i) {
 					printk(KERN_CRIT "%d: %p %d\n", i,
-					       (page_address(sg->page) +
+					       (page_address(sg_page(sg)) +
 						sg->offset), sg->length);
 				};
 				printk(KERN_CRIT "cptr %x: ", (unsigned int) cptr);
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index f817775..f7a2528 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -1343,7 +1343,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \
 						/* 4 bytes: Areca io control code */
 
 	sg = scsi_sglist(cmd);
-	buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+	buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 	if (scsi_sg_count(cmd) > 1) {
 		retvalue = ARCMSR_MESSAGE_FAIL;
 		goto message_out;
@@ -1593,7 +1593,7 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,
 		strncpy(&inqdata[32], "R001", 4); /* Product Revision */
 
 		sg = scsi_sglist(cmd);
-		buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+		buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 
 		memcpy(buffer, inqdata, sizeof(inqdata));
 		sg = scsi_sglist(cmd);
diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
index 5d282e6..dc4e463 100644
--- a/drivers/scsi/fdomain.c
+++ b/drivers/scsi/fdomain.c
@@ -1321,7 +1321,7 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id)
 	    if (current_SC->SCp.buffers_residual) {
 	       --current_SC->SCp.buffers_residual;
 	       ++current_SC->SCp.buffer;
-	       current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
+	       current_SC->SCp.ptr = page_address(sg_page(current_SC->SCp.buffer)) + current_SC->SCp.buffer->offset;
 	       current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
 	    } else
 		  break;
@@ -1354,7 +1354,7 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id)
 	     && current_SC->SCp.buffers_residual) {
 	    --current_SC->SCp.buffers_residual;
 	    ++current_SC->SCp.buffer;
-	    current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
+	    current_SC->SCp.ptr = page_address(sg_page(current_SC->SCp.buffer)) + current_SC->SCp.buffer->offset;
 	    current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
 	 }
       }
@@ -1439,7 +1439,7 @@ static int fdomain_16x0_queue(struct scsi_cmnd *SCpnt,
 
    if (scsi_sg_count(current_SC)) {
 	   current_SC->SCp.buffer = scsi_sglist(current_SC);
-	   current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page)
+	   current_SC->SCp.ptr = page_address(sg_page(current_SC->SCp.buffer))
 		   + current_SC->SCp.buffer->offset;
 	   current_SC->SCp.this_residual    = current_SC->SCp.buffer->length;
 	   current_SC->SCp.buffers_residual = scsi_sg_count(current_SC) - 1;
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 3ac080e..ac6c57a 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -2374,13 +2374,13 @@ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
             if (cpsum+cpnow > cpcount) 
                 cpnow = cpcount - cpsum;
             cpsum += cpnow;
-            if (!sl->page) {
+            if (!sg_page(sl)) {
                 printk("GDT-HA %d: invalid sc/gt element in gdth_copy_internal_data()\n",
                        ha->hanum);
                 return;
             }
             local_irq_save(flags);
-            address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset;
+            address = kmap_atomic(sg_page(sl), KM_BIO_SRC_IRQ) + sl->offset;
             if (to_buffer)
                 memcpy(buffer, address, cpnow);
             else
diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
index 714e627..db004a4 100644
--- a/drivers/scsi/ibmmca.c
+++ b/drivers/scsi/ibmmca.c
@@ -1828,7 +1828,7 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 		BUG_ON(scsi_sg_count(cmd) > 16);
 
 		scsi_for_each_sg(cmd, sg, scsi_sg_count(cmd), i) {
-			ld(shpnt)[ldn].sge[i].address = (void *) (isa_page_to_bus(sg->page) + sg->offset);
+			ld(shpnt)[ldn].sge[i].address = (void *) (isa_page_to_bus(sg_page(sg)) + sg->offset);
 			ld(shpnt)[ldn].sge[i].byte_length = sg->length;
 		}
 		scb->enable |= IM_POINTER_TO_LIST;
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index fa7ba64..2c7dd8b 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -175,18 +175,18 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
 
 	while (bcount) {
 		count = min(pc->sg->length - pc->b_count, bcount);
-		if (PageHighMem(pc->sg->page)) {
+		if (PageHighMem(sg_page(pc->sg))) {
 			unsigned long flags;
 
 			local_irq_save(flags);
-			buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
+			buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) +
 					pc->sg->offset;
 			drive->hwif->atapi_input_bytes(drive,
 						buf + pc->b_count, count);
 			kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
 			local_irq_restore(flags);
 		} else {
-			buf = page_address(pc->sg->page) + pc->sg->offset;
+			buf = page_address(sg_page(pc->sg)) + pc->sg->offset;
 			drive->hwif->atapi_input_bytes(drive,
 						buf + pc->b_count, count);
 		}
@@ -212,18 +212,18 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
 
 	while (bcount) {
 		count = min(pc->sg->length - pc->b_count, bcount);
-		if (PageHighMem(pc->sg->page)) {
+		if (PageHighMem(sg_page(pc->sg))) {
 			unsigned long flags;
 
 			local_irq_save(flags);
-			buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
+			buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) +
 						pc->sg->offset;
 			drive->hwif->atapi_output_bytes(drive,
 						buf + pc->b_count, count);
 			kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
 			local_irq_restore(flags);
 		} else {
-			buf = page_address(pc->sg->page) + pc->sg->offset;
+			buf = page_address(sg_page(pc->sg)) + pc->sg->offset;
 			drive->hwif->atapi_output_bytes(drive,
 						buf + pc->b_count, count);
 		}
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c
index 74cdc1f..da9b0ba 100644
--- a/drivers/scsi/imm.c
+++ b/drivers/scsi/imm.c
@@ -706,7 +706,7 @@ static int imm_completion(struct scsi_cmnd *cmd)
 				cmd->SCp.this_residual =
 				    cmd->SCp.buffer->length;
 				cmd->SCp.ptr =
-				    page_address(cmd->SCp.buffer->page) +
+				    page_address(sg_page(cmd->SCp.buffer)) +
 				    cmd->SCp.buffer->offset;
 
 				/*
@@ -845,7 +845,7 @@ static int imm_engine(imm_struct *dev, struct scsi_cmnd *cmd)
 			    (struct scatterlist *) cmd->request_buffer;
 			cmd->SCp.this_residual = cmd->SCp.buffer->length;
 			cmd->SCp.ptr =
-			    page_address(cmd->SCp.buffer->page) +
+			    page_address(sg_page(cmd->SCp.buffer)) +
 			    cmd->SCp.buffer->offset;
 		} else {
 			/* else fill the only available buffer */
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index b41dfb5..dc98a85 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -2872,6 +2872,7 @@ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len)
 	}
 
 	scatterlist = sglist->scatterlist;
+	sg_init_table(scatterlist, num_elem);
 
 	sglist->order = order;
 	sglist->num_sg = num_elem;
@@ -2884,12 +2885,12 @@ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len)
 
 			/* Free up what we already allocated */
 			for (j = i - 1; j >= 0; j--)
-				__free_pages(scatterlist[j].page, order);
+				__free_pages(sg_page(&scatterlist[j]), order);
 			kfree(sglist);
 			return NULL;
 		}
 
-		scatterlist[i].page = page;
+		sg_set_page(&scatterlist[i], page);
 	}
 
 	return sglist;
@@ -2910,7 +2911,7 @@ static void ipr_free_ucode_buffer(struct ipr_sglist *sglist)
 	int i;
 
 	for (i = 0; i < sglist->num_sg; i++)
-		__free_pages(sglist->scatterlist[i].page, sglist->order);
+		__free_pages(sg_page(&sglist->scatterlist[i]), sglist->order);
 
 	kfree(sglist);
 }
@@ -2940,9 +2941,11 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist,
 	scatterlist = sglist->scatterlist;
 
 	for (i = 0; i < (len / bsize_elem); i++, buffer += bsize_elem) {
-		kaddr = kmap(scatterlist[i].page);
+		struct page *page = sg_page(&scatterlist[i]);
+
+		kaddr = kmap(page);
 		memcpy(kaddr, buffer, bsize_elem);
-		kunmap(scatterlist[i].page);
+		kunmap(page);
 
 		scatterlist[i].length = bsize_elem;
 
@@ -2953,9 +2956,11 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist,
 	}
 
 	if (len % bsize_elem) {
-		kaddr = kmap(scatterlist[i].page);
+		struct page *page = sg_page(&scatterlist[i]);
+
+		kaddr = kmap(page);
 		memcpy(kaddr, buffer, len % bsize_elem);
-		kunmap(scatterlist[i].page);
+		kunmap(page);
 
 		scatterlist[i].length = len % bsize_elem;
 	}
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index edaac27..5c5a9b2 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -1515,7 +1515,7 @@ static int ips_is_passthru(struct scsi_cmnd *SC)
                 /* kmap_atomic() ensures addressability of the user buffer.*/
                 /* local_irq_save() protects the KM_IRQ0 address slot.     */
                 local_irq_save(flags);
-                buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+                buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
                 if (buffer && buffer[0] == 'C' && buffer[1] == 'O' &&
                     buffer[2] == 'P' && buffer[3] == 'P') {
                         kunmap_atomic(buffer - sg->offset, KM_IRQ0);
@@ -3523,7 +3523,7 @@ ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count)
                 /* kmap_atomic() ensures addressability of the data buffer.*/
                 /* local_irq_save() protects the KM_IRQ0 address slot.     */
                 local_irq_save(flags);
-                buffer = kmap_atomic(sg[i].page, KM_IRQ0) + sg[i].offset;
+                buffer = kmap_atomic(sg_page(&sg[i]), KM_IRQ0) + sg[i].offset;
                 memcpy(buffer, &cdata[xfer_cnt], min_cnt);
                 kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
                 local_irq_restore(flags);
@@ -3556,7 +3556,7 @@ ips_scmd_buf_read(struct scsi_cmnd *scmd, void *data, unsigned int count)
                 /* kmap_atomic() ensures addressability of the data buffer.*/
                 /* local_irq_save() protects the KM_IRQ0 address slot.     */
                 local_irq_save(flags);
-                buffer = kmap_atomic(sg[i].page, KM_IRQ0) + sg[i].offset;
+                buffer = kmap_atomic(sg_page(&sg[i]), KM_IRQ0) + sg[i].offset;
                 memcpy(&cdata[xfer_cnt], buffer, min_cnt);
                 kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
                 local_irq_restore(flags);
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index a21455d..6ce4109 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -70,9 +70,7 @@ module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);
 static inline void
 iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size)
 {
-	ibuf->sg.page = virt_to_page(vbuf);
-	ibuf->sg.offset = offset_in_page(vbuf);
-	ibuf->sg.length = size;
+	sg_init_one(&ibuf->sg, vbuf, size);
 	ibuf->sent = 0;
 	ibuf->use_sendmsg = 1;
 }
@@ -80,13 +78,14 @@ iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size)
 static inline void
 iscsi_buf_init_sg(struct iscsi_buf *ibuf, struct scatterlist *sg)
 {
-	ibuf->sg.page = sg->page;
+	sg_init_table(&ibuf->sg, 1);
+	sg_set_page(&ibuf->sg, sg_page(sg));
 	ibuf->sg.offset = sg->offset;
 	ibuf->sg.length = sg->length;
 	/*
 	 * Fastpath: sg element fits into single page
 	 */
-	if (sg->length + sg->offset <= PAGE_SIZE && !PageSlab(sg->page))
+	if (sg->length + sg->offset <= PAGE_SIZE && !PageSlab(sg_page(sg)))
 		ibuf->use_sendmsg = 0;
 	else
 		ibuf->use_sendmsg = 1;
@@ -716,7 +715,7 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn)
 	for (i = tcp_ctask->sg_count; i < scsi_sg_count(sc); i++) {
 		char *dest;
 
-		dest = kmap_atomic(sg[i].page, KM_SOFTIRQ0);
+		dest = kmap_atomic(sg_page(&sg[i]), KM_SOFTIRQ0);
 		rc = iscsi_ctask_copy(tcp_conn, ctask, dest + sg[i].offset,
 				      sg[i].length, offset);
 		kunmap_atomic(dest, KM_SOFTIRQ0);
@@ -1103,9 +1102,9 @@ iscsi_send(struct iscsi_conn *conn, struct iscsi_buf *buf, int size, int flags)
 	 * slab case.
 	 */
 	if (buf->use_sendmsg)
-		res = sock_no_sendpage(sk, buf->sg.page, offset, size, flags);
+		res = sock_no_sendpage(sk, sg_page(&buf->sg), offset, size, flags);
 	else
-		res = tcp_conn->sendpage(sk, buf->sg.page, offset, size, flags);
+		res = tcp_conn->sendpage(sk, sg_page(&buf->sg), offset, size, flags);
 
 	if (res >= 0) {
 		conn->txdata_octets += res;
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 10d1aff..0a848e8 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -658,7 +658,7 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
 			struct scatterlist *sg;
 
 			sg = scsi_sglist(cmd);
-			buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+			buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 
 			memset(buf, 0, cmd->cmnd[4]);
 			kunmap_atomic(buf - sg->offset, KM_IRQ0);
@@ -1542,9 +1542,9 @@ mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status)
 		if( cmd->cmnd[0] == INQUIRY && !islogical ) {
 
 			sgl = scsi_sglist(cmd);
-			if( sgl->page ) {
+			if( sg_page(sgl) ) {
 				c = *(unsigned char *)
-					page_address((&sgl[0])->page) +
+					page_address((sg_page(&sgl[0]))) +
 					(&sgl[0])->offset; 
 			} else {
 				printk(KERN_WARNING
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index e4e4c6a..376263c 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -1584,9 +1584,9 @@ megaraid_mbox_build_cmd(adapter_t *adapter, struct scsi_cmnd *scp, int *busy)
 			caddr_t			vaddr;
 
 			sgl = scsi_sglist(scp);
-			if (sgl->page) {
+			if (sg_page(sgl)) {
 				vaddr = (caddr_t)
-					(page_address((&sgl[0])->page)
+					(page_address(sg_page(&sgl[0]))
 					 + (&sgl[0])->offset);
 
 				memset(vaddr, 0, scp->cmnd[4]);
@@ -2328,9 +2328,9 @@ megaraid_mbox_dpc(unsigned long devp)
 				&& IS_RAID_CH(raid_dev, scb->dev_channel)) {
 
 			sgl = scsi_sglist(scp);
-			if (sgl->page) {
+			if (sg_page(sgl)) {
 				c = *(unsigned char *)
-					(page_address((&sgl[0])->page) +
+					(page_address(sg_page(&sgl[0])) +
 					 (&sgl[0])->offset);
 			} else {
 				con_log(CL_ANN, (KERN_WARNING
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 331b789..1c5c4b6 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -542,7 +542,7 @@ static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int q
 	if (STp->raw) {
 		if (STp->buffer->syscall_result) {
 			for (i=0; i < STp->buffer->sg_segs; i++)
-				memset(page_address(STp->buffer->sg[i].page),
+				memset(page_address(sg_page(&STp->buffer->sg[i])),
 				       0, STp->buffer->sg[i].length);
 			strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");
                 } else
@@ -4437,7 +4437,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp)
 		for (i = 0, b_size = 0; 
 		     (i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE); 
 		     b_size += STp->buffer->sg[i++].length);
-		STp->buffer->aux = (os_aux_t *) (page_address(STp->buffer->sg[i].page) + OS_DATA_SIZE - b_size);
+		STp->buffer->aux = (os_aux_t *) (page_address(sg_page(&STp->buffer->sg[i])) + OS_DATA_SIZE - b_size);
 #if DEBUG
 		printk(OSST_DEB_MSG "%s:D: b_data points to %p in segment 0 at %p\n", name,
 			STp->buffer->b_data, page_address(STp->buffer->sg[0].page));
@@ -5252,25 +5252,26 @@ static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
 	/* Try to allocate the first segment up to OS_DATA_SIZE and the others
 	   big enough to reach the goal (code assumes no segments in place) */
 	for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) {
-		STbuffer->sg[0].page = alloc_pages(priority, order);
+		struct page *page = alloc_pages(priority, order);
+
 		STbuffer->sg[0].offset = 0;
-		if (STbuffer->sg[0].page != NULL) {
+		if (page != NULL) {
+		    sg_set_page(&STbuffer->sg[0], page);
 		    STbuffer->sg[0].length = b_size;
-		    STbuffer->b_data = page_address(STbuffer->sg[0].page);
+		    STbuffer->b_data = page_address(page);
 		    break;
 		}
 	}
-	if (STbuffer->sg[0].page == NULL) {
+	if (sg_page(&STbuffer->sg[0]) == NULL) {
 		printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n");
 		return 0;
 	}
 	/* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */
 	for (segs=STbuffer->sg_segs=1, got=b_size;
 	     segs < max_segs && got < OS_FRAME_SIZE; ) {
-		STbuffer->sg[segs].page =
-				alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
+		struct page *page = alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
 		STbuffer->sg[segs].offset = 0;
-		if (STbuffer->sg[segs].page == NULL) {
+		if (page == NULL) {
 			if (OS_FRAME_SIZE - got <= (max_segs - segs) * b_size / 2 && order) {
 				b_size /= 2;  /* Large enough for the rest of the buffers */
 				order--;
@@ -5284,6 +5285,7 @@ static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
 			normalize_buffer(STbuffer);
 			return 0;
 		}
+		sg_set_page(&STbuffer->sg[segs], page);
 		STbuffer->sg[segs].length = (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size;
 		got += STbuffer->sg[segs].length;
 		STbuffer->buffer_size = got;
@@ -5316,7 +5318,7 @@ static void normalize_buffer(struct osst_buffer *STbuffer)
 		     b_size < STbuffer->sg[i].length;
 		     b_size *= 2, order++);
 
-		__free_pages(STbuffer->sg[i].page, order);
+		__free_pages(sg_page(&STbuffer->sg[i]), order);
 		STbuffer->buffer_size -= STbuffer->sg[i].length;
 	}
 #if DEBUG
@@ -5344,7 +5346,7 @@ static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, i
 	for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length - offset < do_count ?
 		      st_bp->sg[i].length - offset : do_count;
-		res = copy_from_user(page_address(st_bp->sg[i].page) + offset, ubp, cnt);
+		res = copy_from_user(page_address(sg_page(&st_bp->sg[i])) + offset, ubp, cnt);
 		if (res)
 			return (-EFAULT);
 		do_count -= cnt;
@@ -5377,7 +5379,7 @@ static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count
 	for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length - offset < do_count ?
 		      st_bp->sg[i].length - offset : do_count;
-		res = copy_to_user(ubp, page_address(st_bp->sg[i].page) + offset, cnt);
+		res = copy_to_user(ubp, page_address(sg_page(&st_bp->sg[i])) + offset, cnt);
 		if (res)
 			return (-EFAULT);
 		do_count -= cnt;
@@ -5410,7 +5412,7 @@ static int osst_zero_buffer_tail(struct osst_buffer *st_bp)
 	     i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length - offset < do_count ?
 		      st_bp->sg[i].length - offset : do_count ;
-		memset(page_address(st_bp->sg[i].page) + offset, 0, cnt);
+		memset(page_address(sg_page(&st_bp->sg[i])) + offset, 0, cnt);
 		do_count -= cnt;
 		offset = 0;
 	}
@@ -5430,7 +5432,7 @@ static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
 	for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length < do_count ?
 		      st_bp->sg[i].length : do_count ;
-		memcpy(page_address(st_bp->sg[i].page), ptr, cnt);
+		memcpy(page_address(sg_page(&st_bp->sg[i])), ptr, cnt);
 		do_count -= cnt;
 		ptr      += cnt;
 	}
@@ -5451,7 +5453,7 @@ static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
 	for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length < do_count ?
 		      st_bp->sg[i].length : do_count ;
-		memcpy(ptr, page_address(st_bp->sg[i].page), cnt);
+		memcpy(ptr, page_address(sg_page(&st_bp->sg[i])), cnt);
 		do_count -= cnt;
 		ptr      += cnt;
 	}
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 190e2a7..26c41b0 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -443,7 +443,7 @@ SYM53C500_intr(int irq, void *dev_id)
 
 			scsi_for_each_sg(curSC, sg, scsi_sg_count(curSC), i) {
 				SYM53C500_pio_write(fast_pio, port_base,
-						    page_address(sg->page) + sg->offset,
+				    page_address(sg_page(sg)) + sg->offset,
 						    sg->length);
 			}
 			REG0(port_base);
@@ -463,8 +463,8 @@ SYM53C500_intr(int irq, void *dev_id)
 
 			scsi_for_each_sg(curSC, sg, scsi_sg_count(curSC), i) {
 				SYM53C500_pio_read(fast_pio, port_base,
-						   page_address(sg->page) + sg->offset,
-						   sg->length);
+					page_address(sg_page(sg)) + sg->offset,
+					sg->length);
 			}
 			REG0(port_base);
 		}
diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
index 67b6d76..07f31e5 100644
--- a/drivers/scsi/ppa.c
+++ b/drivers/scsi/ppa.c
@@ -609,7 +609,7 @@ static int ppa_completion(struct scsi_cmnd *cmd)
 				cmd->SCp.this_residual =
 				    cmd->SCp.buffer->length;
 				cmd->SCp.ptr =
-				    page_address(cmd->SCp.buffer->page) +
+				    page_address(sg_page(cmd->SCp.buffer)) +
 				    cmd->SCp.buffer->offset;
 			}
 		}
@@ -756,7 +756,7 @@ static int ppa_engine(ppa_struct *dev, struct scsi_cmnd *cmd)
 			/* if many buffers are available, start filling the first */
 			cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
 			cmd->SCp.this_residual = cmd->SCp.buffer->length;
-			cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) +
+			cmd->SCp.ptr = page_address(sg_page(cmd->SCp.buffer)) +
 			    cmd->SCp.buffer->offset;
 		} else {
 			/* else fill the only available buffer */
diff --git a/drivers/scsi/qlogicfas408.c b/drivers/scsi/qlogicfas408.c
index 2bfbf26..feff3f7 100644
--- a/drivers/scsi/qlogicfas408.c
+++ b/drivers/scsi/qlogicfas408.c
@@ -317,7 +317,7 @@ static unsigned int ql_pcmd(struct scsi_cmnd *cmd)
 				return ((priv->qabort == 1 ?
 					 DID_ABORT : DID_RESET) << 16);
 			}
-			buf = page_address(sg->page) + sg->offset;
+			buf = page_address(sg_page(sg)) + sg->offset;
 			if (ql_pdma(priv, phase, buf, sg->length))
 				break;
 		}
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 72ee4c9..46cae5a 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -625,7 +625,7 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
 	scsi_for_each_sg(scp, sg, scp->use_sg, k) {
 		if (active) {
 			kaddr = (unsigned char *)
-				kmap_atomic(sg->page, KM_USER0);
+				kmap_atomic(sg_page(sg), KM_USER0);
 			if (NULL == kaddr)
 				return (DID_ERROR << 16);
 			kaddr_off = (unsigned char *)kaddr + sg->offset;
@@ -672,7 +672,7 @@ static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
 	sg = scsi_sglist(scp);
 	req_len = fin = 0;
 	for (k = 0; k < scp->use_sg; ++k, sg = sg_next(sg)) {
-		kaddr = (unsigned char *)kmap_atomic(sg->page, KM_USER0);
+		kaddr = (unsigned char *)kmap_atomic(sg_page(sg), KM_USER0);
 		if (NULL == kaddr)
 			return -1;
 		kaddr_off = (unsigned char *)kaddr + sg->offset;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index aac8a02..61fdaf0 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -295,7 +295,7 @@ static int scsi_req_map_sg(struct request *rq, struct scatterlist *sgl,
 	int i, err, nr_vecs = 0;
 
 	for_each_sg(sgl, sg, nsegs, i) {
-		page = sg->page;
+		page = sg_page(sg);
 		off = sg->offset;
 		len = sg->length;
  		data_len += len;
@@ -764,7 +764,7 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
 		if (unlikely(!sgl))
 			goto enomem;
 
-		memset(sgl, 0, sizeof(*sgl) * sgp->size);
+		sg_init_table(sgl, sgp->size);
 
 		/*
 		 * first loop through, set initial index and return value
@@ -781,6 +781,13 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
 			sg_chain(prev, SCSI_MAX_SG_SEGMENTS, sgl);
 
 		/*
+		 * if we have nothing left, mark the last segment as
+		 * end-of-list
+		 */
+		if (!left)
+			sg_mark_end(sgl, this);
+
+		/*
 		 * don't allow subsequent mempool allocs to sleep, it would
 		 * violate the mempool principle.
 		 */
@@ -2353,7 +2360,7 @@ void *scsi_kmap_atomic_sg(struct scatterlist *sgl, int sg_count,
 	*offset = *offset - len_complete + sg->offset;
 
 	/* Assumption: contiguous pages can be accessed as "page + i" */
-	page = nth_page(sg->page, (*offset >> PAGE_SHIFT));
+	page = nth_page(sg_page(sg), (*offset >> PAGE_SHIFT));
 	*offset &= ~PAGE_MASK;
 
 	/* Bytes in this sg-entry from *offset to the end of the page */
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 7238b2d..cc19710 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1169,7 +1169,7 @@ sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type)
 		len = vma->vm_end - sa;
 		len = (len < sg->length) ? len : sg->length;
 		if (offset < len) {
-			page = virt_to_page(page_address(sg->page) + offset);
+			page = virt_to_page(page_address(sg_page(sg)) + offset);
 			get_page(page);	/* increment page count */
 			break;
 		}
@@ -1717,13 +1717,13 @@ st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,
 		   goto out_unlock; */
         }
 
-	sgl[0].page = pages[0];
+	sg_set_page(sgl, pages[0]);
 	sgl[0].offset = uaddr & ~PAGE_MASK;
 	if (nr_pages > 1) {
 		sgl[0].length = PAGE_SIZE - sgl[0].offset;
 		count -= sgl[0].length;
 		for (i=1; i < nr_pages ; i++) {
-			sgl[i].page = pages[i]; 
+			sg_set_page(&sgl[i], pages[i]);
 			sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
 			count -= PAGE_SIZE;
 		}
@@ -1754,7 +1754,7 @@ st_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_pages,
 	int i;
 
 	for (i=0; i < nr_pages; i++) {
-		struct page *page = sgl[i].page;
+		struct page *page = sg_page(&sgl[i]);
 
 		if (dirtied)
 			SetPageDirty(page);
@@ -1854,7 +1854,7 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
 				scatter_elem_sz_prev = ret_sz;
 			}
 		}
-		sg->page = p;
+		sg_set_page(sg, p);
 		sg->length = (ret_sz > num) ? num : ret_sz;
 
 		SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k=%d, num=%d, "
@@ -1907,14 +1907,14 @@ sg_write_xfer(Sg_request * srp)
 		onum = 1;
 
 	ksglen = sg->length;
-	p = page_address(sg->page);
+	p = page_address(sg_page(sg));
 	for (j = 0, k = 0; j < onum; ++j) {
 		res = sg_u_iovec(hp, iovec_count, j, 1, &usglen, &up);
 		if (res)
 			return res;
 
 		for (; p; sg = sg_next(sg), ksglen = sg->length,
-		     p = page_address(sg->page)) {
+		     p = page_address(sg_page(sg))) {
 			if (usglen <= 0)
 				break;
 			if (ksglen > usglen) {
@@ -1991,12 +1991,12 @@ sg_remove_scat(Sg_scatter_hold * schp)
 		} else {
 			int k;
 
-			for (k = 0; (k < schp->k_use_sg) && sg->page;
+			for (k = 0; (k < schp->k_use_sg) && sg_page(sg);
 			     ++k, sg = sg_next(sg)) {
 				SCSI_LOG_TIMEOUT(5, printk(
 				    "sg_remove_scat: k=%d, pg=0x%p, len=%d\n",
-				    k, sg->page, sg->length));
-				sg_page_free(sg->page, sg->length);
+				    k, sg_page(sg), sg->length));
+				sg_page_free(sg_page(sg), sg->length);
 			}
 		}
 		kfree(schp->buffer);
@@ -2038,7 +2038,7 @@ sg_read_xfer(Sg_request * srp)
 	} else
 		onum = 1;
 
-	p = page_address(sg->page);
+	p = page_address(sg_page(sg));
 	ksglen = sg->length;
 	for (j = 0, k = 0; j < onum; ++j) {
 		res = sg_u_iovec(hp, iovec_count, j, 0, &usglen, &up);
@@ -2046,7 +2046,7 @@ sg_read_xfer(Sg_request * srp)
 			return res;
 
 		for (; p; sg = sg_next(sg), ksglen = sg->length,
-		     p = page_address(sg->page)) {
+		     p = page_address(sg_page(sg))) {
 			if (usglen <= 0)
 				break;
 			if (ksglen > usglen) {
@@ -2092,15 +2092,15 @@ sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer)
 	if ((!outp) || (num_read_xfer <= 0))
 		return 0;
 
-	for (k = 0; (k < schp->k_use_sg) && sg->page; ++k, sg = sg_next(sg)) {
+	for (k = 0; (k < schp->k_use_sg) && sg_page(sg); ++k, sg = sg_next(sg)) {
 		num = sg->length;
 		if (num > num_read_xfer) {
-			if (__copy_to_user(outp, page_address(sg->page),
+			if (__copy_to_user(outp, page_address(sg_page(sg)),
 					   num_read_xfer))
 				return -EFAULT;
 			break;
 		} else {
-			if (__copy_to_user(outp, page_address(sg->page),
+			if (__copy_to_user(outp, page_address(sg_page(sg)),
 					   num))
 				return -EFAULT;
 			num_read_xfer -= num;
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 73c44cb..ce69b9e 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -3797,7 +3797,7 @@ static void buf_to_sg(struct st_buffer *STbp, unsigned int length)
 	sg = &(STbp->sg[0]);
 	frp = STbp->frp;
 	for (i=count=0; count < length; i++) {
-		sg[i].page = frp[i].page;
+		sg_set_page(&sg[i], frp[i].page);
 		if (length - count > frp[i].length)
 			sg[i].length = frp[i].length;
 		else
@@ -4446,14 +4446,14 @@ static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pa
         }
 
 	/* Populate the scatter/gather list */
-	sgl[0].page = pages[0]; 
+	sg_set_page(&sgl[0], pages[0]);
 	sgl[0].offset = uaddr & ~PAGE_MASK;
 	if (nr_pages > 1) {
 		sgl[0].length = PAGE_SIZE - sgl[0].offset;
 		count -= sgl[0].length;
 		for (i=1; i < nr_pages ; i++) {
+			sg_set_page(&sgl[i], pages[i]);;
 			sgl[i].offset = 0;
-			sgl[i].page = pages[i]; 
 			sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
 			count -= PAGE_SIZE;
 		}
@@ -4483,7 +4483,7 @@ static int sgl_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_p
 	int i;
 
 	for (i=0; i < nr_pages; i++) {
-		struct page *page = sgl[i].page;
+		struct page *page = sg_page(&sgl[i]);
 
 		if (dirtied)
 			SetPageDirty(page);
diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c
index 5c72ca3..4419304 100644
--- a/drivers/scsi/tmscsim.c
+++ b/drivers/scsi/tmscsim.c
@@ -430,10 +430,7 @@ static __inline__ void dc390_Going_remove (struct dc390_dcb* pDCB, struct dc390_
 
 static struct scatterlist* dc390_sg_build_single(struct scatterlist *sg, void *addr, unsigned int length)
 {
-	memset(sg, 0, sizeof(struct scatterlist));
-	sg->page	= virt_to_page(addr);
-	sg->length	= length;
-	sg->offset	= (unsigned long)addr & ~PAGE_MASK;
+	sg_init_one(sg, addr, length);
 	return sg;
 }
 
diff --git a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c
index ea72bbe..6d1f0ed 100644
--- a/drivers/scsi/ultrastor.c
+++ b/drivers/scsi/ultrastor.c
@@ -681,7 +681,7 @@ static inline void build_sg_list(struct mscp *mscp, struct scsi_cmnd *SCpnt)
 
 	max = scsi_sg_count(SCpnt);
 	scsi_for_each_sg(SCpnt, sg, max, i) {
-		mscp->sglist[i].address = isa_page_to_bus(sg->page) + sg->offset;
+		mscp->sglist[i].address = isa_page_to_bus(sg_page(sg)) + sg->offset;
 		mscp->sglist[i].num_bytes = sg->length;
 		transfer_length += sg->length;
 	}
diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c
index 255c611..03cd44f 100644
--- a/drivers/scsi/wd7000.c
+++ b/drivers/scsi/wd7000.c
@@ -1123,7 +1123,7 @@ static int wd7000_queuecommand(struct scsi_cmnd *SCpnt,
 		any2scsi(scb->maxlen, nseg * sizeof(Sgb));
 
 		scsi_for_each_sg(SCpnt, sg, nseg, i) {
-			any2scsi(sgb[i].ptr, isa_page_to_bus(sg->page) + sg->offset);
+			any2scsi(sgb[i].ptr, isa_page_to_bus(sg_page(sg)) + sg->offset);
 			any2scsi(sgb[i].len, sg->length);
 		}
 	} else {
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index c021af3..3577453 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -438,12 +438,12 @@ int usb_sg_init (
 			io->urbs[i]->transfer_buffer = NULL;
 #else
 			io->urbs[i]->transfer_buffer =
-				page_address(sg[i].page) + sg[i].offset;
+				page_address(sg_page(&sg[i])) + sg[i].offset;
 #endif
 		} else {
 			/* hc may use _only_ transfer_buffer */
 			io->urbs [i]->transfer_buffer =
-				page_address (sg [i].page) + sg [i].offset;
+				page_address(sg_page(&sg[i])) + sg [i].offset;
 			len = sg [i].length;
 		}
 
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
index e7d982a..4866baf 100644
--- a/drivers/usb/image/microtek.c
+++ b/drivers/usb/image/microtek.c
@@ -519,7 +519,7 @@ static void mts_do_sg (struct urb* transfer)
 	context->fragment++;
 	mts_int_submit_urb(transfer,
 			   context->data_pipe,
-			   page_address(sg[context->fragment].page) +
+			   page_address(sg_page(&sg[context->fragment])) +
 			   sg[context->fragment].offset,
 			   sg[context->fragment].length,
 			   context->fragment + 1 == scsi_sg_count(context->srb) ?
@@ -557,7 +557,7 @@ mts_build_transfer_context(struct scsi_cmnd *srb, struct mts_desc* desc)
 		return;
 	} else {
 		sg = scsi_sglist(srb);
-		desc->context.data = page_address(sg[0].page) + sg[0].offset;
+		desc->context.data = page_address(sg_page(&sg[0])) + sg[0].offset;
 		desc->context.data_length = sg[0].length;
 	}
 
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index e901d31..ca8cb34 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -360,9 +360,10 @@ static void free_sglist (struct scatterlist *sg, int nents)
 	if (!sg)
 		return;
 	for (i = 0; i < nents; i++) {
-		if (!sg [i].page)
+		struct page *page = sg_page(&sg[i]);
+		if (!page)
 			continue;
-		kfree (page_address (sg [i].page) + sg [i].offset);
+		kfree (page_address (page) + sg [i].offset);
 	}
 	kfree (sg);
 }
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c
index cc8f7c5..889622b 100644
--- a/drivers/usb/storage/protocol.c
+++ b/drivers/usb/storage/protocol.c
@@ -195,7 +195,7 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
 		 * the *offset and *index values for the next loop. */
 		cnt = 0;
 		while (cnt < buflen) {
-			struct page *page = sg->page +
+			struct page *page = sg_page(sg) +
 					((sg->offset + *offset) >> PAGE_SHIFT);
 			unsigned int poff =
 					(sg->offset + *offset) & (PAGE_SIZE-1);
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index 1ae90ef..0a9882e 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -283,7 +283,7 @@ int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg,
 		pg = virt_to_page(addr);
 		offset = offset_in_page(addr);
 		if (sg) {
-			sg[i].page = pg;
+			sg_set_page(&sg[i], pg);
 			sg[i].offset = offset;
 		}
 		remainder_of_page = PAGE_CACHE_SIZE - offset;
@@ -713,10 +713,13 @@ ecryptfs_encrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
 {
 	struct scatterlist src_sg, dst_sg;
 
-	src_sg.page = src_page;
+	sg_init_table(&src_sg, 1);
+	sg_init_table(&dst_sg, 1);
+
+	sg_set_page(&src_sg, src_page);
 	src_sg.offset = src_offset;
 	src_sg.length = size;
-	dst_sg.page = dst_page;
+	sg_set_page(&dst_sg, dst_page);
 	dst_sg.offset = dst_offset;
 	dst_sg.length = size;
 	return encrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
@@ -742,10 +745,13 @@ ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
 {
 	struct scatterlist src_sg, dst_sg;
 
-	src_sg.page = src_page;
+	sg_init_table(&src_sg, 1);
+	sg_init_table(&dst_sg, 1);
+
+	sg_set_page(&src_sg, src_page);
 	src_sg.offset = src_offset;
 	src_sg.length = size;
-	dst_sg.page = dst_page;
+	sg_set_page(&dst_sg, dst_page);
 	dst_sg.offset = dst_offset;
 	dst_sg.length = size;
 	return decrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 89d9710..263fed8 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -1040,6 +1040,9 @@ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
 	};
 	int rc = 0;
 
+	sg_init_table(&dst_sg, 1);
+	sg_init_table(&src_sg, 1);
+
 	if (unlikely(ecryptfs_verbosity > 0)) {
 		ecryptfs_printk(
 			KERN_DEBUG, "Session key encryption key (size [%d]):\n",
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index ebd03cc..6f03918 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -88,7 +88,7 @@ nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname)
 {
 	struct xdr_netobj cksum;
 	struct hash_desc desc;
-	struct scatterlist sg[1];
+	struct scatterlist sg;
 	__be32 status = nfserr_resource;
 
 	dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n",
@@ -102,11 +102,9 @@ nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname)
 	if (cksum.data == NULL)
  		goto out;
 
-	sg[0].page = virt_to_page(clname->data);
-	sg[0].offset = offset_in_page(clname->data);
-	sg[0].length = clname->len;
+	sg_init_one(&sg, clname->data, clname->len);
 
-	if (crypto_hash_digest(&desc, sg, sg->length, cksum.data))
+	if (crypto_hash_digest(&desc, &sg, sg.length, cksum.data))
 		goto out;
 
 	md5_to_hex(dname, cksum.data);
diff --git a/include/asm-alpha/scatterlist.h b/include/asm-alpha/scatterlist.h
index 9173654..b764706 100644
--- a/include/asm-alpha/scatterlist.h
+++ b/include/asm-alpha/scatterlist.h
@@ -5,7 +5,7 @@
 #include <asm/types.h>
   
 struct scatterlist {
-	struct page *page;
+	unsigned long page_link;
 	unsigned int offset;
 
 	unsigned int length;
diff --git a/include/asm-arm/scatterlist.h b/include/asm-arm/scatterlist.h
index de2f65e..ab1d85d 100644
--- a/include/asm-arm/scatterlist.h
+++ b/include/asm-arm/scatterlist.h
@@ -5,7 +5,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page	*page;		/* buffer page			 */
+	unsigned long	page_link;
 	unsigned int	offset;		/* buffer offset		 */
 	dma_addr_t	dma_address;	/* dma address			 */
 	unsigned int	length;		/* length			 */
diff --git a/include/asm-avr32/scatterlist.h b/include/asm-avr32/scatterlist.h
index c6d5ce3..1356f29 100644
--- a/include/asm-avr32/scatterlist.h
+++ b/include/asm-avr32/scatterlist.h
@@ -4,7 +4,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page		*page;
+    unsigned long	page_link;
     unsigned int	offset;
     dma_addr_t		dma_address;
     unsigned int	length;
diff --git a/include/asm-blackfin/scatterlist.h b/include/asm-blackfin/scatterlist.h
index 60e07b9..384af54 100644
--- a/include/asm-blackfin/scatterlist.h
+++ b/include/asm-blackfin/scatterlist.h
@@ -4,7 +4,7 @@
 #include <linux/mm.h>
 
 struct scatterlist {
-	struct page *page;
+	unsigned long page_link;
 	unsigned int offset;
 	dma_addr_t dma_address;
 	unsigned int length;
diff --git a/include/asm-cris/scatterlist.h b/include/asm-cris/scatterlist.h
index 4bdc44c..5a8a834 100644
--- a/include/asm-cris/scatterlist.h
+++ b/include/asm-cris/scatterlist.h
@@ -6,7 +6,7 @@ struct scatterlist {
 	unsigned int length;
 
 	/* The following is i386 highmem junk - not used by us */
-	struct page * page; /* Location for highmem page, if any */
+	unsigned long page_link;
 	unsigned int offset;/* for highmem, page offset */
 
 };
diff --git a/include/asm-frv/scatterlist.h b/include/asm-frv/scatterlist.h
index 8e827fa..53dade7 100644
--- a/include/asm-frv/scatterlist.h
+++ b/include/asm-frv/scatterlist.h
@@ -22,7 +22,7 @@
  * and that's it. There's no excuse for not highmem enabling YOUR driver. /jens
  */
 struct scatterlist {
-	struct page	*page;		/* Location for highmem page, if any */
+	unsigned long	page_link;
 	unsigned int	offset;		/* for highmem, page offset */
 
 	dma_addr_t	dma_address;
diff --git a/include/asm-h8300/scatterlist.h b/include/asm-h8300/scatterlist.h
index 985fdf5..7e41983 100644
--- a/include/asm-h8300/scatterlist.h
+++ b/include/asm-h8300/scatterlist.h
@@ -4,7 +4,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page	*page;
+	unsigned long	page_link;
 	unsigned int	offset;
 	dma_addr_t	dma_address;
 	unsigned int	length;
diff --git a/include/asm-ia64/scatterlist.h b/include/asm-ia64/scatterlist.h
index 7d5234d..2f76ce3 100644
--- a/include/asm-ia64/scatterlist.h
+++ b/include/asm-ia64/scatterlist.h
@@ -9,7 +9,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page *page;
+	unsigned long page_link;
 	unsigned int offset;
 	unsigned int length;	/* buffer length */
 
diff --git a/include/asm-m32r/scatterlist.h b/include/asm-m32r/scatterlist.h
index 352415f..33b4b4d 100644
--- a/include/asm-m32r/scatterlist.h
+++ b/include/asm-m32r/scatterlist.h
@@ -6,7 +6,7 @@
 struct scatterlist {
     char *  address;    /* Location data is to be transferred to, NULL for
                          * highmem page */
-    struct page * page; /* Location for highmem page, if any */
+    unsigned long page_link;
     unsigned int offset;/* for highmem, page offset */
 
     dma_addr_t dma_address;
diff --git a/include/asm-m68k/scatterlist.h b/include/asm-m68k/scatterlist.h
index 24887a2..e06bb89 100644
--- a/include/asm-m68k/scatterlist.h
+++ b/include/asm-m68k/scatterlist.h
@@ -4,7 +4,7 @@
 #include <linux/types.h>
 
 struct scatterlist {
-	struct page *page;
+	unsigned long page_link;
 	unsigned int offset;
 	unsigned int length;
 
diff --git a/include/asm-m68knommu/scatterlist.h b/include/asm-m68knommu/scatterlist.h
index 4da79d3..28bed41 100644
--- a/include/asm-m68knommu/scatterlist.h
+++ b/include/asm-m68knommu/scatterlist.h
@@ -5,7 +5,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page	*page;
+	unsigned long	page_link;
 	unsigned int	offset;
 	dma_addr_t	dma_address;
 	unsigned int	length;
diff --git a/include/asm-mips/scatterlist.h b/include/asm-mips/scatterlist.h
index 7af104c..787797c 100644
--- a/include/asm-mips/scatterlist.h
+++ b/include/asm-mips/scatterlist.h
@@ -4,7 +4,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page *	page;
+	unsigned long	page_link;
 	unsigned int	offset;
 	dma_addr_t	dma_address;
 	unsigned int	length;
diff --git a/include/asm-parisc/scatterlist.h b/include/asm-parisc/scatterlist.h
index e7211c7..26da914 100644
--- a/include/asm-parisc/scatterlist.h
+++ b/include/asm-parisc/scatterlist.h
@@ -5,7 +5,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page *page;
+	unsigned long page_link;
 	unsigned int offset;
 
 	unsigned int length;
diff --git a/include/asm-powerpc/scatterlist.h b/include/asm-powerpc/scatterlist.h
index b075f61..b9f1dbc 100644
--- a/include/asm-powerpc/scatterlist.h
+++ b/include/asm-powerpc/scatterlist.h
@@ -14,7 +14,7 @@
 #include <asm/dma.h>
 
 struct scatterlist {
-	struct page *page;
+	unsigned long page_link;
 	unsigned int offset;
 	unsigned int length;
 
diff --git a/include/asm-s390/scatterlist.h b/include/asm-s390/scatterlist.h
index a43b3af..eb39486 100644
--- a/include/asm-s390/scatterlist.h
+++ b/include/asm-s390/scatterlist.h
@@ -2,7 +2,7 @@
 #define _ASMS390_SCATTERLIST_H
 
 struct scatterlist {
-    struct page *page;
+    unsigned long page_link;
     unsigned int offset;
     unsigned int length;
 };
diff --git a/include/asm-sh/scatterlist.h b/include/asm-sh/scatterlist.h
index b9ae53c..bc7c809 100644
--- a/include/asm-sh/scatterlist.h
+++ b/include/asm-sh/scatterlist.h
@@ -4,7 +4,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page * page; /* Location for highmem page, if any */
+    unsigned long page_link;
     unsigned int offset;/* for highmem, page offset */
     dma_addr_t dma_address;
     unsigned int length;
diff --git a/include/asm-sh64/scatterlist.h b/include/asm-sh64/scatterlist.h
index 1c723f2..0afd856 100644
--- a/include/asm-sh64/scatterlist.h
+++ b/include/asm-sh64/scatterlist.h
@@ -14,7 +14,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page * page; /* Location for highmem page, if any */
+    unsigned long page_link;
     unsigned int offset;/* for highmem, page offset */
     dma_addr_t dma_address;
     unsigned int length;
diff --git a/include/asm-sparc/scatterlist.h b/include/asm-sparc/scatterlist.h
index 4055af9..45b16f1 100644
--- a/include/asm-sparc/scatterlist.h
+++ b/include/asm-sparc/scatterlist.h
@@ -5,7 +5,7 @@
 #include <linux/types.h>
 
 struct scatterlist {
-	struct page *page;
+	unsigned long page_link;
 	unsigned int offset;
 
 	unsigned int length;
diff --git a/include/asm-sparc64/scatterlist.h b/include/asm-sparc64/scatterlist.h
index 703c5bb..6df23f0 100644
--- a/include/asm-sparc64/scatterlist.h
+++ b/include/asm-sparc64/scatterlist.h
@@ -6,7 +6,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page	*page;
+#ifdef CONFIG_DEBUG_SG
+	unsigned long	sg_magic;
+#endif
+	unsigned long	page_link;
 	unsigned int	offset;
 
 	unsigned int	length;
diff --git a/include/asm-v850/scatterlist.h b/include/asm-v850/scatterlist.h
index 56f4029..db91feb 100644
--- a/include/asm-v850/scatterlist.h
+++ b/include/asm-v850/scatterlist.h
@@ -17,7 +17,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page	*page;
+	unsigned long	page_link;
 	unsigned	offset;
 	dma_addr_t	dma_address;
 	unsigned	length;
diff --git a/include/asm-x86/dma-mapping_32.h b/include/asm-x86/dma-mapping_32.h
index 6a2d26c..e0d38d8 100644
--- a/include/asm-x86/dma-mapping_32.h
+++ b/include/asm-x86/dma-mapping_32.h
@@ -45,9 +45,9 @@ dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
 	WARN_ON(nents == 0 || sglist[0].length == 0);
 
 	for_each_sg(sglist, sg, nents, i) {
-		BUG_ON(!sg->page);
+		BUG_ON(!sg_page(sg));
 
-		sg->dma_address = page_to_phys(sg->page) + sg->offset;
+		sg->dma_address = page_to_phys(sg_page(sg)) + sg->offset;
 	}
 
 	flush_write_buffers();
diff --git a/include/asm-x86/scatterlist_32.h b/include/asm-x86/scatterlist_32.h
index bd5164a..0e7d997 100644
--- a/include/asm-x86/scatterlist_32.h
+++ b/include/asm-x86/scatterlist_32.h
@@ -4,7 +4,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page		*page;
+#ifdef CONFIG_DEBUG_SG
+    unsigned long	sg_magic;
+#endif
+    unsigned long	page_link;
     unsigned int	offset;
     dma_addr_t		dma_address;
     unsigned int	length;
diff --git a/include/asm-x86/scatterlist_64.h b/include/asm-x86/scatterlist_64.h
index ef3986b..1847c72 100644
--- a/include/asm-x86/scatterlist_64.h
+++ b/include/asm-x86/scatterlist_64.h
@@ -4,7 +4,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page		*page;
+#ifdef CONFIG_DEBUG_SG
+    unsigned long	sg_magic;
+#endif
+    unsigned long	page_link;
     unsigned int	offset;
     unsigned int	length;
     dma_addr_t		dma_address;
diff --git a/include/asm-xtensa/scatterlist.h b/include/asm-xtensa/scatterlist.h
index ca337a2..3b8aba5 100644
--- a/include/asm-xtensa/scatterlist.h
+++ b/include/asm-xtensa/scatterlist.h
@@ -14,7 +14,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page 	*page;
+	unsigned long	page_link;
 	unsigned int	offset;
 	dma_addr_t	dma_address;
 	unsigned int	length;
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index 2dc7464..3ab94c8 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -5,29 +5,72 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 
+/*
+ * Notes on SG table design.
+ *
+ * Architectures must provide an unsigned long page_link field in the
+ * scatterlist struct. We use that to place the page pointer AND encode
+ * information about the sg table as well. The two lower bits are reserved
+ * for this information.
+ *
+ * If bit 0 is set, then the page_link contains a pointer to the next sg
+ * table list. Otherwise the next entry is at sg + 1.
+ *
+ * If bit 1 is set, then this sg entry is the last element in a list.
+ *
+ * See sg_next().
+ *
+ */
+
+#define SG_MAGIC	0x87654321
+
+/**
+ * sg_set_page - Set sg entry to point at given page
+ * @sg:		 SG entry
+ * @page:	 The page
+ *
+ * Use this function to set an sg entry pointing at a page, never assign
+ * the page directly. We encode sg table information in the lower bits
+ * of the page pointer. See sg_page() for looking up the page belonging
+ * to an sg entry.
+ *
+ */
+static inline void sg_set_page(struct scatterlist *sg, struct page *page)
+{
+	unsigned long page_link = sg->page_link & 0x3;
+
+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(sg->sg_magic != SG_MAGIC);
+#endif
+	sg->page_link = page_link | (unsigned long) page;
+}
+
+#define sg_page(sg)	((struct page *) ((sg)->page_link & ~0x3))
+
+/**
+ * sg_set_buf - Set sg entry to point at given data
+ * @sg:		 SG entry
+ * @buf:	 Data
+ * @buflen:	 Data length
+ * 
+*/
 static inline void sg_set_buf(struct scatterlist *sg, const void *buf,
 			      unsigned int buflen)
 {
-	sg->page = virt_to_page(buf);
+	sg_set_page(sg, virt_to_page(buf));
 	sg->offset = offset_in_page(buf);
 	sg->length = buflen;
 }
 
-static inline void sg_init_one(struct scatterlist *sg, const void *buf,
-			       unsigned int buflen)
-{
-	memset(sg, 0, sizeof(*sg));
-	sg_set_buf(sg, buf, buflen);
-}
-
 /*
  * We overload the LSB of the page pointer to indicate whether it's
  * a valid sg entry, or whether it points to the start of a new scatterlist.
  * Those low bits are there for everyone! (thanks mason :-)
  */
-#define sg_is_chain(sg)		((unsigned long) (sg)->page & 0x01)
+#define sg_is_chain(sg)		((sg)->page_link & 0x01)
+#define sg_is_last(sg)		((sg)->page_link & 0x02)
 #define sg_chain_ptr(sg)	\
-	((struct scatterlist *) ((unsigned long) (sg)->page & ~0x01))
+	((struct scatterlist *) ((sg)->page_link & ~0x03))
 
 /**
  * sg_next - return the next scatterlist entry in a list
@@ -37,14 +80,16 @@ static inline void sg_init_one(struct scatterlist *sg, const void *buf,
  * of a chained scatterlist, it could jump to the start of a new
  * scatterlist array.
  *
- * Note that the caller must ensure that there are further entries after
- * the current entry, this function will NOT return NULL for an end-of-list.
- *
  */
 static inline struct scatterlist *sg_next(struct scatterlist *sg)
 {
-	sg++;
+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(sg->sg_magic != SG_MAGIC);
+#endif
+	if (sg_is_last(sg))
+		return NULL;
 
+	sg++;
 	if (unlikely(sg_is_chain(sg)))
 		sg = sg_chain_ptr(sg);
 
@@ -83,6 +128,10 @@ static inline struct scatterlist *sg_last(struct scatterlist *sgl,
 		ret = sg;
 
 #endif
+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(sgl[0].sg_magic != SG_MAGIC);
+	BUG_ON(!sg_is_last(ret));
+#endif
 	return ret;
 }
 
@@ -101,7 +150,63 @@ static inline void sg_chain(struct scatterlist *prv, unsigned int prv_nents,
 #ifndef ARCH_HAS_SG_CHAIN
 	BUG();
 #endif
-	prv[prv_nents - 1].page = (struct page *) ((unsigned long) sgl | 0x01);
+	prv[prv_nents - 1].page_link = (unsigned long) sgl | 0x01;
+}
+
+/**
+ * sg_mark_end - Mark the end of the scatterlist
+ * @sgl:	Scatterlist
+ * @nents:	Number of entries in sgl
+ *
+ * Marks the last entry as the termination point for sg_next()
+ *
+ */
+static inline void sg_mark_end(struct scatterlist *sgl, unsigned int nents)
+{
+	sgl[nents - 1].page_link = 0x02;
+}
+
+/**
+ * sg_init_one - Initialize a single entry sg list
+ * @sg:		 SG entry
+ * @buf:	 Virtual address for IO
+ * @buflen:	 IO length
+ *
+ * Note: this should not be used on a single entry that is part of a larger
+ * table. Use sg_init_table() for that.
+ *
+ */
+static inline void sg_init_one(struct scatterlist *sg, const void *buf,
+			       unsigned int buflen)
+{
+	memset(sg, 0, sizeof(*sg));
+#ifdef CONFIG_DEBUG_SG
+	sg->sg_magic = SG_MAGIC;
+#endif
+	sg_mark_end(sg, 1);
+	sg_set_buf(sg, buf, buflen);
+}
+
+/**
+ * sg_init_table - Initialize SG table
+ * @sgl:	   The SG table
+ * @nents:	   Number of entries in table
+ *
+ * Note: If this is part of a chained sg table, sg_mark_end() should be
+ * used only on the last table part.
+ *
+ */
+static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents)
+{
+	memset(sgl, 0, sizeof(*sgl) * nents);
+	sg_mark_end(sgl, nents);
+#ifdef CONFIG_DEBUG_SG
+	{
+		int i;
+		for (i = 0; i < nents; i++)
+			sgl[i].sg_magic = SG_MAGIC;
+	}
+#endif
 }
 
 #endif /* _LINUX_SCATTERLIST_H */
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 7d16e64..183f42c 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -389,6 +389,16 @@ config DEBUG_LIST
 
 	  If unsure, say N.
 
+config DEBUG_SG
+	bool "Debug SG table operations"
+	depends on DEBUG_KERNEL
+	help
+	  Enable this to turn on checks on scatter-gather tables. This can
+	  help find problems with drivers that do not properly initialize
+	  their sg tables.
+
+	  If unsure, say N.
+
 config FRAME_POINTER
 	bool "Compile the kernel with frame pointers"
 	depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML || S390 || AVR32 || SUPERH || BFIN)
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 752fd95..e58909e 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -35,7 +35,7 @@
 #define OFFSET(val,align) ((unsigned long)	\
 	                   ( (val) & ( (align) - 1)))
 
-#define SG_ENT_VIRT_ADDRESS(sg)	(page_address((sg)->page) + (sg)->offset)
+#define SG_ENT_VIRT_ADDRESS(sg)	(page_address(sg_page((sg)) + (sg)->offset))
 #define SG_ENT_PHYS_ADDRESS(sg)	virt_to_bus(SG_ENT_VIRT_ADDRESS(sg))
 
 /*
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 70d9b5d..4e2c84f 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2045,7 +2045,7 @@ skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
 	if (copy > 0) {
 		if (copy > len)
 			copy = len;
-		sg[elt].page = virt_to_page(skb->data + offset);
+		sg_set_page(&sg[elt], virt_to_page(skb->data + offset));
 		sg[elt].offset = (unsigned long)(skb->data + offset) % PAGE_SIZE;
 		sg[elt].length = copy;
 		elt++;
@@ -2065,7 +2065,7 @@ skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
 
 			if (copy > len)
 				copy = len;
-			sg[elt].page = frag->page;
+			sg_set_page(&sg[elt], frag->page);
 			sg[elt].offset = frag->page_offset+offset-start;
 			sg[elt].length = copy;
 			elt++;
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
index 6cc54ee..34d4c77 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -390,9 +390,7 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	icv[3] = crc >> 24;
 
 	crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = len + 4;
+	sg_init_one(&sg, pos, len + 4);
 	return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
 }
 
@@ -485,9 +483,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	plen = skb->len - hdr_len - 12;
 
 	crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = plen + 4;
+	sg_init_one(&sg, pos, plen + 4);
 	if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG ": TKIP: failed to decrypt "
@@ -539,11 +535,12 @@ static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
 		printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
 		return -1;
 	}
-	sg[0].page = virt_to_page(hdr);
+	sg_init_table(sg, 2);
+	sg_set_page(&sg[0], virt_to_page(hdr));
 	sg[0].offset = offset_in_page(hdr);
 	sg[0].length = 16;
 
-	sg[1].page = virt_to_page(data);
+	sg_set_page(&sg[1], virt_to_page(data));
 	sg[1].offset = offset_in_page(data);
 	sg[1].length = data_len;
 
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
index 8d18245..0af6103 100644
--- a/net/ieee80211/ieee80211_crypt_wep.c
+++ b/net/ieee80211/ieee80211_crypt_wep.c
@@ -170,9 +170,7 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	icv[3] = crc >> 24;
 
 	crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = len + 4;
+	sg_init_one(&sg, pos, len + 4);
 	return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
 }
 
@@ -212,9 +210,7 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	plen = skb->len - hdr_len - 8;
 
 	crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = plen + 4;
+	sg_init_one(&sg, pos, plen + 4);
 	if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
 		return -7;
 
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 6675261..cc806d6 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -138,9 +138,7 @@ void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
 	*icv = cpu_to_le32(~crc32_le(~0, data, data_len));
 
 	crypto_blkcipher_setkey(tfm, rc4key, klen);
-	sg.page = virt_to_page(data);
-	sg.offset = offset_in_page(data);
-	sg.length = data_len + WEP_ICV_LEN;
+	sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
 	crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length);
 }
 
@@ -204,9 +202,7 @@ int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
 	__le32 crc;
 
 	crypto_blkcipher_setkey(tfm, rc4key, klen);
-	sg.page = virt_to_page(data);
-	sg.offset = offset_in_page(data);
-	sg.length = data_len + WEP_ICV_LEN;
+	sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
 	crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length);
 
 	crc = cpu_to_le32(~crc32_le(~0, data, data_len));
diff --git a/net/sctp/auth.c b/net/sctp/auth.c
index 7818107..cbd64b2 100644
--- a/net/sctp/auth.c
+++ b/net/sctp/auth.c
@@ -726,7 +726,8 @@ void sctp_auth_calculate_hmac(const struct sctp_association *asoc,
 
 	/* set up scatter list */
 	end = skb_tail_pointer(skb);
-	sg.page = virt_to_page(auth);
+	sg_init_table(&sg, 1);
+	sg_set_page(&sg, virt_to_page(auth));
 	sg.offset = (unsigned long)(auth) % PAGE_SIZE;
 	sg.length = end - (unsigned char *)auth;
 
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index f983a36..d5a9785 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1513,7 +1513,8 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
 		struct hash_desc desc;
 
 		/* Sign the message.  */
-		sg.page = virt_to_page(&cookie->c);
+		sg_init_table(&sg, 1);
+		sg_set_page(&sg, virt_to_page(&cookie->c));
 		sg.offset = (unsigned long)(&cookie->c) % PAGE_SIZE;
 		sg.length = bodysize;
 		keylen = SCTP_SECRET_SIZE;
@@ -1585,7 +1586,8 @@ struct sctp_association *sctp_unpack_cookie(
 
 	/* Check the signature.  */
 	keylen = SCTP_SECRET_SIZE;
-	sg.page = virt_to_page(bear_cookie);
+	sg_init_table(&sg, 1);
+	sg_set_page(&sg, virt_to_page(bear_cookie));
 	sg.offset = (unsigned long)(bear_cookie) % PAGE_SIZE;
 	sg.length = bodysize;
 	key = (char *)ep->secret_key[ep->current_key];
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index bfb6a29..32be431 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -197,9 +197,9 @@ encryptor(struct scatterlist *sg, void *data)
 		int i = (page_pos + outbuf->page_base) >> PAGE_CACHE_SHIFT;
 		in_page = desc->pages[i];
 	} else {
-		in_page = sg->page;
+		in_page = sg_page(sg);
 	}
-	desc->infrags[desc->fragno].page = in_page;
+	sg_set_page(&desc->infrags[desc->fragno], in_page);
 	desc->fragno++;
 	desc->fraglen += sg->length;
 	desc->pos += sg->length;
@@ -215,11 +215,11 @@ encryptor(struct scatterlist *sg, void *data)
 	if (ret)
 		return ret;
 	if (fraglen) {
-		desc->outfrags[0].page = sg->page;
+		sg_set_page(&desc->outfrags[0], sg_page(sg));
 		desc->outfrags[0].offset = sg->offset + sg->length - fraglen;
 		desc->outfrags[0].length = fraglen;
 		desc->infrags[0] = desc->outfrags[0];
-		desc->infrags[0].page = in_page;
+		sg_set_page(&desc->infrags[0], in_page);
 		desc->fragno = 1;
 		desc->fraglen = fraglen;
 	} else {
@@ -287,7 +287,7 @@ decryptor(struct scatterlist *sg, void *data)
 	if (ret)
 		return ret;
 	if (fraglen) {
-		desc->frags[0].page = sg->page;
+		sg_set_page(&desc->frags[0], sg_page(sg));
 		desc->frags[0].offset = sg->offset + sg->length - fraglen;
 		desc->frags[0].length = fraglen;
 		desc->fragno = 1;
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 6a59180..3d1f7cd 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -1059,7 +1059,7 @@ xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len,
 		do {
 			if (thislen > page_len)
 				thislen = page_len;
-			sg->page = buf->pages[i];
+			sg_set_page(sg, buf->pages[i]);
 			sg->offset = page_offset;
 			sg->length = thislen;
 			ret = actor(sg, data);
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index 5ced62c..fb2220a 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -552,7 +552,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
 		if (copy > len)
 			copy = len;
 
-		sg.page = virt_to_page(skb->data + offset);
+		sg_set_page(&sg, virt_to_page(skb->data + offset));
 		sg.offset = (unsigned long)(skb->data + offset) % PAGE_SIZE;
 		sg.length = copy;
 
@@ -577,7 +577,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
 			if (copy > len)
 				copy = len;
 
-			sg.page = frag->page;
+			sg_set_page(&sg, frag->page);
 			sg.offset = frag->page_offset + offset-start;
 			sg.length = copy;
 

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 13:34                                                               ` Jens Axboe
@ 2007-10-18 13:59                                                                 ` Mark Lord
  2007-10-18 14:04                                                                   ` Jens Axboe
  0 siblings, 1 reply; 151+ messages in thread
From: Mark Lord @ 2007-10-18 13:59 UTC (permalink / raw)
  To: Jens Axboe
  Cc: Jeff Garzik, Linus Torvalds, David Miller, fujita.tomonori, mingo,
	linux-kernel, alan, tomof

Jens Axboe wrote:
> On Thu, Oct 18 2007, Mark Lord wrote:
>> Jens Axboe wrote:
>>> On Thu, Oct 18 2007, Mark Lord wrote:
>>>> Jens Axboe wrote:
>>>>> On Thu, Oct 18 2007, Jeff Garzik wrote:
>>>>>> Mark Lord wrote:
>>>>>>> Okay, mine is dying with EIP at blk_rq_map_sg+0xcb/0x160.
>>>>>>> Screen photo is at http://rtr.ca/recent/2.6.23-git12-crash.jpg,
>>>>>>> but the top was cut off (isn't there a new config option or patch
>>>>>>> to do double-columns or scrollback or something ???.
>>>>>> Is this a sata_mv box?  If so, could you try this patch?
>>>>> If anything, that shrinks the size of the resulting request. Did this
>>>>> patch make any difference to you?
>>>> Not a sata_mv box, so no point here.
>>> Can you try the big patch I just posted?
>> I'll hunt for it and try it, but your earlier little patch already works 
>> fine.

I found the latest rev, and it failed to apply cleanly on -git12 or -git13
due to scsi_lib.c. After fixing that portion (replacement chunk below),
I'm now running with -git12, with the sg list debug option enabled (no messages).

Looks okay so far

 
--- a/drivers/scsi/scsi_lib.c	2007-10-18 09:35:28.000000000 -0400
+++ b/drivers/scsi/scsi_lib.c	2007-10-18 09:46:47.000000000 -0400
@@ -295,7 +295,7 @@
 	int i, err, nr_vecs = 0;
 
 	for_each_sg(sgl, sg, nsegs, i) {
-		page = sg->page;
+		page = sg_page(sg);
 		off = sg->offset;
 		len = sg->length;
  		data_len += len;
@@ -764,6 +764,8 @@
 		if (unlikely(!sgl))
 			goto enomem;
 
+		sg_init_table(sgl, sgp->size);
+
 		/*
 		 * first loop through, set initial index and return value
 		 */
@@ -779,6 +781,13 @@
 			sg_chain(prev, SCSI_MAX_SG_SEGMENTS, sgl);
 
 		/*
+		 * if we have nothing left, mark the last segment as
+		 * end-of-list
+		 */
+		if (!left)
+			sg_mark_end(sgl, this);
+
+		/*
 		 * don't allow subsequent mempool allocs to sleep, it would
 		 * violate the mempool principle.
 		 */
@@ -2351,7 +2360,7 @@
 	*offset = *offset - len_complete + sg->offset;
 
 	/* Assumption: contiguous pages can be accessed as "page + i" */
-	page = nth_page(sg->page, (*offset >> PAGE_SHIFT));
+	page = nth_page(sg_page(sg), (*offset >> PAGE_SHIFT));
 	*offset &= ~PAGE_MASK;
 
 	/* Bytes in this sg-entry from *offset to the end of the page */

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 13:58                                                             ` Jens Axboe
@ 2007-10-18 14:03                                                               ` Mark Lord
  2007-10-18 14:10                                                               ` Mark Lord
  1 sibling, 0 replies; 151+ messages in thread
From: Mark Lord @ 2007-10-18 14:03 UTC (permalink / raw)
  To: Jens Axboe
  Cc: David Miller, torvalds, fujita.tomonori, mingo, linux-kernel,
	jgarzik, alan, tomof

Jens Axboe wrote:
> On Thu, Oct 18 2007, Mark Lord wrote:
>> Jens wrote:
>>> OK, I think that covers every arch out there. I haven't been able to
>>> compile any of them, but it's mostly search'n replace operations. I hope
>>> nothing is missing linux/scatterlist.h includes...
>> Patch fails on drivers/scsi/scsi_lib.c.
>>
>> I replaced that part of the patch with this updated portion instead:
> 
> Hmm, what are you applying against? Must be a clean tree, throw away any
> patches that you already applied in this thread.


Squeaky-clean linux-2.6.23 + patch-2.6.23-git13 + your patch.
Fails on scsi_lib.c.

-ml

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 13:59                                                                 ` Mark Lord
@ 2007-10-18 14:04                                                                   ` Jens Axboe
  0 siblings, 0 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-18 14:04 UTC (permalink / raw)
  To: Mark Lord
  Cc: Jeff Garzik, Linus Torvalds, David Miller, fujita.tomonori, mingo,
	linux-kernel, alan, tomof

On Thu, Oct 18 2007, Mark Lord wrote:
> Jens Axboe wrote:
>> On Thu, Oct 18 2007, Mark Lord wrote:
>>> Jens Axboe wrote:
>>>> On Thu, Oct 18 2007, Mark Lord wrote:
>>>>> Jens Axboe wrote:
>>>>>> On Thu, Oct 18 2007, Jeff Garzik wrote:
>>>>>>> Mark Lord wrote:
>>>>>>>> Okay, mine is dying with EIP at blk_rq_map_sg+0xcb/0x160.
>>>>>>>> Screen photo is at http://rtr.ca/recent/2.6.23-git12-crash.jpg,
>>>>>>>> but the top was cut off (isn't there a new config option or patch
>>>>>>>> to do double-columns or scrollback or something ???.
>>>>>>> Is this a sata_mv box?  If so, could you try this patch?
>>>>>> If anything, that shrinks the size of the resulting request. Did this
>>>>>> patch make any difference to you?
>>>>> Not a sata_mv box, so no point here.
>>>> Can you try the big patch I just posted?
>>> I'll hunt for it and try it, but your earlier little patch already works 
>>> fine.
>
> I found the latest rev, and it failed to apply cleanly on -git12 or -git13
> due to scsi_lib.c. After fixing that portion (replacement chunk below),
> I'm now running with -git12, with the sg list debug option enabled (no 
> messages).
>
> Looks okay so far

OK, thanks a lot for testing!

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 13:56                                                         ` Jens Axboe
@ 2007-10-18 14:05                                                           ` Jens Axboe
  2007-10-18 14:16                                                             ` Benny Halevy
  0 siblings, 1 reply; 151+ messages in thread
From: Jens Axboe @ 2007-10-18 14:05 UTC (permalink / raw)
  To: Benny Halevy
  Cc: David Miller, torvalds, fujita.tomonori, mingo, linux-kernel,
	jgarzik, alan, tomof

On Thu, Oct 18 2007, Jens Axboe wrote:
> On Thu, Oct 18 2007, Benny Halevy wrote:
> > >  	return sg;
> > >  }
> > > @@ -83,6 +96,9 @@ static inline struct scatterlist *sg_last(struct scatterlist *sgl,
> > >  		ret = sg;
> > >  
> > >  #endif
> > > +#ifdef CONFIG_DEBUG_SG
> > > +	BUG_ON(sgl[0].sg_magic != SG_MAGIC);
> > 
> > can it also do BUG_ON(!sg_is_last(sg))?
> 
> That would make sense, definitely. I'll add that.

        BUG_ON(!sg_is_last(ret));

it should be, not sg. That's what I merged.

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 13:58                                                             ` Jens Axboe
  2007-10-18 14:03                                                               ` Mark Lord
@ 2007-10-18 14:10                                                               ` Mark Lord
  2007-10-18 14:13                                                                 ` Mark Lord
  1 sibling, 1 reply; 151+ messages in thread
From: Mark Lord @ 2007-10-18 14:10 UTC (permalink / raw)
  To: Jens Axboe
  Cc: David Miller, torvalds, fujita.tomonori, mingo, linux-kernel,
	jgarzik, alan, tomof

> On Thu, Oct 18 2007, Mark Lord wrote:
>> > Jens wrote:
>>> >> OK, I think that covers every arch out there. I haven't been able to
>>> >> compile any of them, but it's mostly search'n replace operations. I hope
>>> >> nothing is missing linux/scatterlist.h includes...
>> >
>> > Patch fails on drivers/scsi/scsi_lib.c.
>> >
>> > I replaced that part of the patch with this updated portion instead:
> 
> Hmm, what are you applying against? Must be a clean tree, throw away any
> patches that you already applied in this thread.
> 
> Updated below.


I'll re-pull everything fresh again from kernel.org and rebuild
with the "updated below" patch you posted.  Thanks.

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 14:10                                                               ` Mark Lord
@ 2007-10-18 14:13                                                                 ` Mark Lord
  2007-10-18 14:14                                                                   ` Jens Axboe
  0 siblings, 1 reply; 151+ messages in thread
From: Mark Lord @ 2007-10-18 14:13 UTC (permalink / raw)
  To: Jens Axboe
  Cc: David Miller, torvalds, fujita.tomonori, mingo, linux-kernel,
	jgarzik, alan, tomof

Mark Lord wrote:
>> On Thu, Oct 18 2007, Mark Lord wrote:
>>> > Jens wrote:
>>>> >> OK, I think that covers every arch out there. I haven't been able to
>>>> >> compile any of them, but it's mostly search'n replace operations. 
>>>> I hope
>>>> >> nothing is missing linux/scatterlist.h includes...
>>> >
>>> > Patch fails on drivers/scsi/scsi_lib.c.
>>> >
>>> > I replaced that part of the patch with this updated portion instead:
>>
>> Hmm, what are you applying against? Must be a clean tree, throw away any
>> patches that you already applied in this thread.
>>
>> Updated below.
> 
> 
> I'll re-pull everything fresh again from kernel.org and rebuild
> with the "updated below" patch you posted.  Thanks.

Okay, fresh pull of everything from kernel.org,
and now your latest patch does apply cleanly to -git13.

Something weird (at this end).

Thanks.

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 14:13                                                                 ` Mark Lord
@ 2007-10-18 14:14                                                                   ` Jens Axboe
  0 siblings, 0 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-18 14:14 UTC (permalink / raw)
  To: Mark Lord
  Cc: David Miller, torvalds, fujita.tomonori, mingo, linux-kernel,
	jgarzik, alan, tomof

On Thu, Oct 18 2007, Mark Lord wrote:
> Mark Lord wrote:
>>> On Thu, Oct 18 2007, Mark Lord wrote:
>>>> > Jens wrote:
>>>>> >> OK, I think that covers every arch out there. I haven't been able to
>>>>> >> compile any of them, but it's mostly search'n replace operations. I 
>>>>> hope
>>>>> >> nothing is missing linux/scatterlist.h includes...
>>>> >
>>>> > Patch fails on drivers/scsi/scsi_lib.c.
>>>> >
>>>> > I replaced that part of the patch with this updated portion instead:
>>>
>>> Hmm, what are you applying against? Must be a clean tree, throw away any
>>> patches that you already applied in this thread.
>>>
>>> Updated below.
>> I'll re-pull everything fresh again from kernel.org and rebuild
>> with the "updated below" patch you posted.  Thanks.
>
> Okay, fresh pull of everything from kernel.org,
> and now your latest patch does apply cleanly to -git13.
>
> Something weird (at this end).

Thanks for confirming, I did double check that my HEAD was uptodate -
and it is.

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 14:05                                                           ` Jens Axboe
@ 2007-10-18 14:16                                                             ` Benny Halevy
  2007-10-18 14:38                                                               ` Jens Axboe
  0 siblings, 1 reply; 151+ messages in thread
From: Benny Halevy @ 2007-10-18 14:16 UTC (permalink / raw)
  To: Jens Axboe
  Cc: David Miller, torvalds, fujita.tomonori, mingo, linux-kernel,
	jgarzik, alan, tomof

On Oct. 18, 2007, 16:05 +0200, Jens Axboe <jens.axboe@oracle.com> wrote:
> On Thu, Oct 18 2007, Jens Axboe wrote:
>> On Thu, Oct 18 2007, Benny Halevy wrote:
>>>>  	return sg;
>>>>  }
>>>> @@ -83,6 +96,9 @@ static inline struct scatterlist *sg_last(struct scatterlist *sgl,
>>>>  		ret = sg;
>>>>  
>>>>  #endif
>>>> +#ifdef CONFIG_DEBUG_SG
>>>> +	BUG_ON(sgl[0].sg_magic != SG_MAGIC);
>>> can it also do BUG_ON(!sg_is_last(sg))?
>> That would make sense, definitely. I'll add that.
> 
>         BUG_ON(!sg_is_last(ret));
> 
> it should be, not sg. That's what I merged.
> 
right. of course.

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 14:16                                                             ` Benny Halevy
@ 2007-10-18 14:38                                                               ` Jens Axboe
  2007-10-18 14:58                                                                 ` Olof Johansson
  0 siblings, 1 reply; 151+ messages in thread
From: Jens Axboe @ 2007-10-18 14:38 UTC (permalink / raw)
  To: Benny Halevy
  Cc: David Miller, torvalds, fujita.tomonori, mingo, linux-kernel,
	jgarzik, alan, tomof

On Thu, Oct 18 2007, Benny Halevy wrote:
> On Oct. 18, 2007, 16:05 +0200, Jens Axboe <jens.axboe@oracle.com> wrote:
> > On Thu, Oct 18 2007, Jens Axboe wrote:
> >> On Thu, Oct 18 2007, Benny Halevy wrote:
> >>>>  	return sg;
> >>>>  }
> >>>> @@ -83,6 +96,9 @@ static inline struct scatterlist *sg_last(struct scatterlist *sgl,
> >>>>  		ret = sg;
> >>>>  
> >>>>  #endif
> >>>> +#ifdef CONFIG_DEBUG_SG
> >>>> +	BUG_ON(sgl[0].sg_magic != SG_MAGIC);
> >>> can it also do BUG_ON(!sg_is_last(sg))?
> >> That would make sense, definitely. I'll add that.
> > 
> >         BUG_ON(!sg_is_last(ret));
> > 
> > it should be, not sg. That's what I merged.
> > 
> right. of course.

OK, that found something interesting - mapping a request may shrink it,
so we need to update the end marker to move it earlier in the list.
Basically just a

        if (sg)
                __sg_mark_end(sg);

at the bottom of blk_rq_map_sg(). Updated patch below, booted on other
machines now as well without incident.


diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index e1c4707..094a95e 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -465,7 +465,7 @@ EXPORT_SYMBOL(pci_free_consistent);
    Write dma_length of each leader with the combined lengths of
    the mergable followers.  */
 
-#define SG_ENT_VIRT_ADDRESS(SG) (page_address((SG)->page) + (SG)->offset)
+#define SG_ENT_VIRT_ADDRESS(SG) (page_address(sg_page((SG)) + (SG)->offset))
 #define SG_ENT_PHYS_ADDRESS(SG) __pa(SG_ENT_VIRT_ADDRESS(SG))
 
 static void
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 44ab0da..9d371e4 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -442,7 +442,7 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 	BUG_ON(dir == DMA_NONE);
 
 	for (i = 0; i < nents; i++, sg++) {
-		struct page *page = sg->page;
+		struct page *page = sg_page(sg);
 		unsigned int offset = sg->offset;
 		unsigned int length = sg->length;
 		void *ptr = page_address(page) + offset;
diff --git a/arch/blackfin/kernel/dma-mapping.c b/arch/blackfin/kernel/dma-mapping.c
index 94d7b11..dbf7222 100644
--- a/arch/blackfin/kernel/dma-mapping.c
+++ b/arch/blackfin/kernel/dma-mapping.c
@@ -160,7 +160,7 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 	BUG_ON(direction == DMA_NONE);
 
 	for (i = 0; i < nents; i++, sg++) {
-		sg->dma_address = (dma_addr_t)(page_address(sg->page) +
+		sg->dma_address = (dma_addr_t)(page_address(sg_page(sg)) +
 					sg->offset);
 
 		invalidate_dcache_range(sg_dma_address(sg),
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index 3c95f41..0b74c63 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -246,7 +246,7 @@ static int reserve_sba_gart = 1;
 static SBA_INLINE void sba_mark_invalid(struct ioc *, dma_addr_t, size_t);
 static SBA_INLINE void sba_free_range(struct ioc *, dma_addr_t, size_t);
 
-#define sba_sg_address(sg)	(page_address((sg)->page) + (sg)->offset)
+#define sba_sg_address(sg)	(page_address(sg_page((sg)) + (sg)->offset))
 
 #ifdef FULL_VALID_PDIR
 static u64 prefetch_spill_page;
diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c
index a3a558a..7f1794f 100644
--- a/arch/ia64/hp/sim/simscsi.c
+++ b/arch/ia64/hp/sim/simscsi.c
@@ -131,7 +131,7 @@ simscsi_sg_readwrite (struct scsi_cmnd *sc, int mode, unsigned long offset)
 	stat.fd = desc[sc->device->id];
 
 	scsi_for_each_sg(sc, sl, scsi_sg_count(sc), i) {
-		req.addr = __pa(page_address(sl->page) + sl->offset);
+		req.addr = __pa(page_address(sg_page(sl)) + sl->offset);
 		req.len  = sl->length;
 		if (DBG)
 			printk("simscsi_sg_%s @ %lx (off %lx) use_sg=%d len=%d\n",
@@ -212,7 +212,7 @@ static void simscsi_fillresult(struct scsi_cmnd *sc, char *buf, unsigned len)
 		if (!len)
 			break;
 		thislen = min(len, slp->length);
-		memcpy(page_address(slp->page) + slp->offset, buf, thislen);
+		memcpy(page_address(sg_page(slp)) + slp->offset, buf, thislen);
 		len -= thislen;
 	}
 }
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index ecd8a52..6048eaf 100644
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -16,7 +16,7 @@
 #include <asm/sn/pcidev.h>
 #include <asm/sn/sn_sal.h>
 
-#define SG_ENT_VIRT_ADDRESS(sg)	(page_address((sg)->page) + (sg)->offset)
+#define SG_ENT_VIRT_ADDRESS(sg)	(page_address(sg_page((sg)) + (sg)->offset))
 #define SG_ENT_PHYS_ADDRESS(SG)	virt_to_phys(SG_ENT_VIRT_ADDRESS(SG))
 
 /**
diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c
index 9d4e4b5..b2d620b 100644
--- a/arch/m68k/kernel/dma.c
+++ b/arch/m68k/kernel/dma.c
@@ -121,7 +121,7 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 	int i;
 
 	for (i = 0; i < nents; sg++, i++) {
-		sg->dma_address = page_to_phys(sg->page) + sg->offset;
+		sg->dma_address = page_to_phys(sg_page(sg)) + sg->offset;
 		dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);
 	}
 	return nents;
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 98b5e5b..4aa143b 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -165,7 +165,7 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 	for (i = 0; i < nents; i++, sg++) {
 		unsigned long addr;
 
-		addr = (unsigned long) page_address(sg->page);
+		addr = (unsigned long) page_address(sg_page(sg));
 		if (!plat_device_is_coherent(dev) && addr)
 			__dma_sync(addr + sg->offset, sg->length, direction);
 		sg->dma_address = plat_map_dma_mem(dev,
@@ -223,7 +223,7 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
 	for (i = 0; i < nhwentries; i++, sg++) {
 		if (!plat_device_is_coherent(dev) &&
 		    direction != DMA_TO_DEVICE) {
-			addr = (unsigned long) page_address(sg->page);
+			addr = (unsigned long) page_address(sg_page(sg));
 			if (addr)
 				__dma_sync(addr + sg->offset, sg->length,
 				           direction);
@@ -304,7 +304,7 @@ void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
 	/* Make sure that gcc doesn't leave the empty loop body.  */
 	for (i = 0; i < nelems; i++, sg++) {
 		if (cpu_is_noncoherent_r10000(dev))
-			__dma_sync((unsigned long)page_address(sg->page),
+			__dma_sync((unsigned long)page_address(sg_page(sg)),
 			           sg->length, direction);
 		plat_unmap_dma_mem(sg->dma_address);
 	}
@@ -322,7 +322,7 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nele
 	/* Make sure that gcc doesn't leave the empty loop body.  */
 	for (i = 0; i < nelems; i++, sg++) {
 		if (!plat_device_is_coherent(dev))
-			__dma_sync((unsigned long)page_address(sg->page),
+			__dma_sync((unsigned long)page_address(sg_page(sg)),
 			           sg->length, direction);
 		plat_unmap_dma_mem(sg->dma_address);
 	}
diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
index 9001104..5d0aa90 100644
--- a/arch/powerpc/kernel/dma_64.c
+++ b/arch/powerpc/kernel/dma_64.c
@@ -161,7 +161,7 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
 	int i;
 
 	for_each_sg(sgl, sg, nents, i) {
-		sg->dma_address = (page_to_phys(sg->page) + sg->offset) |
+		sg->dma_address = (page_to_phys(sg_page(sg)) + sg->offset) |
 			dma_direct_offset;
 		sg->dma_length = sg->length;
 	}
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index 289d7e9..3d0e71b 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -102,7 +102,7 @@ static int ibmebus_map_sg(struct device *dev,
 	int i;
 
 	for_each_sg(sgl, sg, nents, i) {
-		sg->dma_address = (dma_addr_t)page_address(sg->page)
+		sg->dma_address = (dma_addr_t)page_address(sg_page(sg))
 			+ sg->offset;
 		sg->dma_length = sg->length;
 	}
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 306a6f7..47d745a 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -307,7 +307,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
 			continue;
 		}
 		/* Allocate iommu entries for that segment */
-		vaddr = (unsigned long)page_address(s->page) + s->offset;
+		vaddr = (unsigned long)page_address(sg_page(s)) + s->offset;
 		npages = iommu_num_pages(vaddr, slen);
 		entry = iommu_range_alloc(tbl, npages, &handle, mask >> IOMMU_PAGE_SHIFT, 0);
 
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 07e64b4..e8202b6 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -629,7 +629,7 @@ static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sgl,
 
 	for_each_sg(sgl, sg, nents, i) {
 		int result = ps3_dma_map(dev->d_region,
-			page_to_phys(sg->page) + sg->offset, sg->length,
+			page_to_phys(sg_page(sg)) + sg->offset, sg->length,
 					 &sg->dma_address, 0);
 
 		if (result) {
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 9c3ed88..abc4470 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -727,9 +727,9 @@ int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents,
 	BUG_ON(direction == PCI_DMA_NONE);
 	/* IIep is write-through, not flushing. */
 	for_each_sg(sgl, sg, nents, n) {
-		BUG_ON(page_address(sg->page) == NULL);
+		BUG_ON(page_address(sg_page(sg)) == NULL);
 		sg->dvma_address =
-			virt_to_phys(page_address(sg->page)) + sg->offset;
+			virt_to_phys(page_address(sg_page(sg))) + sg->offset;
 		sg->dvma_length = sg->length;
 	}
 	return nents;
@@ -748,9 +748,9 @@ void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents,
 	BUG_ON(direction == PCI_DMA_NONE);
 	if (direction != PCI_DMA_TODEVICE) {
 		for_each_sg(sgl, sg, nents, n) {
-			BUG_ON(page_address(sg->page) == NULL);
+			BUG_ON(page_address(sg_page(sg)) == NULL);
 			mmu_inval_dma_area(
-			    (unsigned long) page_address(sg->page),
+			    (unsigned long) page_address(sg_page(sg)),
 			    (sg->length + PAGE_SIZE-1) & PAGE_MASK);
 		}
 	}
@@ -798,9 +798,9 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sgl, int
 	BUG_ON(direction == PCI_DMA_NONE);
 	if (direction != PCI_DMA_TODEVICE) {
 		for_each_sg(sgl, sg, nents, n) {
-			BUG_ON(page_address(sg->page) == NULL);
+			BUG_ON(page_address(sg_page(sg)) == NULL);
 			mmu_inval_dma_area(
-			    (unsigned long) page_address(sg->page),
+			    (unsigned long) page_address(sg_page(sg)),
 			    (sg->length + PAGE_SIZE-1) & PAGE_MASK);
 		}
 	}
@@ -814,9 +814,9 @@ void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sgl,
 	BUG_ON(direction == PCI_DMA_NONE);
 	if (direction != PCI_DMA_TODEVICE) {
 		for_each_sg(sgl, sg, nents, n) {
-			BUG_ON(page_address(sg->page) == NULL);
+			BUG_ON(page_address(sg_page(sg)) == NULL);
 			mmu_inval_dma_area(
-			    (unsigned long) page_address(sg->page),
+			    (unsigned long) page_address(sg_page(sg)),
 			    (sg->length + PAGE_SIZE-1) & PAGE_MASK);
 		}
 	}
diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c
index 375b4db..0f2ad57 100644
--- a/arch/sparc/mm/io-unit.c
+++ b/arch/sparc/mm/io-unit.c
@@ -144,7 +144,7 @@ static void iounit_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus
 	spin_lock_irqsave(&iounit->lock, flags);
 	while (sz != 0) {
 		--sz;
-		sg->dvma_address = iounit_get_area(iounit, (unsigned long)page_address(sg->page) + sg->offset, sg->length);
+		sg->dvma_address = iounit_get_area(iounit, (unsigned long)page_address(sg_page(sg)) + sg->offset, sg->length);
 		sg->dvma_length = sg->length;
 		sg = sg_next(sg);
 	}
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
index 283656d..4b93427 100644
--- a/arch/sparc/mm/iommu.c
+++ b/arch/sparc/mm/iommu.c
@@ -238,7 +238,7 @@ static void iommu_get_scsi_sgl_noflush(struct scatterlist *sg, int sz, struct sb
 	while (sz != 0) {
 		--sz;
 		n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
-		sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset;
+		sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset;
 		sg->dvma_length = (__u32) sg->length;
 		sg = sg_next(sg);
 	}
@@ -252,7 +252,7 @@ static void iommu_get_scsi_sgl_gflush(struct scatterlist *sg, int sz, struct sbu
 	while (sz != 0) {
 		--sz;
 		n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
-		sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset;
+		sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset;
 		sg->dvma_length = (__u32) sg->length;
 		sg = sg_next(sg);
 	}
@@ -273,7 +273,7 @@ static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbu
 		 * XXX Is this a good assumption?
 		 * XXX What if someone else unmaps it here and races us?
 		 */
-		if ((page = (unsigned long) page_address(sg->page)) != 0) {
+		if ((page = (unsigned long) page_address(sg_page(sg))) != 0) {
 			for (i = 0; i < n; i++) {
 				if (page != oldpage) {	/* Already flushed? */
 					flush_page_for_dma(page);
@@ -283,7 +283,7 @@ static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbu
 			}
 		}
 
-		sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset;
+		sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset;
 		sg->dvma_length = (__u32) sg->length;
 		sg = sg_next(sg);
 	}
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
index ee6708f..f172dbe 100644
--- a/arch/sparc/mm/sun4c.c
+++ b/arch/sparc/mm/sun4c.c
@@ -1228,7 +1228,7 @@ static void sun4c_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *
 {
 	while (sz != 0) {
 		--sz;
-		sg->dvma_address = (__u32)sun4c_lockarea(page_address(sg->page) + sg->offset, sg->length);
+		sg->dvma_address = (__u32)sun4c_lockarea(page_address(sg_page(sg)) + sg->offset, sg->length);
 		sg->dvma_length = sg->length;
 		sg = sg_next(sg);
 	}
diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c
index 29af777..73852a2 100644
--- a/arch/sparc64/kernel/iommu.c
+++ b/arch/sparc64/kernel/iommu.c
@@ -473,7 +473,7 @@ static void dma_4u_unmap_single(struct device *dev, dma_addr_t bus_addr,
 }
 
 #define SG_ENT_PHYS_ADDRESS(SG)	\
-	(__pa(page_address((SG)->page)) + (SG)->offset)
+	(__pa(page_address(sg_page(SG))) + (SG)->offset)
 
 static void fill_sg(iopte_t *iopte, struct scatterlist *sg,
 		    int nused, int nelems,
@@ -566,7 +566,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
 	if (nelems == 1) {
 		sglist->dma_address =
 			dma_4u_map_single(dev,
-					  (page_address(sglist->page) +
+					  (page_address(sg_page(sglist)) +
 					   sglist->offset),
 					  sglist->length, direction);
 		if (unlikely(sglist->dma_address == DMA_ERROR_CODE))
diff --git a/arch/sparc64/kernel/iommu_common.c b/arch/sparc64/kernel/iommu_common.c
index d7ca900..ec863e0 100644
--- a/arch/sparc64/kernel/iommu_common.c
+++ b/arch/sparc64/kernel/iommu_common.c
@@ -73,7 +73,7 @@ static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg,
 
 	daddr = dma_sg->dma_address;
 	sglen = sg->length;
-	sgaddr = (unsigned long) (page_address(sg->page) + sg->offset);
+	sgaddr = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
 	while (dlen > 0) {
 		unsigned long paddr;
 
@@ -123,7 +123,7 @@ static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg,
 		sg = sg_next(sg);
 		if (--nents <= 0)
 			break;
-		sgaddr = (unsigned long) (page_address(sg->page) + sg->offset);
+		sgaddr = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
 		sglen = sg->length;
 	}
 	if (dlen < 0) {
@@ -191,7 +191,7 @@ void verify_sglist(struct scatterlist *sglist, int nents, iopte_t *iopte, int np
 			printk("sg(%d): page_addr(%p) off(%x) length(%x) "
 			       "dma_address[%016x] dma_length[%016x]\n",
 			       i,
-			       page_address(sg->page), sg->offset,
+			       page_address(sg_page(sg)), sg->offset,
 			       sg->length,
 			       sg->dma_address, sg->dma_length);
 		}
@@ -207,15 +207,15 @@ unsigned long prepare_sg(struct scatterlist *sg, int nents)
 	unsigned long prev;
 	u32 dent_addr, dent_len;
 
-	prev  = (unsigned long) (page_address(sg->page) + sg->offset);
+	prev  = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
 	prev += (unsigned long) (dent_len = sg->length);
-	dent_addr = (u32) ((unsigned long)(page_address(sg->page) + sg->offset)
+	dent_addr = (u32) ((unsigned long)(page_address(sg_page(sg)) + sg->offset)
 			   & (IO_PAGE_SIZE - 1UL));
 	while (--nents) {
 		unsigned long addr;
 
 		sg = sg_next(sg);
-		addr = (unsigned long) (page_address(sg->page) + sg->offset);
+		addr = (unsigned long) (page_address(sg_page(sg)) + sg->offset);
 		if (! VCONTIG(prev, addr)) {
 			dma_sg->dma_address = dent_addr;
 			dma_sg->dma_length = dent_len;
diff --git a/arch/sparc64/kernel/ldc.c b/arch/sparc64/kernel/ldc.c
index 85a2be0..c8313cb 100644
--- a/arch/sparc64/kernel/ldc.c
+++ b/arch/sparc64/kernel/ldc.c
@@ -2057,7 +2057,7 @@ static void fill_cookies(struct cookie_state *sp, unsigned long pa,
 
 static int sg_count_one(struct scatterlist *sg)
 {
-	unsigned long base = page_to_pfn(sg->page) << PAGE_SHIFT;
+	unsigned long base = page_to_pfn(sg_page(sg)) << PAGE_SHIFT;
 	long len = sg->length;
 
 	if ((sg->offset | len) & (8UL - 1))
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index fe46ace..5324a34 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -366,7 +366,7 @@ static void dma_4v_unmap_single(struct device *dev, dma_addr_t bus_addr,
 }
 
 #define SG_ENT_PHYS_ADDRESS(SG)	\
-	(__pa(page_address((SG)->page)) + (SG)->offset)
+	(__pa(page_address(sg_page(SG))) + (SG)->offset)
 
 static long fill_sg(long entry, struct device *dev,
 		    struct scatterlist *sg,
@@ -478,7 +478,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
 	if (nelems == 1) {
 		sglist->dma_address =
 			dma_4v_map_single(dev,
-					  (page_address(sglist->page) +
+					  (page_address(sg_page(sglist)) +
 					   sglist->offset),
 					  sglist->length, direction);
 		if (unlikely(sglist->dma_address == DMA_ERROR_CODE))
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 25b248a..3a8cd3d 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -1115,7 +1115,7 @@ static void do_ubd_request(struct request_queue *q)
 			}
 			prepare_request(req, io_req,
 					(unsigned long long) req->sector << 9,
-					sg->offset, sg->length, sg->page);
+					sg->offset, sg->length, sg_page(sg));
 
 			last_sectors = sg->length >> 9;
 			n = os_write_file(thread_fd, &io_req,
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 5098f58..c9f0eb0 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -411,8 +411,10 @@ static int calgary_nontranslate_map_sg(struct device* dev,
 	int i;
 
 	for_each_sg(sg, s, nelems, i) {
-		BUG_ON(!s->page);
-		s->dma_address = virt_to_bus(page_address(s->page) +s->offset);
+		struct page *p = sg_page(s);
+
+		BUG_ON(!p);
+		s->dma_address = virt_to_bus(page_address(p) + s->offset);
 		s->dma_length = s->length;
 	}
 	return nelems;
@@ -432,9 +434,11 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
 		return calgary_nontranslate_map_sg(dev, sg, nelems, direction);
 
 	for_each_sg(sg, s, nelems, i) {
-		BUG_ON(!s->page);
+		struct page *p = sg_page(s);
+
+		BUG_ON(!p);
 
-		vaddr = (unsigned long)page_address(s->page) + s->offset;
+		vaddr = (unsigned long)page_address(p) + s->offset;
 		npages = num_dma_pages(vaddr, s->length);
 
 		entry = iommu_range_alloc(tbl, npages);
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index 5cdfab6..daaf636 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -302,7 +302,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
 #endif
 
 	for_each_sg(sg, s, nents, i) {
-		unsigned long addr = page_to_phys(s->page) + s->offset; 
+		unsigned long addr = page_to_phys(sg_page(s)) + s->offset; 
 		if (nonforced_iommu(dev, addr, s->length)) { 
 			addr = dma_map_area(dev, addr, s->length, dir);
 			if (addr == bad_dma_address) { 
@@ -397,7 +397,7 @@ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 	start_sg = sgmap = sg;
 	ps = NULL; /* shut up gcc */
 	for_each_sg(sg, s, nents, i) {
-		dma_addr_t addr = page_to_phys(s->page) + s->offset;
+		dma_addr_t addr = page_to_phys(sg_page(s)) + s->offset;
 		s->dma_address = addr;
 		BUG_ON(s->length == 0); 
 
diff --git a/arch/x86/kernel/pci-nommu_64.c b/arch/x86/kernel/pci-nommu_64.c
index e85d436..d64a4a5 100644
--- a/arch/x86/kernel/pci-nommu_64.c
+++ b/arch/x86/kernel/pci-nommu_64.c
@@ -62,8 +62,8 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
 	int i;
 
 	for_each_sg(sg, s, nents, i) {
-		BUG_ON(!s->page);
-		s->dma_address = virt_to_bus(page_address(s->page) +s->offset);
+		BUG_ON(!sg_page(s));
+		s->dma_address = virt_to_bus(page_address(sg_page(s)) +s->offset);
 		if (!check_addr("map_sg", hwdev, s->dma_address, s->length))
 			return 0;
 		s->dma_length = s->length;
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 3935469..37ed29b 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -1354,8 +1354,9 @@ new_segment:
 			else
 				sg = sg_next(sg);
 
-			memset(sg, 0, sizeof(*sg));
-			sg->page = bvec->bv_page;
+			sg_dma_len(sg) = 0;
+			sg_dma_address(sg) = 0;
+			sg_set_page(sg, bvec->bv_page);
 			sg->length = nbytes;
 			sg->offset = bvec->bv_offset;
 			nsegs++;
@@ -1363,6 +1364,9 @@ new_segment:
 		bvprv = bvec;
 	} /* segments in rq */
 
+	if (sg)
+		__sg_mark_end(sg);
+
 	return nsegs;
 }
 
diff --git a/crypto/digest.c b/crypto/digest.c
index e56de67..8871dec 100644
--- a/crypto/digest.c
+++ b/crypto/digest.c
@@ -41,7 +41,7 @@ static int update2(struct hash_desc *desc,
 		return 0;
 
 	for (;;) {
-		struct page *pg = sg->page;
+		struct page *pg = sg_page(sg);
 		unsigned int offset = sg->offset;
 		unsigned int l = sg->length;
 
diff --git a/crypto/hmac.c b/crypto/hmac.c
index 8802fb6..e4eb6ac 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -159,7 +159,8 @@ static int hmac_digest(struct hash_desc *pdesc, struct scatterlist *sg,
 	desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP;
 
 	sg_set_buf(sg1, ipad, bs);
-	sg1[1].page = (void *)sg;
+
+	sg_set_page(&sg[1], (void *) sg);
 	sg1[1].length = 0;
 	sg_set_buf(sg2, opad, bs + ds);
 
diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c
index d6852c3..b9bbda0 100644
--- a/crypto/scatterwalk.c
+++ b/crypto/scatterwalk.c
@@ -54,7 +54,7 @@ static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
 	if (out) {
 		struct page *page;
 
-		page = walk->sg->page + ((walk->offset - 1) >> PAGE_SHIFT);
+		page = sg_page(walk->sg) + ((walk->offset - 1) >> PAGE_SHIFT);
 		flush_dcache_page(page);
 	}
 
diff --git a/crypto/scatterwalk.h b/crypto/scatterwalk.h
index 9c73e37..87ed681 100644
--- a/crypto/scatterwalk.h
+++ b/crypto/scatterwalk.h
@@ -22,13 +22,13 @@
 
 static inline struct scatterlist *scatterwalk_sg_next(struct scatterlist *sg)
 {
-	return (++sg)->length ? sg : (void *)sg->page;
+	return (++sg)->length ? sg : (void *) sg_page(sg);
 }
 
 static inline unsigned long scatterwalk_samebuf(struct scatter_walk *walk_in,
 						struct scatter_walk *walk_out)
 {
-	return !(((walk_in->sg->page - walk_out->sg->page) << PAGE_SHIFT) +
+	return !(((sg_page(walk_in->sg) - sg_page(walk_out->sg)) << PAGE_SHIFT) +
 		 (int)(walk_in->offset - walk_out->offset));
 }
 
@@ -60,7 +60,7 @@ static inline unsigned int scatterwalk_aligned(struct scatter_walk *walk,
 
 static inline struct page *scatterwalk_page(struct scatter_walk *walk)
 {
-	return walk->sg->page + (walk->offset >> PAGE_SHIFT);
+	return sg_page(walk->sg) + (walk->offset >> PAGE_SHIFT);
 }
 
 static inline void scatterwalk_unmap(void *vaddr, int out)
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 18d489c..d741c63 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -317,7 +317,7 @@ static void test_cipher(char *algo, int enc,
 				goto out;
 			}
 
-			q = kmap(sg[0].page) + sg[0].offset;
+			q = kmap(sg_page(&sg[0])) + sg[0].offset;
 			hexdump(q, cipher_tv[i].rlen);
 
 			printk("%s\n",
@@ -390,7 +390,7 @@ static void test_cipher(char *algo, int enc,
 			temp = 0;
 			for (k = 0; k < cipher_tv[i].np; k++) {
 				printk("page %u\n", k);
-				q = kmap(sg[k].page) + sg[k].offset;
+				q = kmap(sg_page(&sg[k])) + sg[k].offset;
 				hexdump(q, cipher_tv[i].tap[k]);
 				printk("%s\n",
 					memcmp(q, cipher_tv[i].result + temp,
diff --git a/crypto/xcbc.c b/crypto/xcbc.c
index 9f502b8..ac68f3b 100644
--- a/crypto/xcbc.c
+++ b/crypto/xcbc.c
@@ -120,7 +120,7 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc,
 
 	do {
 
-		struct page *pg = sg[i].page;
+		struct page *pg = sg_page(&sg[i]);
 		unsigned int offset = sg[i].offset;
 		unsigned int slen = sg[i].length;
 
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index bbaa545..b1fa70a 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4296,7 +4296,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
 		sg_last(sg, qc->orig_n_elem)->length += qc->pad_len;
 		if (pad_buf) {
 			struct scatterlist *psg = &qc->pad_sgent;
-			void *addr = kmap_atomic(psg->page, KM_IRQ0);
+			void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
 			memcpy(addr + psg->offset, pad_buf, qc->pad_len);
 			kunmap_atomic(addr, KM_IRQ0);
 		}
@@ -4686,11 +4686,11 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
 		 * data in this function or read data in ata_sg_clean.
 		 */
 		offset = lsg->offset + lsg->length - qc->pad_len;
-		psg->page = nth_page(lsg->page, offset >> PAGE_SHIFT);
+		sg_set_page(psg, nth_page(sg_page(lsg), offset >> PAGE_SHIFT));
 		psg->offset = offset_in_page(offset);
 
 		if (qc->tf.flags & ATA_TFLAG_WRITE) {
-			void *addr = kmap_atomic(psg->page, KM_IRQ0);
+			void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
 			memcpy(pad_buf, addr + psg->offset, qc->pad_len);
 			kunmap_atomic(addr, KM_IRQ0);
 		}
@@ -4836,7 +4836,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
 	if (qc->curbytes == qc->nbytes - qc->sect_size)
 		ap->hsm_task_state = HSM_ST_LAST;
 
-	page = qc->cursg->page;
+	page = sg_page(qc->cursg);
 	offset = qc->cursg->offset + qc->cursg_ofs;
 
 	/* get the current page and offset */
@@ -4988,7 +4988,7 @@ next_sg:
 
 	sg = qc->cursg;
 
-	page = sg->page;
+	page = sg_page(sg);
 	offset = sg->offset + qc->cursg_ofs;
 
 	/* get the current page and offset */
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 9fbb39c..5b758b9 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1544,7 +1544,7 @@ static unsigned int ata_scsi_rbuf_get(struct scsi_cmnd *cmd, u8 **buf_out)
 	struct scatterlist *sg = scsi_sglist(cmd);
 
 	if (sg) {
-		buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+		buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 		buflen = sg->length;
 	} else {
 		buf = NULL;
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 7c2cfde..5a6fe17 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -2610,7 +2610,7 @@ static void do_cciss_request(struct request_queue *q)
 	       (int)creq->nr_sectors);
 #endif				/* CCISS_DEBUG */
 
-	memset(tmp_sg, 0, sizeof(tmp_sg));
+	sg_init_table(tmp_sg, MAXSGENTRIES);
 	seg = blk_rq_map_sg(q, creq, tmp_sg);
 
 	/* get the DMA records for the setup */
@@ -2621,7 +2621,7 @@ static void do_cciss_request(struct request_queue *q)
 
 	for (i = 0; i < seg; i++) {
 		c->SG[i].Len = tmp_sg[i].length;
-		temp64.val = (__u64) pci_map_page(h->pdev, tmp_sg[i].page,
+		temp64.val = (__u64) pci_map_page(h->pdev, sg_page(&tmp_sg[i]),
 						  tmp_sg[i].offset,
 						  tmp_sg[i].length, dir);
 		c->SG[i].Addr.lower = temp64.val32.lower;
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index 568603d..efab27f 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -918,6 +918,7 @@ queue_next:
 DBGPX(
 	printk("sector=%d, nr_sectors=%d\n", creq->sector, creq->nr_sectors);
 );
+	sg_init_table(tmp_sg, SG_MAX);
 	seg = blk_rq_map_sg(q, creq, tmp_sg);
 
 	/* Now do all the DMA Mappings */
@@ -929,7 +930,7 @@ DBGPX(
 	{
 		c->req.sg[i].size = tmp_sg[i].length;
 		c->req.sg[i].addr = (__u32) pci_map_page(h->pci_dev,
-						 tmp_sg[i].page,
+						 sg_page(&tmp_sg[i]),
 						 tmp_sg[i].offset,
 						 tmp_sg[i].length, dir);
 	}
diff --git a/drivers/block/cryptoloop.c b/drivers/block/cryptoloop.c
index 4053503..1b58b01 100644
--- a/drivers/block/cryptoloop.c
+++ b/drivers/block/cryptoloop.c
@@ -26,6 +26,7 @@
 #include <linux/crypto.h>
 #include <linux/blkdev.h>
 #include <linux/loop.h>
+#include <linux/scatterlist.h>
 #include <asm/semaphore.h>
 #include <asm/uaccess.h>
 
@@ -119,14 +120,17 @@ cryptoloop_transfer(struct loop_device *lo, int cmd,
 		.tfm = tfm,
 		.flags = CRYPTO_TFM_REQ_MAY_SLEEP,
 	};
-	struct scatterlist sg_out = { NULL, };
-	struct scatterlist sg_in = { NULL, };
+	struct scatterlist sg_out;
+	struct scatterlist sg_in;
 
 	encdec_cbc_t encdecfunc;
 	struct page *in_page, *out_page;
 	unsigned in_offs, out_offs;
 	int err;
 
+	sg_init_table(&sg_out, 1);
+	sg_init_table(&sg_in, 1);
+
 	if (cmd == READ) {
 		in_page = raw_page;
 		in_offs = raw_off;
@@ -146,11 +150,11 @@ cryptoloop_transfer(struct loop_device *lo, int cmd,
 		u32 iv[4] = { 0, };
 		iv[0] = cpu_to_le32(IV & 0xffffffff);
 
-		sg_in.page = in_page;
+		sg_set_page(&sg_in, in_page);
 		sg_in.offset = in_offs;
 		sg_in.length = sz;
 
-		sg_out.page = out_page;
+		sg_set_page(&sg_out, out_page);
 		sg_out.offset = out_offs;
 		sg_out.length = sz;
 
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index c57dd2b..d6f7b43 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -25,6 +25,7 @@
 #include <linux/usb_usual.h>
 #include <linux/blkdev.h>
 #include <linux/timer.h>
+#include <linux/scatterlist.h>
 #include <scsi/scsi.h>
 
 #define DRV_NAME "ub"
@@ -656,6 +657,7 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq)
 	if ((cmd = ub_get_cmd(lun)) == NULL)
 		return -1;
 	memset(cmd, 0, sizeof(struct ub_scsi_cmd));
+	sg_init_table(cmd->sgv, UB_MAX_REQ_SG);
 
 	blkdev_dequeue_request(rq);
 
@@ -1310,7 +1312,7 @@ static void ub_data_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 		pipe = sc->send_bulk_pipe;
 	sc->last_pipe = pipe;
 	usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe,
-	    page_address(sg->page) + sg->offset, sg->length,
+	    page_address(sg_page(sg)) + sg->offset, sg->length,
 	    ub_urb_complete, sc);
 	sc->work_urb.actual_length = 0;
 	sc->work_urb.error_count = 0;
@@ -1427,7 +1429,7 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 	scmd->state = UB_CMDST_INIT;
 	scmd->nsg = 1;
 	sg = &scmd->sgv[0];
-	sg->page = virt_to_page(sc->top_sense);
+	sg_set_page(sg, virt_to_page(sc->top_sense));
 	sg->offset = (unsigned long)sc->top_sense & (PAGE_SIZE-1);
 	sg->length = UB_SENSE_SIZE;
 	scmd->len = UB_SENSE_SIZE;
@@ -1863,7 +1865,7 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
 	cmd->state = UB_CMDST_INIT;
 	cmd->nsg = 1;
 	sg = &cmd->sgv[0];
-	sg->page = virt_to_page(p);
+	sg_set_page(sg, virt_to_page(p));
 	sg->offset = (unsigned long)p & (PAGE_SIZE-1);
 	sg->length = 8;
 	cmd->len = 8;
diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c
index 06c75f1..3979bf4 100644
--- a/drivers/ide/cris/ide-cris.c
+++ b/drivers/ide/cris/ide-cris.c
@@ -934,11 +934,11 @@ static int cris_ide_build_dmatable (ide_drive_t *drive)
 		 * than two possibly non-adjacent physical 4kB pages.
 		 */
 		/* group sequential buffers into one large buffer */
-		addr = page_to_phys(sg->page) + sg->offset;
+		addr = page_to_phys(sg_page(sg)) + sg->offset;
 		size = sg_dma_len(sg);
 		while (--i) {
 			sg = sg_next(sg);
-			if ((addr + size) != page_to_phys(sg->page) + sg->offset)
+			if ((addr + size) != page_to_phys(sg_page(sg)) + sg->offset)
 				break;
 			size += sg_dma_len(sg);
 		}
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 3c945d6..7c640cd 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -1337,12 +1337,14 @@ static int hwif_init(ide_hwif_t *hwif)
 	if (!hwif->sg_max_nents)
 		hwif->sg_max_nents = PRD_ENTRIES;
 
-	hwif->sg_table = kzalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
+	hwif->sg_table = kmalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
 				 GFP_KERNEL);
 	if (!hwif->sg_table) {
 		printk(KERN_ERR "%s: unable to allocate SG table.\n", hwif->name);
 		goto out;
 	}
+
+	sg_init_table(hwif->sg_table, hwif->sg_max_nents);
 	
 	if (init_irq(hwif) == 0)
 		goto done;
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 2a3c8d4..086157f 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -278,7 +278,7 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
 		hwif->cursg = sg;
 	}
 
-	page = cursg->page;
+	page = sg_page(cursg);
 	offset = cursg->offset + hwif->cursg_ofs * SECTOR_SIZE;
 
 	/* get the current page and offset */
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
index 47c035a..1b22ab7 100644
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -276,7 +276,7 @@ static int auide_build_dmatable(ide_drive_t *drive)
 
 			if (iswrite) {
 				if(!put_source_flags(ahwif->tx_chan, 
-						     (void*)(page_address(sg->page) 
+						     (void*)(page_address(sg_page(sg)) 
 							     + sg->offset), 
 						     tc, flags)) { 
 					printk(KERN_ERR "%s failed %d\n", 
@@ -285,7 +285,7 @@ static int auide_build_dmatable(ide_drive_t *drive)
 			} else 
 			{
 				if(!put_dest_flags(ahwif->rx_chan, 
-						   (void*)(page_address(sg->page) 
+						   (void*)(page_address(sg_page(sg)) 
 							   + sg->offset), 
 						   tc, flags)) { 
 					printk(KERN_ERR "%s failed %d\n", 
diff --git a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c
index 45d6055..25e113b 100644
--- a/drivers/ieee1394/dma.c
+++ b/drivers/ieee1394/dma.c
@@ -111,7 +111,7 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes,
 		unsigned long va =
 		    (unsigned long)dma->kvirt + (i << PAGE_SHIFT);
 
-		dma->sglist[i].page = vmalloc_to_page((void *)va);
+		sg_set_page(&dma->sglist[i], vmalloc_to_page((void *)va));
 		dma->sglist[i].length = PAGE_SIZE;
 	}
 
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 1b353b9..d5dfe11 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -1466,7 +1466,7 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb,
 		cmd->dma_size = sgpnt[0].length;
 		cmd->dma_type = CMD_DMA_PAGE;
 		cmd->cmd_dma = dma_map_page(hi->host->device.parent,
-					    sgpnt[0].page, sgpnt[0].offset,
+					    sg_page(&sgpnt[0]), sgpnt[0].offset,
 					    cmd->dma_size, cmd->dma_dir);
 
 		orb->data_descriptor_lo = cmd->cmd_dma;
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index 2f54e29..14159ff 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -55,9 +55,11 @@ static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int d
 		ib_dma_unmap_sg(dev, chunk->page_list,
 				chunk->nents, DMA_BIDIRECTIONAL);
 		for (i = 0; i < chunk->nents; ++i) {
+			struct page *page = sg_page(&chunk->page_list[i]);
+
 			if (umem->writable && dirty)
-				set_page_dirty_lock(chunk->page_list[i].page);
-			put_page(chunk->page_list[i].page);
+				set_page_dirty_lock(page);
+			put_page(page);
 		}
 
 		kfree(chunk);
@@ -164,11 +166,12 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
 			}
 
 			chunk->nents = min_t(int, ret, IB_UMEM_MAX_PAGE_CHUNK);
+			sg_init_table(chunk->page_list, chunk->nents);
 			for (i = 0; i < chunk->nents; ++i) {
 				if (vma_list &&
 				    !is_vm_hugetlb_page(vma_list[i + off]))
 					umem->hugetlb = 0;
-				chunk->page_list[i].page   = page_list[i + off];
+				sg_set_page(&chunk->page_list[i], page_list[i + off]);
 				chunk->page_list[i].offset = 0;
 				chunk->page_list[i].length = PAGE_SIZE;
 			}
@@ -179,7 +182,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
 						    DMA_BIDIRECTIONAL);
 			if (chunk->nmap <= 0) {
 				for (i = 0; i < chunk->nents; ++i)
-					put_page(chunk->page_list[i].page);
+					put_page(sg_page(&chunk->page_list[i]));
 				kfree(chunk);
 
 				ret = -ENOMEM;
diff --git a/drivers/infiniband/hw/ipath/ipath_dma.c b/drivers/infiniband/hw/ipath/ipath_dma.c
index 22709a4..e90a0ea 100644
--- a/drivers/infiniband/hw/ipath/ipath_dma.c
+++ b/drivers/infiniband/hw/ipath/ipath_dma.c
@@ -108,7 +108,7 @@ static int ipath_map_sg(struct ib_device *dev, struct scatterlist *sgl,
 	BUG_ON(!valid_dma_direction(direction));
 
 	for_each_sg(sgl, sg, nents, i) {
-		addr = (u64) page_address(sg->page);
+		addr = (u64) page_address(sg_page(sg));
 		/* TODO: handle highmem pages */
 		if (!addr) {
 			ret = 0;
@@ -127,7 +127,7 @@ static void ipath_unmap_sg(struct ib_device *dev,
 
 static u64 ipath_sg_dma_address(struct ib_device *dev, struct scatterlist *sg)
 {
-	u64 addr = (u64) page_address(sg->page);
+	u64 addr = (u64) page_address(sg_page(sg));
 
 	if (addr)
 		addr += sg->offset;
diff --git a/drivers/infiniband/hw/ipath/ipath_mr.c b/drivers/infiniband/hw/ipath/ipath_mr.c
index e442470..db4ba92 100644
--- a/drivers/infiniband/hw/ipath/ipath_mr.c
+++ b/drivers/infiniband/hw/ipath/ipath_mr.c
@@ -225,7 +225,7 @@ struct ib_mr *ipath_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
 		for (i = 0; i < chunk->nents; i++) {
 			void *vaddr;
 
-			vaddr = page_address(chunk->page_list[i].page);
+			vaddr = page_address(sg_page(&chunk->page_list[i]));
 			if (!vaddr) {
 				ret = ERR_PTR(-EINVAL);
 				goto bail;
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
index e61f3e6..007b381 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -71,7 +71,7 @@ static void mthca_free_icm_pages(struct mthca_dev *dev, struct mthca_icm_chunk *
 			     PCI_DMA_BIDIRECTIONAL);
 
 	for (i = 0; i < chunk->npages; ++i)
-		__free_pages(chunk->mem[i].page,
+		__free_pages(sg_page(&chunk->mem[i]),
 			     get_order(chunk->mem[i].length));
 }
 
@@ -81,7 +81,7 @@ static void mthca_free_icm_coherent(struct mthca_dev *dev, struct mthca_icm_chun
 
 	for (i = 0; i < chunk->npages; ++i) {
 		dma_free_coherent(&dev->pdev->dev, chunk->mem[i].length,
-				  lowmem_page_address(chunk->mem[i].page),
+				  lowmem_page_address(sg_page(&chunk->mem[i])),
 				  sg_dma_address(&chunk->mem[i]));
 	}
 }
@@ -107,10 +107,13 @@ void mthca_free_icm(struct mthca_dev *dev, struct mthca_icm *icm, int coherent)
 
 static int mthca_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_mask)
 {
-	mem->page = alloc_pages(gfp_mask, order);
-	if (!mem->page)
+	struct page *page;
+
+	page = alloc_pages(gfp_mask, order);
+	if (!page)
 		return -ENOMEM;
 
+	sg_set_page(mem, page);
 	mem->length = PAGE_SIZE << order;
 	mem->offset = 0;
 	return 0;
@@ -157,6 +160,7 @@ struct mthca_icm *mthca_alloc_icm(struct mthca_dev *dev, int npages,
 			if (!chunk)
 				goto fail;
 
+			sg_init_table(chunk->mem, MTHCA_ICM_CHUNK_LEN);
 			chunk->npages = 0;
 			chunk->nsg    = 0;
 			list_add_tail(&chunk->list, &icm->chunk_list);
@@ -304,7 +308,7 @@ void *mthca_table_find(struct mthca_icm_table *table, int obj, dma_addr_t *dma_h
 			 * so if we found the page, dma_handle has already
 			 * been assigned to. */
 			if (chunk->mem[i].length > offset) {
-				page = chunk->mem[i].page;
+				page = sg_page(&chunk->mem[i]);
 				goto out;
 			}
 			offset -= chunk->mem[i].length;
@@ -445,6 +449,7 @@ static u64 mthca_uarc_virt(struct mthca_dev *dev, struct mthca_uar *uar, int pag
 int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
 		      struct mthca_user_db_table *db_tab, int index, u64 uaddr)
 {
+	struct page *pages[1];
 	int ret = 0;
 	u8 status;
 	int i;
@@ -472,16 +477,17 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
 	}
 
 	ret = get_user_pages(current, current->mm, uaddr & PAGE_MASK, 1, 1, 0,
-			     &db_tab->page[i].mem.page, NULL);
+			     pages, NULL);
 	if (ret < 0)
 		goto out;
 
+	sg_set_page(&db_tab->page[i].mem, pages[0]);
 	db_tab->page[i].mem.length = MTHCA_ICM_PAGE_SIZE;
 	db_tab->page[i].mem.offset = uaddr & ~PAGE_MASK;
 
 	ret = pci_map_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
 	if (ret < 0) {
-		put_page(db_tab->page[i].mem.page);
+		put_page(pages[0]);
 		goto out;
 	}
 
@@ -491,7 +497,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
 		ret = -EINVAL;
 	if (ret) {
 		pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
-		put_page(db_tab->page[i].mem.page);
+		put_page(sg_page(&db_tab->page[i].mem));
 		goto out;
 	}
 
@@ -557,7 +563,7 @@ void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar,
 		if (db_tab->page[i].uvirt) {
 			mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, uar, i), 1, &status);
 			pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
-			put_page(db_tab->page[i].mem.page);
+			put_page(sg_page(&db_tab->page[i].mem));
 		}
 	}
 
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
index f3529b6..813b96b 100644
--- a/drivers/infiniband/ulp/iser/iser_memory.c
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -131,7 +131,7 @@ static int iser_start_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
 
 		p = mem;
 		for_each_sg(sgl, sg, data->size, i) {
-			from = kmap_atomic(sg->page, KM_USER0);
+			from = kmap_atomic(sg_page(sg), KM_USER0);
 			memcpy(p,
 			       from + sg->offset,
 			       sg->length);
@@ -191,7 +191,7 @@ void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
 
 		p = mem;
 		for_each_sg(sgl, sg, sg_size, i) {
-			to = kmap_atomic(sg->page, KM_SOFTIRQ0);
+			to = kmap_atomic(sg_page(sg), KM_SOFTIRQ0);
 			memcpy(to + sg->offset,
 			       p,
 			       sg->length);
@@ -300,7 +300,7 @@ static unsigned int iser_data_buf_aligned_len(struct iser_data_buf *data,
 	for_each_sg(sgl, sg, data->dma_nents, i) {
 		/* iser_dbg("Checking sg iobuf [%d]: phys=0x%08lX "
 		   "offset: %ld sz: %ld\n", i,
-		   (unsigned long)page_to_phys(sg->page),
+		   (unsigned long)page_to_phys(sg_page(sg)),
 		   (unsigned long)sg->offset,
 		   (unsigned long)sg->length); */
 		end_addr = ib_sg_dma_address(ibdev, sg) +
@@ -336,7 +336,7 @@ static void iser_data_buf_dump(struct iser_data_buf *data,
 		iser_err("sg[%d] dma_addr:0x%lX page:0x%p "
 			 "off:0x%x sz:0x%x dma_len:0x%x\n",
 			 i, (unsigned long)ib_sg_dma_address(ibdev, sg),
-			 sg->page, sg->offset,
+			 sg_page(sg), sg->offset,
 			 sg->length, ib_sg_dma_len(ibdev, sg));
 }
 
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 64fee90..cde915f 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -346,16 +346,17 @@ static int crypt_convert(struct crypt_config *cc,
 	      ctx->idx_out < ctx->bio_out->bi_vcnt) {
 		struct bio_vec *bv_in = bio_iovec_idx(ctx->bio_in, ctx->idx_in);
 		struct bio_vec *bv_out = bio_iovec_idx(ctx->bio_out, ctx->idx_out);
-		struct scatterlist sg_in = {
-			.page = bv_in->bv_page,
-			.offset = bv_in->bv_offset + ctx->offset_in,
-			.length = 1 << SECTOR_SHIFT
-		};
-		struct scatterlist sg_out = {
-			.page = bv_out->bv_page,
-			.offset = bv_out->bv_offset + ctx->offset_out,
-			.length = 1 << SECTOR_SHIFT
-		};
+		struct scatterlist sg_in, sg_out;
+
+		sg_init_table(&sg_in, 1);
+		sg_set_page(&sg_in, bv_in->bv_page);
+		sg_in.offset = bv_in->bv_offset + ctx->offset_in;
+		sg_in.length = 1 << SECTOR_SHIFT;
+		
+		sg_init_table(&sg_out, 1);
+		sg_set_page(&sg_out, bv_out->bv_page);
+		sg_out.offset = bv_out->bv_offset + ctx->offset_out;
+		sg_out.length = 1 << SECTOR_SHIFT;
 
 		ctx->offset_in += sg_in.length;
 		if (ctx->offset_in >= bv_in->bv_len) {
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c
index 365a221..2b1f8b4 100644
--- a/drivers/media/common/saa7146_core.c
+++ b/drivers/media/common/saa7146_core.c
@@ -112,12 +112,13 @@ static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages)
 	sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL);
 	if (NULL == sglist)
 		return NULL;
+	sg_init_table(sglist, nr_pages);
 	for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
 		pg = vmalloc_to_page(virt);
 		if (NULL == pg)
 			goto err;
 		BUG_ON(PageHighMem(pg));
-		sglist[i].page   = pg;
+		sg_set_page(&sglist[i], pg);
 		sglist[i].length = PAGE_SIZE;
 	}
 	return sglist;
diff --git a/drivers/media/video/ivtv/ivtv-udma.c b/drivers/media/video/ivtv/ivtv-udma.c
index c4626d1..912b424 100644
--- a/drivers/media/video/ivtv/ivtv-udma.c
+++ b/drivers/media/video/ivtv/ivtv-udma.c
@@ -63,10 +63,10 @@ int ivtv_udma_fill_sg_list (struct ivtv_user_dma *dma, struct ivtv_dma_page_info
 			memcpy(page_address(dma->bouncemap[map_offset]) + offset, src, len);
 			kunmap_atomic(src, KM_BOUNCE_READ);
 			local_irq_restore(flags);
-			dma->SGlist[map_offset].page = dma->bouncemap[map_offset];
+			sg_set_page(&dma->SGlist[map_offset], dma->bouncemap[map_offset]);
 		}
 		else {
-			dma->SGlist[map_offset].page = dma->map[map_offset];
+			sg_set_page(&dma->SGlist[map_offset], dma->map[map_offset]);
 		}
 		offset = 0;
 		map_offset++;
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
index 3eb6123..0a18286 100644
--- a/drivers/media/video/videobuf-dma-sg.c
+++ b/drivers/media/video/videobuf-dma-sg.c
@@ -60,12 +60,13 @@ videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages)
 	sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL);
 	if (NULL == sglist)
 		return NULL;
+	sg_init_table(sglist, nr_pages);
 	for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
 		pg = vmalloc_to_page(virt);
 		if (NULL == pg)
 			goto err;
 		BUG_ON(PageHighMem(pg));
-		sglist[i].page   = pg;
+		sg_set_page(&sglist[i], pg);
 		sglist[i].length = PAGE_SIZE;
 	}
 	return sglist;
@@ -86,13 +87,14 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
 	sglist = kcalloc(nr_pages, sizeof(*sglist), GFP_KERNEL);
 	if (NULL == sglist)
 		return NULL;
+	sg_init_table(sglist, nr_pages);
 
 	if (NULL == pages[0])
 		goto nopage;
 	if (PageHighMem(pages[0]))
 		/* DMA to highmem pages might not work */
 		goto highmem;
-	sglist[0].page   = pages[0];
+	sg_set_page(&sglist[0], pages[0]);
 	sglist[0].offset = offset;
 	sglist[0].length = PAGE_SIZE - offset;
 	for (i = 1; i < nr_pages; i++) {
@@ -100,7 +102,7 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
 			goto nopage;
 		if (PageHighMem(pages[i]))
 			goto highmem;
-		sglist[i].page   = pages[i];
+		sg_set_page(&sglist[i], pages[i]);
 		sglist[i].length = PAGE_SIZE;
 	}
 	return sglist;
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index a5d0354..68c1fe9 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -13,6 +13,7 @@
 #include <linux/blkdev.h>
 #include <linux/freezer.h>
 #include <linux/kthread.h>
+#include <linux/scatterlist.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
@@ -153,19 +154,21 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
 			blk_queue_max_hw_segments(mq->queue, bouncesz / 512);
 			blk_queue_max_segment_size(mq->queue, bouncesz);
 
-			mq->sg = kzalloc(sizeof(struct scatterlist),
+			mq->sg = kmalloc(sizeof(struct scatterlist),
 				GFP_KERNEL);
 			if (!mq->sg) {
 				ret = -ENOMEM;
 				goto cleanup_queue;
 			}
+			sg_init_table(mq->sg, 1);
 
-			mq->bounce_sg = kzalloc(sizeof(struct scatterlist) *
+			mq->bounce_sg = kmalloc(sizeof(struct scatterlist) *
 				bouncesz / 512, GFP_KERNEL);
 			if (!mq->bounce_sg) {
 				ret = -ENOMEM;
 				goto cleanup_queue;
 			}
+			sg_init_table(mq->bounce_sg, bouncesz / 512);
 		}
 	}
 #endif
@@ -302,12 +305,12 @@ static void copy_sg(struct scatterlist *dst, unsigned int dst_len,
 		BUG_ON(dst_len == 0);
 
 		if (dst_size == 0) {
-			dst_buf = page_address(dst->page) + dst->offset;
+			dst_buf = page_address(sg_page(dst)) + dst->offset;
 			dst_size = dst->length;
 		}
 
 		if (src_size == 0) {
-			src_buf = page_address(src->page) + src->offset;
+			src_buf = page_address(sg_page(src)) + src->offset;
 			src_size = src->length;
 		}
 
@@ -353,9 +356,7 @@ unsigned int mmc_queue_map_sg(struct mmc_queue *mq)
 		return 1;
 	}
 
-	mq->sg[0].page = virt_to_page(mq->bounce_buf);
-	mq->sg[0].offset = offset_in_page(mq->bounce_buf);
-	mq->sg[0].length = 0;
+	sg_init_one(mq->sg, mq->bounce_buf, 0);
 
 	while (sg_len) {
 		mq->sg[0].length += mq->bounce_sg[sg_len - 1].length;
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index 7a452c2..b1edcef 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -149,7 +149,7 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data
 
 		sg = &data->sg[i];
 
-		sgbuffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
+		sgbuffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
 		amount = min(size, sg->length);
 		size -= amount;
 
@@ -226,7 +226,7 @@ static void at91_mci_pre_dma_read(struct at91mci_host *host)
 		sg = &data->sg[host->transfer_index++];
 		pr_debug("sg = %p\n", sg);
 
-		sg->dma_address = dma_map_page(NULL, sg->page, sg->offset, sg->length, DMA_FROM_DEVICE);
+		sg->dma_address = dma_map_page(NULL, sg_page(sg), sg->offset, sg->length, DMA_FROM_DEVICE);
 
 		pr_debug("dma address = %08X, length = %d\n", sg->dma_address, sg->length);
 
@@ -283,7 +283,7 @@ static void at91_mci_post_dma_read(struct at91mci_host *host)
 			int index;
 
 			/* Swap the contents of the buffer */
-			buffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
+			buffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
 			pr_debug("buffer = %p, length = %d\n", buffer, sg->length);
 
 			for (index = 0; index < (sg->length / 4); index++)
@@ -292,7 +292,7 @@ static void at91_mci_post_dma_read(struct at91mci_host *host)
 			kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
 		}
 
-		flush_dcache_page(sg->page);
+		flush_dcache_page(sg_page(sg));
 	}
 
 	/* Is there another transfer to trigger? */
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c
index 92c4d0d..0632f4d 100644
--- a/drivers/mmc/host/au1xmmc.c
+++ b/drivers/mmc/host/au1xmmc.c
@@ -340,7 +340,7 @@ static void au1xmmc_send_pio(struct au1xmmc_host *host)
 
 	/* This is the pointer to the data buffer */
 	sg = &data->sg[host->pio.index];
-	sg_ptr = page_address(sg->page) + sg->offset + host->pio.offset;
+	sg_ptr = page_address(sg_page(sg)) + sg->offset + host->pio.offset;
 
 	/* This is the space left inside the buffer */
 	sg_len = data->sg[host->pio.index].length - host->pio.offset;
@@ -400,7 +400,7 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host)
 
 	if (host->pio.index < host->dma.len) {
 		sg = &data->sg[host->pio.index];
-		sg_ptr = page_address(sg->page) + sg->offset + host->pio.offset;
+		sg_ptr = page_address(sg_page(sg)) + sg->offset + host->pio.offset;
 
 		/* This is the space left inside the buffer */
 		sg_len = sg_dma_len(&data->sg[host->pio.index]) - host->pio.offset;
@@ -613,13 +613,13 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data)
 
     			if (host->flags & HOST_F_XMIT){
       				ret = au1xxx_dbdma_put_source_flags(channel,
-					(void *) (page_address(sg->page) +
+					(void *) (page_address(sg_page(sg)) +
 						  sg->offset),
 					len, flags);
 			}
     			else {
       				ret = au1xxx_dbdma_put_dest_flags(channel,
-					(void *) (page_address(sg->page) +
+					(void *) (page_address(sg_page(sg)) +
 						  sg->offset),
 					len, flags);
 			}
diff --git a/drivers/mmc/host/imxmmc.c b/drivers/mmc/host/imxmmc.c
index 6ebc41e..581bb8f 100644
--- a/drivers/mmc/host/imxmmc.c
+++ b/drivers/mmc/host/imxmmc.c
@@ -262,7 +262,7 @@ static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data)
 		}
 
 		/* Convert back to virtual address */
-		host->data_ptr = (u16*)(page_address(data->sg->page) + data->sg->offset);
+		host->data_ptr = (u16*)(page_address(sg_page(data->sg)) + data->sg->offset);
 		host->data_cnt = 0;
 
 		clear_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events);
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 7ae18ea..12c2d80 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -813,7 +813,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
 					&& dir == DMA_FROM_DEVICE)
 				dir = DMA_BIDIRECTIONAL;
 
-			dma_addr = dma_map_page(dma_dev, sg->page, 0,
+			dma_addr = dma_map_page(dma_dev, sg_page(sg), 0,
 						PAGE_SIZE, dir);
 			if (direction == DMA_TO_DEVICE)
 				t->tx_dma = dma_addr + sg->offset;
@@ -822,7 +822,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
 		}
 
 		/* allow pio too; we don't allow highmem */
-		kmap_addr = kmap(sg->page);
+		kmap_addr = kmap(sg_page(sg));
 		if (direction == DMA_TO_DEVICE)
 			t->tx_buf = kmap_addr + sg->offset;
 		else
@@ -855,8 +855,8 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
 
 		/* discard mappings */
 		if (direction == DMA_FROM_DEVICE)
-			flush_kernel_dcache_page(sg->page);
-		kunmap(sg->page);
+			flush_kernel_dcache_page(sg_page(sg));
+		kunmap(sg_page(sg));
 		if (dma_dev)
 			dma_unmap_page(dma_dev, dma_addr, PAGE_SIZE, dir);
 
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 60a67df..649f647 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -24,10 +24,10 @@
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
 #include <linux/clk.h>
+#include <linux/scatterlist.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/scatterlist.h>
 #include <asm/mach-types.h>
 
 #include <asm/arch/board.h>
@@ -383,7 +383,7 @@ mmc_omap_sg_to_buf(struct mmc_omap_host *host)
 
 	sg = host->data->sg + host->sg_idx;
 	host->buffer_bytes_left = sg->length;
-	host->buffer = page_address(sg->page) + sg->offset;
+	host->buffer = page_address(sg_page(sg)) + sg->offset;
 	if (host->buffer_bytes_left > host->total_bytes_left)
 		host->buffer_bytes_left = host->total_bytes_left;
 }
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index b397121..b6500e9 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -231,7 +231,7 @@ static void sdhci_deactivate_led(struct sdhci_host *host)
 
 static inline char* sdhci_sg_to_buffer(struct sdhci_host* host)
 {
-	return page_address(host->cur_sg->page) + host->cur_sg->offset;
+	return page_address(sg_page(host->cur_sg)) + host->cur_sg->offset;
 }
 
 static inline int sdhci_next_sg(struct sdhci_host* host)
diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c
index 9b90479..c11a3d2 100644
--- a/drivers/mmc/host/tifm_sd.c
+++ b/drivers/mmc/host/tifm_sd.c
@@ -192,7 +192,7 @@ static void tifm_sd_transfer_data(struct tifm_sd *host)
 		}
 		off = sg[host->sg_pos].offset + host->block_pos;
 
-		pg = nth_page(sg[host->sg_pos].page, off >> PAGE_SHIFT);
+		pg = nth_page(sg_page(&sg[host->sg_pos]), off >> PAGE_SHIFT);
 		p_off = offset_in_page(off);
 		p_cnt = PAGE_SIZE - p_off;
 		p_cnt = min(p_cnt, cnt);
@@ -241,18 +241,18 @@ static void tifm_sd_bounce_block(struct tifm_sd *host, struct mmc_data *r_data)
 		}
 		off = sg[host->sg_pos].offset + host->block_pos;
 
-		pg = nth_page(sg[host->sg_pos].page, off >> PAGE_SHIFT);
+		pg = nth_page(sg_page(&sg[host->sg_pos]), off >> PAGE_SHIFT);
 		p_off = offset_in_page(off);
 		p_cnt = PAGE_SIZE - p_off;
 		p_cnt = min(p_cnt, cnt);
 		p_cnt = min(p_cnt, t_size);
 
 		if (r_data->flags & MMC_DATA_WRITE)
-			tifm_sd_copy_page(host->bounce_buf.page,
+			tifm_sd_copy_page(sg_page(&host->bounce_buf),
 					  r_data->blksz - t_size,
 					  pg, p_off, p_cnt);
 		else if (r_data->flags & MMC_DATA_READ)
-			tifm_sd_copy_page(pg, p_off, host->bounce_buf.page,
+			tifm_sd_copy_page(pg, p_off, sg_page(&host->bounce_buf),
 					  r_data->blksz - t_size, p_cnt);
 
 		t_size -= p_cnt;
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c
index 80db11c..971ca0f 100644
--- a/drivers/mmc/host/wbsd.c
+++ b/drivers/mmc/host/wbsd.c
@@ -269,7 +269,7 @@ static inline int wbsd_next_sg(struct wbsd_host *host)
 
 static inline char *wbsd_sg_to_buffer(struct wbsd_host *host)
 {
-	return page_address(host->cur_sg->page) + host->cur_sg->offset;
+	return page_address(sg_page(host->cur_sg)) + host->cur_sg->offset;
 }
 
 static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data)
@@ -283,7 +283,7 @@ static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data)
 	len = data->sg_len;
 
 	for (i = 0; i < len; i++) {
-		sgbuf = page_address(sg[i].page) + sg[i].offset;
+		sgbuf = page_address(sg_page(&sg[i])) + sg[i].offset;
 		memcpy(dmabuf, sgbuf, sg[i].length);
 		dmabuf += sg[i].length;
 	}
@@ -300,7 +300,7 @@ static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data)
 	len = data->sg_len;
 
 	for (i = 0; i < len; i++) {
-		sgbuf = page_address(sg[i].page) + sg[i].offset;
+		sgbuf = page_address(sg_page(&sg[i])) + sg[i].offset;
 		memcpy(sgbuf, dmabuf, sg[i].length);
 		dmabuf += sg[i].length;
 	}
diff --git a/drivers/net/mlx4/icm.c b/drivers/net/mlx4/icm.c
index 4b3c109..887633b 100644
--- a/drivers/net/mlx4/icm.c
+++ b/drivers/net/mlx4/icm.c
@@ -60,7 +60,7 @@ static void mlx4_free_icm_pages(struct mlx4_dev *dev, struct mlx4_icm_chunk *chu
 			     PCI_DMA_BIDIRECTIONAL);
 
 	for (i = 0; i < chunk->npages; ++i)
-		__free_pages(chunk->mem[i].page,
+		__free_pages(sg_page(&chunk->mem[i]),
 			     get_order(chunk->mem[i].length));
 }
 
@@ -70,7 +70,7 @@ static void mlx4_free_icm_coherent(struct mlx4_dev *dev, struct mlx4_icm_chunk *
 
 	for (i = 0; i < chunk->npages; ++i)
 		dma_free_coherent(&dev->pdev->dev, chunk->mem[i].length,
-				  lowmem_page_address(chunk->mem[i].page),
+				  lowmem_page_address(sg_page(&chunk->mem[i])),
 				  sg_dma_address(&chunk->mem[i]));
 }
 
@@ -95,10 +95,13 @@ void mlx4_free_icm(struct mlx4_dev *dev, struct mlx4_icm *icm, int coherent)
 
 static int mlx4_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_mask)
 {
-	mem->page = alloc_pages(gfp_mask, order);
-	if (!mem->page)
+	struct page *page;
+
+	page = alloc_pages(gfp_mask, order);
+	if (!page)
 		return -ENOMEM;
 
+	sg_set_page(mem, page);
 	mem->length = PAGE_SIZE << order;
 	mem->offset = 0;
 	return 0;
@@ -145,6 +148,7 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
 			if (!chunk)
 				goto fail;
 
+			sg_init_table(chunk->mem, MLX4_ICM_CHUNK_LEN);
 			chunk->npages = 0;
 			chunk->nsg    = 0;
 			list_add_tail(&chunk->list, &icm->chunk_list);
@@ -334,7 +338,7 @@ void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_han
 			 * been assigned to.
 			 */
 			if (chunk->mem[i].length > offset) {
-				page = chunk->mem[i].page;
+				page = sg_page(&chunk->mem[i]);
 				goto out;
 			}
 			offset -= chunk->mem[i].length;
diff --git a/drivers/net/ppp_mppe.c b/drivers/net/ppp_mppe.c
index c0b6d19..bcb0885 100644
--- a/drivers/net/ppp_mppe.c
+++ b/drivers/net/ppp_mppe.c
@@ -55,7 +55,7 @@
 #include <linux/mm.h>
 #include <linux/ppp_defs.h>
 #include <linux/ppp-comp.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 
 #include "ppp_mppe.h"
 
@@ -68,9 +68,7 @@ MODULE_VERSION("1.0.2");
 static unsigned int
 setup_sg(struct scatterlist *sg, const void *address, unsigned int length)
 {
-	sg[0].page = virt_to_page(address);
-	sg[0].offset = offset_in_page(address);
-	sg[0].length = length;
+	sg_init_one(sg, address, length);
 	return length;
 }
 
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index fb14014..afb262b 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -1840,7 +1840,7 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
 			    (scsi_bufflen(srb) < TW_MIN_SGL_LENGTH)) {
 				if (srb->sc_data_direction == DMA_TO_DEVICE || srb->sc_data_direction == DMA_BIDIRECTIONAL) {
 					struct scatterlist *sg = scsi_sglist(srb);
-					char *buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+					char *buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 					memcpy(tw_dev->generic_buffer_virt[request_id], buf, sg->length);
 					kunmap_atomic(buf - sg->offset, KM_IRQ0);
 				}
@@ -1919,7 +1919,7 @@ static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int re
 			char *buf;
 			unsigned long flags = 0;
 			local_irq_save(flags);
-			buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+			buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 			memcpy(buf, tw_dev->generic_buffer_virt[request_id], sg->length);
 			kunmap_atomic(buf - sg->offset, KM_IRQ0);
 			local_irq_restore(flags);
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index a64153b..59716eb 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -1469,7 +1469,7 @@ static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id,
 	struct scatterlist *sg = scsi_sglist(cmd);
 
 	local_irq_save(flags);
-	buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+	buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 	transfer_len = min(sg->length, len);
 
 	memcpy(buf, data, transfer_len);
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index 988f0bc..7a76b4b 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -298,7 +298,7 @@ static __inline__ void initialize_SCp(Scsi_Cmnd * cmd)
 	if (cmd->use_sg) {
 		cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
 		cmd->SCp.buffers_residual = cmd->use_sg - 1;
-		cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+
+		cmd->SCp.ptr = page_address(sg_page(cmd->SCp.buffer))+
 			       cmd->SCp.buffer->offset;
 		cmd->SCp.this_residual = cmd->SCp.buffer->length;
 	} else {
@@ -2143,7 +2143,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
 					++cmd->SCp.buffer;
 					--cmd->SCp.buffers_residual;
 					cmd->SCp.this_residual = cmd->SCp.buffer->length;
-					cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+
+					cmd->SCp.ptr = page_address(sg_page(cmd->SCp.buffer))+
 						       cmd->SCp.buffer->offset;
 					dprintk(NDEBUG_INFORMATION, ("scsi%d : %d bytes and %d buffers left\n", instance->host_no, cmd->SCp.this_residual, cmd->SCp.buffers_residual));
 				}
diff --git a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c
index 3168a17..db1a8bc 100644
--- a/drivers/scsi/NCR53c406a.c
+++ b/drivers/scsi/NCR53c406a.c
@@ -875,7 +875,7 @@ static void NCR53c406a_intr(void *dev_id)
 			outb(TRANSFER_INFO | DMA_OP, CMD_REG);
 #if USE_PIO
                         scsi_for_each_sg(current_SC, sg, scsi_sg_count(current_SC), i) {
-                                NCR53c406a_pio_write(page_address(sg->page) + sg->offset,
+                                NCR53c406a_pio_write(page_address(sg_page(sg)) + sg->offset,
                                                      sg->length);
                         }
 			REG0;
@@ -897,7 +897,7 @@ static void NCR53c406a_intr(void *dev_id)
 			outb(TRANSFER_INFO | DMA_OP, CMD_REG);
 #if USE_PIO
                         scsi_for_each_sg(current_SC, sg, scsi_sg_count(current_SC), i) {
-                                NCR53c406a_pio_read(page_address(sg->page) + sg->offset,
+                                NCR53c406a_pio_read(page_address(sg_page(sg)) + sg->offset,
                                                     sg->length);
                         }
 			REG0;
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 80e448d..a77ab8d 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -356,7 +356,7 @@ static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigne
 	int transfer_len;
 	struct scatterlist *sg = scsi_sglist(scsicmd);
 
-	buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+	buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 	transfer_len = min(sg->length, len + offset);
 
 	transfer_len -= offset;
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
index 961a188..50da0a3 100644
--- a/drivers/scsi/aha1542.c
+++ b/drivers/scsi/aha1542.c
@@ -49,7 +49,7 @@
 #include "aha1542.h"
 
 #define SCSI_BUF_PA(address)	isa_virt_to_bus(address)
-#define SCSI_SG_PA(sgent)	(isa_page_to_bus((sgent)->page) + (sgent)->offset)
+#define SCSI_SG_PA(sgent)	(isa_page_to_bus(sg_page((sgent))) + (sgent)->offset)
 
 static void BAD_DMA(void *address, unsigned int length)
 {
@@ -67,7 +67,7 @@ static void BAD_SG_DMA(Scsi_Cmnd * SCpnt,
 {
 	printk(KERN_CRIT "sgpnt[%d:%d] page %p/0x%llx length %u\n",
 	       badseg, nseg,
-	       page_address(sgp->page) + sgp->offset,
+	       page_address(sg_page(sgp)) + sgp->offset,
 	       (unsigned long long)SCSI_SG_PA(sgp),
 	       sgp->length);
 
@@ -712,7 +712,7 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 				printk(KERN_CRIT "Bad segment list supplied to aha1542.c (%d, %d)\n", SCpnt->use_sg, i);
 				scsi_for_each_sg(SCpnt, sg, SCpnt->use_sg, i) {
 					printk(KERN_CRIT "%d: %p %d\n", i,
-					       (page_address(sg->page) +
+					       (page_address(sg_page(sg)) +
 						sg->offset), sg->length);
 				};
 				printk(KERN_CRIT "cptr %x: ", (unsigned int) cptr);
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index f817775..f7a2528 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -1343,7 +1343,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \
 						/* 4 bytes: Areca io control code */
 
 	sg = scsi_sglist(cmd);
-	buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+	buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 	if (scsi_sg_count(cmd) > 1) {
 		retvalue = ARCMSR_MESSAGE_FAIL;
 		goto message_out;
@@ -1593,7 +1593,7 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,
 		strncpy(&inqdata[32], "R001", 4); /* Product Revision */
 
 		sg = scsi_sglist(cmd);
-		buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+		buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 
 		memcpy(buffer, inqdata, sizeof(inqdata));
 		sg = scsi_sglist(cmd);
diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
index 5d282e6..dc4e463 100644
--- a/drivers/scsi/fdomain.c
+++ b/drivers/scsi/fdomain.c
@@ -1321,7 +1321,7 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id)
 	    if (current_SC->SCp.buffers_residual) {
 	       --current_SC->SCp.buffers_residual;
 	       ++current_SC->SCp.buffer;
-	       current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
+	       current_SC->SCp.ptr = page_address(sg_page(current_SC->SCp.buffer)) + current_SC->SCp.buffer->offset;
 	       current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
 	    } else
 		  break;
@@ -1354,7 +1354,7 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id)
 	     && current_SC->SCp.buffers_residual) {
 	    --current_SC->SCp.buffers_residual;
 	    ++current_SC->SCp.buffer;
-	    current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
+	    current_SC->SCp.ptr = page_address(sg_page(current_SC->SCp.buffer)) + current_SC->SCp.buffer->offset;
 	    current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
 	 }
       }
@@ -1439,7 +1439,7 @@ static int fdomain_16x0_queue(struct scsi_cmnd *SCpnt,
 
    if (scsi_sg_count(current_SC)) {
 	   current_SC->SCp.buffer = scsi_sglist(current_SC);
-	   current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page)
+	   current_SC->SCp.ptr = page_address(sg_page(current_SC->SCp.buffer))
 		   + current_SC->SCp.buffer->offset;
 	   current_SC->SCp.this_residual    = current_SC->SCp.buffer->length;
 	   current_SC->SCp.buffers_residual = scsi_sg_count(current_SC) - 1;
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 3ac080e..ac6c57a 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -2374,13 +2374,13 @@ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
             if (cpsum+cpnow > cpcount) 
                 cpnow = cpcount - cpsum;
             cpsum += cpnow;
-            if (!sl->page) {
+            if (!sg_page(sl)) {
                 printk("GDT-HA %d: invalid sc/gt element in gdth_copy_internal_data()\n",
                        ha->hanum);
                 return;
             }
             local_irq_save(flags);
-            address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset;
+            address = kmap_atomic(sg_page(sl), KM_BIO_SRC_IRQ) + sl->offset;
             if (to_buffer)
                 memcpy(buffer, address, cpnow);
             else
diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
index 714e627..db004a4 100644
--- a/drivers/scsi/ibmmca.c
+++ b/drivers/scsi/ibmmca.c
@@ -1828,7 +1828,7 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 		BUG_ON(scsi_sg_count(cmd) > 16);
 
 		scsi_for_each_sg(cmd, sg, scsi_sg_count(cmd), i) {
-			ld(shpnt)[ldn].sge[i].address = (void *) (isa_page_to_bus(sg->page) + sg->offset);
+			ld(shpnt)[ldn].sge[i].address = (void *) (isa_page_to_bus(sg_page(sg)) + sg->offset);
 			ld(shpnt)[ldn].sge[i].byte_length = sg->length;
 		}
 		scb->enable |= IM_POINTER_TO_LIST;
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index fa7ba64..2c7dd8b 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -175,18 +175,18 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
 
 	while (bcount) {
 		count = min(pc->sg->length - pc->b_count, bcount);
-		if (PageHighMem(pc->sg->page)) {
+		if (PageHighMem(sg_page(pc->sg))) {
 			unsigned long flags;
 
 			local_irq_save(flags);
-			buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
+			buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) +
 					pc->sg->offset;
 			drive->hwif->atapi_input_bytes(drive,
 						buf + pc->b_count, count);
 			kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
 			local_irq_restore(flags);
 		} else {
-			buf = page_address(pc->sg->page) + pc->sg->offset;
+			buf = page_address(sg_page(pc->sg)) + pc->sg->offset;
 			drive->hwif->atapi_input_bytes(drive,
 						buf + pc->b_count, count);
 		}
@@ -212,18 +212,18 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
 
 	while (bcount) {
 		count = min(pc->sg->length - pc->b_count, bcount);
-		if (PageHighMem(pc->sg->page)) {
+		if (PageHighMem(sg_page(pc->sg))) {
 			unsigned long flags;
 
 			local_irq_save(flags);
-			buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
+			buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) +
 						pc->sg->offset;
 			drive->hwif->atapi_output_bytes(drive,
 						buf + pc->b_count, count);
 			kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
 			local_irq_restore(flags);
 		} else {
-			buf = page_address(pc->sg->page) + pc->sg->offset;
+			buf = page_address(sg_page(pc->sg)) + pc->sg->offset;
 			drive->hwif->atapi_output_bytes(drive,
 						buf + pc->b_count, count);
 		}
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c
index 74cdc1f..da9b0ba 100644
--- a/drivers/scsi/imm.c
+++ b/drivers/scsi/imm.c
@@ -706,7 +706,7 @@ static int imm_completion(struct scsi_cmnd *cmd)
 				cmd->SCp.this_residual =
 				    cmd->SCp.buffer->length;
 				cmd->SCp.ptr =
-				    page_address(cmd->SCp.buffer->page) +
+				    page_address(sg_page(cmd->SCp.buffer)) +
 				    cmd->SCp.buffer->offset;
 
 				/*
@@ -845,7 +845,7 @@ static int imm_engine(imm_struct *dev, struct scsi_cmnd *cmd)
 			    (struct scatterlist *) cmd->request_buffer;
 			cmd->SCp.this_residual = cmd->SCp.buffer->length;
 			cmd->SCp.ptr =
-			    page_address(cmd->SCp.buffer->page) +
+			    page_address(sg_page(cmd->SCp.buffer)) +
 			    cmd->SCp.buffer->offset;
 		} else {
 			/* else fill the only available buffer */
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index b41dfb5..dc98a85 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -2872,6 +2872,7 @@ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len)
 	}
 
 	scatterlist = sglist->scatterlist;
+	sg_init_table(scatterlist, num_elem);
 
 	sglist->order = order;
 	sglist->num_sg = num_elem;
@@ -2884,12 +2885,12 @@ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len)
 
 			/* Free up what we already allocated */
 			for (j = i - 1; j >= 0; j--)
-				__free_pages(scatterlist[j].page, order);
+				__free_pages(sg_page(&scatterlist[j]), order);
 			kfree(sglist);
 			return NULL;
 		}
 
-		scatterlist[i].page = page;
+		sg_set_page(&scatterlist[i], page);
 	}
 
 	return sglist;
@@ -2910,7 +2911,7 @@ static void ipr_free_ucode_buffer(struct ipr_sglist *sglist)
 	int i;
 
 	for (i = 0; i < sglist->num_sg; i++)
-		__free_pages(sglist->scatterlist[i].page, sglist->order);
+		__free_pages(sg_page(&sglist->scatterlist[i]), sglist->order);
 
 	kfree(sglist);
 }
@@ -2940,9 +2941,11 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist,
 	scatterlist = sglist->scatterlist;
 
 	for (i = 0; i < (len / bsize_elem); i++, buffer += bsize_elem) {
-		kaddr = kmap(scatterlist[i].page);
+		struct page *page = sg_page(&scatterlist[i]);
+
+		kaddr = kmap(page);
 		memcpy(kaddr, buffer, bsize_elem);
-		kunmap(scatterlist[i].page);
+		kunmap(page);
 
 		scatterlist[i].length = bsize_elem;
 
@@ -2953,9 +2956,11 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist,
 	}
 
 	if (len % bsize_elem) {
-		kaddr = kmap(scatterlist[i].page);
+		struct page *page = sg_page(&scatterlist[i]);
+
+		kaddr = kmap(page);
 		memcpy(kaddr, buffer, len % bsize_elem);
-		kunmap(scatterlist[i].page);
+		kunmap(page);
 
 		scatterlist[i].length = len % bsize_elem;
 	}
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index edaac27..5c5a9b2 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -1515,7 +1515,7 @@ static int ips_is_passthru(struct scsi_cmnd *SC)
                 /* kmap_atomic() ensures addressability of the user buffer.*/
                 /* local_irq_save() protects the KM_IRQ0 address slot.     */
                 local_irq_save(flags);
-                buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+                buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
                 if (buffer && buffer[0] == 'C' && buffer[1] == 'O' &&
                     buffer[2] == 'P' && buffer[3] == 'P') {
                         kunmap_atomic(buffer - sg->offset, KM_IRQ0);
@@ -3523,7 +3523,7 @@ ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count)
                 /* kmap_atomic() ensures addressability of the data buffer.*/
                 /* local_irq_save() protects the KM_IRQ0 address slot.     */
                 local_irq_save(flags);
-                buffer = kmap_atomic(sg[i].page, KM_IRQ0) + sg[i].offset;
+                buffer = kmap_atomic(sg_page(&sg[i]), KM_IRQ0) + sg[i].offset;
                 memcpy(buffer, &cdata[xfer_cnt], min_cnt);
                 kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
                 local_irq_restore(flags);
@@ -3556,7 +3556,7 @@ ips_scmd_buf_read(struct scsi_cmnd *scmd, void *data, unsigned int count)
                 /* kmap_atomic() ensures addressability of the data buffer.*/
                 /* local_irq_save() protects the KM_IRQ0 address slot.     */
                 local_irq_save(flags);
-                buffer = kmap_atomic(sg[i].page, KM_IRQ0) + sg[i].offset;
+                buffer = kmap_atomic(sg_page(&sg[i]), KM_IRQ0) + sg[i].offset;
                 memcpy(&cdata[xfer_cnt], buffer, min_cnt);
                 kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
                 local_irq_restore(flags);
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index a21455d..6ce4109 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -70,9 +70,7 @@ module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);
 static inline void
 iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size)
 {
-	ibuf->sg.page = virt_to_page(vbuf);
-	ibuf->sg.offset = offset_in_page(vbuf);
-	ibuf->sg.length = size;
+	sg_init_one(&ibuf->sg, vbuf, size);
 	ibuf->sent = 0;
 	ibuf->use_sendmsg = 1;
 }
@@ -80,13 +78,14 @@ iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size)
 static inline void
 iscsi_buf_init_sg(struct iscsi_buf *ibuf, struct scatterlist *sg)
 {
-	ibuf->sg.page = sg->page;
+	sg_init_table(&ibuf->sg, 1);
+	sg_set_page(&ibuf->sg, sg_page(sg));
 	ibuf->sg.offset = sg->offset;
 	ibuf->sg.length = sg->length;
 	/*
 	 * Fastpath: sg element fits into single page
 	 */
-	if (sg->length + sg->offset <= PAGE_SIZE && !PageSlab(sg->page))
+	if (sg->length + sg->offset <= PAGE_SIZE && !PageSlab(sg_page(sg)))
 		ibuf->use_sendmsg = 0;
 	else
 		ibuf->use_sendmsg = 1;
@@ -716,7 +715,7 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn)
 	for (i = tcp_ctask->sg_count; i < scsi_sg_count(sc); i++) {
 		char *dest;
 
-		dest = kmap_atomic(sg[i].page, KM_SOFTIRQ0);
+		dest = kmap_atomic(sg_page(&sg[i]), KM_SOFTIRQ0);
 		rc = iscsi_ctask_copy(tcp_conn, ctask, dest + sg[i].offset,
 				      sg[i].length, offset);
 		kunmap_atomic(dest, KM_SOFTIRQ0);
@@ -1103,9 +1102,9 @@ iscsi_send(struct iscsi_conn *conn, struct iscsi_buf *buf, int size, int flags)
 	 * slab case.
 	 */
 	if (buf->use_sendmsg)
-		res = sock_no_sendpage(sk, buf->sg.page, offset, size, flags);
+		res = sock_no_sendpage(sk, sg_page(&buf->sg), offset, size, flags);
 	else
-		res = tcp_conn->sendpage(sk, buf->sg.page, offset, size, flags);
+		res = tcp_conn->sendpage(sk, sg_page(&buf->sg), offset, size, flags);
 
 	if (res >= 0) {
 		conn->txdata_octets += res;
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 10d1aff..0a848e8 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -658,7 +658,7 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
 			struct scatterlist *sg;
 
 			sg = scsi_sglist(cmd);
-			buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+			buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 
 			memset(buf, 0, cmd->cmnd[4]);
 			kunmap_atomic(buf - sg->offset, KM_IRQ0);
@@ -1542,9 +1542,9 @@ mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status)
 		if( cmd->cmnd[0] == INQUIRY && !islogical ) {
 
 			sgl = scsi_sglist(cmd);
-			if( sgl->page ) {
+			if( sg_page(sgl) ) {
 				c = *(unsigned char *)
-					page_address((&sgl[0])->page) +
+					page_address((sg_page(&sgl[0]))) +
 					(&sgl[0])->offset; 
 			} else {
 				printk(KERN_WARNING
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index e4e4c6a..376263c 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -1584,9 +1584,9 @@ megaraid_mbox_build_cmd(adapter_t *adapter, struct scsi_cmnd *scp, int *busy)
 			caddr_t			vaddr;
 
 			sgl = scsi_sglist(scp);
-			if (sgl->page) {
+			if (sg_page(sgl)) {
 				vaddr = (caddr_t)
-					(page_address((&sgl[0])->page)
+					(page_address(sg_page(&sgl[0]))
 					 + (&sgl[0])->offset);
 
 				memset(vaddr, 0, scp->cmnd[4]);
@@ -2328,9 +2328,9 @@ megaraid_mbox_dpc(unsigned long devp)
 				&& IS_RAID_CH(raid_dev, scb->dev_channel)) {
 
 			sgl = scsi_sglist(scp);
-			if (sgl->page) {
+			if (sg_page(sgl)) {
 				c = *(unsigned char *)
-					(page_address((&sgl[0])->page) +
+					(page_address(sg_page(&sgl[0])) +
 					 (&sgl[0])->offset);
 			} else {
 				con_log(CL_ANN, (KERN_WARNING
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 331b789..1c5c4b6 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -542,7 +542,7 @@ static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int q
 	if (STp->raw) {
 		if (STp->buffer->syscall_result) {
 			for (i=0; i < STp->buffer->sg_segs; i++)
-				memset(page_address(STp->buffer->sg[i].page),
+				memset(page_address(sg_page(&STp->buffer->sg[i])),
 				       0, STp->buffer->sg[i].length);
 			strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");
                 } else
@@ -4437,7 +4437,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp)
 		for (i = 0, b_size = 0; 
 		     (i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE); 
 		     b_size += STp->buffer->sg[i++].length);
-		STp->buffer->aux = (os_aux_t *) (page_address(STp->buffer->sg[i].page) + OS_DATA_SIZE - b_size);
+		STp->buffer->aux = (os_aux_t *) (page_address(sg_page(&STp->buffer->sg[i])) + OS_DATA_SIZE - b_size);
 #if DEBUG
 		printk(OSST_DEB_MSG "%s:D: b_data points to %p in segment 0 at %p\n", name,
 			STp->buffer->b_data, page_address(STp->buffer->sg[0].page));
@@ -5252,25 +5252,26 @@ static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
 	/* Try to allocate the first segment up to OS_DATA_SIZE and the others
 	   big enough to reach the goal (code assumes no segments in place) */
 	for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) {
-		STbuffer->sg[0].page = alloc_pages(priority, order);
+		struct page *page = alloc_pages(priority, order);
+
 		STbuffer->sg[0].offset = 0;
-		if (STbuffer->sg[0].page != NULL) {
+		if (page != NULL) {
+		    sg_set_page(&STbuffer->sg[0], page);
 		    STbuffer->sg[0].length = b_size;
-		    STbuffer->b_data = page_address(STbuffer->sg[0].page);
+		    STbuffer->b_data = page_address(page);
 		    break;
 		}
 	}
-	if (STbuffer->sg[0].page == NULL) {
+	if (sg_page(&STbuffer->sg[0]) == NULL) {
 		printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n");
 		return 0;
 	}
 	/* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */
 	for (segs=STbuffer->sg_segs=1, got=b_size;
 	     segs < max_segs && got < OS_FRAME_SIZE; ) {
-		STbuffer->sg[segs].page =
-				alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
+		struct page *page = alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
 		STbuffer->sg[segs].offset = 0;
-		if (STbuffer->sg[segs].page == NULL) {
+		if (page == NULL) {
 			if (OS_FRAME_SIZE - got <= (max_segs - segs) * b_size / 2 && order) {
 				b_size /= 2;  /* Large enough for the rest of the buffers */
 				order--;
@@ -5284,6 +5285,7 @@ static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
 			normalize_buffer(STbuffer);
 			return 0;
 		}
+		sg_set_page(&STbuffer->sg[segs], page);
 		STbuffer->sg[segs].length = (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size;
 		got += STbuffer->sg[segs].length;
 		STbuffer->buffer_size = got;
@@ -5316,7 +5318,7 @@ static void normalize_buffer(struct osst_buffer *STbuffer)
 		     b_size < STbuffer->sg[i].length;
 		     b_size *= 2, order++);
 
-		__free_pages(STbuffer->sg[i].page, order);
+		__free_pages(sg_page(&STbuffer->sg[i]), order);
 		STbuffer->buffer_size -= STbuffer->sg[i].length;
 	}
 #if DEBUG
@@ -5344,7 +5346,7 @@ static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, i
 	for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length - offset < do_count ?
 		      st_bp->sg[i].length - offset : do_count;
-		res = copy_from_user(page_address(st_bp->sg[i].page) + offset, ubp, cnt);
+		res = copy_from_user(page_address(sg_page(&st_bp->sg[i])) + offset, ubp, cnt);
 		if (res)
 			return (-EFAULT);
 		do_count -= cnt;
@@ -5377,7 +5379,7 @@ static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count
 	for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length - offset < do_count ?
 		      st_bp->sg[i].length - offset : do_count;
-		res = copy_to_user(ubp, page_address(st_bp->sg[i].page) + offset, cnt);
+		res = copy_to_user(ubp, page_address(sg_page(&st_bp->sg[i])) + offset, cnt);
 		if (res)
 			return (-EFAULT);
 		do_count -= cnt;
@@ -5410,7 +5412,7 @@ static int osst_zero_buffer_tail(struct osst_buffer *st_bp)
 	     i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length - offset < do_count ?
 		      st_bp->sg[i].length - offset : do_count ;
-		memset(page_address(st_bp->sg[i].page) + offset, 0, cnt);
+		memset(page_address(sg_page(&st_bp->sg[i])) + offset, 0, cnt);
 		do_count -= cnt;
 		offset = 0;
 	}
@@ -5430,7 +5432,7 @@ static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
 	for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length < do_count ?
 		      st_bp->sg[i].length : do_count ;
-		memcpy(page_address(st_bp->sg[i].page), ptr, cnt);
+		memcpy(page_address(sg_page(&st_bp->sg[i])), ptr, cnt);
 		do_count -= cnt;
 		ptr      += cnt;
 	}
@@ -5451,7 +5453,7 @@ static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
 	for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length < do_count ?
 		      st_bp->sg[i].length : do_count ;
-		memcpy(ptr, page_address(st_bp->sg[i].page), cnt);
+		memcpy(ptr, page_address(sg_page(&st_bp->sg[i])), cnt);
 		do_count -= cnt;
 		ptr      += cnt;
 	}
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 190e2a7..26c41b0 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -443,7 +443,7 @@ SYM53C500_intr(int irq, void *dev_id)
 
 			scsi_for_each_sg(curSC, sg, scsi_sg_count(curSC), i) {
 				SYM53C500_pio_write(fast_pio, port_base,
-						    page_address(sg->page) + sg->offset,
+				    page_address(sg_page(sg)) + sg->offset,
 						    sg->length);
 			}
 			REG0(port_base);
@@ -463,8 +463,8 @@ SYM53C500_intr(int irq, void *dev_id)
 
 			scsi_for_each_sg(curSC, sg, scsi_sg_count(curSC), i) {
 				SYM53C500_pio_read(fast_pio, port_base,
-						   page_address(sg->page) + sg->offset,
-						   sg->length);
+					page_address(sg_page(sg)) + sg->offset,
+					sg->length);
 			}
 			REG0(port_base);
 		}
diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
index 67b6d76..07f31e5 100644
--- a/drivers/scsi/ppa.c
+++ b/drivers/scsi/ppa.c
@@ -609,7 +609,7 @@ static int ppa_completion(struct scsi_cmnd *cmd)
 				cmd->SCp.this_residual =
 				    cmd->SCp.buffer->length;
 				cmd->SCp.ptr =
-				    page_address(cmd->SCp.buffer->page) +
+				    page_address(sg_page(cmd->SCp.buffer)) +
 				    cmd->SCp.buffer->offset;
 			}
 		}
@@ -756,7 +756,7 @@ static int ppa_engine(ppa_struct *dev, struct scsi_cmnd *cmd)
 			/* if many buffers are available, start filling the first */
 			cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
 			cmd->SCp.this_residual = cmd->SCp.buffer->length;
-			cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) +
+			cmd->SCp.ptr = page_address(sg_page(cmd->SCp.buffer)) +
 			    cmd->SCp.buffer->offset;
 		} else {
 			/* else fill the only available buffer */
diff --git a/drivers/scsi/qlogicfas408.c b/drivers/scsi/qlogicfas408.c
index 2bfbf26..feff3f7 100644
--- a/drivers/scsi/qlogicfas408.c
+++ b/drivers/scsi/qlogicfas408.c
@@ -317,7 +317,7 @@ static unsigned int ql_pcmd(struct scsi_cmnd *cmd)
 				return ((priv->qabort == 1 ?
 					 DID_ABORT : DID_RESET) << 16);
 			}
-			buf = page_address(sg->page) + sg->offset;
+			buf = page_address(sg_page(sg)) + sg->offset;
 			if (ql_pdma(priv, phase, buf, sg->length))
 				break;
 		}
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 72ee4c9..46cae5a 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -625,7 +625,7 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
 	scsi_for_each_sg(scp, sg, scp->use_sg, k) {
 		if (active) {
 			kaddr = (unsigned char *)
-				kmap_atomic(sg->page, KM_USER0);
+				kmap_atomic(sg_page(sg), KM_USER0);
 			if (NULL == kaddr)
 				return (DID_ERROR << 16);
 			kaddr_off = (unsigned char *)kaddr + sg->offset;
@@ -672,7 +672,7 @@ static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
 	sg = scsi_sglist(scp);
 	req_len = fin = 0;
 	for (k = 0; k < scp->use_sg; ++k, sg = sg_next(sg)) {
-		kaddr = (unsigned char *)kmap_atomic(sg->page, KM_USER0);
+		kaddr = (unsigned char *)kmap_atomic(sg_page(sg), KM_USER0);
 		if (NULL == kaddr)
 			return -1;
 		kaddr_off = (unsigned char *)kaddr + sg->offset;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index aac8a02..61fdaf0 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -295,7 +295,7 @@ static int scsi_req_map_sg(struct request *rq, struct scatterlist *sgl,
 	int i, err, nr_vecs = 0;
 
 	for_each_sg(sgl, sg, nsegs, i) {
-		page = sg->page;
+		page = sg_page(sg);
 		off = sg->offset;
 		len = sg->length;
  		data_len += len;
@@ -764,7 +764,7 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
 		if (unlikely(!sgl))
 			goto enomem;
 
-		memset(sgl, 0, sizeof(*sgl) * sgp->size);
+		sg_init_table(sgl, sgp->size);
 
 		/*
 		 * first loop through, set initial index and return value
@@ -781,6 +781,13 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
 			sg_chain(prev, SCSI_MAX_SG_SEGMENTS, sgl);
 
 		/*
+		 * if we have nothing left, mark the last segment as
+		 * end-of-list
+		 */
+		if (!left)
+			sg_mark_end(sgl, this);
+
+		/*
 		 * don't allow subsequent mempool allocs to sleep, it would
 		 * violate the mempool principle.
 		 */
@@ -2353,7 +2360,7 @@ void *scsi_kmap_atomic_sg(struct scatterlist *sgl, int sg_count,
 	*offset = *offset - len_complete + sg->offset;
 
 	/* Assumption: contiguous pages can be accessed as "page + i" */
-	page = nth_page(sg->page, (*offset >> PAGE_SHIFT));
+	page = nth_page(sg_page(sg), (*offset >> PAGE_SHIFT));
 	*offset &= ~PAGE_MASK;
 
 	/* Bytes in this sg-entry from *offset to the end of the page */
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 7238b2d..cc19710 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1169,7 +1169,7 @@ sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type)
 		len = vma->vm_end - sa;
 		len = (len < sg->length) ? len : sg->length;
 		if (offset < len) {
-			page = virt_to_page(page_address(sg->page) + offset);
+			page = virt_to_page(page_address(sg_page(sg)) + offset);
 			get_page(page);	/* increment page count */
 			break;
 		}
@@ -1717,13 +1717,13 @@ st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,
 		   goto out_unlock; */
         }
 
-	sgl[0].page = pages[0];
+	sg_set_page(sgl, pages[0]);
 	sgl[0].offset = uaddr & ~PAGE_MASK;
 	if (nr_pages > 1) {
 		sgl[0].length = PAGE_SIZE - sgl[0].offset;
 		count -= sgl[0].length;
 		for (i=1; i < nr_pages ; i++) {
-			sgl[i].page = pages[i]; 
+			sg_set_page(&sgl[i], pages[i]);
 			sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
 			count -= PAGE_SIZE;
 		}
@@ -1754,7 +1754,7 @@ st_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_pages,
 	int i;
 
 	for (i=0; i < nr_pages; i++) {
-		struct page *page = sgl[i].page;
+		struct page *page = sg_page(&sgl[i]);
 
 		if (dirtied)
 			SetPageDirty(page);
@@ -1854,7 +1854,7 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
 				scatter_elem_sz_prev = ret_sz;
 			}
 		}
-		sg->page = p;
+		sg_set_page(sg, p);
 		sg->length = (ret_sz > num) ? num : ret_sz;
 
 		SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k=%d, num=%d, "
@@ -1907,14 +1907,14 @@ sg_write_xfer(Sg_request * srp)
 		onum = 1;
 
 	ksglen = sg->length;
-	p = page_address(sg->page);
+	p = page_address(sg_page(sg));
 	for (j = 0, k = 0; j < onum; ++j) {
 		res = sg_u_iovec(hp, iovec_count, j, 1, &usglen, &up);
 		if (res)
 			return res;
 
 		for (; p; sg = sg_next(sg), ksglen = sg->length,
-		     p = page_address(sg->page)) {
+		     p = page_address(sg_page(sg))) {
 			if (usglen <= 0)
 				break;
 			if (ksglen > usglen) {
@@ -1991,12 +1991,12 @@ sg_remove_scat(Sg_scatter_hold * schp)
 		} else {
 			int k;
 
-			for (k = 0; (k < schp->k_use_sg) && sg->page;
+			for (k = 0; (k < schp->k_use_sg) && sg_page(sg);
 			     ++k, sg = sg_next(sg)) {
 				SCSI_LOG_TIMEOUT(5, printk(
 				    "sg_remove_scat: k=%d, pg=0x%p, len=%d\n",
-				    k, sg->page, sg->length));
-				sg_page_free(sg->page, sg->length);
+				    k, sg_page(sg), sg->length));
+				sg_page_free(sg_page(sg), sg->length);
 			}
 		}
 		kfree(schp->buffer);
@@ -2038,7 +2038,7 @@ sg_read_xfer(Sg_request * srp)
 	} else
 		onum = 1;
 
-	p = page_address(sg->page);
+	p = page_address(sg_page(sg));
 	ksglen = sg->length;
 	for (j = 0, k = 0; j < onum; ++j) {
 		res = sg_u_iovec(hp, iovec_count, j, 0, &usglen, &up);
@@ -2046,7 +2046,7 @@ sg_read_xfer(Sg_request * srp)
 			return res;
 
 		for (; p; sg = sg_next(sg), ksglen = sg->length,
-		     p = page_address(sg->page)) {
+		     p = page_address(sg_page(sg))) {
 			if (usglen <= 0)
 				break;
 			if (ksglen > usglen) {
@@ -2092,15 +2092,15 @@ sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer)
 	if ((!outp) || (num_read_xfer <= 0))
 		return 0;
 
-	for (k = 0; (k < schp->k_use_sg) && sg->page; ++k, sg = sg_next(sg)) {
+	for (k = 0; (k < schp->k_use_sg) && sg_page(sg); ++k, sg = sg_next(sg)) {
 		num = sg->length;
 		if (num > num_read_xfer) {
-			if (__copy_to_user(outp, page_address(sg->page),
+			if (__copy_to_user(outp, page_address(sg_page(sg)),
 					   num_read_xfer))
 				return -EFAULT;
 			break;
 		} else {
-			if (__copy_to_user(outp, page_address(sg->page),
+			if (__copy_to_user(outp, page_address(sg_page(sg)),
 					   num))
 				return -EFAULT;
 			num_read_xfer -= num;
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 73c44cb..ce69b9e 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -3797,7 +3797,7 @@ static void buf_to_sg(struct st_buffer *STbp, unsigned int length)
 	sg = &(STbp->sg[0]);
 	frp = STbp->frp;
 	for (i=count=0; count < length; i++) {
-		sg[i].page = frp[i].page;
+		sg_set_page(&sg[i], frp[i].page);
 		if (length - count > frp[i].length)
 			sg[i].length = frp[i].length;
 		else
@@ -4446,14 +4446,14 @@ static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pa
         }
 
 	/* Populate the scatter/gather list */
-	sgl[0].page = pages[0]; 
+	sg_set_page(&sgl[0], pages[0]);
 	sgl[0].offset = uaddr & ~PAGE_MASK;
 	if (nr_pages > 1) {
 		sgl[0].length = PAGE_SIZE - sgl[0].offset;
 		count -= sgl[0].length;
 		for (i=1; i < nr_pages ; i++) {
+			sg_set_page(&sgl[i], pages[i]);;
 			sgl[i].offset = 0;
-			sgl[i].page = pages[i]; 
 			sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
 			count -= PAGE_SIZE;
 		}
@@ -4483,7 +4483,7 @@ static int sgl_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_p
 	int i;
 
 	for (i=0; i < nr_pages; i++) {
-		struct page *page = sgl[i].page;
+		struct page *page = sg_page(&sgl[i]);
 
 		if (dirtied)
 			SetPageDirty(page);
diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c
index 5c72ca3..4419304 100644
--- a/drivers/scsi/tmscsim.c
+++ b/drivers/scsi/tmscsim.c
@@ -430,10 +430,7 @@ static __inline__ void dc390_Going_remove (struct dc390_dcb* pDCB, struct dc390_
 
 static struct scatterlist* dc390_sg_build_single(struct scatterlist *sg, void *addr, unsigned int length)
 {
-	memset(sg, 0, sizeof(struct scatterlist));
-	sg->page	= virt_to_page(addr);
-	sg->length	= length;
-	sg->offset	= (unsigned long)addr & ~PAGE_MASK;
+	sg_init_one(sg, addr, length);
 	return sg;
 }
 
diff --git a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c
index ea72bbe..6d1f0ed 100644
--- a/drivers/scsi/ultrastor.c
+++ b/drivers/scsi/ultrastor.c
@@ -681,7 +681,7 @@ static inline void build_sg_list(struct mscp *mscp, struct scsi_cmnd *SCpnt)
 
 	max = scsi_sg_count(SCpnt);
 	scsi_for_each_sg(SCpnt, sg, max, i) {
-		mscp->sglist[i].address = isa_page_to_bus(sg->page) + sg->offset;
+		mscp->sglist[i].address = isa_page_to_bus(sg_page(sg)) + sg->offset;
 		mscp->sglist[i].num_bytes = sg->length;
 		transfer_length += sg->length;
 	}
diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c
index 255c611..03cd44f 100644
--- a/drivers/scsi/wd7000.c
+++ b/drivers/scsi/wd7000.c
@@ -1123,7 +1123,7 @@ static int wd7000_queuecommand(struct scsi_cmnd *SCpnt,
 		any2scsi(scb->maxlen, nseg * sizeof(Sgb));
 
 		scsi_for_each_sg(SCpnt, sg, nseg, i) {
-			any2scsi(sgb[i].ptr, isa_page_to_bus(sg->page) + sg->offset);
+			any2scsi(sgb[i].ptr, isa_page_to_bus(sg_page(sg)) + sg->offset);
 			any2scsi(sgb[i].len, sg->length);
 		}
 	} else {
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index c021af3..3577453 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -438,12 +438,12 @@ int usb_sg_init (
 			io->urbs[i]->transfer_buffer = NULL;
 #else
 			io->urbs[i]->transfer_buffer =
-				page_address(sg[i].page) + sg[i].offset;
+				page_address(sg_page(&sg[i])) + sg[i].offset;
 #endif
 		} else {
 			/* hc may use _only_ transfer_buffer */
 			io->urbs [i]->transfer_buffer =
-				page_address (sg [i].page) + sg [i].offset;
+				page_address(sg_page(&sg[i])) + sg [i].offset;
 			len = sg [i].length;
 		}
 
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
index e7d982a..4866baf 100644
--- a/drivers/usb/image/microtek.c
+++ b/drivers/usb/image/microtek.c
@@ -519,7 +519,7 @@ static void mts_do_sg (struct urb* transfer)
 	context->fragment++;
 	mts_int_submit_urb(transfer,
 			   context->data_pipe,
-			   page_address(sg[context->fragment].page) +
+			   page_address(sg_page(&sg[context->fragment])) +
 			   sg[context->fragment].offset,
 			   sg[context->fragment].length,
 			   context->fragment + 1 == scsi_sg_count(context->srb) ?
@@ -557,7 +557,7 @@ mts_build_transfer_context(struct scsi_cmnd *srb, struct mts_desc* desc)
 		return;
 	} else {
 		sg = scsi_sglist(srb);
-		desc->context.data = page_address(sg[0].page) + sg[0].offset;
+		desc->context.data = page_address(sg_page(&sg[0])) + sg[0].offset;
 		desc->context.data_length = sg[0].length;
 	}
 
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index e901d31..ca8cb34 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -360,9 +360,10 @@ static void free_sglist (struct scatterlist *sg, int nents)
 	if (!sg)
 		return;
 	for (i = 0; i < nents; i++) {
-		if (!sg [i].page)
+		struct page *page = sg_page(&sg[i]);
+		if (!page)
 			continue;
-		kfree (page_address (sg [i].page) + sg [i].offset);
+		kfree (page_address (page) + sg [i].offset);
 	}
 	kfree (sg);
 }
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c
index cc8f7c5..889622b 100644
--- a/drivers/usb/storage/protocol.c
+++ b/drivers/usb/storage/protocol.c
@@ -195,7 +195,7 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
 		 * the *offset and *index values for the next loop. */
 		cnt = 0;
 		while (cnt < buflen) {
-			struct page *page = sg->page +
+			struct page *page = sg_page(sg) +
 					((sg->offset + *offset) >> PAGE_SHIFT);
 			unsigned int poff =
 					(sg->offset + *offset) & (PAGE_SIZE-1);
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index 1ae90ef..0a9882e 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -283,7 +283,7 @@ int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg,
 		pg = virt_to_page(addr);
 		offset = offset_in_page(addr);
 		if (sg) {
-			sg[i].page = pg;
+			sg_set_page(&sg[i], pg);
 			sg[i].offset = offset;
 		}
 		remainder_of_page = PAGE_CACHE_SIZE - offset;
@@ -713,10 +713,13 @@ ecryptfs_encrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
 {
 	struct scatterlist src_sg, dst_sg;
 
-	src_sg.page = src_page;
+	sg_init_table(&src_sg, 1);
+	sg_init_table(&dst_sg, 1);
+
+	sg_set_page(&src_sg, src_page);
 	src_sg.offset = src_offset;
 	src_sg.length = size;
-	dst_sg.page = dst_page;
+	sg_set_page(&dst_sg, dst_page);
 	dst_sg.offset = dst_offset;
 	dst_sg.length = size;
 	return encrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
@@ -742,10 +745,13 @@ ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
 {
 	struct scatterlist src_sg, dst_sg;
 
-	src_sg.page = src_page;
+	sg_init_table(&src_sg, 1);
+	sg_init_table(&dst_sg, 1);
+
+	sg_set_page(&src_sg, src_page);
 	src_sg.offset = src_offset;
 	src_sg.length = size;
-	dst_sg.page = dst_page;
+	sg_set_page(&dst_sg, dst_page);
 	dst_sg.offset = dst_offset;
 	dst_sg.length = size;
 	return decrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 89d9710..263fed8 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -1040,6 +1040,9 @@ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
 	};
 	int rc = 0;
 
+	sg_init_table(&dst_sg, 1);
+	sg_init_table(&src_sg, 1);
+
 	if (unlikely(ecryptfs_verbosity > 0)) {
 		ecryptfs_printk(
 			KERN_DEBUG, "Session key encryption key (size [%d]):\n",
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index ebd03cc..6f03918 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -88,7 +88,7 @@ nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname)
 {
 	struct xdr_netobj cksum;
 	struct hash_desc desc;
-	struct scatterlist sg[1];
+	struct scatterlist sg;
 	__be32 status = nfserr_resource;
 
 	dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n",
@@ -102,11 +102,9 @@ nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname)
 	if (cksum.data == NULL)
  		goto out;
 
-	sg[0].page = virt_to_page(clname->data);
-	sg[0].offset = offset_in_page(clname->data);
-	sg[0].length = clname->len;
+	sg_init_one(&sg, clname->data, clname->len);
 
-	if (crypto_hash_digest(&desc, sg, sg->length, cksum.data))
+	if (crypto_hash_digest(&desc, &sg, sg.length, cksum.data))
 		goto out;
 
 	md5_to_hex(dname, cksum.data);
diff --git a/include/asm-alpha/scatterlist.h b/include/asm-alpha/scatterlist.h
index 9173654..b764706 100644
--- a/include/asm-alpha/scatterlist.h
+++ b/include/asm-alpha/scatterlist.h
@@ -5,7 +5,7 @@
 #include <asm/types.h>
   
 struct scatterlist {
-	struct page *page;
+	unsigned long page_link;
 	unsigned int offset;
 
 	unsigned int length;
diff --git a/include/asm-arm/scatterlist.h b/include/asm-arm/scatterlist.h
index de2f65e..ab1d85d 100644
--- a/include/asm-arm/scatterlist.h
+++ b/include/asm-arm/scatterlist.h
@@ -5,7 +5,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page	*page;		/* buffer page			 */
+	unsigned long	page_link;
 	unsigned int	offset;		/* buffer offset		 */
 	dma_addr_t	dma_address;	/* dma address			 */
 	unsigned int	length;		/* length			 */
diff --git a/include/asm-avr32/scatterlist.h b/include/asm-avr32/scatterlist.h
index c6d5ce3..1356f29 100644
--- a/include/asm-avr32/scatterlist.h
+++ b/include/asm-avr32/scatterlist.h
@@ -4,7 +4,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page		*page;
+    unsigned long	page_link;
     unsigned int	offset;
     dma_addr_t		dma_address;
     unsigned int	length;
diff --git a/include/asm-blackfin/scatterlist.h b/include/asm-blackfin/scatterlist.h
index 60e07b9..384af54 100644
--- a/include/asm-blackfin/scatterlist.h
+++ b/include/asm-blackfin/scatterlist.h
@@ -4,7 +4,7 @@
 #include <linux/mm.h>
 
 struct scatterlist {
-	struct page *page;
+	unsigned long page_link;
 	unsigned int offset;
 	dma_addr_t dma_address;
 	unsigned int length;
diff --git a/include/asm-cris/scatterlist.h b/include/asm-cris/scatterlist.h
index 4bdc44c..5a8a834 100644
--- a/include/asm-cris/scatterlist.h
+++ b/include/asm-cris/scatterlist.h
@@ -6,7 +6,7 @@ struct scatterlist {
 	unsigned int length;
 
 	/* The following is i386 highmem junk - not used by us */
-	struct page * page; /* Location for highmem page, if any */
+	unsigned long page_link;
 	unsigned int offset;/* for highmem, page offset */
 
 };
diff --git a/include/asm-frv/scatterlist.h b/include/asm-frv/scatterlist.h
index 8e827fa..53dade7 100644
--- a/include/asm-frv/scatterlist.h
+++ b/include/asm-frv/scatterlist.h
@@ -22,7 +22,7 @@
  * and that's it. There's no excuse for not highmem enabling YOUR driver. /jens
  */
 struct scatterlist {
-	struct page	*page;		/* Location for highmem page, if any */
+	unsigned long	page_link;
 	unsigned int	offset;		/* for highmem, page offset */
 
 	dma_addr_t	dma_address;
diff --git a/include/asm-h8300/scatterlist.h b/include/asm-h8300/scatterlist.h
index 985fdf5..7e41983 100644
--- a/include/asm-h8300/scatterlist.h
+++ b/include/asm-h8300/scatterlist.h
@@ -4,7 +4,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page	*page;
+	unsigned long	page_link;
 	unsigned int	offset;
 	dma_addr_t	dma_address;
 	unsigned int	length;
diff --git a/include/asm-ia64/scatterlist.h b/include/asm-ia64/scatterlist.h
index 7d5234d..2f76ce3 100644
--- a/include/asm-ia64/scatterlist.h
+++ b/include/asm-ia64/scatterlist.h
@@ -9,7 +9,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page *page;
+	unsigned long page_link;
 	unsigned int offset;
 	unsigned int length;	/* buffer length */
 
diff --git a/include/asm-m32r/scatterlist.h b/include/asm-m32r/scatterlist.h
index 352415f..33b4b4d 100644
--- a/include/asm-m32r/scatterlist.h
+++ b/include/asm-m32r/scatterlist.h
@@ -6,7 +6,7 @@
 struct scatterlist {
     char *  address;    /* Location data is to be transferred to, NULL for
                          * highmem page */
-    struct page * page; /* Location for highmem page, if any */
+    unsigned long page_link;
     unsigned int offset;/* for highmem, page offset */
 
     dma_addr_t dma_address;
diff --git a/include/asm-m68k/scatterlist.h b/include/asm-m68k/scatterlist.h
index 24887a2..e06bb89 100644
--- a/include/asm-m68k/scatterlist.h
+++ b/include/asm-m68k/scatterlist.h
@@ -4,7 +4,7 @@
 #include <linux/types.h>
 
 struct scatterlist {
-	struct page *page;
+	unsigned long page_link;
 	unsigned int offset;
 	unsigned int length;
 
diff --git a/include/asm-m68knommu/scatterlist.h b/include/asm-m68knommu/scatterlist.h
index 4da79d3..28bed41 100644
--- a/include/asm-m68knommu/scatterlist.h
+++ b/include/asm-m68knommu/scatterlist.h
@@ -5,7 +5,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page	*page;
+	unsigned long	page_link;
 	unsigned int	offset;
 	dma_addr_t	dma_address;
 	unsigned int	length;
diff --git a/include/asm-mips/scatterlist.h b/include/asm-mips/scatterlist.h
index 7af104c..787797c 100644
--- a/include/asm-mips/scatterlist.h
+++ b/include/asm-mips/scatterlist.h
@@ -4,7 +4,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page *	page;
+	unsigned long	page_link;
 	unsigned int	offset;
 	dma_addr_t	dma_address;
 	unsigned int	length;
diff --git a/include/asm-parisc/scatterlist.h b/include/asm-parisc/scatterlist.h
index e7211c7..26da914 100644
--- a/include/asm-parisc/scatterlist.h
+++ b/include/asm-parisc/scatterlist.h
@@ -5,7 +5,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page *page;
+	unsigned long page_link;
 	unsigned int offset;
 
 	unsigned int length;
diff --git a/include/asm-powerpc/scatterlist.h b/include/asm-powerpc/scatterlist.h
index b075f61..b9f1dbc 100644
--- a/include/asm-powerpc/scatterlist.h
+++ b/include/asm-powerpc/scatterlist.h
@@ -14,7 +14,7 @@
 #include <asm/dma.h>
 
 struct scatterlist {
-	struct page *page;
+	unsigned long page_link;
 	unsigned int offset;
 	unsigned int length;
 
diff --git a/include/asm-s390/scatterlist.h b/include/asm-s390/scatterlist.h
index a43b3af..eb39486 100644
--- a/include/asm-s390/scatterlist.h
+++ b/include/asm-s390/scatterlist.h
@@ -2,7 +2,7 @@
 #define _ASMS390_SCATTERLIST_H
 
 struct scatterlist {
-    struct page *page;
+    unsigned long page_link;
     unsigned int offset;
     unsigned int length;
 };
diff --git a/include/asm-sh/scatterlist.h b/include/asm-sh/scatterlist.h
index b9ae53c..bc7c809 100644
--- a/include/asm-sh/scatterlist.h
+++ b/include/asm-sh/scatterlist.h
@@ -4,7 +4,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page * page; /* Location for highmem page, if any */
+    unsigned long page_link;
     unsigned int offset;/* for highmem, page offset */
     dma_addr_t dma_address;
     unsigned int length;
diff --git a/include/asm-sh64/scatterlist.h b/include/asm-sh64/scatterlist.h
index 1c723f2..0afd856 100644
--- a/include/asm-sh64/scatterlist.h
+++ b/include/asm-sh64/scatterlist.h
@@ -14,7 +14,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page * page; /* Location for highmem page, if any */
+    unsigned long page_link;
     unsigned int offset;/* for highmem, page offset */
     dma_addr_t dma_address;
     unsigned int length;
diff --git a/include/asm-sparc/scatterlist.h b/include/asm-sparc/scatterlist.h
index 4055af9..45b16f1 100644
--- a/include/asm-sparc/scatterlist.h
+++ b/include/asm-sparc/scatterlist.h
@@ -5,7 +5,7 @@
 #include <linux/types.h>
 
 struct scatterlist {
-	struct page *page;
+	unsigned long page_link;
 	unsigned int offset;
 
 	unsigned int length;
diff --git a/include/asm-sparc64/scatterlist.h b/include/asm-sparc64/scatterlist.h
index 703c5bb..6df23f0 100644
--- a/include/asm-sparc64/scatterlist.h
+++ b/include/asm-sparc64/scatterlist.h
@@ -6,7 +6,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page	*page;
+#ifdef CONFIG_DEBUG_SG
+	unsigned long	sg_magic;
+#endif
+	unsigned long	page_link;
 	unsigned int	offset;
 
 	unsigned int	length;
diff --git a/include/asm-v850/scatterlist.h b/include/asm-v850/scatterlist.h
index 56f4029..db91feb 100644
--- a/include/asm-v850/scatterlist.h
+++ b/include/asm-v850/scatterlist.h
@@ -17,7 +17,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page	*page;
+	unsigned long	page_link;
 	unsigned	offset;
 	dma_addr_t	dma_address;
 	unsigned	length;
diff --git a/include/asm-x86/dma-mapping_32.h b/include/asm-x86/dma-mapping_32.h
index 6a2d26c..e0d38d8 100644
--- a/include/asm-x86/dma-mapping_32.h
+++ b/include/asm-x86/dma-mapping_32.h
@@ -45,9 +45,9 @@ dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
 	WARN_ON(nents == 0 || sglist[0].length == 0);
 
 	for_each_sg(sglist, sg, nents, i) {
-		BUG_ON(!sg->page);
+		BUG_ON(!sg_page(sg));
 
-		sg->dma_address = page_to_phys(sg->page) + sg->offset;
+		sg->dma_address = page_to_phys(sg_page(sg)) + sg->offset;
 	}
 
 	flush_write_buffers();
diff --git a/include/asm-x86/scatterlist_32.h b/include/asm-x86/scatterlist_32.h
index bd5164a..0e7d997 100644
--- a/include/asm-x86/scatterlist_32.h
+++ b/include/asm-x86/scatterlist_32.h
@@ -4,7 +4,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page		*page;
+#ifdef CONFIG_DEBUG_SG
+    unsigned long	sg_magic;
+#endif
+    unsigned long	page_link;
     unsigned int	offset;
     dma_addr_t		dma_address;
     unsigned int	length;
diff --git a/include/asm-x86/scatterlist_64.h b/include/asm-x86/scatterlist_64.h
index ef3986b..1847c72 100644
--- a/include/asm-x86/scatterlist_64.h
+++ b/include/asm-x86/scatterlist_64.h
@@ -4,7 +4,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page		*page;
+#ifdef CONFIG_DEBUG_SG
+    unsigned long	sg_magic;
+#endif
+    unsigned long	page_link;
     unsigned int	offset;
     unsigned int	length;
     dma_addr_t		dma_address;
diff --git a/include/asm-xtensa/scatterlist.h b/include/asm-xtensa/scatterlist.h
index ca337a2..3b8aba5 100644
--- a/include/asm-xtensa/scatterlist.h
+++ b/include/asm-xtensa/scatterlist.h
@@ -14,7 +14,7 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page 	*page;
+	unsigned long	page_link;
 	unsigned int	offset;
 	dma_addr_t	dma_address;
 	unsigned int	length;
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index 2dc7464..eb70970 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -5,29 +5,72 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 
+/*
+ * Notes on SG table design.
+ *
+ * Architectures must provide an unsigned long page_link field in the
+ * scatterlist struct. We use that to place the page pointer AND encode
+ * information about the sg table as well. The two lower bits are reserved
+ * for this information.
+ *
+ * If bit 0 is set, then the page_link contains a pointer to the next sg
+ * table list. Otherwise the next entry is at sg + 1.
+ *
+ * If bit 1 is set, then this sg entry is the last element in a list.
+ *
+ * See sg_next().
+ *
+ */
+
+#define SG_MAGIC	0x87654321
+
+/**
+ * sg_set_page - Set sg entry to point at given page
+ * @sg:		 SG entry
+ * @page:	 The page
+ *
+ * Use this function to set an sg entry pointing at a page, never assign
+ * the page directly. We encode sg table information in the lower bits
+ * of the page pointer. See sg_page() for looking up the page belonging
+ * to an sg entry.
+ *
+ */
+static inline void sg_set_page(struct scatterlist *sg, struct page *page)
+{
+	unsigned long page_link = sg->page_link & 0x3;
+
+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(sg->sg_magic != SG_MAGIC);
+#endif
+	sg->page_link = page_link | (unsigned long) page;
+}
+
+#define sg_page(sg)	((struct page *) ((sg)->page_link & ~0x3))
+
+/**
+ * sg_set_buf - Set sg entry to point at given data
+ * @sg:		 SG entry
+ * @buf:	 Data
+ * @buflen:	 Data length
+ * 
+*/
 static inline void sg_set_buf(struct scatterlist *sg, const void *buf,
 			      unsigned int buflen)
 {
-	sg->page = virt_to_page(buf);
+	sg_set_page(sg, virt_to_page(buf));
 	sg->offset = offset_in_page(buf);
 	sg->length = buflen;
 }
 
-static inline void sg_init_one(struct scatterlist *sg, const void *buf,
-			       unsigned int buflen)
-{
-	memset(sg, 0, sizeof(*sg));
-	sg_set_buf(sg, buf, buflen);
-}
-
 /*
  * We overload the LSB of the page pointer to indicate whether it's
  * a valid sg entry, or whether it points to the start of a new scatterlist.
  * Those low bits are there for everyone! (thanks mason :-)
  */
-#define sg_is_chain(sg)		((unsigned long) (sg)->page & 0x01)
+#define sg_is_chain(sg)		((sg)->page_link & 0x01)
+#define sg_is_last(sg)		((sg)->page_link & 0x02)
 #define sg_chain_ptr(sg)	\
-	((struct scatterlist *) ((unsigned long) (sg)->page & ~0x01))
+	((struct scatterlist *) ((sg)->page_link & ~0x03))
 
 /**
  * sg_next - return the next scatterlist entry in a list
@@ -37,14 +80,16 @@ static inline void sg_init_one(struct scatterlist *sg, const void *buf,
  * of a chained scatterlist, it could jump to the start of a new
  * scatterlist array.
  *
- * Note that the caller must ensure that there are further entries after
- * the current entry, this function will NOT return NULL for an end-of-list.
- *
  */
 static inline struct scatterlist *sg_next(struct scatterlist *sg)
 {
-	sg++;
+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(sg->sg_magic != SG_MAGIC);
+#endif
+	if (sg_is_last(sg))
+		return NULL;
 
+	sg++;
 	if (unlikely(sg_is_chain(sg)))
 		sg = sg_chain_ptr(sg);
 
@@ -83,6 +128,10 @@ static inline struct scatterlist *sg_last(struct scatterlist *sgl,
 		ret = sg;
 
 #endif
+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(sgl[0].sg_magic != SG_MAGIC);
+	BUG_ON(!sg_is_last(ret));
+#endif
 	return ret;
 }
 
@@ -101,7 +150,68 @@ static inline void sg_chain(struct scatterlist *prv, unsigned int prv_nents,
 #ifndef ARCH_HAS_SG_CHAIN
 	BUG();
 #endif
-	prv[prv_nents - 1].page = (struct page *) ((unsigned long) sgl | 0x01);
+	prv[prv_nents - 1].page_link = (unsigned long) sgl | 0x01;
+}
+
+/**
+ * sg_mark_end - Mark the end of the scatterlist
+ * @sgl:	Scatterlist
+ * @nents:	Number of entries in sgl
+ *
+ * Marks the last entry as the termination point for sg_next()
+ *
+ */
+static inline void sg_mark_end(struct scatterlist *sgl, unsigned int nents)
+{
+	sgl[nents - 1].page_link = 0x02;
+}
+
+static inline void __sg_mark_end(struct scatterlist *sg)
+{
+	sg->page_link |= 0x02;
+}
+
+/**
+ * sg_init_one - Initialize a single entry sg list
+ * @sg:		 SG entry
+ * @buf:	 Virtual address for IO
+ * @buflen:	 IO length
+ *
+ * Note: this should not be used on a single entry that is part of a larger
+ * table. Use sg_init_table() for that.
+ *
+ */
+static inline void sg_init_one(struct scatterlist *sg, const void *buf,
+			       unsigned int buflen)
+{
+	memset(sg, 0, sizeof(*sg));
+#ifdef CONFIG_DEBUG_SG
+	sg->sg_magic = SG_MAGIC;
+#endif
+	sg_mark_end(sg, 1);
+	sg_set_buf(sg, buf, buflen);
+}
+
+/**
+ * sg_init_table - Initialize SG table
+ * @sgl:	   The SG table
+ * @nents:	   Number of entries in table
+ *
+ * Note: If this is part of a chained sg table, sg_mark_end() should be
+ * used only on the last table part.
+ *
+ */
+static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents)
+{
+	memset(sgl, 0, sizeof(*sgl) * nents);
+	sg_mark_end(sgl, nents);
+#ifdef CONFIG_DEBUG_SG
+	{
+		int i;
+		for (i = 0; i < nents; i++)
+			sgl[i].sg_magic = SG_MAGIC;
+	}
+#endif
 }
 
 #endif /* _LINUX_SCATTERLIST_H */
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 7d16e64..183f42c 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -389,6 +389,16 @@ config DEBUG_LIST
 
 	  If unsure, say N.
 
+config DEBUG_SG
+	bool "Debug SG table operations"
+	depends on DEBUG_KERNEL
+	help
+	  Enable this to turn on checks on scatter-gather tables. This can
+	  help find problems with drivers that do not properly initialize
+	  their sg tables.
+
+	  If unsure, say N.
+
 config FRAME_POINTER
 	bool "Compile the kernel with frame pointers"
 	depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML || S390 || AVR32 || SUPERH || BFIN)
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 752fd95..e58909e 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -35,7 +35,7 @@
 #define OFFSET(val,align) ((unsigned long)	\
 	                   ( (val) & ( (align) - 1)))
 
-#define SG_ENT_VIRT_ADDRESS(sg)	(page_address((sg)->page) + (sg)->offset)
+#define SG_ENT_VIRT_ADDRESS(sg)	(page_address(sg_page((sg)) + (sg)->offset))
 #define SG_ENT_PHYS_ADDRESS(sg)	virt_to_bus(SG_ENT_VIRT_ADDRESS(sg))
 
 /*
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 70d9b5d..4e2c84f 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2045,7 +2045,7 @@ skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
 	if (copy > 0) {
 		if (copy > len)
 			copy = len;
-		sg[elt].page = virt_to_page(skb->data + offset);
+		sg_set_page(&sg[elt], virt_to_page(skb->data + offset));
 		sg[elt].offset = (unsigned long)(skb->data + offset) % PAGE_SIZE;
 		sg[elt].length = copy;
 		elt++;
@@ -2065,7 +2065,7 @@ skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
 
 			if (copy > len)
 				copy = len;
-			sg[elt].page = frag->page;
+			sg_set_page(&sg[elt], frag->page);
 			sg[elt].offset = frag->page_offset+offset-start;
 			sg[elt].length = copy;
 			elt++;
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
index 6cc54ee..34d4c77 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -390,9 +390,7 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	icv[3] = crc >> 24;
 
 	crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = len + 4;
+	sg_init_one(&sg, pos, len + 4);
 	return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
 }
 
@@ -485,9 +483,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	plen = skb->len - hdr_len - 12;
 
 	crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = plen + 4;
+	sg_init_one(&sg, pos, plen + 4);
 	if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG ": TKIP: failed to decrypt "
@@ -539,11 +535,12 @@ static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
 		printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
 		return -1;
 	}
-	sg[0].page = virt_to_page(hdr);
+	sg_init_table(sg, 2);
+	sg_set_page(&sg[0], virt_to_page(hdr));
 	sg[0].offset = offset_in_page(hdr);
 	sg[0].length = 16;
 
-	sg[1].page = virt_to_page(data);
+	sg_set_page(&sg[1], virt_to_page(data));
 	sg[1].offset = offset_in_page(data);
 	sg[1].length = data_len;
 
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
index 8d18245..0af6103 100644
--- a/net/ieee80211/ieee80211_crypt_wep.c
+++ b/net/ieee80211/ieee80211_crypt_wep.c
@@ -170,9 +170,7 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	icv[3] = crc >> 24;
 
 	crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = len + 4;
+	sg_init_one(&sg, pos, len + 4);
 	return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
 }
 
@@ -212,9 +210,7 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	plen = skb->len - hdr_len - 8;
 
 	crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = plen + 4;
+	sg_init_one(&sg, pos, plen + 4);
 	if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
 		return -7;
 
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 6675261..cc806d6 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -138,9 +138,7 @@ void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
 	*icv = cpu_to_le32(~crc32_le(~0, data, data_len));
 
 	crypto_blkcipher_setkey(tfm, rc4key, klen);
-	sg.page = virt_to_page(data);
-	sg.offset = offset_in_page(data);
-	sg.length = data_len + WEP_ICV_LEN;
+	sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
 	crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length);
 }
 
@@ -204,9 +202,7 @@ int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
 	__le32 crc;
 
 	crypto_blkcipher_setkey(tfm, rc4key, klen);
-	sg.page = virt_to_page(data);
-	sg.offset = offset_in_page(data);
-	sg.length = data_len + WEP_ICV_LEN;
+	sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
 	crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length);
 
 	crc = cpu_to_le32(~crc32_le(~0, data, data_len));
diff --git a/net/sctp/auth.c b/net/sctp/auth.c
index 7818107..cbd64b2 100644
--- a/net/sctp/auth.c
+++ b/net/sctp/auth.c
@@ -726,7 +726,8 @@ void sctp_auth_calculate_hmac(const struct sctp_association *asoc,
 
 	/* set up scatter list */
 	end = skb_tail_pointer(skb);
-	sg.page = virt_to_page(auth);
+	sg_init_table(&sg, 1);
+	sg_set_page(&sg, virt_to_page(auth));
 	sg.offset = (unsigned long)(auth) % PAGE_SIZE;
 	sg.length = end - (unsigned char *)auth;
 
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index f983a36..d5a9785 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1513,7 +1513,8 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
 		struct hash_desc desc;
 
 		/* Sign the message.  */
-		sg.page = virt_to_page(&cookie->c);
+		sg_init_table(&sg, 1);
+		sg_set_page(&sg, virt_to_page(&cookie->c));
 		sg.offset = (unsigned long)(&cookie->c) % PAGE_SIZE;
 		sg.length = bodysize;
 		keylen = SCTP_SECRET_SIZE;
@@ -1585,7 +1586,8 @@ struct sctp_association *sctp_unpack_cookie(
 
 	/* Check the signature.  */
 	keylen = SCTP_SECRET_SIZE;
-	sg.page = virt_to_page(bear_cookie);
+	sg_init_table(&sg, 1);
+	sg_set_page(&sg, virt_to_page(bear_cookie));
 	sg.offset = (unsigned long)(bear_cookie) % PAGE_SIZE;
 	sg.length = bodysize;
 	key = (char *)ep->secret_key[ep->current_key];
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index bfb6a29..32be431 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -197,9 +197,9 @@ encryptor(struct scatterlist *sg, void *data)
 		int i = (page_pos + outbuf->page_base) >> PAGE_CACHE_SHIFT;
 		in_page = desc->pages[i];
 	} else {
-		in_page = sg->page;
+		in_page = sg_page(sg);
 	}
-	desc->infrags[desc->fragno].page = in_page;
+	sg_set_page(&desc->infrags[desc->fragno], in_page);
 	desc->fragno++;
 	desc->fraglen += sg->length;
 	desc->pos += sg->length;
@@ -215,11 +215,11 @@ encryptor(struct scatterlist *sg, void *data)
 	if (ret)
 		return ret;
 	if (fraglen) {
-		desc->outfrags[0].page = sg->page;
+		sg_set_page(&desc->outfrags[0], sg_page(sg));
 		desc->outfrags[0].offset = sg->offset + sg->length - fraglen;
 		desc->outfrags[0].length = fraglen;
 		desc->infrags[0] = desc->outfrags[0];
-		desc->infrags[0].page = in_page;
+		sg_set_page(&desc->infrags[0], in_page);
 		desc->fragno = 1;
 		desc->fraglen = fraglen;
 	} else {
@@ -287,7 +287,7 @@ decryptor(struct scatterlist *sg, void *data)
 	if (ret)
 		return ret;
 	if (fraglen) {
-		desc->frags[0].page = sg->page;
+		sg_set_page(&desc->frags[0], sg_page(sg));
 		desc->frags[0].offset = sg->offset + sg->length - fraglen;
 		desc->frags[0].length = fraglen;
 		desc->fragno = 1;
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 6a59180..3d1f7cd 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -1059,7 +1059,7 @@ xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len,
 		do {
 			if (thislen > page_len)
 				thislen = page_len;
-			sg->page = buf->pages[i];
+			sg_set_page(sg, buf->pages[i]);
 			sg->offset = page_offset;
 			sg->length = thislen;
 			ret = actor(sg, data);
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index 5ced62c..fb2220a 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -552,7 +552,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
 		if (copy > len)
 			copy = len;
 
-		sg.page = virt_to_page(skb->data + offset);
+		sg_set_page(&sg, virt_to_page(skb->data + offset));
 		sg.offset = (unsigned long)(skb->data + offset) % PAGE_SIZE;
 		sg.length = copy;
 
@@ -577,7 +577,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
 			if (copy > len)
 				copy = len;
 
-			sg.page = frag->page;
+			sg_set_page(&sg, frag->page);
 			sg.offset = frag->page_offset + offset-start;
 			sg.length = copy;
 

-- 
Jens Axboe


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

* Re: [PATCH] Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 10:42                                           ` [PATCH] " Jeff Garzik
  2007-10-18 10:54                                             ` Ingo Molnar
@ 2007-10-18 14:52                                             ` Olof Johansson
  1 sibling, 0 replies; 151+ messages in thread
From: Olof Johansson @ 2007-10-18 14:52 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: Jens Axboe, Ingo Molnar, Linus Torvalds, linux-kernel, Alan Cox,
	Tejun Heo, Brian King

On Thu, Oct 18, 2007 at 06:42:46AM -0400, Jeff Garzik wrote:
> Jens Axboe wrote:
>> On Thu, Oct 18 2007, Jeff Garzik wrote:
>>> Jens Axboe wrote:
>>>> That should work as well. WRT ata_sg_is_last(), if we go ahead with my
>>>> recent sg chaining updates, we can keep the test as it would be a single
>>>> conditional and not require any looping.
>>>> Let me know when you have tested this!
>>> The patch I attached to the last email got both sata_mv test boxes 
>>> working reliably (so far).
>>>
>>> I worked up a patch that kills ata_sg_is_last() (plus the 
>>> max_phys_segments sata_mv fix), see attached.  I'm thinking this is what 
>>> I like to see in upstream.
>> Great!
>>> Of course, this doesn't explain why ata_sg_is_last() was broken, but 
>>> since it's working _and_ slightly more efficient, I don't really care :)
>> Tomo and I agreed to kill sg_last() a few days ago anyways, so this is
>> perfectly fine with me.
>
> Yep, the [attached] patch that kills ata_sg_is_last() is working here on 
> both machines that were previously croaking.
>
> It would be nice to get pdc_adma, sata_sil24 and ipr it-works test done, 
> but IMO the patch is pretty straightforward and should be OK.

Tested-by: Olof Johansson <olof@lixom.net>

Looks ok on SATA_SIL24 and SATA_MV here on PPC (together with Jens' latest
patch). Both barfed before.


Thanks!

-Olof

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 14:38                                                               ` Jens Axboe
@ 2007-10-18 14:58                                                                 ` Olof Johansson
  2007-10-18 15:25                                                                   ` Jens Axboe
  0 siblings, 1 reply; 151+ messages in thread
From: Olof Johansson @ 2007-10-18 14:58 UTC (permalink / raw)
  To: Jens Axboe
  Cc: Benny Halevy, David Miller, torvalds, fujita.tomonori, mingo,
	linux-kernel, jgarzik, alan, tomof

On Thu, Oct 18, 2007 at 04:38:36PM +0200, Jens Axboe wrote:
> On Thu, Oct 18 2007, Benny Halevy wrote:
> > On Oct. 18, 2007, 16:05 +0200, Jens Axboe <jens.axboe@oracle.com> wrote:
> > > On Thu, Oct 18 2007, Jens Axboe wrote:
> > >> On Thu, Oct 18 2007, Benny Halevy wrote:
> > >>>>  	return sg;
> > >>>>  }
> > >>>> @@ -83,6 +96,9 @@ static inline struct scatterlist *sg_last(struct scatterlist *sgl,
> > >>>>  		ret = sg;
> > >>>>  
> > >>>>  #endif
> > >>>> +#ifdef CONFIG_DEBUG_SG
> > >>>> +	BUG_ON(sgl[0].sg_magic != SG_MAGIC);
> > >>> can it also do BUG_ON(!sg_is_last(sg))?
> > >> That would make sense, definitely. I'll add that.
> > > 
> > >         BUG_ON(!sg_is_last(ret));
> > > 
> > > it should be, not sg. That's what I merged.
> > > 
> > right. of course.
> 
> OK, that found something interesting - mapping a request may shrink it,
> so we need to update the end marker to move it earlier in the list.
> Basically just a
> 
>         if (sg)
>                 __sg_mark_end(sg);
> 
> at the bottom of blk_rq_map_sg(). Updated patch below, booted on other
> machines now as well without incident.

PPC needs this. I'm guessing other arches might too. Otherwise seems to boot
and work well (with Jeff's sata patch).


Thanks,

-Olof

diff --git a/include/asm-powerpc/scatterlist.h b/include/asm-powerpc/scatterlist.h
index b9f1dbc..fcf7d55 100644
--- a/include/asm-powerpc/scatterlist.h
+++ b/include/asm-powerpc/scatterlist.h
@@ -14,6 +14,9 @@
 #include <asm/dma.h>
 
 struct scatterlist {
+#ifdef CONFIG_DEBUG_SG
+	unsigned long sg_magic;
+#endif
 	unsigned long page_link;
 	unsigned int offset;
 	unsigned int length;

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 14:58                                                                 ` Olof Johansson
@ 2007-10-18 15:25                                                                   ` Jens Axboe
  0 siblings, 0 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-18 15:25 UTC (permalink / raw)
  To: Olof Johansson
  Cc: Benny Halevy, David Miller, torvalds, fujita.tomonori, mingo,
	linux-kernel, jgarzik, alan, tomof

On Thu, Oct 18 2007, Olof Johansson wrote:
> On Thu, Oct 18, 2007 at 04:38:36PM +0200, Jens Axboe wrote:
> > On Thu, Oct 18 2007, Benny Halevy wrote:
> > > On Oct. 18, 2007, 16:05 +0200, Jens Axboe <jens.axboe@oracle.com> wrote:
> > > > On Thu, Oct 18 2007, Jens Axboe wrote:
> > > >> On Thu, Oct 18 2007, Benny Halevy wrote:
> > > >>>>  	return sg;
> > > >>>>  }
> > > >>>> @@ -83,6 +96,9 @@ static inline struct scatterlist *sg_last(struct scatterlist *sgl,
> > > >>>>  		ret = sg;
> > > >>>>  
> > > >>>>  #endif
> > > >>>> +#ifdef CONFIG_DEBUG_SG
> > > >>>> +	BUG_ON(sgl[0].sg_magic != SG_MAGIC);
> > > >>> can it also do BUG_ON(!sg_is_last(sg))?
> > > >> That would make sense, definitely. I'll add that.
> > > > 
> > > >         BUG_ON(!sg_is_last(ret));
> > > > 
> > > > it should be, not sg. That's what I merged.
> > > > 
> > > right. of course.
> > 
> > OK, that found something interesting - mapping a request may shrink it,
> > so we need to update the end marker to move it earlier in the list.
> > Basically just a
> > 
> >         if (sg)
> >                 __sg_mark_end(sg);
> > 
> > at the bottom of blk_rq_map_sg(). Updated patch below, booted on other
> > machines now as well without incident.
> 
> PPC needs this. I'm guessing other arches might too. Otherwise seems to boot
> and work well (with Jeff's sata patch).

Oh duh, indeed I didn't add that to the archs when converting. Thanks
for the patch, I'll update the rest as well.

And thanks a lot for boot testing it!

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  8:21                                           ` Jens Axboe
  2007-10-18 11:55                                             ` David Miller
@ 2007-10-18 16:55                                             ` Linus Torvalds
  2007-10-18 17:01                                               ` Jens Axboe
                                                                 ` (2 more replies)
  1 sibling, 3 replies; 151+ messages in thread
From: Linus Torvalds @ 2007-10-18 16:55 UTC (permalink / raw)
  To: Jens Axboe
  Cc: David Miller, fujita.tomonori, mingo, linux-kernel, jgarzik, alan,
	tomof



On Thu, 18 Oct 2007, Jens Axboe wrote:
> -		unsigned long addr = page_to_phys(s->page) + s->offset; 
> +		unsigned long addr = page_to_phys(sg_page(s)) + s->offset; 

Umm. May I suggest (I haven't read the whole thread yet, maybe somebody 
else already did) that

	static inline unsigned long sg_phys(struct scatterlist *sg)
	{
		return 	page_to_phys(sg_page(sg)) + sg->offset;
	}

would be a good thing to have?

Very few drivers should care so much about the *page* itself (or the 
offset). That's something that the generic allocation code etc cares 
about, but the driver is almost bound to care mostly about the actual DMA 
address, so adding that helper function that abstracts the sg access would 
be helpful in hiding some of the cruft?

		Linus

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 16:55                                             ` Linus Torvalds
@ 2007-10-18 17:01                                               ` Jens Axboe
  2007-10-18 17:10                                                 ` Jens Axboe
  2007-10-18 17:10                                               ` Arjan van de Ven
  2007-10-18 19:20                                               ` Jeff Garzik
  2 siblings, 1 reply; 151+ messages in thread
From: Jens Axboe @ 2007-10-18 17:01 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: David Miller, fujita.tomonori, mingo, linux-kernel, jgarzik, alan,
	tomof

On Thu, Oct 18 2007, Linus Torvalds wrote:
> 
> 
> On Thu, 18 Oct 2007, Jens Axboe wrote:
> > -		unsigned long addr = page_to_phys(s->page) + s->offset; 
> > +		unsigned long addr = page_to_phys(sg_page(s)) + s->offset; 
> 
> Umm. May I suggest (I haven't read the whole thread yet, maybe somebody 
> else already did) that
> 
> 	static inline unsigned long sg_phys(struct scatterlist *sg)
> 	{
> 		return 	page_to_phys(sg_page(sg)) + sg->offset;
> 	}
> 
> would be a good thing to have?

Sure thing, it's used quite a lot.

> Very few drivers should care so much about the *page* itself (or the 
> offset). That's something that the generic allocation code etc cares 
> about, but the driver is almost bound to care mostly about the actual DMA 
> address, so adding that helper function that abstracts the sg access would 
> be helpful in hiding some of the cruft?

I'll add it to the mix.

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 16:55                                             ` Linus Torvalds
  2007-10-18 17:01                                               ` Jens Axboe
@ 2007-10-18 17:10                                               ` Arjan van de Ven
  2007-10-18 17:14                                                 ` Jens Axboe
  2007-10-18 19:20                                               ` Jeff Garzik
  2 siblings, 1 reply; 151+ messages in thread
From: Arjan van de Ven @ 2007-10-18 17:10 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Jens Axboe, David Miller, fujita.tomonori, mingo, linux-kernel,
	jgarzik, alan, tomof

On Thu, 18 Oct 2007 09:55:04 -0700 (PDT)
Linus Torvalds <torvalds@linux-foundation.org> wrote:

> 
> 
> On Thu, 18 Oct 2007, Jens Axboe wrote:
> > -		unsigned long addr = page_to_phys(s->page) +
> > s->offset; 
> > +		unsigned long addr = page_to_phys(sg_page(s)) +
> > s->offset; 
> 
> Umm. May I suggest (I haven't read the whole thread yet, maybe
> somebody else already did) that
> 
> 	static inline unsigned long sg_phys(struct scatterlist *sg)
> 	{
> 		return 	page_to_phys(sg_page(sg)) + sg->offset;
> 	}
> 
> would be a good thing to have?
> 
> Very few drivers should care so much about the *page* itself (or the 
> offset). That's something that the generic allocation code etc cares 
> about, but the driver is almost bound to care mostly about the actual
> DMA address

.... but will that work for systems with IOMMU ? or is it fundamentally
the wrong interface

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 17:01                                               ` Jens Axboe
@ 2007-10-18 17:10                                                 ` Jens Axboe
  0 siblings, 0 replies; 151+ messages in thread
From: Jens Axboe @ 2007-10-18 17:10 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: David Miller, fujita.tomonori, mingo, linux-kernel, jgarzik, alan,
	tomof

On Thu, Oct 18 2007, Jens Axboe wrote:
> On Thu, Oct 18 2007, Linus Torvalds wrote:
> > 
> > 
> > On Thu, 18 Oct 2007, Jens Axboe wrote:
> > > -		unsigned long addr = page_to_phys(s->page) + s->offset; 
> > > +		unsigned long addr = page_to_phys(sg_page(s)) + s->offset; 
> > 
> > Umm. May I suggest (I haven't read the whole thread yet, maybe somebody 
> > else already did) that
> > 
> > 	static inline unsigned long sg_phys(struct scatterlist *sg)
> > 	{
> > 		return 	page_to_phys(sg_page(sg)) + sg->offset;
> > 	}
> > 
> > would be a good thing to have?
> 
> Sure thing, it's used quite a lot.

Actually, only 11 occurrences in the patch. But still a nice little
cleanup.

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 17:10                                               ` Arjan van de Ven
@ 2007-10-18 17:14                                                 ` Jens Axboe
  2007-10-19  8:59                                                   ` FUJITA Tomonori
  0 siblings, 1 reply; 151+ messages in thread
From: Jens Axboe @ 2007-10-18 17:14 UTC (permalink / raw)
  To: Arjan van de Ven
  Cc: Linus Torvalds, David Miller, fujita.tomonori, mingo,
	linux-kernel, jgarzik, alan, tomof

On Thu, Oct 18 2007, Arjan van de Ven wrote:
> On Thu, 18 Oct 2007 09:55:04 -0700 (PDT)
> Linus Torvalds <torvalds@linux-foundation.org> wrote:
> 
> > 
> > 
> > On Thu, 18 Oct 2007, Jens Axboe wrote:
> > > -		unsigned long addr = page_to_phys(s->page) +
> > > s->offset; 
> > > +		unsigned long addr = page_to_phys(sg_page(s)) +
> > > s->offset; 
> > 
> > Umm. May I suggest (I haven't read the whole thread yet, maybe
> > somebody else already did) that
> > 
> > 	static inline unsigned long sg_phys(struct scatterlist *sg)
> > 	{
> > 		return 	page_to_phys(sg_page(sg)) + sg->offset;
> > 	}
> > 
> > would be a good thing to have?
> > 
> > Very few drivers should care so much about the *page* itself (or the 
> > offset). That's something that the generic allocation code etc cares 
> > about, but the driver is almost bound to care mostly about the actual
> > DMA address
> 
> .... but will that work for systems with IOMMU ? or is it fundamentally
> the wrong interface

They use foo_to_bus() on the address. sg_phys() should of course only be
used where the user previously did page_to_phys() on the sg page.

-- 
Jens Axboe


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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 16:55                                             ` Linus Torvalds
  2007-10-18 17:01                                               ` Jens Axboe
  2007-10-18 17:10                                               ` Arjan van de Ven
@ 2007-10-18 19:20                                               ` Jeff Garzik
  2 siblings, 0 replies; 151+ messages in thread
From: Jeff Garzik @ 2007-10-18 19:20 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Jens Axboe, David Miller, fujita.tomonori, mingo, linux-kernel,
	alan, tomof

Linus Torvalds wrote:
> Very few drivers should care so much about the *page* itself (or the 
> offset). That's something that the generic allocation code etc cares 
> about, but the driver is almost bound to care mostly about the actual DMA 
> address, so adding that helper function that abstracts the sg access would 
> be helpful in hiding some of the cruft?


FWIW libata cares about both.  When doing DMA, it cares about the DMA 
address.  When doing PIO, it cares about the actual page, because it 
does a kmap before sending the data through a 16-bit/32-bit data FIFO.

	Jeff



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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18 17:14                                                 ` Jens Axboe
@ 2007-10-19  8:59                                                   ` FUJITA Tomonori
  0 siblings, 0 replies; 151+ messages in thread
From: FUJITA Tomonori @ 2007-10-19  8:59 UTC (permalink / raw)
  To: jens.axboe
  Cc: arjan, torvalds, davem, fujita.tomonori, mingo, linux-kernel,
	jgarzik, alan, tomof

On Thu, 18 Oct 2007 19:14:29 +0200
Jens Axboe <jens.axboe@oracle.com> wrote:

> On Thu, Oct 18 2007, Arjan van de Ven wrote:
> > On Thu, 18 Oct 2007 09:55:04 -0700 (PDT)
> > Linus Torvalds <torvalds@linux-foundation.org> wrote:
> > 
> > > 
> > > 
> > > On Thu, 18 Oct 2007, Jens Axboe wrote:
> > > > -		unsigned long addr = page_to_phys(s->page) +
> > > > s->offset; 
> > > > +		unsigned long addr = page_to_phys(sg_page(s)) +
> > > > s->offset; 
> > > 
> > > Umm. May I suggest (I haven't read the whole thread yet, maybe
> > > somebody else already did) that
> > > 
> > > 	static inline unsigned long sg_phys(struct scatterlist *sg)
> > > 	{
> > > 		return 	page_to_phys(sg_page(sg)) + sg->offset;
> > > 	}
> > > 
> > > would be a good thing to have?
> > > 
> > > Very few drivers should care so much about the *page* itself (or the 
> > > offset). That's something that the generic allocation code etc cares 
> > > about, but the driver is almost bound to care mostly about the actual
> > > DMA address
> > 
> > .... but will that work for systems with IOMMU ? or is it fundamentally
> > the wrong interface
> 
> They use foo_to_bus() on the address. sg_phys() should of course only be
> used where the user previously did page_to_phys() on the sg page.

I can take care of IOMMU stuff when I'll send IOMMU merging fix
patchset:

http://marc.info/?l=linux-scsi&m=119079718126157&w=2

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

* Re: [bug] ata subsystem related crash with latest -git
  2007-10-18  8:32                             ` Jens Axboe
  2007-10-18  8:38                               ` Jeff Garzik
  2007-10-18  9:01                               ` Jeff Garzik
@ 2007-10-20 11:55                               ` Torsten Kaiser
  2 siblings, 0 replies; 151+ messages in thread
From: Torsten Kaiser @ 2007-10-20 11:55 UTC (permalink / raw)
  To: Jens Axboe
  Cc: Jeff Garzik, Ingo Molnar, Linus Torvalds, linux-kernel, Alan Cox

[Just catching with reading lkml to this post]

On 10/18/07, Jens Axboe <jens.axboe@oracle.com> wrote:
>
> Theory - ata_sg_is_last() isn't returning true for the last entry. Can
> you double check that it correcly marks the last entry in mv_fill_sg()?
> Alternatively, just try this patch.

I "hate" to point this out, but I already reported that sata_sil24
fails on 1. Sep.:
http://lkml.org/lkml/2007/9/1/95

In the thread "sata_sil24 broken since 2.6.23-rc4-mm1" I spent over a
week to trace this back to ata_sg_is_last (finally found on 7. Oct):
http://lkml.org/lkml/2007/10/7/43

Thanks for finally patching this now...

Torsten

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

end of thread, other threads:[~2007-10-20 11:56 UTC | newest]

Thread overview: 151+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-10-17 15:46 [bug] block subsystem related crash with latest -git Ingo Molnar
2007-10-17 15:50 ` Ingo Molnar
2007-10-17 16:32   ` Jens Axboe
2007-10-17 16:50 ` Linus Torvalds
2007-10-17 16:59   ` Jens Axboe
2007-10-17 17:08     ` Jens Axboe
2007-10-17 17:21       ` Jens Axboe
2007-10-17 17:29         ` Jens Axboe
2007-10-17 17:34           ` Ingo Molnar
2007-10-17 17:36             ` Jens Axboe
2007-10-17 17:45             ` [bug] ata " Ingo Molnar
2007-10-17 17:53               ` Jens Axboe
2007-10-17 17:55                 ` Jens Axboe
2007-10-17 17:58                   ` Ingo Molnar
2007-10-17 18:37                 ` Jens Axboe
2007-10-17 19:04                   ` Ingo Molnar
2007-10-17 19:08                     ` Jens Axboe
2007-10-17 19:14                       ` Ingo Molnar
2007-10-17 19:17                         ` Ingo Molnar
2007-10-17 19:25                           ` Jens Axboe
2007-10-17 19:25                         ` Jens Axboe
2007-10-17 19:09                   ` Ingo Molnar
2007-10-17 19:28                     ` Linus Torvalds
2007-10-17 19:35                       ` Jens Axboe
2007-10-17 19:45                         ` Linus Torvalds
2007-10-17 19:56                           ` Jens Axboe
2007-10-17 20:06                             ` Jens Axboe
2007-10-17 20:24                               ` Linus Torvalds
2007-10-17 20:31                                 ` Jens Axboe
2007-10-17 21:11                                   ` Linus Torvalds
2007-10-17 23:00                                     ` FUJITA Tomonori
2007-10-18  1:07                                       ` Linus Torvalds
2007-10-18  1:14                                         ` Jeff Garzik
2007-10-18  1:19                                         ` David Miller
2007-10-18  1:36                                           ` Linus Torvalds
2007-10-18  1:49                                             ` David Miller
2007-10-18  3:44                                             ` Mark Lord
2007-10-18  4:01                                               ` Linus Torvalds
2007-10-18  4:05                                                 ` Mark Lord
2007-10-18  4:14                                                   ` Jeff Garzik
2007-10-18  4:18                                                   ` Mark Lord
2007-10-18  4:31                                                     ` Jeff Garzik
2007-10-18  4:41                                                       ` Mark Lord
2007-10-18  4:53                                                       ` Linus Torvalds
2007-10-18  7:05                                                       ` Jens Axboe
2007-10-18 13:13                                                         ` Mark Lord
2007-10-18 13:23                                                           ` Jens Axboe
2007-10-18 13:32                                                             ` Mark Lord
2007-10-18 13:34                                                               ` Jens Axboe
2007-10-18 13:59                                                                 ` Mark Lord
2007-10-18 14:04                                                                   ` Jens Axboe
2007-10-18  4:45                                                     ` Linus Torvalds
2007-10-18  4:54                                                     ` Mark Lord
2007-10-18  5:09                                                       ` Mark Lord
2007-10-18  4:20                                                   ` Linus Torvalds
2007-10-18  5:25                                                 ` Mark Lord
2007-10-18  5:34                                                   ` Mark Lord
2007-10-18  5:45                                                     ` Jeff Garzik
2007-10-18  7:09                                                       ` Jens Axboe
2007-10-18  7:30                                                         ` Jeff Garzik
2007-10-18  8:21                                           ` Jens Axboe
2007-10-18 11:55                                             ` David Miller
2007-10-18 11:57                                               ` Jens Axboe
2007-10-18 12:05                                                 ` David Miller
2007-10-18 12:09                                                   ` Jens Axboe
2007-10-18 12:15                                                     ` Jens Axboe
2007-10-18 12:36                                                       ` David Miller
2007-10-18 12:39                                                         ` Jens Axboe
2007-10-18 12:58                                                       ` Benny Halevy
2007-10-18 13:56                                                         ` Jens Axboe
2007-10-18 14:05                                                           ` Jens Axboe
2007-10-18 14:16                                                             ` Benny Halevy
2007-10-18 14:38                                                               ` Jens Axboe
2007-10-18 14:58                                                                 ` Olof Johansson
2007-10-18 15:25                                                                   ` Jens Axboe
2007-10-18 12:58                                                       ` Jens Axboe
2007-10-18 13:32                                                         ` Jens Axboe
2007-10-18 13:49                                                           ` Benny Halevy
2007-10-18 13:55                                                             ` Jens Axboe
2007-10-18 13:51                                                           ` Mark Lord
2007-10-18 13:58                                                             ` Jens Axboe
2007-10-18 14:03                                                               ` Mark Lord
2007-10-18 14:10                                                               ` Mark Lord
2007-10-18 14:13                                                                 ` Mark Lord
2007-10-18 14:14                                                                   ` Jens Axboe
2007-10-18 16:55                                             ` Linus Torvalds
2007-10-18 17:01                                               ` Jens Axboe
2007-10-18 17:10                                                 ` Jens Axboe
2007-10-18 17:10                                               ` Arjan van de Ven
2007-10-18 17:14                                                 ` Jens Axboe
2007-10-19  8:59                                                   ` FUJITA Tomonori
2007-10-18 19:20                                               ` Jeff Garzik
2007-10-17 20:51                               ` Ingo Molnar
2007-10-17 19:49                         ` Jens Axboe
2007-10-17 20:05                           ` Ingo Molnar
2007-10-17 20:10                           ` Linus Torvalds
2007-10-18  7:07                         ` Ingo Molnar
2007-10-18  7:10                           ` Jens Axboe
2007-10-18  8:22                           ` Jeff Garzik
2007-10-18  8:32                             ` Jens Axboe
2007-10-18  8:38                               ` Jeff Garzik
2007-10-18  8:51                                 ` Jeff Garzik
2007-10-18  9:01                               ` Jeff Garzik
     [not found]                                 ` <bd58e4af0710180210tcc0d31ep9d05a0f2e9d6df29@mail.gmail.com>
2007-10-18  9:14                                   ` Jeff Garzik
2007-10-18  9:17                                 ` Jens Axboe
2007-10-18  9:32                                   ` Jeff Garzik
2007-10-18  9:41                                     ` Jens Axboe
2007-10-18 10:04                                       ` Jeff Garzik
2007-10-18 10:10                                         ` Jens Axboe
2007-10-18 10:13                                           ` Ingo Molnar
2007-10-18 10:16                                             ` Jens Axboe
2007-10-18 10:17                                               ` Jens Axboe
2007-10-18 10:49                                                 ` Ingo Molnar
2007-10-18 10:50                                                   ` Jeff Garzik
2007-10-18 10:56                                                   ` Jens Axboe
2007-10-18 10:42                                           ` [PATCH] " Jeff Garzik
2007-10-18 10:54                                             ` Ingo Molnar
2007-10-18 11:02                                               ` Jeff Garzik
2007-10-18 11:40                                                 ` Ingo Molnar
2007-10-18 14:52                                             ` Olof Johansson
2007-10-20 11:55                               ` Torsten Kaiser
2007-10-18 11:03                           ` Ingo Molnar
2007-10-18 11:05                             ` Jens Axboe
2007-10-17 19:42                       ` Linus Torvalds
2007-10-17 19:55                         ` Jens Axboe
2007-10-17 18:08               ` Linus Torvalds
2007-10-17 18:13                 ` Ingo Molnar
2007-10-17 17:56           ` [bug] block " Linus Torvalds
2007-10-17 18:02             ` Jens Axboe
2007-10-17 18:13               ` Linus Torvalds
2007-10-17 18:20                 ` Jens Axboe
2007-10-17 18:58                   ` Linus Torvalds
2007-10-17 19:03                     ` Jens Axboe
2007-10-17 19:15                       ` Linus Torvalds
2007-10-17 18:02             ` Ingo Molnar
2007-10-17 18:14               ` Linus Torvalds
2007-10-17 20:15           ` Luca Tettamanti
2007-10-17 17:30         ` Ingo Molnar
2007-10-17 17:31           ` Jens Axboe
2007-10-17 17:28       ` Ingo Molnar
2007-10-17 17:52       ` Linus Torvalds
2007-10-17 18:00         ` Jens Axboe
2007-10-17 18:18           ` Linus Torvalds
2007-10-17 18:22             ` Jens Axboe
2007-10-18 10:52               ` Benny Halevy
2007-10-18 10:55                 ` Jens Axboe
2007-10-18 12:03                   ` David Miller
2007-10-18 12:28                     ` Jens Axboe
2007-10-17 18:22             ` Linus Torvalds
2007-10-17 18:40               ` Jens Axboe
2007-10-17 17:11     ` Ingo Molnar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox