From 1f0abae87812244ad8d68034609c86129c6b8404 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 5 Dec 2007 14:32:13 -0800 Subject: [PATCH 01/25] [IA64] increase .data.patch offset /opt/crosstool/gcc-3.4.5-glibc-2.3.6/ia64-unknown-linux-gnu/lib/gcc/ia64-unknown-linux-gnu/3.4.5/../../../../ia64-unknown-linux-gnu/bin/ld: section .data.patch [a000000000000500 -> a000000000000507] overlaps section .dynamic [a0000000000003c8 -> a000000000000507] This only appears to be a problem with strangely configured cross-compilation ... native compilers don't have this issue. But in the interests of helping others at least compile for ia64, this can go in. -Tony Signed-off-by: Andrew Morton Signed-off-by: Tony Luck --- arch/ia64/kernel/gate.lds.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ia64/kernel/gate.lds.S b/arch/ia64/kernel/gate.lds.S index 454d7a7dfa9d..3cb1abc00e24 100644 --- a/arch/ia64/kernel/gate.lds.S +++ b/arch/ia64/kernel/gate.lds.S @@ -30,7 +30,7 @@ SECTIONS * the dynamic symbol table et al. If this amount is insufficient, * ld -shared will barf. Just increase it here. */ - . = GATE_ADDR + 0x500; + . = GATE_ADDR + 0x600; .data.patch : { __start_gate_mckinley_e9_patchlist = .; From ff08e657f3e7224d090dd816e00cea2c110575c4 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 7 Dec 2007 14:42:08 -0800 Subject: [PATCH 02/25] [IA64] don't assume that unwcheck.py is executable Don't assume that this file has execute permissions. For example, patch(1) loses that information. Signed-off-by: Andrew Morton Signed-off-by: Tony Luck --- arch/ia64/Makefile | 2 +- arch/ia64/scripts/unwcheck.py | 0 2 files changed, 1 insertion(+), 1 deletion(-) mode change 100755 => 100644 arch/ia64/scripts/unwcheck.py diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index 34951aa2370b..b916ccfdef84 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile @@ -77,7 +77,7 @@ vmlinux.gz: vmlinux $(Q)$(MAKE) $(build)=$(boot) $@ unwcheck: vmlinux - -$(Q)READELF=$(READELF) $(srctree)/arch/ia64/scripts/unwcheck.py $< + -$(Q)READELF=$(READELF) python $(srctree)/arch/ia64/scripts/unwcheck.py $< archclean: $(Q)$(MAKE) $(clean)=$(boot) diff --git a/arch/ia64/scripts/unwcheck.py b/arch/ia64/scripts/unwcheck.py old mode 100755 new mode 100644 From bdc2619ab95d45d434c16d5c216bc6243761f6fb Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 7 Dec 2007 16:10:19 -0800 Subject: [PATCH 03/25] [IA64] export copy_page() to modules With the unionfs patch applied I get ERROR: "copy_page" [fs/unionfs/unionfs.ko] undefined! the other architectures (some, at least) export copy_page() so I guess ia64 should also do so. To do this we need to move the copy_page() functions out of lib.a and into built-in.o and add the EXPORT_SYMBOL(). Cc: Sam Ravnborg Cc: Kyle McMartin Signed-off-by: Andrew Morton Signed-off-by: Tony Luck --- arch/ia64/hp/sim/boot/Makefile | 2 +- arch/ia64/kernel/ia64_ksyms.c | 3 +++ arch/ia64/lib/Makefile | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/ia64/hp/sim/boot/Makefile b/arch/ia64/hp/sim/boot/Makefile index df6e9968c845..2e805e0cc560 100644 --- a/arch/ia64/hp/sim/boot/Makefile +++ b/arch/ia64/hp/sim/boot/Makefile @@ -33,5 +33,5 @@ $(obj)/vmlinux.bin: vmlinux FORCE LDFLAGS_bootloader = -static -T $(obj)/bootloader: $(src)/bootloader.lds $(obj)/bootloader.o $(obj)/boot_head.o $(obj)/fw-emu.o \ - lib/lib.a arch/ia64/lib/lib.a FORCE + lib/lib.a arch/ia64/lib/built-in.o arch/ia64/lib/lib.a FORCE $(call if_changed,ld) diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c index bd17190bebb6..c3b4412ccc67 100644 --- a/arch/ia64/kernel/ia64_ksyms.c +++ b/arch/ia64/kernel/ia64_ksyms.c @@ -63,6 +63,9 @@ EXPORT_SYMBOL(__udivdi3); EXPORT_SYMBOL(__moddi3); EXPORT_SYMBOL(__umoddi3); +#include +EXPORT_SYMBOL(copy_page); + #if defined(CONFIG_MD_RAID456) || defined(CONFIG_MD_RAID456_MODULE) extern void xor_ia64_2(void); extern void xor_ia64_3(void); diff --git a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile index 46edf8444c7e..98771e2a78af 100644 --- a/arch/ia64/lib/Makefile +++ b/arch/ia64/lib/Makefile @@ -11,8 +11,8 @@ lib-y := __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \ flush.o ip_fast_csum.o do_csum.o \ memset.o strlen.o xor.o -lib-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o -lib-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o +obj-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o +obj-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o lib-$(CONFIG_PERFMON) += carta_random.o AFLAGS___divdi3.o = From b9ab117c2f2eac8432def6a2ea03711bfa7f35d5 Mon Sep 17 00:00:00 2001 From: Shi Weihua Date: Mon, 3 Dec 2007 12:57:50 +0800 Subject: [PATCH 04/25] [IA64] signal : fix missing error checkings Not all the return value of __copy_from_user and __put_user is checked.This patch fixed it. Signed-off-by: Shi Weihua Signed-off-by: Tony Luck --- arch/ia64/kernel/signal.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index cdb64cc4d9c8..4c730099d58f 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c @@ -98,7 +98,7 @@ restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr) if ((flags & IA64_SC_FLAG_FPH_VALID) != 0) { struct ia64_psr *psr = ia64_psr(&scr->pt); - __copy_from_user(current->thread.fph, &sc->sc_fr[32], 96*16); + err |= __copy_from_user(current->thread.fph, &sc->sc_fr[32], 96*16); psr->mfh = 0; /* drop signal handler's fph contents... */ preempt_disable(); if (psr->dfh) @@ -244,7 +244,7 @@ static long setup_sigcontext (struct sigcontext __user *sc, sigset_t *mask, struct sigscratch *scr) { unsigned long flags = 0, ifs, cfm, nat; - long err; + long err = 0; ifs = scr->pt.cr_ifs; @@ -257,12 +257,12 @@ setup_sigcontext (struct sigcontext __user *sc, sigset_t *mask, struct sigscratc ia64_flush_fph(current); if ((current->thread.flags & IA64_THREAD_FPH_VALID)) { flags |= IA64_SC_FLAG_FPH_VALID; - __copy_to_user(&sc->sc_fr[32], current->thread.fph, 96*16); + err = __copy_to_user(&sc->sc_fr[32], current->thread.fph, 96*16); } nat = ia64_get_scratch_nat_bits(&scr->pt, scr->scratch_unat); - err = __put_user(flags, &sc->sc_flags); + err |= __put_user(flags, &sc->sc_flags); err |= __put_user(nat, &sc->sc_nat); err |= PUT_SIGSET(mask, &sc->sc_mask); err |= __put_user(cfm, &sc->sc_cfm); From 9e004ebd2dab980d663784d096aa6dc449225bd8 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Fri, 7 Dec 2007 14:44:05 -0800 Subject: [PATCH 05/25] [IA64] iosapic cleanup Make some IOSAPIC functions static and remove one that is unused. Signed-off-by: Simon Horman Signed-off-by: Tony Luck --- arch/ia64/kernel/iosapic.c | 19 +++---------------- include/asm-ia64/iosapic.h | 2 -- 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index 274a59383043..96460ca2b906 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c @@ -199,19 +199,6 @@ static inline int __gsi_to_irq(unsigned int gsi) return -1; } -/* - * Translate GSI number to the corresponding IA-64 interrupt vector. If no - * entry exists, return -1. - */ -inline int -gsi_to_vector (unsigned int gsi) -{ - int irq = __gsi_to_irq(gsi); - if (check_irq_used(irq) < 0) - return -1; - return irq_to_vector(irq); -} - int gsi_to_irq (unsigned int gsi) { @@ -429,7 +416,7 @@ iosapic_end_level_irq (unsigned int irq) #define iosapic_disable_level_irq mask_irq #define iosapic_ack_level_irq nop -struct irq_chip irq_type_iosapic_level = { +static struct irq_chip irq_type_iosapic_level = { .name = "IO-SAPIC-level", .startup = iosapic_startup_level_irq, .shutdown = iosapic_shutdown_level_irq, @@ -478,7 +465,7 @@ iosapic_ack_edge_irq (unsigned int irq) #define iosapic_disable_edge_irq nop #define iosapic_end_edge_irq nop -struct irq_chip irq_type_iosapic_edge = { +static struct irq_chip irq_type_iosapic_edge = { .name = "IO-SAPIC-edge", .startup = iosapic_startup_edge_irq, .shutdown = iosapic_disable_edge_irq, @@ -491,7 +478,7 @@ struct irq_chip irq_type_iosapic_edge = { .set_affinity = iosapic_set_affinity }; -unsigned int +static unsigned int iosapic_version (char __iomem *addr) { /* diff --git a/include/asm-ia64/iosapic.h b/include/asm-ia64/iosapic.h index b8f712859140..a3a4288daae8 100644 --- a/include/asm-ia64/iosapic.h +++ b/include/asm-ia64/iosapic.h @@ -80,7 +80,6 @@ extern int iosapic_remove (unsigned int gsi_base); #else #define iosapic_remove(gsi_base) (-EINVAL) #endif /* CONFIG_HOTPLUG */ -extern int gsi_to_vector (unsigned int gsi); extern int gsi_to_irq (unsigned int gsi); extern int iosapic_register_intr (unsigned int gsi, unsigned long polarity, unsigned long trigger); @@ -94,7 +93,6 @@ extern int __init iosapic_register_platform_intr (u32 int_type, u16 eid, u16 id, unsigned long polarity, unsigned long trigger); -extern unsigned int iosapic_version (char __iomem *addr); #ifdef CONFIG_NUMA extern void __devinit map_iosapic_to_node (unsigned int, int); From afc2cf35b43ca58bd73b86b2f72af8b9bdb67ab8 Mon Sep 17 00:00:00 2001 From: Mike Habeck Date: Mon, 26 Nov 2007 11:19:57 -0600 Subject: [PATCH 06/25] [IA64] SGI Altix : fix bug in sn_io_late_init() When initializing pci_controller->node to point to the closest node we need to take into consideration that a PIC PCI Bridge ASIC can be connected to a headless/memless node just like the TIOCP and TIOCE Bridge ASICs Signed-off-by: Mike Habeck Signed-off-by: Tony Luck --- arch/ia64/sn/kernel/io_common.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/arch/ia64/sn/kernel/io_common.c b/arch/ia64/sn/kernel/io_common.c index 4594770e685a..f3250c177650 100644 --- a/arch/ia64/sn/kernel/io_common.c +++ b/arch/ia64/sn/kernel/io_common.c @@ -545,19 +545,18 @@ sn_io_late_init(void) nasid = NASID_GET(bussoft->bs_base); cnode = nasid_to_cnodeid(nasid); if ((bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP) || - (bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCE)) { - /* TIO PCI Bridge: find nearest node with CPUs */ + (bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCE) || + (bussoft->bs_asic_type == PCIIO_ASIC_TYPE_PIC)) { + /* PCI Bridge: find nearest node with CPUs */ int e = sn_hwperf_get_nearest_node(cnode, NULL, &near_cnode); if (e < 0) { near_cnode = (cnodeid_t)-1; /* use any node */ - printk(KERN_WARNING "pcibr_bus_fixup: failed " - "to find near node with CPUs to TIO " + printk(KERN_WARNING "sn_io_late_init: failed " + "to find near node with CPUs for " "node %d, err=%d\n", cnode, e); } PCI_CONTROLLER(bus)->node = near_cnode; - } else if (bussoft->bs_asic_type == PCIIO_ASIC_TYPE_PIC) { - PCI_CONTROLLER(bus)->node = cnode; } } From b898a424ed68ba73d6d4562d6370985b2e9bec61 Mon Sep 17 00:00:00 2001 From: Bernhard Walle Date: Wed, 21 Nov 2007 14:58:25 -0800 Subject: [PATCH 07/25] [IA64] rename _bss to __bss_start Rename _bss to __bss_start as on other architectures. That makes it possible to use the instead of own declarations. Also add __bss_stop because that symbol exists on other architectures. Signed-off-by: Bernhard Walle Cc: "Luck, Tony" Signed-off-by: Andrew Morton Signed-off-by: Tony Luck --- arch/ia64/hp/sim/boot/bootloader.lds | 3 ++- arch/ia64/kernel/setup.c | 3 +-- arch/ia64/kernel/vmlinux.lds.S | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/ia64/hp/sim/boot/bootloader.lds b/arch/ia64/hp/sim/boot/bootloader.lds index 69ae58531033..3977f25a1265 100644 --- a/arch/ia64/hp/sim/boot/bootloader.lds +++ b/arch/ia64/hp/sim/boot/bootloader.lds @@ -22,10 +22,11 @@ SECTIONS .sdata : { *(.sdata) } _edata = .; - _bss = .; + __bss_start = .; .sbss : { *(.sbss) *(.scommon) } .bss : { *(.bss) *(COMMON) } . = ALIGN(64 / 8); + __bss_stop = .; _end = . ; /* Stabs debugging sections. */ diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 2b3751eef5ce..4ac2b1f1bd3b 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -95,7 +95,6 @@ static struct resource bss_resource = { .name = "Kernel bss", .flags = IORESOURCE_BUSY | IORESOURCE_MEM }; -extern char _text[], _end[], _etext[], _edata[], _bss[]; unsigned long ia64_max_cacheline_size; @@ -206,7 +205,7 @@ static int __init register_memory(void) code_resource.end = ia64_tpa(_etext) - 1; data_resource.start = ia64_tpa(_etext); data_resource.end = ia64_tpa(_edata) - 1; - bss_resource.start = ia64_tpa(_bss); + bss_resource.start = ia64_tpa(__bss_start); bss_resource.end = ia64_tpa(_end) - 1; efi_initialize_iomem_resources(&code_resource, &data_resource, &bss_resource); diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S index 00232b4357ba..757e419ebcf8 100644 --- a/arch/ia64/kernel/vmlinux.lds.S +++ b/arch/ia64/kernel/vmlinux.lds.S @@ -240,11 +240,12 @@ SECTIONS .sdata : AT(ADDR(.sdata) - LOAD_OFFSET) { *(.sdata) *(.sdata1) *(.srdata) } _edata = .; - _bss = .; + __bss_start = .; .sbss : AT(ADDR(.sbss) - LOAD_OFFSET) { *(.sbss) *(.scommon) } .bss : AT(ADDR(.bss) - LOAD_OFFSET) { *(.bss) *(COMMON) } + __bss_stop = .; _end = .; From 685c7f5d3629d558b17ee193b6d7f194e82aadf0 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Wed, 21 Nov 2007 14:58:26 -0800 Subject: [PATCH 08/25] [IA64] make full use of macro efi_md_size Macro efi_md_size is defined in efi.c, and here we apply it throughout efi.c. Signed-off-by: Li Zefan Acked-by: Simon Horman Signed-off-by: Andrew Morton Signed-off-by: Tony Luck --- arch/ia64/kernel/efi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index 8e8f8b6193ee..242d79341120 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -370,7 +370,7 @@ efi_get_pal_addr (void) continue; } - if (md->num_pages << EFI_PAGE_SHIFT > IA64_GRANULE_SIZE) + if (efi_md_size(md) > IA64_GRANULE_SIZE) panic("Woah! PAL code size bigger than a granule!"); #if EFI_DEBUG @@ -378,7 +378,7 @@ efi_get_pal_addr (void) printk(KERN_INFO "CPU %d: mapping PAL code [0x%lx-0x%lx) into [0x%lx-0x%lx)\n", smp_processor_id(), md->phys_addr, - md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT), + md->phys_addr + efi_md_size(md), vaddr & mask, (vaddr & mask) + IA64_GRANULE_SIZE); #endif return __va(md->phys_addr); @@ -523,7 +523,7 @@ efi_init (void) md = p; printk("mem%02u: type=%u, attr=0x%lx, range=[0x%016lx-0x%016lx) (%luMB)\n", i, md->type, md->attribute, md->phys_addr, - md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT), + md->phys_addr + efi_md_size(md), md->num_pages >> (20 - EFI_PAGE_SHIFT)); } } @@ -656,7 +656,7 @@ efi_memory_descriptor (unsigned long phys_addr) for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { md = p; - if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT)) + if (phys_addr - md->phys_addr < efi_md_size(md)) return md; } return NULL; @@ -1158,7 +1158,7 @@ efi_initialize_iomem_resources(struct resource *code_resource, res->name = name; res->start = md->phys_addr; - res->end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1; + res->end = md->phys_addr + efi_md_size(md) - 1; res->flags = flags; if (insert_resource(&iomem_resource, res) < 0) From c2eeb321a8f059112bdf0f8d4ac7ab35800f3f66 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 19 Nov 2007 17:47:53 -0800 Subject: [PATCH 09/25] [IA64] Add missing "space" to concatenated strings Signed-off-by: Joe Perches Signed-off-by: Tony Luck --- arch/ia64/kernel/kprobes.c | 10 +++++----- arch/ia64/mm/tlb.c | 2 +- arch/ia64/sn/kernel/io_common.c | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index 5fd65d8302c8..90518e43aba0 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c @@ -182,8 +182,8 @@ static int __kprobes unsupported_inst(uint template, uint slot, qp = kprobe_inst & 0x3f; if (is_cmp_ctype_unc_inst(template, slot, major_opcode, kprobe_inst)) { if (slot == 1 && qp) { - printk(KERN_WARNING "Kprobes on cmp unc" - "instruction on slot 1 at <0x%lx>" + printk(KERN_WARNING "Kprobes on cmp unc " + "instruction on slot 1 at <0x%lx> " "is not supported\n", addr); return -EINVAL; @@ -221,8 +221,8 @@ static int __kprobes unsupported_inst(uint template, uint slot, * bit 12 to be equal to 1 */ if (slot == 1 && qp) { - printk(KERN_WARNING "Kprobes on test bit" - "instruction on slot at <0x%lx>" + printk(KERN_WARNING "Kprobes on test bit " + "instruction on slot at <0x%lx> " "is not supported\n", addr); return -EINVAL; } @@ -242,7 +242,7 @@ static int __kprobes unsupported_inst(uint template, uint slot, */ int x6=(kprobe_inst >> 27) & 0x3F; if ((x6 == 0x10) || (x6 == 0x11)) { - printk(KERN_WARNING "Kprobes on" + printk(KERN_WARNING "Kprobes on " "Indirect Predict is not supported\n"); return -EINVAL; } diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c index 1682fc639038..cef164729db7 100644 --- a/arch/ia64/mm/tlb.c +++ b/arch/ia64/mm/tlb.c @@ -180,7 +180,7 @@ ia64_tlb_init (void) long status; if ((status = ia64_pal_vm_page_size(&tr_pgbits, &purge.mask)) != 0) { - printk(KERN_ERR "PAL_VM_PAGE_SIZE failed with status=%ld;" + printk(KERN_ERR "PAL_VM_PAGE_SIZE failed with status=%ld; " "defaulting to architected purge page-sizes.\n", status); purge.mask = 0x115557000UL; } diff --git a/arch/ia64/sn/kernel/io_common.c b/arch/ia64/sn/kernel/io_common.c index f3250c177650..c4eb84f9e781 100644 --- a/arch/ia64/sn/kernel/io_common.c +++ b/arch/ia64/sn/kernel/io_common.c @@ -347,7 +347,7 @@ sn_common_bus_fixup(struct pci_bus *bus, if (controller->node >= num_online_nodes()) { struct pcibus_bussoft *b = SN_PCIBUS_BUSSOFT(bus); - printk(KERN_WARNING "Device ASIC=%u XID=%u PBUSNUM=%u" + printk(KERN_WARNING "Device ASIC=%u XID=%u PBUSNUM=%u " "L_IO=%lx L_MEM=%lx BASE=%lx\n", b->bs_asic_type, b->bs_xid, b->bs_persist_busnum, b->bs_legacy_io, b->bs_legacy_mem, b->bs_base); From 965d747264c91ed206846d74ae09f757a36a373b Mon Sep 17 00:00:00 2001 From: Roel Kluin <12o3l@tiscali.nl> Date: Fri, 7 Dec 2007 14:59:30 -0800 Subject: [PATCH 10/25] [IA64] operator priority fix in acpi_map_lsapic() '!' has a higher priority than '&', so as was this won't test the first bit, but rather evaluates to false for any non-zero lsapic->lapic_flags. Signed-off-by: Roel Kluin <12o3l@tiscali.nl> Acked-by: Simon Horman Signed-off-by: Tony Luck --- arch/ia64/kernel/acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 897e2083a3b1..00b5d08f6da8 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -860,7 +860,7 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu) lsapic = (struct acpi_madt_local_sapic *)obj->buffer.pointer; if ((lsapic->header.type != ACPI_MADT_TYPE_LOCAL_SAPIC) || - (!lsapic->lapic_flags & ACPI_MADT_ENABLED)) { + (!(lsapic->lapic_flags & ACPI_MADT_ENABLED))) { kfree(buffer.pointer); return -EINVAL; } From 3661999a17b0397c7a93c200b280c55958ba3593 Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Tue, 13 Nov 2007 14:55:20 +0800 Subject: [PATCH 11/25] [IA64] kprobe: make kreturn probe handler stack unwind correct Restore regs->ccr_iip before kreturn probe handler runs. In this way, if probe handler does unwind, unwind can correctly get the stack trace. Fixes: http://sourceware.org/bugzilla/show_bug.cgi?id=5051 Signed-off-by: Shaohua Li Signed-off-by: Tony Luck --- arch/ia64/kernel/kprobes.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index 90518e43aba0..fc4d2676264f 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c @@ -430,6 +430,23 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) * real return address, and all the rest will point to * kretprobe_trampoline */ + hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { + if (ri->task != current) + /* another task is sharing our hash bucket */ + continue; + + orig_ret_address = (unsigned long)ri->ret_addr; + if (orig_ret_address != trampoline_address) + /* + * This is the real return address. Any other + * instances associated with this task are for + * other calls deeper on the call stack + */ + break; + } + + regs->cr_iip = orig_ret_address; + hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { if (ri->task != current) /* another task is sharing our hash bucket */ @@ -452,8 +469,6 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) kretprobe_assert(ri, orig_ret_address, trampoline_address); - regs->cr_iip = orig_ret_address; - reset_current_kprobe(); spin_unlock_irqrestore(&kretprobe_lock, flags); preempt_enable_no_resched(); From aa0ebec9cfb8a3fab966db75ac21d05a43f312a1 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Fri, 9 Nov 2007 10:51:01 +0900 Subject: [PATCH 12/25] [IA64] Fix iosapic interrupt delivery mode for CPE If "CPEI Processor Override" bit is not set in "Platform Interrupt Source Flags" in "Platform Interrupt Sources Structure" in ACPI MADT, the target processor of CPEI is restricted to a specific CPU. Because of this, the delivery mode for CPEI should be IOSAPIC_FIXED. Signed-off-by: Kenji Kaneshige Signed-off-by: Tony Luck --- arch/ia64/kernel/iosapic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index 96460ca2b906..398e2fd1cd25 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c @@ -925,7 +925,7 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi, case ACPI_INTERRUPT_CPEI: irq = vector = IA64_CPE_VECTOR; BUG_ON(bind_irq_vector(irq, vector, CPU_MASK_ALL)); - delivery = IOSAPIC_LOWEST_PRIORITY; + delivery = IOSAPIC_FIXED; mask = 1; break; default: From 1cacc9ab8bf10e60b3ed93d7a10b070c4cbc6c9f Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Thu, 6 Dec 2007 22:20:11 +0100 Subject: [PATCH 13/25] kbuild: fix building with redirected output. Jan Altenberg reported that building with redirected input like this failed: make O=dir oldconfig bzImage < /dev/null The problem were caused by a make silentoldconfig being run before oldconfig and with a non-recent .config the build failed because silentoldconfig requires non-redirected stdin. Silentoldconfig was run as a side-effect of having the top-level Makefile re-made by make. Introducing an empty rule for the top-level Makefile (and Kbuild.include) fixed the issue. Signed-off-by: Sam Ravnborg --- Makefile | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 92dc3cb5f43d..a5252f451bfd 100644 --- a/Makefile +++ b/Makefile @@ -108,6 +108,9 @@ endif PHONY := _all _all: +# Cancel implicit rules on top Makefile +$(CURDIR)/Makefile Makefile: ; + ifneq ($(KBUILD_OUTPUT),) # Invoke a second make in the output directory, passing relevant variables # check that the output directory actually exists @@ -121,7 +124,7 @@ $(if $(filter-out $(KBUILD_OUTPUT),$(shell /bin/pwd)),, \ PHONY += $(MAKECMDGOALS) sub-make -$(filter-out _all sub-make,$(MAKECMDGOALS)) _all: sub-make +$(filter-out _all sub-make $(CURDIR)/Makefile, $(MAKECMDGOALS)) _all: sub-make $(Q)@: sub-make: FORCE @@ -291,7 +294,8 @@ export quiet Q KBUILD_VERBOSE # Look for make include files relative to root of kernel src MAKEFLAGS += --include-dir=$(srctree) -# We need some generic definitions. +# We need some generic definitions (do not try to remake the file). +$(srctree)/scripts/Kbuild.include: ; include $(srctree)/scripts/Kbuild.include # Make variables (CC, etc...) @@ -1560,9 +1564,6 @@ endif # skip-makefile PHONY += FORCE FORCE: -# Cancel implicit rules on top Makefile, `-rR' will apply to sub-makes. -Makefile: ; - # Declare the contents of the .PHONY variable as phony. We keep that # information in a variable se we can use it in if_changed and friends. .PHONY: $(PHONY) From 18c32dac75b187d1a4e858f3cfdf03e844129f5e Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 9 Dec 2007 08:55:13 +0100 Subject: [PATCH 14/25] kbuild: fix building with O=.. options The check introduced in commit: 4f1127e204377cbd2a56d112d323466f668e8334 "kbuild: fix infinite make recursion" caused certain external modules not to build and also caused 'make targz-pkg' to fail. This is a minimal fix so we revert to previous behaviour - but we do not overwrite the Makefile in the top-level directory. Signed-off-by: Sam Ravnborg Tested-by: Jay Cliburn Cc: Jay Cliburn --- Makefile | 3 --- scripts/mkmakefile | 6 ++++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index a5252f451bfd..7fb1a2c08305 100644 --- a/Makefile +++ b/Makefile @@ -118,9 +118,6 @@ saved-output := $(KBUILD_OUTPUT) KBUILD_OUTPUT := $(shell cd $(KBUILD_OUTPUT) && /bin/pwd) $(if $(KBUILD_OUTPUT),, \ $(error output directory "$(saved-output)" does not exist)) -# Check that OUTPUT directory is not the same as where we have kernel src -$(if $(filter-out $(KBUILD_OUTPUT),$(shell /bin/pwd)),, \ - $(error Output directory (O=...) specifies kernel src dir)) PHONY += $(MAKECMDGOALS) sub-make diff --git a/scripts/mkmakefile b/scripts/mkmakefile index ee39facee152..9ad1bd793252 100644 --- a/scripts/mkmakefile +++ b/scripts/mkmakefile @@ -11,6 +11,12 @@ test ! -r $2/Makefile -o -O $2/Makefile || exit 0 +# Only overwrite automatically generated Makefiles +# (so we do not overwrite kernel Makefile) +if ! grep -q Automatically $2/Makefile +then + exit 0 +fi echo " GEN $2/Makefile" cat << EOF > $2/Makefile From 7fd272550bd43cc1d7289ef0ab2fa50de137e767 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 9 Dec 2007 10:14:36 -0800 Subject: [PATCH 15/25] Avoid double memclear() in SLOB/SLUB Both slob and slub react to __GFP_ZERO by clearing the allocation, which means that passing the GFP_ZERO bit down to the page allocator is just wasteful and pointless. Acked-by: Matt Mackall Reviewed-by: Pekka Enberg Signed-off-by: Linus Torvalds --- mm/slob.c | 2 +- mm/slub.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/mm/slob.c b/mm/slob.c index ee2ef8af0d43..773a7aa80ab5 100644 --- a/mm/slob.c +++ b/mm/slob.c @@ -330,7 +330,7 @@ static void *slob_alloc(size_t size, gfp_t gfp, int align, int node) /* Not enough space: must allocate a new page */ if (!b) { - b = slob_new_page(gfp, 0, node); + b = slob_new_page(gfp & ~__GFP_ZERO, 0, node); if (!b) return 0; sp = (struct slob_page *)virt_to_page(b); diff --git a/mm/slub.c b/mm/slub.c index b9f37cb0f2e6..9c1d9f3b364f 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -1468,6 +1468,9 @@ static void *__slab_alloc(struct kmem_cache *s, void **object; struct page *new; + /* We handle __GFP_ZERO in the caller */ + gfpflags &= ~__GFP_ZERO; + if (!c->page) goto new_slab; From d757762bf2f6aea954745c76b4d767067b85be9d Mon Sep 17 00:00:00 2001 From: Donald Douwsma Date: Fri, 23 Nov 2007 16:27:42 +1100 Subject: [PATCH 16/25] [XFS] Fix dbflush panic in xfs_qm_sync. The recent behaviour layer removal dropped the check for quotas that have been requested at mount time but have subsequently been turned off. This results in a panic when accessing m_quotainfo which has been freed. This patch adds the check originally made by xfs_qm_syncall() to xfs_qm_sync(). SGI-PV: 969769 SGI-Modid: xfs-linux-melb:xfs-kern:29908a Signed-off-by: Donald Douwsma Signed-off-by: David Chinner Signed-off-by: Lachlan McIlroy --- fs/xfs/quota/xfs_qm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index b5f91281b707..d488645f833d 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c @@ -1008,6 +1008,9 @@ xfs_qm_sync( boolean_t nowait; int error; + if (! XFS_IS_QUOTA_ON(mp)) + return 0; + restarts = 0; /* * We won't block unless we are asked to. From cd57e594adc624dd9ee4c0ded3949da21ec24b2f Mon Sep 17 00:00:00 2001 From: Lachlan McIlroy Date: Fri, 23 Nov 2007 16:30:32 +1100 Subject: [PATCH 17/25] [XFS] 971064 Various fixups for xfs_bulkstat(). - sanity check for NULL user buffer in xfs_ioc_bulkstat[_compat]() - remove the special case for XFS_IOC_FSBULKSTAT with count == 1. This special case causes bulkstat to fail because the special case uses xfs_bulkstat_single() instead of xfs_bulkstat() and the two functions have different semantics. xfs_bulkstat() will return the next inode after the one supplied while skipping internal inodes (ie quota inodes). xfs_bulkstate_single() will only lookup the inode supplied and return an error if it is an internal inode. - in xfs_bulkstat(), need to initialise 'lastino' to the inode supplied so in cases were we return without examining any inodes the scan wont restart back at zero. - sanity check for valid *ubcountp values. Cannot sanity check for valid ubuffer here because some users of xfs_bulkstat() don't supply a buffer. - checks against 'ubleft' (the space left in the user's buffer) should be against 'statstruct_size' which is the supplied minimum object size. The mixture of checks against statstruct_size and 0 was one of the reasons we were skipping inodes. - if the formatter function returns BULKSTAT_RV_NOTHING and an error and the error is not ENOENT or EINVAL then we need to abort the scan. ENOENT is for inodes that are no longer valid and we just skip them. EINVAL is returned if we try to lookup an internal inode so we skip them too. For a DMF scan if the inode and DMF attribute cannot fit into the space left in the user's buffer it would return ERANGE. We didn't handle this error and skipped the inode. We would continue to skip inodes until one fitted into the user's buffer or we completed the scan. - put back the recalculation of agino (that got removed with the last fix) at the end of the while loop. This is because the code at the start of the loop expects agino to be the last inode examined if it is non-zero. - if we found some inodes but then encountered an error, return success this time and the error next time. If the formatter aborted with ENOMEM we will now return this error but only if we couldn't read any inodes. Previously if we encountered ENOMEM without reading any inodes we returned a zero count and no error which falsely indicated the scan was complete. SGI-PV: 973431 SGI-Modid: xfs-linux-melb:xfs-kern:30089a Signed-off-by: Lachlan McIlroy Signed-off-by: David Chinner --- fs/xfs/linux-2.6/xfs_ioctl.c | 20 +++++++--------- fs/xfs/linux-2.6/xfs_ioctl32.c | 3 +++ fs/xfs/xfs_itable.c | 43 +++++++++++++++++++++++----------- 3 files changed, 40 insertions(+), 26 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index 2b34bad48b07..98a56568bb24 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c @@ -1047,24 +1047,20 @@ xfs_ioc_bulkstat( if ((count = bulkreq.icount) <= 0) return -XFS_ERROR(EINVAL); + if (bulkreq.ubuffer == NULL) + return -XFS_ERROR(EINVAL); + if (cmd == XFS_IOC_FSINUMBERS) error = xfs_inumbers(mp, &inlast, &count, bulkreq.ubuffer, xfs_inumbers_fmt); else if (cmd == XFS_IOC_FSBULKSTAT_SINGLE) error = xfs_bulkstat_single(mp, &inlast, bulkreq.ubuffer, &done); - else { /* XFS_IOC_FSBULKSTAT */ - if (count == 1 && inlast != 0) { - inlast++; - error = xfs_bulkstat_single(mp, &inlast, - bulkreq.ubuffer, &done); - } else { - error = xfs_bulkstat(mp, &inlast, &count, - (bulkstat_one_pf)xfs_bulkstat_one, NULL, - sizeof(xfs_bstat_t), bulkreq.ubuffer, - BULKSTAT_FG_QUICK, &done); - } - } + else /* XFS_IOC_FSBULKSTAT */ + error = xfs_bulkstat(mp, &inlast, &count, + (bulkstat_one_pf)xfs_bulkstat_one, NULL, + sizeof(xfs_bstat_t), bulkreq.ubuffer, + BULKSTAT_FG_QUICK, &done); if (error) return -error; diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c index 0046bdd5b7f1..bf2a956b63c2 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl32.c +++ b/fs/xfs/linux-2.6/xfs_ioctl32.c @@ -291,6 +291,9 @@ xfs_ioc_bulkstat_compat( if ((count = bulkreq.icount) <= 0) return -XFS_ERROR(EINVAL); + if (bulkreq.ubuffer == NULL) + return -XFS_ERROR(EINVAL); + if (cmd == XFS_IOC_FSINUMBERS) error = xfs_inumbers(mp, &inlast, &count, bulkreq.ubuffer, xfs_inumbers_fmt_compat); diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 9972992fd3c3..9fc4c2886529 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -316,6 +316,8 @@ xfs_bulkstat_use_dinode( return 1; } +#define XFS_BULKSTAT_UBLEFT(ubleft) ((ubleft) >= statstruct_size) + /* * Return stat information in bulk (by-inode) for the filesystem. */ @@ -353,7 +355,7 @@ xfs_bulkstat( xfs_inobt_rec_incore_t *irbp; /* current irec buffer pointer */ xfs_inobt_rec_incore_t *irbuf; /* start of irec buffer */ xfs_inobt_rec_incore_t *irbufend; /* end of good irec buffer entries */ - xfs_ino_t lastino=0; /* last inode number returned */ + xfs_ino_t lastino; /* last inode number returned */ int nbcluster; /* # of blocks in a cluster */ int nicluster; /* # of inodes in a cluster */ int nimask; /* mask for inode clusters */ @@ -373,6 +375,7 @@ xfs_bulkstat( * Get the last inode value, see if there's nothing to do. */ ino = (xfs_ino_t)*lastinop; + lastino = ino; dip = NULL; agno = XFS_INO_TO_AGNO(mp, ino); agino = XFS_INO_TO_AGINO(mp, ino); @@ -382,6 +385,9 @@ xfs_bulkstat( *ubcountp = 0; return 0; } + if (!ubcountp || *ubcountp <= 0) { + return EINVAL; + } ubcount = *ubcountp; /* statstruct's */ ubleft = ubcount * statstruct_size; /* bytes */ *ubcountp = ubelem = 0; @@ -402,7 +408,8 @@ xfs_bulkstat( * inode returned; 0 means start of the allocation group. */ rval = 0; - while (ubleft >= statstruct_size && agno < mp->m_sb.sb_agcount) { + while (XFS_BULKSTAT_UBLEFT(ubleft) && agno < mp->m_sb.sb_agcount) { + cond_resched(); bp = NULL; down_read(&mp->m_peraglock); error = xfs_ialloc_read_agi(mp, NULL, agno, &agbp); @@ -499,6 +506,7 @@ xfs_bulkstat( break; error = xfs_inobt_lookup_ge(cur, agino, 0, 0, &tmp); + cond_resched(); } /* * If ran off the end of the ag either with an error, @@ -542,6 +550,7 @@ xfs_bulkstat( */ agino = gino + XFS_INODES_PER_CHUNK; error = xfs_inobt_increment(cur, 0, &tmp); + cond_resched(); } /* * Drop the btree buffers and the agi buffer. @@ -555,12 +564,12 @@ xfs_bulkstat( */ irbufend = irbp; for (irbp = irbuf; - irbp < irbufend && ubleft >= statstruct_size; irbp++) { + irbp < irbufend && XFS_BULKSTAT_UBLEFT(ubleft); irbp++) { /* * Now process this chunk of inodes. */ for (agino = irbp->ir_startino, chunkidx = clustidx = 0; - ubleft > 0 && + XFS_BULKSTAT_UBLEFT(ubleft) && irbp->ir_freecount < XFS_INODES_PER_CHUNK; chunkidx++, clustidx++, agino++) { ASSERT(chunkidx < XFS_INODES_PER_CHUNK); @@ -663,15 +672,13 @@ xfs_bulkstat( ubleft, private_data, bno, &ubused, dip, &fmterror); if (fmterror == BULKSTAT_RV_NOTHING) { - if (error == EFAULT) { - ubleft = 0; - rval = error; - break; - } - else if (error == ENOMEM) + if (error && error != ENOENT && + error != EINVAL) { ubleft = 0; - else - lastino = ino; + rval = error; + break; + } + lastino = ino; continue; } if (fmterror == BULKSTAT_RV_GIVEUP) { @@ -686,6 +693,8 @@ xfs_bulkstat( ubelem++; lastino = ino; } + + cond_resched(); } if (bp) @@ -694,11 +703,12 @@ xfs_bulkstat( /* * Set up for the next loop iteration. */ - if (ubleft > 0) { + if (XFS_BULKSTAT_UBLEFT(ubleft)) { if (end_of_ag) { agno++; agino = 0; - } + } else + agino = XFS_INO_TO_AGINO(mp, lastino); } else break; } @@ -707,6 +717,11 @@ xfs_bulkstat( */ kmem_free(irbuf, irbsize); *ubcountp = ubelem; + /* + * Found some inodes, return them now and return the error next time. + */ + if (ubelem) + rval = 0; if (agno >= mp->m_sb.sb_agcount) { /* * If we ran out of filesystem, mark lastino as off From d1afb678ce77b930334a8a640a05b8e68178a377 Mon Sep 17 00:00:00 2001 From: Lachlan McIlroy Date: Tue, 27 Nov 2007 17:01:24 +1100 Subject: [PATCH 18/25] [XFS] Fixed a few bugs in xfs_buf_associate_memory() - calculation of 'page_count' was incorrect as it did not consider the offset of 'mem' into the first page. The logic to bump 'page_count' didn't work if 'len' was <= PAGE_CACHE_SIZE (ie offset = 3k, len = 2k). - setting b_buffer_length to 'len' is incorrect if 'offset' is > 0. Set it to the total length of the buffer. - I suspect that passing a non-aligned address into mem_to_page() for the first page may have been causing issues - don't know but just tidy up that code anyway. SGI-PV: 971596 SGI-Modid: xfs-linux-melb:xfs-kern:30143a Signed-off-by: Lachlan McIlroy Signed-off-by: Christoph Hellwig --- fs/xfs/linux-2.6/xfs_buf.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index b9c8589e05c2..48bf477cbca5 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -725,15 +725,15 @@ xfs_buf_associate_memory( { int rval; int i = 0; - size_t ptr; - size_t end, end_cur; - off_t offset; + unsigned long pageaddr; + unsigned long offset; + size_t buflen; int page_count; - page_count = PAGE_CACHE_ALIGN(len) >> PAGE_CACHE_SHIFT; - offset = (off_t) mem - ((off_t)mem & PAGE_CACHE_MASK); - if (offset && (len > PAGE_CACHE_SIZE)) - page_count++; + pageaddr = (unsigned long)mem & PAGE_CACHE_MASK; + offset = (unsigned long)mem - pageaddr; + buflen = PAGE_CACHE_ALIGN(len + offset); + page_count = buflen >> PAGE_CACHE_SHIFT; /* Free any previous set of page pointers */ if (bp->b_pages) @@ -747,22 +747,15 @@ xfs_buf_associate_memory( return rval; bp->b_offset = offset; - ptr = (size_t) mem & PAGE_CACHE_MASK; - end = PAGE_CACHE_ALIGN((size_t) mem + len); - end_cur = end; - /* set up first page */ - bp->b_pages[0] = mem_to_page(mem); - ptr += PAGE_CACHE_SIZE; - bp->b_page_count = ++i; - while (ptr < end) { - bp->b_pages[i] = mem_to_page((void *)ptr); - bp->b_page_count = ++i; - ptr += PAGE_CACHE_SIZE; + for (i = 0; i < bp->b_page_count; i++) { + bp->b_pages[i] = mem_to_page((void *)pageaddr); + pageaddr += PAGE_CACHE_SIZE; } bp->b_locked = 0; - bp->b_count_desired = bp->b_buffer_length = len; + bp->b_count_desired = len; + bp->b_buffer_length = buflen; bp->b_flags |= XBF_MAPPED; return 0; From 77be55a5a13d9c7ddf780a93861f2fba33f8be1a Mon Sep 17 00:00:00 2001 From: Lachlan McIlroy Date: Fri, 23 Nov 2007 16:31:00 +1100 Subject: [PATCH 19/25] [XFS] Clear XBF_READ_AHEAD flag on I/O completion. SGI-PV: 972554 SGI-Modid: xfs-linux-melb:xfs-kern:30128a Signed-off-by: Lachlan McIlroy Signed-off-by: Christoph Hellwig --- fs/xfs/linux-2.6/xfs_buf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 48bf477cbca5..43d6c7a290e2 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -1025,7 +1025,7 @@ xfs_buf_ioend( xfs_buf_t *bp, int schedule) { - bp->b_flags &= ~(XBF_READ | XBF_WRITE); + bp->b_flags &= ~(XBF_READ | XBF_WRITE | XBF_READ_AHEAD); if (bp->b_error == 0) bp->b_flags |= XBF_DONE; From a7430847fcb19297d6db833f35b9c9645c4a6395 Mon Sep 17 00:00:00 2001 From: David Chinner Date: Fri, 23 Nov 2007 16:30:23 +1100 Subject: [PATCH 20/25] [XFS] Fix broken inode cluster setup. The radix tree based inode caches did away with the inode cluster hashes, replacing them with a bunch of masking and gang lookups on the radix tree. This masking got broken when moving the code to per-ag radix trees and indexing by agino # rather than straight inode number. The result is clustered inode writeback does not cluster and things can go extremely slowly when there are lots of inodes to write. Fix it up by comparing the agino # of the inode we just looked up to the index of the cluster we are looking for. Tested-by: Torsten Kaiser SGI-PV: 972915 SGI-Modid: xfs-linux-melb:xfs-kern:30033a Signed-off-by: David Chinner Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_iget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index 488836e204a3..fb69ef180b27 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c @@ -267,7 +267,7 @@ xfs_iget_core( icl = NULL; if (radix_tree_gang_lookup(&pag->pag_ici_root, (void**)&iq, first_index, 1)) { - if ((iq->i_ino & mask) == first_index) + if ((XFS_INO_TO_AGINO(mp, iq->i_ino) & mask) == first_index) icl = iq->i_cluster; } From e89bc612d61edbcefaeb6f2244f86c0f3ec89d23 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 7 Dec 2007 14:07:53 +1100 Subject: [PATCH 21/25] [XFS] revert to double-buffering readdir The current readdir implementation deadlocks on a btree buffers locks because nfsd calls back into ->lookup from the filldir callback. The only short-term fix for this is to revert to the old inefficient double-buffering scheme. SGI-PV: 973377 SGI-Modid: xfs-linux-melb:xfs-kern:30201a Signed-off-by: Christoph Hellwig Signed-off-by: David Chinner Signed-off-by: Lachlan McIlroy --- fs/xfs/linux-2.6/xfs_file.c | 124 ++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index fb8dd34041eb..54c564693d93 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c @@ -218,6 +218,15 @@ xfs_vm_fault( } #endif /* CONFIG_XFS_DMAPI */ +/* + * Unfortunately we can't just use the clean and simple readdir implementation + * below, because nfs might call back into ->lookup from the filldir callback + * and that will deadlock the low-level btree code. + * + * Hopefully we'll find a better workaround that allows to use the optimal + * version at least for local readdirs for 2.6.25. + */ +#if 0 STATIC int xfs_file_readdir( struct file *filp, @@ -249,6 +258,121 @@ xfs_file_readdir( return -error; return 0; } +#else + +struct hack_dirent { + int namlen; + loff_t offset; + u64 ino; + unsigned int d_type; + char name[]; +}; + +struct hack_callback { + char *dirent; + size_t len; + size_t used; +}; + +STATIC int +xfs_hack_filldir( + void *__buf, + const char *name, + int namlen, + loff_t offset, + u64 ino, + unsigned int d_type) +{ + struct hack_callback *buf = __buf; + struct hack_dirent *de = (struct hack_dirent *)(buf->dirent + buf->used); + + if (buf->used + sizeof(struct hack_dirent) + namlen > buf->len) + return -EINVAL; + + de->namlen = namlen; + de->offset = offset; + de->ino = ino; + de->d_type = d_type; + memcpy(de->name, name, namlen); + buf->used += sizeof(struct hack_dirent) + namlen; + return 0; +} + +STATIC int +xfs_file_readdir( + struct file *filp, + void *dirent, + filldir_t filldir) +{ + struct inode *inode = filp->f_path.dentry->d_inode; + xfs_inode_t *ip = XFS_I(inode); + struct hack_callback buf; + struct hack_dirent *de; + int error; + loff_t size; + int eof = 0; + xfs_off_t start_offset, curr_offset, offset; + + /* + * Try fairly hard to get memory + */ + buf.len = PAGE_CACHE_SIZE; + do { + buf.dirent = kmalloc(buf.len, GFP_KERNEL); + if (buf.dirent) + break; + buf.len >>= 1; + } while (buf.len >= 1024); + + if (!buf.dirent) + return -ENOMEM; + + curr_offset = filp->f_pos; + if (curr_offset == 0x7fffffff) + offset = 0xffffffff; + else + offset = filp->f_pos; + + while (!eof) { + int reclen; + start_offset = offset; + + buf.used = 0; + error = -xfs_readdir(ip, &buf, buf.len, &offset, + xfs_hack_filldir); + if (error || offset == start_offset) { + size = 0; + break; + } + + size = buf.used; + de = (struct hack_dirent *)buf.dirent; + while (size > 0) { + if (filldir(dirent, de->name, de->namlen, + curr_offset & 0x7fffffff, + de->ino, de->d_type)) { + goto done; + } + + reclen = sizeof(struct hack_dirent) + de->namlen; + size -= reclen; + curr_offset = de->offset /* & 0x7fffffff */; + de = (struct hack_dirent *)((char *)de + reclen); + } + } + + done: + if (!error) { + if (size == 0) + filp->f_pos = offset & 0x7fffffff; + else if (de) + filp->f_pos = curr_offset; + } + + kfree(buf.dirent); + return error; +} +#endif STATIC int xfs_file_mmap( From 978c7b2ff49597ab76ff7529a933bd366941ac25 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 7 Dec 2007 14:09:02 +1100 Subject: [PATCH 22/25] [XFS] Make xfsbufd threads freezable Fix breakage caused by commit 831441862956fffa17b9801db37e6ea1650b0f69 that did not introduce the necessary call to set_freezable() in xfs/linux-2.6/xfs_buf.c . SGI-PV: 974224 SGI-Modid: xfs-linux-melb:xfs-kern:30203a Signed-off-by: Rafael J. Wysocki Signed-off-by: David Chinner Signed-off-by: Lachlan McIlroy --- fs/xfs/linux-2.6/xfs_buf.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 43d6c7a290e2..a49dd8d4b069 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -1743,6 +1743,8 @@ xfsbufd( current->flags |= PF_MEMALLOC; + set_freezable(); + do { if (unlikely(freezing(current))) { set_bit(XBT_FORCE_SLEEP, &target->bt_flags); From cf10e82bdc0d38d09dfaf46d0daf56136138ef3f Mon Sep 17 00:00:00 2001 From: David Chinner Date: Fri, 7 Dec 2007 14:09:11 +1100 Subject: [PATCH 23/25] [XFS] Fix xfs_ichgtime()s broken usage of I_SYNC The recent I_LOCK->I_SYNC changes mistakenly changed xfs_ichgtime to look at I_SYNC instead of I_LOCK. This was incorrect and prevents newly created inodes from moving to the dirty list. Change this to the correct check which is for I_NEW, not I_LOCK or I_SYNC so that behaviour is correct. SGI-PV: 974225 SGI-Modid: xfs-linux-melb:xfs-kern:30204a Signed-off-by: David Chinner Signed-off-by: Lachlan McIlroy --- fs/xfs/linux-2.6/xfs_iops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index ac50f8a37582..37e116779eb1 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c @@ -117,7 +117,7 @@ xfs_ichgtime( */ SYNCHRONIZE(); ip->i_update_core = 1; - if (!(inode->i_state & I_SYNC)) + if (!(inode->i_state & I_NEW)) mark_inode_dirty_sync(inode); } @@ -169,7 +169,7 @@ xfs_ichgtime_fast( */ SYNCHRONIZE(); ip->i_update_core = 1; - if (!(inode->i_state & I_SYNC)) + if (!(inode->i_state & I_NEW)) mark_inode_dirty_sync(inode); } From 6d98bda79bea0e1be26c0767d0e9923ad3b72f2e Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 10 Dec 2007 15:29:22 +1100 Subject: [PATCH 24/25] powerpc: Fix IDE legacy vs. native fixups PowerMac and CHRP/BriQ platforms have quirks to switch some IDE controllers from legacy mode to fully native mode. Those quirks however will not work properly anymore due to a change to the generic code to better handle legacy IDE resources. This fixes it by moving those quirk to "early" quirks (so they run before resources are probed for the devices) and clearing all BARs after the conversion to force a reallocation of sane values. Signed-off-by: Benjamin Herrenschmidt Acked-by: Alan Cox Signed-off-by: Linus Torvalds --- arch/powerpc/platforms/chrp/pci.c | 21 +++++++++++++++------ arch/powerpc/platforms/powermac/pci.c | 11 +++++++++-- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c index e43465d34d29..0340a342f772 100644 --- a/arch/powerpc/platforms/chrp/pci.c +++ b/arch/powerpc/platforms/chrp/pci.c @@ -317,8 +317,12 @@ chrp_find_bridges(void) /* SL82C105 IDE Control/Status Register */ #define SL82C105_IDECSR 0x40 -/* Fixup for Winbond ATA quirk, required for briq */ -void chrp_pci_fixup_winbond_ata(struct pci_dev *sl82c105) +/* Fixup for Winbond ATA quirk, required for briq mostly because the + * 8259 is configured for level sensitive IRQ 14 and so wants the + * ATA controller to be set to fully native mode or bad things + * will happen. + */ +static void __devinit chrp_pci_fixup_winbond_ata(struct pci_dev *sl82c105) { u8 progif; @@ -334,10 +338,15 @@ void chrp_pci_fixup_winbond_ata(struct pci_dev *sl82c105) sl82c105->class |= 0x05; /* Disable SL82C105 second port */ pci_write_config_word(sl82c105, SL82C105_IDECSR, 0x0003); + /* Clear IO BARs, they will be reassigned */ + pci_write_config_dword(sl82c105, PCI_BASE_ADDRESS_0, 0); + pci_write_config_dword(sl82c105, PCI_BASE_ADDRESS_1, 0); + pci_write_config_dword(sl82c105, PCI_BASE_ADDRESS_2, 0); + pci_write_config_dword(sl82c105, PCI_BASE_ADDRESS_3, 0); } } -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, - chrp_pci_fixup_winbond_ata); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, + chrp_pci_fixup_winbond_ata); /* Pegasos2 firmware version 20040810 configures the built-in IDE controller * in legacy mode, but sets the PCI registers to PCI native mode. @@ -345,7 +354,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, * mode as well. The same fixup must be done to the class-code property in * the IDE node /pci@80000000/ide@C,1 */ -static void chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide) +static void __devinit chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide) { u8 progif; struct pci_dev *viaisa; @@ -366,4 +375,4 @@ static void chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide) pci_dev_put(viaisa); } -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata); diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index ec49099830d5..f852ae3e0ee4 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c @@ -1243,15 +1243,22 @@ void pmac_pci_fixup_pciata(struct pci_dev* dev) good: pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); if ((progif & 5) != 5) { - printk(KERN_INFO "Forcing PCI IDE into native mode: %s\n", + printk(KERN_INFO "PCI: %s Forcing PCI IDE into native mode\n", pci_name(dev)); (void) pci_write_config_byte(dev, PCI_CLASS_PROG, progif|5); if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif) || (progif & 5) != 5) printk(KERN_ERR "Rewrite of PROGIF failed !\n"); + else { + /* Clear IO BARs, they will be reassigned */ + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_2, 0); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_3, 0); + } } } -DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pmac_pci_fixup_pciata); +DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, pmac_pci_fixup_pciata); #endif /* From af1bff4f1d117f99ad8a88e6532baff475fb44a5 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 10 Dec 2007 07:40:54 -0800 Subject: [PATCH 25/25] Revert "PCI: fix IDE legacy mode resources" This reverts commit fd6e732186ab522c812ab19c2c5e5befb8ec8115, which helped up things on MIPS, but was wrong for everything else. As Ralf Baechle puts it: "It seems the whole MIPS resource managment is complicated enough (out of necessity) that only a few people actually grok it. Ioports being actually memory mapped on MIPS only makes the confusion worse, sigh." Requested-by: Benjamin Herrenschmidt Acked-by: Alan Cox Acked-by: Ralf Baechle Signed-off-by: Linus Torvalds --- drivers/pci/probe.c | 48 ++++++++++++--------------------------------- 1 file changed, 12 insertions(+), 36 deletions(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 463a5a9d583d..c2f8a78c894c 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -743,46 +743,22 @@ static int pci_setup_device(struct pci_dev * dev) */ if (class == PCI_CLASS_STORAGE_IDE) { u8 progif; - struct pci_bus_region region; - pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); if ((progif & 1) == 0) { - struct resource resource = { - .start = 0x1F0, - .end = 0x1F7, - .flags = LEGACY_IO_RESOURCE, - }; - - pcibios_resource_to_bus(dev, ®ion, &resource); - dev->resource[0].start = region.start; - dev->resource[0].end = region.end; - dev->resource[0].flags = resource.flags; - resource.start = 0x3F6; - resource.end = 0x3F6; - resource.flags = LEGACY_IO_RESOURCE; - pcibios_resource_to_bus(dev, ®ion, &resource); - dev->resource[1].start = region.start; - dev->resource[1].end = region.end; - dev->resource[1].flags = resource.flags; + dev->resource[0].start = 0x1F0; + dev->resource[0].end = 0x1F7; + dev->resource[0].flags = LEGACY_IO_RESOURCE; + dev->resource[1].start = 0x3F6; + dev->resource[1].end = 0x3F6; + dev->resource[1].flags = LEGACY_IO_RESOURCE; } if ((progif & 4) == 0) { - struct resource resource = { - .start = 0x170, - .end = 0x177, - .flags = LEGACY_IO_RESOURCE, - }; - - pcibios_resource_to_bus(dev, ®ion, &resource); - dev->resource[2].start = region.start; - dev->resource[2].end = region.end; - dev->resource[2].flags = resource.flags; - resource.start = 0x376; - resource.end = 0x376; - resource.flags = LEGACY_IO_RESOURCE; - pcibios_resource_to_bus(dev, ®ion, &resource); - dev->resource[3].start = region.start; - dev->resource[3].end = region.end; - dev->resource[3].flags = resource.flags; + dev->resource[2].start = 0x170; + dev->resource[2].end = 0x177; + dev->resource[2].flags = LEGACY_IO_RESOURCE; + dev->resource[3].start = 0x376; + dev->resource[3].end = 0x376; + dev->resource[3].flags = LEGACY_IO_RESOURCE; } } break;