From 7e6cebc59917a27593988e5e58533e991fedb635 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 10 Sep 2011 06:02:12 -0700 Subject: [PATCH] --- yaml --- r: 263838 b: refs/heads/master c: 40257b953fdd519c743138f3fbe3962d54991116 h: refs/heads/master v: v3 --- [refs] | 2 +- .../ABI/testing/sysfs-class-scsi_host | 13 - trunk/Documentation/cgroups/memory.txt | 85 +++++- trunk/Documentation/kernel-parameters.txt | 9 +- trunk/MAINTAINERS | 13 +- trunk/arch/alpha/Kconfig | 2 +- trunk/arch/um/Kconfig.x86 | 4 - trunk/arch/um/Makefile | 2 +- trunk/arch/um/drivers/line.c | 61 ++-- trunk/arch/um/drivers/xterm.c | 1 - trunk/arch/um/include/asm/ptrace-generic.h | 4 + trunk/arch/um/include/shared/line.h | 1 - trunk/arch/um/include/shared/registers.h | 2 +- trunk/arch/um/kernel/process.c | 2 +- trunk/arch/um/kernel/ptrace.c | 28 ++ trunk/arch/um/os-Linux/registers.c | 9 +- trunk/arch/um/os-Linux/skas/mem.c | 2 +- trunk/arch/um/os-Linux/skas/process.c | 19 +- trunk/arch/um/sys-i386/asm/ptrace.h | 5 + trunk/arch/um/sys-i386/ptrace.c | 28 +- trunk/arch/um/sys-i386/shared/sysdep/ptrace.h | 1 - trunk/arch/um/sys-x86_64/ptrace.c | 12 +- .../arch/um/sys-x86_64/shared/sysdep/ptrace.h | 1 - trunk/arch/x86/xen/time.c | 5 +- trunk/drivers/acpi/acpica/acconfig.h | 2 +- trunk/drivers/acpi/apei/Kconfig | 1 - trunk/drivers/acpi/apei/apei-base.c | 2 +- trunk/drivers/cpufreq/pcc-cpufreq.c | 3 - trunk/drivers/gpio/gpio-generic.c | 15 +- trunk/drivers/hwmon/pmbus/pmbus_core.c | 9 +- trunk/drivers/leds/ledtrig-timer.c | 2 - trunk/drivers/misc/pti.c | 12 +- trunk/drivers/pci/probe.c | 3 +- trunk/drivers/rtc/rtc-imxdi.c | 1 - trunk/drivers/rtc/rtc-s3c.c | 26 -- trunk/drivers/scsi/bnx2i/bnx2i_hwi.c | 2 +- trunk/drivers/scsi/fcoe/fcoe.c | 13 +- trunk/drivers/scsi/hpsa.c | 57 ++-- trunk/drivers/scsi/isci/host.c | 13 +- trunk/drivers/scsi/isci/host.h | 3 - trunk/drivers/scsi/isci/init.c | 47 ++- trunk/drivers/scsi/isci/phy.c | 13 - trunk/drivers/scsi/isci/registers.h | 12 - trunk/drivers/scsi/isci/request.c | 30 +- .../scsi/isci/unsolicited_frame_control.c | 2 +- .../scsi/isci/unsolicited_frame_control.h | 2 +- trunk/drivers/scsi/libfc/fc_exch.c | 59 ++-- trunk/drivers/scsi/libfc/fc_fcp.c | 11 +- trunk/drivers/scsi/libfc/fc_lport.c | 11 +- trunk/drivers/scsi/qla2xxx/qla_attr.c | 7 +- trunk/drivers/scsi/qla2xxx/qla_dbg.c | 36 +-- trunk/drivers/scsi/qla2xxx/qla_def.h | 2 - trunk/drivers/scsi/qla2xxx/qla_fw.h | 5 - trunk/drivers/scsi/qla2xxx/qla_init.c | 3 + trunk/drivers/scsi/qla2xxx/qla_inline.h | 29 -- trunk/drivers/scsi/qla2xxx/qla_iocb.c | 282 +++--------------- trunk/drivers/scsi/qla2xxx/qla_isr.c | 109 ++----- trunk/drivers/scsi/qla2xxx/qla_mid.c | 2 +- trunk/drivers/scsi/qla2xxx/qla_nx.c | 25 +- trunk/drivers/scsi/qla2xxx/qla_os.c | 30 +- trunk/drivers/scsi/qla2xxx/qla_version.h | 2 +- trunk/drivers/tty/serial/crisv10.c | 4 +- trunk/fs/hfsplus/super.c | 15 +- trunk/fs/hfsplus/wrapper.c | 4 +- trunk/fs/namei.c | 4 - trunk/fs/xfs/xfs_aops.c | 3 +- trunk/include/linux/basic_mmio_gpio.h | 15 +- trunk/include/linux/memcontrol.h | 19 ++ trunk/include/linux/swap.h | 6 - trunk/kernel/workqueue.c | 7 +- trunk/lib/sha1.c | 1 - trunk/mm/filemap.c | 6 +- trunk/mm/memcontrol.c | 172 ++++++++++- trunk/mm/mempolicy.c | 9 +- trunk/mm/vmalloc.c | 8 - trunk/mm/vmscan.c | 66 ++-- trunk/mm/vmstat.c | 4 +- 77 files changed, 660 insertions(+), 877 deletions(-) delete mode 100644 trunk/Documentation/ABI/testing/sysfs-class-scsi_host diff --git a/[refs] b/[refs] index 18c2b2314d61..1c0342af3565 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f1fcd9f0e96d12498afb5543107f560f196cfcf3 +refs/heads/master: 40257b953fdd519c743138f3fbe3962d54991116 diff --git a/trunk/Documentation/ABI/testing/sysfs-class-scsi_host b/trunk/Documentation/ABI/testing/sysfs-class-scsi_host deleted file mode 100644 index 29a4f892e433..000000000000 --- a/trunk/Documentation/ABI/testing/sysfs-class-scsi_host +++ /dev/null @@ -1,13 +0,0 @@ -What: /sys/class/scsi_host/hostX/isci_id -Date: June 2011 -Contact: Dave Jiang -Description: - This file contains the enumerated host ID for the Intel - SCU controller. The Intel(R) C600 Series Chipset SATA/SAS - Storage Control Unit embeds up to two 4-port controllers in - a single PCI device. The controllers are enumerated in order - which usually means the lowest number scsi_host corresponds - with the first controller, but this association is not - guaranteed. The 'isci_id' attribute unambiguously identifies - the controller index: '0' for the first controller, - '1' for the second. diff --git a/trunk/Documentation/cgroups/memory.txt b/trunk/Documentation/cgroups/memory.txt index 06eb6d957c83..6f3c598971fc 100644 --- a/trunk/Documentation/cgroups/memory.txt +++ b/trunk/Documentation/cgroups/memory.txt @@ -380,7 +380,7 @@ will be charged as a new owner of it. 5.2 stat file -memory.stat file includes following statistics +5.2.1 memory.stat file includes following statistics # per-memory cgroup local status cache - # of bytes of page cache memory. @@ -438,6 +438,89 @@ Note: file_mapped is accounted only when the memory cgroup is owner of page cache.) +5.2.2 memory.vmscan_stat + +memory.vmscan_stat includes statistics information for memory scanning and +freeing, reclaiming. The statistics shows memory scanning information since +memory cgroup creation and can be reset to 0 by writing 0 as + + #echo 0 > ../memory.vmscan_stat + +This file contains following statistics. + +[param]_[file_or_anon]_pages_by_[reason]_[under_heararchy] +[param]_elapsed_ns_by_[reason]_[under_hierarchy] + +For example, + + scanned_file_pages_by_limit indicates the number of scanned + file pages at vmscan. + +Now, 3 parameters are supported + + scanned - the number of pages scanned by vmscan + rotated - the number of pages activated at vmscan + freed - the number of pages freed by vmscan + +If "rotated" is high against scanned/freed, the memcg seems busy. + +Now, 2 reason are supported + + limit - the memory cgroup's limit + system - global memory pressure + softlimit + (global memory pressure not under softlimit is not handled now) + +When under_hierarchy is added in the tail, the number indicates the +total memcg scan of its children and itself. + +elapsed_ns is a elapsed time in nanosecond. This may include sleep time +and not indicates CPU usage. So, please take this as just showing +latency. + +Here is an example. + +# cat /cgroup/memory/A/memory.vmscan_stat +scanned_pages_by_limit 9471864 +scanned_anon_pages_by_limit 6640629 +scanned_file_pages_by_limit 2831235 +rotated_pages_by_limit 4243974 +rotated_anon_pages_by_limit 3971968 +rotated_file_pages_by_limit 272006 +freed_pages_by_limit 2318492 +freed_anon_pages_by_limit 962052 +freed_file_pages_by_limit 1356440 +elapsed_ns_by_limit 351386416101 +scanned_pages_by_system 0 +scanned_anon_pages_by_system 0 +scanned_file_pages_by_system 0 +rotated_pages_by_system 0 +rotated_anon_pages_by_system 0 +rotated_file_pages_by_system 0 +freed_pages_by_system 0 +freed_anon_pages_by_system 0 +freed_file_pages_by_system 0 +elapsed_ns_by_system 0 +scanned_pages_by_limit_under_hierarchy 9471864 +scanned_anon_pages_by_limit_under_hierarchy 6640629 +scanned_file_pages_by_limit_under_hierarchy 2831235 +rotated_pages_by_limit_under_hierarchy 4243974 +rotated_anon_pages_by_limit_under_hierarchy 3971968 +rotated_file_pages_by_limit_under_hierarchy 272006 +freed_pages_by_limit_under_hierarchy 2318492 +freed_anon_pages_by_limit_under_hierarchy 962052 +freed_file_pages_by_limit_under_hierarchy 1356440 +elapsed_ns_by_limit_under_hierarchy 351386416101 +scanned_pages_by_system_under_hierarchy 0 +scanned_anon_pages_by_system_under_hierarchy 0 +scanned_file_pages_by_system_under_hierarchy 0 +rotated_pages_by_system_under_hierarchy 0 +rotated_anon_pages_by_system_under_hierarchy 0 +rotated_file_pages_by_system_under_hierarchy 0 +freed_pages_by_system_under_hierarchy 0 +freed_anon_pages_by_system_under_hierarchy 0 +freed_file_pages_by_system_under_hierarchy 0 +elapsed_ns_by_system_under_hierarchy 0 + 5.3 swappiness Similar to /proc/sys/vm/swappiness, but affecting a hierarchy of groups only. diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index 854ed5ca7e3f..614d0382e2cb 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -2086,12 +2086,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. Override pmtimer IOPort with a hex value. e.g. pmtmr=0x508 - pnp.debug=1 [PNP] - Enable PNP debug messages (depends on the - CONFIG_PNP_DEBUG_MESSAGES option). Change at run-time - via /sys/module/pnp/parameters/debug. We always show - current resource usage; turning this on also shows - possible settings and some assignment information. + pnp.debug [PNP] + Enable PNP debug messages. This depends on the + CONFIG_PNP_DEBUG_MESSAGES option. pnpacpi= [ACPI] { off } diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 7658e1ffd58e..28f65c249b97 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -3262,17 +3262,6 @@ F: Documentation/input/multi-touch-protocol.txt F: drivers/input/input-mt.c K: \b(ABS|SYN)_MT_ -INTEL C600 SERIES SAS CONTROLLER DRIVER -M: Intel SCU Linux support -M: Dan Williams -M: Dave Jiang -M: Ed Nadolski -L: linux-scsi@vger.kernel.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/djbw/isci.git -S: Maintained -F: drivers/scsi/isci/ -F: firmware/isci/ - INTEL IDLE DRIVER M: Len Brown L: linux-pm@lists.linux-foundation.org @@ -4785,7 +4774,7 @@ F: drivers/net/wireless/orinoco/ OSD LIBRARY and FILESYSTEM M: Boaz Harrosh -M: Benny Halevy +M: Benny Halevy L: osd-dev@open-osd.org W: http://open-osd.org T: git git://git.open-osd.org/open-osd.git diff --git a/trunk/arch/alpha/Kconfig b/trunk/arch/alpha/Kconfig index 8bb936226dee..60cde53d266c 100644 --- a/trunk/arch/alpha/Kconfig +++ b/trunk/arch/alpha/Kconfig @@ -51,7 +51,7 @@ config GENERIC_CMOS_UPDATE def_bool y config GENERIC_GPIO - bool + def_bool y config ZONE_DMA bool diff --git a/trunk/arch/um/Kconfig.x86 b/trunk/arch/um/Kconfig.x86 index 21bebe63df66..d31ecf346b4e 100644 --- a/trunk/arch/um/Kconfig.x86 +++ b/trunk/arch/um/Kconfig.x86 @@ -10,10 +10,6 @@ config CMPXCHG_LOCAL bool default n -config CMPXCHG_DOUBLE - bool - default n - source "arch/x86/Kconfig.cpu" endmenu diff --git a/trunk/arch/um/Makefile b/trunk/arch/um/Makefile index c0f712cc7c5f..fab8121d2b32 100644 --- a/trunk/arch/um/Makefile +++ b/trunk/arch/um/Makefile @@ -41,7 +41,7 @@ KBUILD_CPPFLAGS += -I$(srctree)/$(ARCH_DIR)/sys-$(SUBARCH) KBUILD_CFLAGS += $(CFLAGS) $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \ $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap \ -Din6addr_loopback=kernel_in6addr_loopback \ - -Din6addr_any=kernel_in6addr_any -Dstrrchr=kernel_strrchr + -Din6addr_any=kernel_in6addr_any KBUILD_AFLAGS += $(ARCH_INCLUDE) diff --git a/trunk/arch/um/drivers/line.c b/trunk/arch/um/drivers/line.c index 364c8a15c4c3..d51c404239a8 100644 --- a/trunk/arch/um/drivers/line.c +++ b/trunk/arch/um/drivers/line.c @@ -399,8 +399,8 @@ int line_setup_irq(int fd, int input, int output, struct line *line, void *data) * is done under a spinlock. Checking whether the device is in use is * line->tty->count > 1, also under the spinlock. * - * line->count serves to decide whether the device should be enabled or - * disabled on the host. If it's equal to 0, then we are doing the + * tty->count serves to decide whether the device should be enabled or + * disabled on the host. If it's equal to 1, then we are doing the * first open or last close. Otherwise, open and close just return. */ @@ -414,16 +414,16 @@ int line_open(struct line *lines, struct tty_struct *tty) goto out_unlock; err = 0; - if (line->count++) + if (tty->count > 1) goto out_unlock; - BUG_ON(tty->driver_data); + spin_unlock(&line->count_lock); + tty->driver_data = line; line->tty = tty; - spin_unlock(&line->count_lock); err = enable_chan(line); - if (err) /* line_close() will be called by our caller */ + if (err) return err; INIT_DELAYED_WORK(&line->task, line_timer_cb); @@ -436,7 +436,7 @@ int line_open(struct line *lines, struct tty_struct *tty) chan_window_size(&line->chan_list, &tty->winsize.ws_row, &tty->winsize.ws_col); - return 0; + return err; out_unlock: spin_unlock(&line->count_lock); @@ -460,16 +460,17 @@ void line_close(struct tty_struct *tty, struct file * filp) flush_buffer(line); spin_lock(&line->count_lock); - BUG_ON(!line->valid); + if (!line->valid) + goto out_unlock; - if (--line->count) + if (tty->count > 1) goto out_unlock; + spin_unlock(&line->count_lock); + line->tty = NULL; tty->driver_data = NULL; - spin_unlock(&line->count_lock); - if (line->sigio) { unregister_winch(tty); line->sigio = 0; @@ -497,7 +498,7 @@ static int setup_one_line(struct line *lines, int n, char *init, int init_prio, spin_lock(&line->count_lock); - if (line->count) { + if (line->tty != NULL) { *error_out = "Device is already open"; goto out; } @@ -721,53 +722,41 @@ struct winch { int pid; struct tty_struct *tty; unsigned long stack; - struct work_struct work; }; -static void __free_winch(struct work_struct *work) +static void free_winch(struct winch *winch, int free_irq_ok) { - struct winch *winch = container_of(work, struct winch, work); - free_irq(WINCH_IRQ, winch); + if (free_irq_ok) + free_irq(WINCH_IRQ, winch); + + list_del(&winch->list); if (winch->pid != -1) os_kill_process(winch->pid, 1); + if (winch->fd != -1) + os_close_file(winch->fd); if (winch->stack != 0) free_stack(winch->stack, 0); kfree(winch); } -static void free_winch(struct winch *winch) -{ - int fd = winch->fd; - winch->fd = -1; - if (fd != -1) - os_close_file(fd); - list_del(&winch->list); - __free_winch(&winch->work); -} - static irqreturn_t winch_interrupt(int irq, void *data) { struct winch *winch = data; struct tty_struct *tty; struct line *line; - int fd = winch->fd; int err; char c; - if (fd != -1) { - err = generic_read(fd, &c, NULL); + if (winch->fd != -1) { + err = generic_read(winch->fd, &c, NULL); if (err < 0) { if (err != -EAGAIN) { - winch->fd = -1; - list_del(&winch->list); - os_close_file(fd); printk(KERN_ERR "winch_interrupt : " "read failed, errno = %d\n", -err); printk(KERN_ERR "fd %d is losing SIGWINCH " "support\n", winch->tty_fd); - INIT_WORK(&winch->work, __free_winch); - schedule_work(&winch->work); + free_winch(winch, 0); return IRQ_HANDLED; } goto out; @@ -839,7 +828,7 @@ static void unregister_winch(struct tty_struct *tty) list_for_each_safe(ele, next, &winch_handlers) { winch = list_entry(ele, struct winch, list); if (winch->tty == tty) { - free_winch(winch); + free_winch(winch, 1); break; } } @@ -855,7 +844,7 @@ static void winch_cleanup(void) list_for_each_safe(ele, next, &winch_handlers) { winch = list_entry(ele, struct winch, list); - free_winch(winch); + free_winch(winch, 1); } spin_unlock(&winch_handler_lock); diff --git a/trunk/arch/um/drivers/xterm.c b/trunk/arch/um/drivers/xterm.c index 2e1de5728604..8ac7146c237f 100644 --- a/trunk/arch/um/drivers/xterm.c +++ b/trunk/arch/um/drivers/xterm.c @@ -123,7 +123,6 @@ static int xterm_open(int input, int output, int primary, void *d, err = -errno; printk(UM_KERN_ERR "xterm_open : unlink failed, errno = %d\n", errno); - close(fd); return err; } close(fd); diff --git a/trunk/arch/um/include/asm/ptrace-generic.h b/trunk/arch/um/include/asm/ptrace-generic.h index 1a7d2757fe05..ae084ad1a3a0 100644 --- a/trunk/arch/um/include/asm/ptrace-generic.h +++ b/trunk/arch/um/include/asm/ptrace-generic.h @@ -42,6 +42,10 @@ extern long subarch_ptrace(struct task_struct *child, long request, unsigned long addr, unsigned long data); extern unsigned long getreg(struct task_struct *child, int regno); extern int putreg(struct task_struct *child, int regno, unsigned long value); +extern int get_fpregs(struct user_i387_struct __user *buf, + struct task_struct *child); +extern int set_fpregs(struct user_i387_struct __user *buf, + struct task_struct *child); extern int arch_copy_tls(struct task_struct *new); extern void clear_flushed_tls(struct task_struct *task); diff --git a/trunk/arch/um/include/shared/line.h b/trunk/arch/um/include/shared/line.h index 63df3ca02ac2..72f4f25af247 100644 --- a/trunk/arch/um/include/shared/line.h +++ b/trunk/arch/um/include/shared/line.h @@ -33,7 +33,6 @@ struct line_driver { struct line { struct tty_struct *tty; spinlock_t count_lock; - unsigned long count; int valid; char *init_str; diff --git a/trunk/arch/um/include/shared/registers.h b/trunk/arch/um/include/shared/registers.h index f1e0aa56c52a..b0b4589e0ebc 100644 --- a/trunk/arch/um/include/shared/registers.h +++ b/trunk/arch/um/include/shared/registers.h @@ -16,7 +16,7 @@ extern int restore_fpx_registers(int pid, unsigned long *fp_regs); extern int save_registers(int pid, struct uml_pt_regs *regs); extern int restore_registers(int pid, struct uml_pt_regs *regs); extern int init_registers(int pid); -extern void get_safe_registers(unsigned long *regs, unsigned long *fp_regs); +extern void get_safe_registers(unsigned long *regs); extern unsigned long get_thread_reg(int reg, jmp_buf *buf); extern int get_fp_registers(int pid, unsigned long *regs); extern int put_fp_registers(int pid, unsigned long *regs); diff --git a/trunk/arch/um/kernel/process.c b/trunk/arch/um/kernel/process.c index 21c1ae7c3d75..fab4371184f6 100644 --- a/trunk/arch/um/kernel/process.c +++ b/trunk/arch/um/kernel/process.c @@ -202,7 +202,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, arch_copy_thread(¤t->thread.arch, &p->thread.arch); } else { - get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp); + get_safe_registers(p->thread.regs.regs.gp); p->thread.request.u.thread = current->thread.request.u.thread; handler = new_thread_handler; } diff --git a/trunk/arch/um/kernel/ptrace.c b/trunk/arch/um/kernel/ptrace.c index c9da32b0c707..701b672c1122 100644 --- a/trunk/arch/um/kernel/ptrace.c +++ b/trunk/arch/um/kernel/ptrace.c @@ -50,11 +50,23 @@ long arch_ptrace(struct task_struct *child, long request, void __user *vp = p; switch (request) { + /* read word at location addr. */ + case PTRACE_PEEKTEXT: + case PTRACE_PEEKDATA: + ret = generic_ptrace_peekdata(child, addr, data); + break; + /* read the word at location addr in the USER area. */ case PTRACE_PEEKUSR: ret = peek_user(child, addr, data); break; + /* write the word at location addr. */ + case PTRACE_POKETEXT: + case PTRACE_POKEDATA: + ret = generic_ptrace_pokedata(child, addr, data); + break; + /* write the word at location addr in the USER area */ case PTRACE_POKEUSR: ret = poke_user(child, addr, data); @@ -94,6 +106,16 @@ long arch_ptrace(struct task_struct *child, long request, ret = 0; break; } +#endif +#ifdef PTRACE_GETFPREGS + case PTRACE_GETFPREGS: /* Get the child FPU state. */ + ret = get_fpregs(vp, child); + break; +#endif +#ifdef PTRACE_SETFPREGS + case PTRACE_SETFPREGS: /* Set the child FPU state. */ + ret = set_fpregs(vp, child); + break; #endif case PTRACE_GET_THREAD_AREA: ret = ptrace_get_thread_area(child, addr, vp); @@ -131,6 +153,12 @@ long arch_ptrace(struct task_struct *child, long request, ret = -EIO; break; } +#endif +#ifdef PTRACE_ARCH_PRCTL + case PTRACE_ARCH_PRCTL: + /* XXX Calls ptrace on the host - needs some SMP thinking */ + ret = arch_prctl(child, data, (void __user *) addr); + break; #endif default: ret = ptrace_request(child, request, addr, data); diff --git a/trunk/arch/um/os-Linux/registers.c b/trunk/arch/um/os-Linux/registers.c index b866b9e3bef9..830fe6a1518a 100644 --- a/trunk/arch/um/os-Linux/registers.c +++ b/trunk/arch/um/os-Linux/registers.c @@ -8,8 +8,6 @@ #include #include #include "sysdep/ptrace.h" -#include "sysdep/ptrace_user.h" -#include "registers.h" int save_registers(int pid, struct uml_pt_regs *regs) { @@ -34,7 +32,6 @@ int restore_registers(int pid, struct uml_pt_regs *regs) /* This is set once at boot time and not changed thereafter */ static unsigned long exec_regs[MAX_REG_NR]; -static unsigned long exec_fp_regs[FP_SIZE]; int init_registers(int pid) { @@ -45,14 +42,10 @@ int init_registers(int pid) return -errno; arch_init_registers(pid); - get_fp_registers(pid, exec_fp_regs); return 0; } -void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) +void get_safe_registers(unsigned long *regs) { memcpy(regs, exec_regs, sizeof(exec_regs)); - - if (fp_regs) - memcpy(fp_regs, exec_fp_regs, sizeof(exec_fp_regs)); } diff --git a/trunk/arch/um/os-Linux/skas/mem.c b/trunk/arch/um/os-Linux/skas/mem.c index e771398be5f3..d261f170d120 100644 --- a/trunk/arch/um/os-Linux/skas/mem.c +++ b/trunk/arch/um/os-Linux/skas/mem.c @@ -39,7 +39,7 @@ static unsigned long syscall_regs[MAX_REG_NR]; static int __init init_syscall_regs(void) { - get_safe_registers(syscall_regs, NULL); + get_safe_registers(syscall_regs); syscall_regs[REGS_IP_INDEX] = STUB_CODE + ((unsigned long) &batch_syscall_stub - (unsigned long) &__syscall_stub_start); diff --git a/trunk/arch/um/os-Linux/skas/process.c b/trunk/arch/um/os-Linux/skas/process.c index dee0e8cf8ad0..d6e0a2234b86 100644 --- a/trunk/arch/um/os-Linux/skas/process.c +++ b/trunk/arch/um/os-Linux/skas/process.c @@ -373,9 +373,6 @@ void userspace(struct uml_pt_regs *regs) if (ptrace(PTRACE_SETREGS, pid, 0, regs->gp)) fatal_sigsegv(); - if (put_fp_registers(pid, regs->fp)) - fatal_sigsegv(); - /* Now we set local_using_sysemu to be used for one loop */ local_using_sysemu = get_using_sysemu(); @@ -402,12 +399,6 @@ void userspace(struct uml_pt_regs *regs) fatal_sigsegv(); } - if (get_fp_registers(pid, regs->fp)) { - printk(UM_KERN_ERR "userspace - get_fp_registers failed, " - "errno = %d\n", errno); - fatal_sigsegv(); - } - UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */ if (WIFSTOPPED(status)) { @@ -466,11 +457,10 @@ void userspace(struct uml_pt_regs *regs) } static unsigned long thread_regs[MAX_REG_NR]; -static unsigned long thread_fp_regs[FP_SIZE]; static int __init init_thread_regs(void) { - get_safe_registers(thread_regs, thread_fp_regs); + get_safe_registers(thread_regs); /* Set parent's instruction pointer to start of clone-stub */ thread_regs[REGS_IP_INDEX] = STUB_CODE + (unsigned long) stub_clone_handler - @@ -513,13 +503,6 @@ int copy_context_skas0(unsigned long new_stack, int pid) return err; } - err = put_fp_registers(pid, thread_fp_regs); - if (err < 0) { - printk(UM_KERN_ERR "copy_context_skas0 : put_fp_registers " - "failed, pid = %d, err = %d\n", pid, err); - return err; - } - /* set a well known return code for detection of child write failure */ child_data->err = 12345678; diff --git a/trunk/arch/um/sys-i386/asm/ptrace.h b/trunk/arch/um/sys-i386/asm/ptrace.h index 5d2a59112537..0273e4d09af7 100644 --- a/trunk/arch/um/sys-i386/asm/ptrace.h +++ b/trunk/arch/um/sys-i386/asm/ptrace.h @@ -42,6 +42,11 @@ */ struct user_desc; +extern int get_fpxregs(struct user_fxsr_struct __user *buf, + struct task_struct *child); +extern int set_fpxregs(struct user_fxsr_struct __user *buf, + struct task_struct *tsk); + extern int ptrace_get_thread_area(struct task_struct *child, int idx, struct user_desc __user *user_desc); diff --git a/trunk/arch/um/sys-i386/ptrace.c b/trunk/arch/um/sys-i386/ptrace.c index 3375c2717851..d23b2d3ea384 100644 --- a/trunk/arch/um/sys-i386/ptrace.c +++ b/trunk/arch/um/sys-i386/ptrace.c @@ -145,7 +145,7 @@ int peek_user(struct task_struct *child, long addr, long data) return put_user(tmp, (unsigned long __user *) data); } -static int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) +int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) { int err, n, cpu = ((struct thread_info *) child->stack)->cpu; struct user_i387_struct fpregs; @@ -161,7 +161,7 @@ static int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *c return n; } -static int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) +int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) { int n, cpu = ((struct thread_info *) child->stack)->cpu; struct user_i387_struct fpregs; @@ -174,7 +174,7 @@ static int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *c (unsigned long *) &fpregs); } -static int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) +int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) { int err, n, cpu = ((struct thread_info *) child->stack)->cpu; struct user_fxsr_struct fpregs; @@ -190,7 +190,7 @@ static int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct * return n; } -static int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) +int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) { int n, cpu = ((struct thread_info *) child->stack)->cpu; struct user_fxsr_struct fpregs; @@ -206,23 +206,5 @@ static int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct * long subarch_ptrace(struct task_struct *child, long request, unsigned long addr, unsigned long data) { - int ret = -EIO; - void __user *datap = (void __user *) data; - switch (request) { - case PTRACE_GETFPREGS: /* Get the child FPU state. */ - ret = get_fpregs(datap, child); - break; - case PTRACE_SETFPREGS: /* Set the child FPU state. */ - ret = set_fpregs(datap, child); - break; - case PTRACE_GETFPXREGS: /* Get the child FPU state. */ - ret = get_fpxregs(datap, child); - break; - case PTRACE_SETFPXREGS: /* Set the child FPU state. */ - ret = set_fpxregs(datap, child); - break; - default: - ret = -EIO; - } - return ret; + return -EIO; } diff --git a/trunk/arch/um/sys-i386/shared/sysdep/ptrace.h b/trunk/arch/um/sys-i386/shared/sysdep/ptrace.h index c398a5076111..d50e62e07070 100644 --- a/trunk/arch/um/sys-i386/shared/sysdep/ptrace.h +++ b/trunk/arch/um/sys-i386/shared/sysdep/ptrace.h @@ -53,7 +53,6 @@ extern int sysemu_supported; struct uml_pt_regs { unsigned long gp[MAX_REG_NR]; - unsigned long fp[HOST_FPX_SIZE]; struct faultinfo faultinfo; long syscall; int is_user; diff --git a/trunk/arch/um/sys-x86_64/ptrace.c b/trunk/arch/um/sys-x86_64/ptrace.c index 4005506834fd..f43613643cdb 100644 --- a/trunk/arch/um/sys-x86_64/ptrace.c +++ b/trunk/arch/um/sys-x86_64/ptrace.c @@ -145,7 +145,7 @@ int is_syscall(unsigned long addr) return instr == 0x050f; } -static int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) +int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) { int err, n, cpu = ((struct thread_info *) child->stack)->cpu; long fpregs[HOST_FP_SIZE]; @@ -162,7 +162,7 @@ static int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *c return n; } -static int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) +int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) { int n, cpu = ((struct thread_info *) child->stack)->cpu; long fpregs[HOST_FP_SIZE]; @@ -182,16 +182,12 @@ long subarch_ptrace(struct task_struct *child, long request, void __user *datap = (void __user *) data; switch (request) { - case PTRACE_GETFPREGS: /* Get the child FPU state. */ + case PTRACE_GETFPXREGS: /* Get the child FPU state. */ ret = get_fpregs(datap, child); break; - case PTRACE_SETFPREGS: /* Set the child FPU state. */ + case PTRACE_SETFPXREGS: /* Set the child FPU state. */ ret = set_fpregs(datap, child); break; - case PTRACE_ARCH_PRCTL: - /* XXX Calls ptrace on the host - needs some SMP thinking */ - ret = arch_prctl(child, data, (void __user *) addr); - break; } return ret; diff --git a/trunk/arch/um/sys-x86_64/shared/sysdep/ptrace.h b/trunk/arch/um/sys-x86_64/shared/sysdep/ptrace.h index 8ee8f8e12af1..fdba5457947a 100644 --- a/trunk/arch/um/sys-x86_64/shared/sysdep/ptrace.h +++ b/trunk/arch/um/sys-x86_64/shared/sysdep/ptrace.h @@ -85,7 +85,6 @@ struct uml_pt_regs { unsigned long gp[MAX_REG_NR]; - unsigned long fp[HOST_FP_SIZE]; struct faultinfo faultinfo; long syscall; int is_user; diff --git a/trunk/arch/x86/xen/time.c b/trunk/arch/x86/xen/time.c index 163b4679556e..5158c505bef9 100644 --- a/trunk/arch/x86/xen/time.c +++ b/trunk/arch/x86/xen/time.c @@ -168,10 +168,9 @@ cycle_t xen_clocksource_read(void) struct pvclock_vcpu_time_info *src; cycle_t ret; - preempt_disable_notrace(); - src = &__get_cpu_var(xen_vcpu)->time; + src = &get_cpu_var(xen_vcpu)->time; ret = pvclock_clocksource_read(src); - preempt_enable_notrace(); + put_cpu_var(xen_vcpu); return ret; } diff --git a/trunk/drivers/acpi/acpica/acconfig.h b/trunk/drivers/acpi/acpica/acconfig.h index f895a244ca7e..bc533dde16c4 100644 --- a/trunk/drivers/acpi/acpica/acconfig.h +++ b/trunk/drivers/acpi/acpica/acconfig.h @@ -121,7 +121,7 @@ /* Maximum sleep allowed via Sleep() operator */ -#define ACPI_MAX_SLEEP 2000 /* Two seconds */ +#define ACPI_MAX_SLEEP 20000 /* Two seconds */ /****************************************************************************** * diff --git a/trunk/drivers/acpi/apei/Kconfig b/trunk/drivers/acpi/apei/Kconfig index e3f47872ec22..c34aa51af4ee 100644 --- a/trunk/drivers/acpi/apei/Kconfig +++ b/trunk/drivers/acpi/apei/Kconfig @@ -13,7 +13,6 @@ config ACPI_APEI_GHES bool "APEI Generic Hardware Error Source" depends on ACPI_APEI && X86 select ACPI_HED - select IRQ_WORK select LLIST select GENERIC_ALLOCATOR help diff --git a/trunk/drivers/acpi/apei/apei-base.c b/trunk/drivers/acpi/apei/apei-base.c index 61540360d5ce..8041248fce9b 100644 --- a/trunk/drivers/acpi/apei/apei-base.c +++ b/trunk/drivers/acpi/apei/apei-base.c @@ -618,7 +618,7 @@ int apei_osc_setup(void) }; capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; - capbuf[OSC_SUPPORT_TYPE] = 1; + capbuf[OSC_SUPPORT_TYPE] = 0; capbuf[OSC_CONTROL_TYPE] = 0; if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle)) diff --git a/trunk/drivers/cpufreq/pcc-cpufreq.c b/trunk/drivers/cpufreq/pcc-cpufreq.c index cdc02ac8f41a..7b0603eb0129 100644 --- a/trunk/drivers/cpufreq/pcc-cpufreq.c +++ b/trunk/drivers/cpufreq/pcc-cpufreq.c @@ -261,9 +261,6 @@ static int pcc_get_offset(int cpu) pr = per_cpu(processors, cpu); pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu); - if (!pr) - return -ENODEV; - status = acpi_evaluate_object(pr->handle, "PCCP", NULL, &buffer); if (ACPI_FAILURE(status)) return -ENODEV; diff --git a/trunk/drivers/gpio/gpio-generic.c b/trunk/drivers/gpio/gpio-generic.c index 4e24436b0f82..231714def4d2 100644 --- a/trunk/drivers/gpio/gpio-generic.c +++ b/trunk/drivers/gpio/gpio-generic.c @@ -351,7 +351,7 @@ static int bgpio_setup_direction(struct bgpio_chip *bgc, return 0; } -int bgpio_remove(struct bgpio_chip *bgc) +int __devexit bgpio_remove(struct bgpio_chip *bgc) { int err = gpiochip_remove(&bgc->gc); @@ -361,10 +361,15 @@ int bgpio_remove(struct bgpio_chip *bgc) } EXPORT_SYMBOL_GPL(bgpio_remove); -int bgpio_init(struct bgpio_chip *bgc, struct device *dev, - unsigned long sz, void __iomem *dat, void __iomem *set, - void __iomem *clr, void __iomem *dirout, void __iomem *dirin, - bool big_endian) +int __devinit bgpio_init(struct bgpio_chip *bgc, + struct device *dev, + unsigned long sz, + void __iomem *dat, + void __iomem *set, + void __iomem *clr, + void __iomem *dirout, + void __iomem *dirin, + bool big_endian) { int ret; diff --git a/trunk/drivers/hwmon/pmbus/pmbus_core.c b/trunk/drivers/hwmon/pmbus/pmbus_core.c index a561c3a0e916..397fc59b5682 100644 --- a/trunk/drivers/hwmon/pmbus/pmbus_core.c +++ b/trunk/drivers/hwmon/pmbus/pmbus_core.c @@ -978,6 +978,8 @@ static void pmbus_find_max_attr(struct i2c_client *client, struct pmbus_limit_attr { u16 reg; /* Limit register */ bool update; /* True if register needs updates */ + bool low; /* True if low limit; for limits with compare + functions only */ const char *attr; /* Attribute name */ const char *alarm; /* Alarm attribute name */ u32 sbit; /* Alarm attribute status bit */ @@ -1029,7 +1031,8 @@ static bool pmbus_add_limit_attrs(struct i2c_client *client, if (attr->compare) { pmbus_add_boolean_cmp(data, name, l->alarm, index, - cbase, cindex, + l->low ? cindex : cbase, + l->low ? cbase : cindex, attr->sbase + page, l->sbit); } else { pmbus_add_boolean_reg(data, name, @@ -1366,11 +1369,13 @@ static const struct pmbus_sensor_attr power_attributes[] = { static const struct pmbus_limit_attr temp_limit_attrs[] = { { .reg = PMBUS_UT_WARN_LIMIT, + .low = true, .attr = "min", .alarm = "min_alarm", .sbit = PB_TEMP_UT_WARNING, }, { .reg = PMBUS_UT_FAULT_LIMIT, + .low = true, .attr = "lcrit", .alarm = "lcrit_alarm", .sbit = PB_TEMP_UT_FAULT, @@ -1399,11 +1404,13 @@ static const struct pmbus_limit_attr temp_limit_attrs[] = { static const struct pmbus_limit_attr temp_limit_attrs23[] = { { .reg = PMBUS_UT_WARN_LIMIT, + .low = true, .attr = "min", .alarm = "min_alarm", .sbit = PB_TEMP_UT_WARNING, }, { .reg = PMBUS_UT_FAULT_LIMIT, + .low = true, .attr = "lcrit", .alarm = "lcrit_alarm", .sbit = PB_TEMP_UT_FAULT, diff --git a/trunk/drivers/leds/ledtrig-timer.c b/trunk/drivers/leds/ledtrig-timer.c index 328c64c0841c..d87c9d02f786 100644 --- a/trunk/drivers/leds/ledtrig-timer.c +++ b/trunk/drivers/leds/ledtrig-timer.c @@ -41,7 +41,6 @@ static ssize_t led_delay_on_store(struct device *dev, if (count == size) { led_blink_set(led_cdev, &state, &led_cdev->blink_delay_off); - led_cdev->blink_delay_on = state; ret = count; } @@ -70,7 +69,6 @@ static ssize_t led_delay_off_store(struct device *dev, if (count == size) { led_blink_set(led_cdev, &led_cdev->blink_delay_on, &state); - led_cdev->blink_delay_off = state; ret = count; } diff --git a/trunk/drivers/misc/pti.c b/trunk/drivers/misc/pti.c index 0b56e3f43573..06df1877ad0f 100644 --- a/trunk/drivers/misc/pti.c +++ b/trunk/drivers/misc/pti.c @@ -165,11 +165,6 @@ static void pti_write_to_aperture(struct pti_masterchannel *mc, static void pti_control_frame_built_and_sent(struct pti_masterchannel *mc, const char *thread_name) { - /* - * Since we access the comm member in current's task_struct, we only - * need to be as large as what 'comm' in that structure is. - */ - char comm[TASK_COMM_LEN]; struct pti_masterchannel mccontrol = {.master = CONTROL_ID, .channel = 0}; const char *thread_name_p; @@ -177,6 +172,13 @@ static void pti_control_frame_built_and_sent(struct pti_masterchannel *mc, u8 control_frame[CONTROL_FRAME_LEN]; if (!thread_name) { + /* + * Since we access the comm member in current's task_struct, + * we only need to be as large as what 'comm' in that + * structure is. + */ + char comm[TASK_COMM_LEN]; + if (!in_interrupt()) get_task_comm(comm, current); else diff --git a/trunk/drivers/pci/probe.c b/trunk/drivers/pci/probe.c index f3f94a5c068f..b1187ff31d89 100644 --- a/trunk/drivers/pci/probe.c +++ b/trunk/drivers/pci/probe.c @@ -1351,8 +1351,7 @@ static int pcie_find_smpss(struct pci_dev *dev, void *data) * will occur as normal. */ if (dev->is_hotplug_bridge && (!list_is_singular(&dev->bus->devices) || - (dev->bus->self && - dev->bus->self->pcie_type != PCI_EXP_TYPE_ROOT_PORT))) + dev->bus->self->pcie_type != PCI_EXP_TYPE_ROOT_PORT)) *smpss = 0; if (*smpss > dev->pcie_mpss) diff --git a/trunk/drivers/rtc/rtc-imxdi.c b/trunk/drivers/rtc/rtc-imxdi.c index d93a9608b1f0..2dd3c0163272 100644 --- a/trunk/drivers/rtc/rtc-imxdi.c +++ b/trunk/drivers/rtc/rtc-imxdi.c @@ -35,7 +35,6 @@ #include #include #include -#include #include /* DryIce Register Definitions */ diff --git a/trunk/drivers/rtc/rtc-s3c.c b/trunk/drivers/rtc/rtc-s3c.c index 7639ab906f02..4e7c04e773e0 100644 --- a/trunk/drivers/rtc/rtc-s3c.c +++ b/trunk/drivers/rtc/rtc-s3c.c @@ -51,27 +51,6 @@ static enum s3c_cpu_type s3c_rtc_cpu_type; static DEFINE_SPINLOCK(s3c_rtc_pie_lock); -static void s3c_rtc_alarm_clk_enable(bool enable) -{ - static DEFINE_SPINLOCK(s3c_rtc_alarm_clk_lock); - static bool alarm_clk_enabled; - unsigned long irq_flags; - - spin_lock_irqsave(&s3c_rtc_alarm_clk_lock, irq_flags); - if (enable) { - if (!alarm_clk_enabled) { - clk_enable(rtc_clk); - alarm_clk_enabled = true; - } - } else { - if (alarm_clk_enabled) { - clk_disable(rtc_clk); - alarm_clk_enabled = false; - } - } - spin_unlock_irqrestore(&s3c_rtc_alarm_clk_lock, irq_flags); -} - /* IRQ Handlers */ static irqreturn_t s3c_rtc_alarmirq(int irq, void *id) @@ -85,9 +64,6 @@ static irqreturn_t s3c_rtc_alarmirq(int irq, void *id) writeb(S3C2410_INTP_ALM, s3c_rtc_base + S3C2410_INTP); clk_disable(rtc_clk); - - s3c_rtc_alarm_clk_enable(false); - return IRQ_HANDLED; } @@ -121,8 +97,6 @@ static int s3c_rtc_setaie(struct device *dev, unsigned int enabled) writeb(tmp, s3c_rtc_base + S3C2410_RTCALM); clk_disable(rtc_clk); - s3c_rtc_alarm_clk_enable(enabled); - return 0; } diff --git a/trunk/drivers/scsi/bnx2i/bnx2i_hwi.c b/trunk/drivers/scsi/bnx2i/bnx2i_hwi.c index dba72a4e6a1c..9ae80cd5953b 100644 --- a/trunk/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/trunk/drivers/scsi/bnx2i/bnx2i_hwi.c @@ -563,7 +563,7 @@ int bnx2i_send_iscsi_nopout(struct bnx2i_conn *bnx2i_conn, nopout_wqe->itt = ((u16)task->itt | (ISCSI_TASK_TYPE_MPATH << ISCSI_TMF_REQUEST_TYPE_SHIFT)); - nopout_wqe->ttt = be32_to_cpu(nopout_hdr->ttt); + nopout_wqe->ttt = nopout_hdr->ttt; nopout_wqe->flags = 0; if (!unsol) nopout_wqe->flags = ISCSI_NOP_OUT_REQUEST_LOCAL_COMPLETION; diff --git a/trunk/drivers/scsi/fcoe/fcoe.c b/trunk/drivers/scsi/fcoe/fcoe.c index 5d0e9a24ae94..ba710e350ac5 100644 --- a/trunk/drivers/scsi/fcoe/fcoe.c +++ b/trunk/drivers/scsi/fcoe/fcoe.c @@ -432,8 +432,6 @@ void fcoe_interface_cleanup(struct fcoe_interface *fcoe) u8 flogi_maddr[ETH_ALEN]; const struct net_device_ops *ops; - rtnl_lock(); - /* * Don't listen for Ethernet packets anymore. * synchronize_net() ensures that the packet handlers are not running @@ -463,8 +461,6 @@ void fcoe_interface_cleanup(struct fcoe_interface *fcoe) " specific feature for LLD.\n"); } - rtnl_unlock(); - /* Release the self-reference taken during fcoe_interface_create() */ fcoe_interface_put(fcoe); } @@ -1955,8 +1951,11 @@ static void fcoe_destroy_work(struct work_struct *work) fcoe_if_destroy(port->lport); /* Do not tear down the fcoe interface for NPIV port */ - if (!npiv) + if (!npiv) { + rtnl_lock(); fcoe_interface_cleanup(fcoe); + rtnl_unlock(); + } mutex_unlock(&fcoe_config_mutex); } @@ -2010,9 +2009,8 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) printk(KERN_ERR "fcoe: Failed to create interface (%s)\n", netdev->name); rc = -EIO; - rtnl_unlock(); fcoe_interface_cleanup(fcoe); - goto out_nortnl; + goto out_nodev; } /* Make this the "master" N_Port */ @@ -2029,7 +2027,6 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) out_nodev: rtnl_unlock(); -out_nortnl: mutex_unlock(&fcoe_config_mutex); return rc; } diff --git a/trunk/drivers/scsi/hpsa.c b/trunk/drivers/scsi/hpsa.c index b200b736b000..ec61bdb833ac 100644 --- a/trunk/drivers/scsi/hpsa.c +++ b/trunk/drivers/scsi/hpsa.c @@ -676,16 +676,6 @@ static void hpsa_scsi_replace_entry(struct ctlr_info *h, int hostno, BUG_ON(entry < 0 || entry >= HPSA_MAX_SCSI_DEVS_PER_HBA); removed[*nremoved] = h->dev[entry]; (*nremoved)++; - - /* - * New physical devices won't have target/lun assigned yet - * so we need to preserve the values in the slot we are replacing. - */ - if (new_entry->target == -1) { - new_entry->target = h->dev[entry]->target; - new_entry->lun = h->dev[entry]->lun; - } - h->dev[entry] = new_entry; added[*nadded] = new_entry; (*nadded)++; @@ -1558,17 +1548,10 @@ static inline void hpsa_set_bus_target_lun(struct hpsa_scsi_dev_t *device, } static int hpsa_update_device_info(struct ctlr_info *h, - unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device, - unsigned char *is_OBDR_device) + unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device) { - -#define OBDR_SIG_OFFSET 43 -#define OBDR_TAPE_SIG "$DR-10" -#define OBDR_SIG_LEN (sizeof(OBDR_TAPE_SIG) - 1) -#define OBDR_TAPE_INQ_SIZE (OBDR_SIG_OFFSET + OBDR_SIG_LEN) - +#define OBDR_TAPE_INQ_SIZE 49 unsigned char *inq_buff; - unsigned char *obdr_sig; inq_buff = kzalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL); if (!inq_buff) @@ -1600,16 +1583,6 @@ static int hpsa_update_device_info(struct ctlr_info *h, else this_device->raid_level = RAID_UNKNOWN; - if (is_OBDR_device) { - /* See if this is a One-Button-Disaster-Recovery device - * by looking for "$DR-10" at offset 43 in inquiry data. - */ - obdr_sig = &inq_buff[OBDR_SIG_OFFSET]; - *is_OBDR_device = (this_device->devtype == TYPE_ROM && - strncmp(obdr_sig, OBDR_TAPE_SIG, - OBDR_SIG_LEN) == 0); - } - kfree(inq_buff); return 0; @@ -1743,7 +1716,7 @@ static int add_msa2xxx_enclosure_device(struct ctlr_info *h, return 0; } - if (hpsa_update_device_info(h, scsi3addr, this_device, NULL)) + if (hpsa_update_device_info(h, scsi3addr, this_device)) return 0; (*nmsa2xxx_enclosures)++; hpsa_set_bus_target_lun(this_device, bus, target, 0); @@ -1835,6 +1808,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) */ struct ReportLUNdata *physdev_list = NULL; struct ReportLUNdata *logdev_list = NULL; + unsigned char *inq_buff = NULL; u32 nphysicals = 0; u32 nlogicals = 0; u32 ndev_allocated = 0; @@ -1850,9 +1824,11 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) GFP_KERNEL); physdev_list = kzalloc(reportlunsize, GFP_KERNEL); logdev_list = kzalloc(reportlunsize, GFP_KERNEL); + inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL); tmpdevice = kzalloc(sizeof(*tmpdevice), GFP_KERNEL); - if (!currentsd || !physdev_list || !logdev_list || !tmpdevice) { + if (!currentsd || !physdev_list || !logdev_list || + !inq_buff || !tmpdevice) { dev_err(&h->pdev->dev, "out of memory\n"); goto out; } @@ -1887,7 +1863,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) /* adjust our table of devices */ nmsa2xxx_enclosures = 0; for (i = 0; i < nphysicals + nlogicals + 1; i++) { - u8 *lunaddrbytes, is_OBDR = 0; + u8 *lunaddrbytes; /* Figure out where the LUN ID info is coming from */ lunaddrbytes = figure_lunaddrbytes(h, raid_ctlr_position, @@ -1898,8 +1874,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) continue; /* Get device type, vendor, model, device id */ - if (hpsa_update_device_info(h, lunaddrbytes, tmpdevice, - &is_OBDR)) + if (hpsa_update_device_info(h, lunaddrbytes, tmpdevice)) continue; /* skip it if we can't talk to it. */ figure_bus_target_lun(h, lunaddrbytes, &bus, &target, &lun, tmpdevice); @@ -1923,7 +1898,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) hpsa_set_bus_target_lun(this_device, bus, target, lun); switch (this_device->devtype) { - case TYPE_ROM: + case TYPE_ROM: { /* We don't *really* support actual CD-ROM devices, * just "One Button Disaster Recovery" tape drive * which temporarily pretends to be a CD-ROM drive. @@ -1931,8 +1906,15 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) * device by checking for "$DR-10" in bytes 43-48 of * the inquiry data. */ - if (is_OBDR) - ncurrent++; + char obdr_sig[7]; +#define OBDR_TAPE_SIG "$DR-10" + strncpy(obdr_sig, &inq_buff[43], 6); + obdr_sig[6] = '\0'; + if (strncmp(obdr_sig, OBDR_TAPE_SIG, 6) != 0) + /* Not OBDR device, ignore it. */ + break; + } + ncurrent++; break; case TYPE_DISK: if (i < nphysicals) @@ -1965,6 +1947,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) for (i = 0; i < ndev_allocated; i++) kfree(currentsd[i]); kfree(currentsd); + kfree(inq_buff); kfree(physdev_list); kfree(logdev_list); } diff --git a/trunk/drivers/scsi/isci/host.c b/trunk/drivers/scsi/isci/host.c index 6981b773a88d..26072f1e9852 100644 --- a/trunk/drivers/scsi/isci/host.c +++ b/trunk/drivers/scsi/isci/host.c @@ -531,9 +531,6 @@ static void sci_controller_process_completions(struct isci_host *ihost) break; case SCU_COMPLETION_TYPE_EVENT: - sci_controller_event_completion(ihost, ent); - break; - case SCU_COMPLETION_TYPE_NOTIFY: { event_cycle ^= ((event_get+1) & SCU_MAX_EVENTS) << (SMU_COMPLETION_QUEUE_GET_EVENT_CYCLE_BIT_SHIFT - SCU_MAX_EVENTS_SHIFT); @@ -1094,7 +1091,6 @@ static void isci_host_completion_routine(unsigned long data) struct isci_request *request; struct isci_request *next_request; struct sas_task *task; - u16 active; INIT_LIST_HEAD(&completed_request_list); INIT_LIST_HEAD(&errored_request_list); @@ -1185,13 +1181,6 @@ static void isci_host_completion_routine(unsigned long data) } } - /* the coalesence timeout doubles at each encoding step, so - * update it based on the ilog2 value of the outstanding requests - */ - active = isci_tci_active(ihost); - writel(SMU_ICC_GEN_VAL(NUMBER, active) | - SMU_ICC_GEN_VAL(TIMER, ISCI_COALESCE_BASE + ilog2(active)), - &ihost->smu_registers->interrupt_coalesce_control); } /** @@ -1482,7 +1471,7 @@ static void sci_controller_ready_state_enter(struct sci_base_state_machine *sm) struct isci_host *ihost = container_of(sm, typeof(*ihost), sm); /* set the default interrupt coalescence number and timeout value. */ - sci_controller_set_interrupt_coalescence(ihost, 0, 0); + sci_controller_set_interrupt_coalescence(ihost, 0x10, 250); } static void sci_controller_ready_state_exit(struct sci_base_state_machine *sm) diff --git a/trunk/drivers/scsi/isci/host.h b/trunk/drivers/scsi/isci/host.h index 9f33831a2f04..062101a39f79 100644 --- a/trunk/drivers/scsi/isci/host.h +++ b/trunk/drivers/scsi/isci/host.h @@ -369,9 +369,6 @@ static inline struct isci_host *dev_to_ihost(struct domain_device *dev) #define ISCI_TAG_SEQ(tag) (((tag) >> 12) & (SCI_MAX_SEQ-1)) #define ISCI_TAG_TCI(tag) ((tag) & (SCI_MAX_IO_REQUESTS-1)) -/* interrupt coalescing baseline: 9 == 3 to 5us interrupt delay per command */ -#define ISCI_COALESCE_BASE 9 - /* expander attached sata devices require 3 rnc slots */ static inline int sci_remote_device_node_count(struct isci_remote_device *idev) { diff --git a/trunk/drivers/scsi/isci/init.c b/trunk/drivers/scsi/isci/init.c index 29aa34efb0f5..61e0d09e2b57 100644 --- a/trunk/drivers/scsi/isci/init.c +++ b/trunk/drivers/scsi/isci/init.c @@ -59,19 +59,10 @@ #include #include #include -#include #include "isci.h" #include "task.h" #include "probe_roms.h" -#define MAJ 1 -#define MIN 0 -#define BUILD 0 -#define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \ - __stringify(BUILD) - -MODULE_VERSION(DRV_VERSION); - static struct scsi_transport_template *isci_transport_template; static DEFINE_PCI_DEVICE_TABLE(isci_id_table) = { @@ -122,22 +113,6 @@ unsigned char max_concurr_spinup = 1; module_param(max_concurr_spinup, byte, 0); MODULE_PARM_DESC(max_concurr_spinup, "Max concurrent device spinup"); -static ssize_t isci_show_id(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct Scsi_Host *shost = container_of(dev, typeof(*shost), shost_dev); - struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost); - struct isci_host *ihost = container_of(sas_ha, typeof(*ihost), sas_ha); - - return snprintf(buf, PAGE_SIZE, "%d\n", ihost->id); -} - -static DEVICE_ATTR(isci_id, S_IRUGO, isci_show_id, NULL); - -struct device_attribute *isci_host_attrs[] = { - &dev_attr_isci_id, - NULL -}; - static struct scsi_host_template isci_sht = { .module = THIS_MODULE, @@ -163,7 +138,6 @@ static struct scsi_host_template isci_sht = { .slave_alloc = sas_slave_alloc, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, - .shost_attrs = isci_host_attrs, }; static struct sas_domain_function_template isci_transport_ops = { @@ -258,6 +232,17 @@ static int isci_register_sas_ha(struct isci_host *isci_host) return 0; } +static ssize_t isci_show_id(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct Scsi_Host *shost = container_of(dev, typeof(*shost), shost_dev); + struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost); + struct isci_host *ihost = container_of(sas_ha, typeof(*ihost), sas_ha); + + return snprintf(buf, PAGE_SIZE, "%d\n", ihost->id); +} + +static DEVICE_ATTR(isci_id, S_IRUGO, isci_show_id, NULL); + static void isci_unregister(struct isci_host *isci_host) { struct Scsi_Host *shost; @@ -266,6 +251,7 @@ static void isci_unregister(struct isci_host *isci_host) return; shost = isci_host->shost; + device_remove_file(&shost->shost_dev, &dev_attr_isci_id); sas_unregister_ha(&isci_host->sas_ha); @@ -429,8 +415,14 @@ static struct isci_host *isci_host_alloc(struct pci_dev *pdev, int id) if (err) goto err_shost_remove; + err = device_create_file(&shost->shost_dev, &dev_attr_isci_id); + if (err) + goto err_unregister_ha; + return isci_host; + err_unregister_ha: + sas_unregister_ha(&(isci_host->sas_ha)); err_shost_remove: scsi_remove_host(shost); err_shost: @@ -548,8 +540,7 @@ static __init int isci_init(void) { int err; - pr_info("%s: Intel(R) C600 SAS Controller Driver - version %s\n", - DRV_NAME, DRV_VERSION); + pr_info("%s: Intel(R) C600 SAS Controller Driver\n", DRV_NAME); isci_transport_template = sas_domain_attach_transport(&isci_transport_ops); if (!isci_transport_template) diff --git a/trunk/drivers/scsi/isci/phy.c b/trunk/drivers/scsi/isci/phy.c index 430fc8ff014a..79313a7a2356 100644 --- a/trunk/drivers/scsi/isci/phy.c +++ b/trunk/drivers/scsi/isci/phy.c @@ -104,7 +104,6 @@ sci_phy_link_layer_initialization(struct isci_phy *iphy, u32 parity_count = 0; u32 llctl, link_rate; u32 clksm_value = 0; - u32 sp_timeouts = 0; iphy->link_layer_registers = reg; @@ -212,18 +211,6 @@ sci_phy_link_layer_initialization(struct isci_phy *iphy, llctl |= SCU_SAS_LLCTL_GEN_VAL(MAX_LINK_RATE, link_rate); writel(llctl, &iphy->link_layer_registers->link_layer_control); - sp_timeouts = readl(&iphy->link_layer_registers->sas_phy_timeouts); - - /* Clear the default 0x36 (54us) RATE_CHANGE timeout value. */ - sp_timeouts &= ~SCU_SAS_PHYTOV_GEN_VAL(RATE_CHANGE, 0xFF); - - /* Set RATE_CHANGE timeout value to 0x3B (59us). This ensures SCU can - * lock with 3Gb drive when SCU max rate is set to 1.5Gb. - */ - sp_timeouts |= SCU_SAS_PHYTOV_GEN_VAL(RATE_CHANGE, 0x3B); - - writel(sp_timeouts, &iphy->link_layer_registers->sas_phy_timeouts); - if (is_a2(ihost->pdev)) { /* Program the max ARB time for the PHY to 700us so we inter-operate with * the PMC expander which shuts down PHYs if the expander PHY generates too diff --git a/trunk/drivers/scsi/isci/registers.h b/trunk/drivers/scsi/isci/registers.h index 00afc738bbed..9b266c7428e8 100644 --- a/trunk/drivers/scsi/isci/registers.h +++ b/trunk/drivers/scsi/isci/registers.h @@ -1299,18 +1299,6 @@ struct scu_transport_layer_registers { #define SCU_AFE_XCVRCR_OFFSET 0x00DC #define SCU_AFE_LUTCR_OFFSET 0x00E0 -#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_ALIGN_DETECTION_SHIFT (0UL) -#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_ALIGN_DETECTION_MASK (0x000000FFUL) -#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_HOT_PLUG_SHIFT (8UL) -#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_HOT_PLUG_MASK (0x0000FF00UL) -#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_COMSAS_DETECTION_SHIFT (16UL) -#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_COMSAS_DETECTION_MASK (0x00FF0000UL) -#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_RATE_CHANGE_SHIFT (24UL) -#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_RATE_CHANGE_MASK (0xFF000000UL) - -#define SCU_SAS_PHYTOV_GEN_VAL(name, value) \ - SCU_GEN_VALUE(SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_##name, value) - #define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_SHIFT (0) #define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_MASK (0x00000003) #define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1 (0) diff --git a/trunk/drivers/scsi/isci/request.c b/trunk/drivers/scsi/isci/request.c index b5d3a8c4d329..a46e07ac789f 100644 --- a/trunk/drivers/scsi/isci/request.c +++ b/trunk/drivers/scsi/isci/request.c @@ -732,20 +732,12 @@ sci_io_request_terminate(struct isci_request *ireq) sci_change_state(&ireq->sm, SCI_REQ_ABORTING); return SCI_SUCCESS; case SCI_REQ_TASK_WAIT_TC_RESP: - /* The task frame was already confirmed to have been - * sent by the SCU HW. Since the state machine is - * now only waiting for the task response itself, - * abort the request and complete it immediately - * and don't wait for the task response. - */ sci_change_state(&ireq->sm, SCI_REQ_ABORTING); sci_change_state(&ireq->sm, SCI_REQ_COMPLETED); return SCI_SUCCESS; case SCI_REQ_ABORTING: - /* If a request has a termination requested twice, return - * a failure indication, since HW confirmation of the first - * abort is still outstanding. - */ + sci_change_state(&ireq->sm, SCI_REQ_COMPLETED); + return SCI_SUCCESS; case SCI_REQ_COMPLETED: default: dev_warn(&ireq->owning_controller->pdev->dev, @@ -2407,19 +2399,22 @@ static void isci_task_save_for_upper_layer_completion( } } -static void isci_process_stp_response(struct sas_task *task, struct dev_to_host_fis *fis) +static void isci_request_process_stp_response(struct sas_task *task, + void *response_buffer) { + struct dev_to_host_fis *d2h_reg_fis = response_buffer; struct task_status_struct *ts = &task->task_status; struct ata_task_resp *resp = (void *)&ts->buf[0]; - resp->frame_len = sizeof(*fis); - memcpy(resp->ending_fis, fis, sizeof(*fis)); + resp->frame_len = le16_to_cpu(*(__le16 *)(response_buffer + 6)); + memcpy(&resp->ending_fis[0], response_buffer + 16, 24); ts->buf_valid_size = sizeof(*resp); - /* If the device fault bit is set in the status register, then + /** + * If the device fault bit is set in the status register, then * set the sense data and return. */ - if (fis->status & ATA_DF) + if (d2h_reg_fis->status & ATA_DF) ts->stat = SAS_PROTO_RESPONSE; else ts->stat = SAM_STAT_GOOD; @@ -2433,6 +2428,7 @@ static void isci_request_io_request_complete(struct isci_host *ihost, { struct sas_task *task = isci_request_access_task(request); struct ssp_response_iu *resp_iu; + void *resp_buf; unsigned long task_flags; struct isci_remote_device *idev = isci_lookup_device(task->dev); enum service_response response = SAS_TASK_UNDELIVERED; @@ -2569,7 +2565,9 @@ static void isci_request_io_request_complete(struct isci_host *ihost, task); if (sas_protocol_ata(task->task_proto)) { - isci_process_stp_response(task, &request->stp.rsp); + resp_buf = &request->stp.rsp; + isci_request_process_stp_response(task, + resp_buf); } else if (SAS_PROTOCOL_SSP == task->task_proto) { /* crack the iu response buffer. */ diff --git a/trunk/drivers/scsi/isci/unsolicited_frame_control.c b/trunk/drivers/scsi/isci/unsolicited_frame_control.c index 16f88ab939c8..e9e1e2abacb9 100644 --- a/trunk/drivers/scsi/isci/unsolicited_frame_control.c +++ b/trunk/drivers/scsi/isci/unsolicited_frame_control.c @@ -72,7 +72,7 @@ int sci_unsolicited_frame_control_construct(struct isci_host *ihost) */ buf_len = SCU_MAX_UNSOLICITED_FRAMES * SCU_UNSOLICITED_FRAME_BUFFER_SIZE; header_len = SCU_MAX_UNSOLICITED_FRAMES * sizeof(struct scu_unsolicited_frame_header); - size = buf_len + header_len + SCU_MAX_UNSOLICITED_FRAMES * sizeof(uf_control->address_table.array[0]); + size = buf_len + header_len + SCU_MAX_UNSOLICITED_FRAMES * sizeof(dma_addr_t); /* * The Unsolicited Frame buffers are set at the start of the UF diff --git a/trunk/drivers/scsi/isci/unsolicited_frame_control.h b/trunk/drivers/scsi/isci/unsolicited_frame_control.h index 75d896686f5a..31cb9506f52d 100644 --- a/trunk/drivers/scsi/isci/unsolicited_frame_control.h +++ b/trunk/drivers/scsi/isci/unsolicited_frame_control.h @@ -214,7 +214,7 @@ struct sci_uf_address_table_array { * starting address of the UF address table. * 64-bit pointers are required by the hardware. */ - u64 *array; + dma_addr_t *array; /** * This field specifies the physical address location for the UF diff --git a/trunk/drivers/scsi/libfc/fc_exch.c b/trunk/drivers/scsi/libfc/fc_exch.c index d261e982a2fa..01ff082dc34c 100644 --- a/trunk/drivers/scsi/libfc/fc_exch.c +++ b/trunk/drivers/scsi/libfc/fc_exch.c @@ -494,9 +494,6 @@ static int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp, */ error = lport->tt.frame_send(lport, fp); - if (fh->fh_type == FC_TYPE_BLS) - return error; - /* * Update the exchange and sequence flags, * assuming all frames for the sequence have been sent. @@ -578,35 +575,42 @@ static void fc_seq_set_resp(struct fc_seq *sp, } /** - * fc_exch_abort_locked() - Abort an exchange - * @ep: The exchange to be aborted + * fc_seq_exch_abort() - Abort an exchange and sequence + * @req_sp: The sequence to be aborted * @timer_msec: The period of time to wait before aborting * - * Locking notes: Called with exch lock held - * - * Return value: 0 on success else error code + * Generally called because of a timeout or an abort from the upper layer. */ -static int fc_exch_abort_locked(struct fc_exch *ep, - unsigned int timer_msec) +static int fc_seq_exch_abort(const struct fc_seq *req_sp, + unsigned int timer_msec) { struct fc_seq *sp; + struct fc_exch *ep; struct fc_frame *fp; int error; + ep = fc_seq_exch(req_sp); + + spin_lock_bh(&ep->ex_lock); if (ep->esb_stat & (ESB_ST_COMPLETE | ESB_ST_ABNORMAL) || - ep->state & (FC_EX_DONE | FC_EX_RST_CLEANUP)) + ep->state & (FC_EX_DONE | FC_EX_RST_CLEANUP)) { + spin_unlock_bh(&ep->ex_lock); return -ENXIO; + } /* * Send the abort on a new sequence if possible. */ sp = fc_seq_start_next_locked(&ep->seq); - if (!sp) + if (!sp) { + spin_unlock_bh(&ep->ex_lock); return -ENOMEM; + } ep->esb_stat |= ESB_ST_SEQ_INIT | ESB_ST_ABNORMAL; if (timer_msec) fc_exch_timer_set_locked(ep, timer_msec); + spin_unlock_bh(&ep->ex_lock); /* * If not logged into the fabric, don't send ABTS but leave @@ -628,28 +632,6 @@ static int fc_exch_abort_locked(struct fc_exch *ep, return error; } -/** - * fc_seq_exch_abort() - Abort an exchange and sequence - * @req_sp: The sequence to be aborted - * @timer_msec: The period of time to wait before aborting - * - * Generally called because of a timeout or an abort from the upper layer. - * - * Return value: 0 on success else error code - */ -static int fc_seq_exch_abort(const struct fc_seq *req_sp, - unsigned int timer_msec) -{ - struct fc_exch *ep; - int error; - - ep = fc_seq_exch(req_sp); - spin_lock_bh(&ep->ex_lock); - error = fc_exch_abort_locked(ep, timer_msec); - spin_unlock_bh(&ep->ex_lock); - return error; -} - /** * fc_exch_timeout() - Handle exchange timer expiration * @work: The work_struct identifying the exchange that timed out @@ -1733,7 +1715,6 @@ static void fc_exch_reset(struct fc_exch *ep) int rc = 1; spin_lock_bh(&ep->ex_lock); - fc_exch_abort_locked(ep, 0); ep->state |= FC_EX_RST_CLEANUP; if (cancel_delayed_work(&ep->timeout_work)) atomic_dec(&ep->ex_refcnt); /* drop hold for timer */ @@ -1981,7 +1962,6 @@ static struct fc_seq *fc_exch_seq_send(struct fc_lport *lport, struct fc_exch *ep; struct fc_seq *sp = NULL; struct fc_frame_header *fh; - struct fc_fcp_pkt *fsp = NULL; int rc = 1; ep = fc_exch_alloc(lport, fp); @@ -2004,10 +1984,8 @@ static struct fc_seq *fc_exch_seq_send(struct fc_lport *lport, fc_exch_setup_hdr(ep, fp, ep->f_ctl); sp->cnt++; - if (ep->xid <= lport->lro_xid && fh->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD) { - fsp = fr_fsp(fp); + if (ep->xid <= lport->lro_xid && fh->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD) fc_fcp_ddp_setup(fr_fsp(fp), ep->xid); - } if (unlikely(lport->tt.frame_send(lport, fp))) goto err; @@ -2021,8 +1999,7 @@ static struct fc_seq *fc_exch_seq_send(struct fc_lport *lport, spin_unlock_bh(&ep->ex_lock); return sp; err: - if (fsp) - fc_fcp_ddp_done(fsp); + fc_fcp_ddp_done(fr_fsp(fp)); rc = fc_exch_done_locked(ep); spin_unlock_bh(&ep->ex_lock); if (!rc) diff --git a/trunk/drivers/scsi/libfc/fc_fcp.c b/trunk/drivers/scsi/libfc/fc_fcp.c index 4c41ee816f0b..afb63c843144 100644 --- a/trunk/drivers/scsi/libfc/fc_fcp.c +++ b/trunk/drivers/scsi/libfc/fc_fcp.c @@ -2019,11 +2019,6 @@ int fc_eh_abort(struct scsi_cmnd *sc_cmd) struct fc_fcp_internal *si; int rc = FAILED; unsigned long flags; - int rval; - - rval = fc_block_scsi_eh(sc_cmd); - if (rval) - return rval; lport = shost_priv(sc_cmd->device->host); if (lport->state != LPORT_ST_READY) @@ -2073,9 +2068,9 @@ int fc_eh_device_reset(struct scsi_cmnd *sc_cmd) int rc = FAILED; int rval; - rval = fc_block_scsi_eh(sc_cmd); + rval = fc_remote_port_chkready(rport); if (rval) - return rval; + goto out; lport = shost_priv(sc_cmd->device->host); @@ -2121,8 +2116,6 @@ int fc_eh_host_reset(struct scsi_cmnd *sc_cmd) FC_SCSI_DBG(lport, "Resetting host\n"); - fc_block_scsi_eh(sc_cmd); - lport->tt.lport_reset(lport); wait_tmo = jiffies + FC_HOST_RESET_TIMEOUT; while (!fc_fcp_lport_queue_ready(lport) && time_before(jiffies, diff --git a/trunk/drivers/scsi/libfc/fc_lport.c b/trunk/drivers/scsi/libfc/fc_lport.c index 628f347404f9..e55ed9cf23fb 100644 --- a/trunk/drivers/scsi/libfc/fc_lport.c +++ b/trunk/drivers/scsi/libfc/fc_lport.c @@ -88,7 +88,6 @@ */ #include -#include #include #include @@ -1030,16 +1029,8 @@ static void fc_lport_enter_reset(struct fc_lport *lport) FCH_EVT_LIPRESET, 0); fc_vports_linkchange(lport); fc_lport_reset_locked(lport); - if (lport->link_up) { - /* - * Wait upto resource allocation time out before - * doing re-login since incomplete FIP exchanged - * from last session may collide with exchanges - * in new session. - */ - msleep(lport->r_a_tov); + if (lport->link_up) fc_lport_enter_flogi(lport); - } } /** diff --git a/trunk/drivers/scsi/qla2xxx/qla_attr.c b/trunk/drivers/scsi/qla2xxx/qla_attr.c index a31e05f3bfd4..7836eb01c7fc 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_attr.c +++ b/trunk/drivers/scsi/qla2xxx/qla_attr.c @@ -1786,16 +1786,13 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable) fc_vport_set_state(fc_vport, FC_VPORT_LINKDOWN); } - if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) { + if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && ql2xenabledif) { if (ha->fw_attributes & BIT_4) { - int prot = 0; vha->flags.difdix_supported = 1; ql_dbg(ql_dbg_user, vha, 0x7082, "Registered for DIF/DIX type 1 and 3 protection.\n"); - if (ql2xenabledif == 1) - prot = SHOST_DIX_TYPE0_PROTECTION; scsi_host_set_prot(vha->host, - prot | SHOST_DIF_TYPE1_PROTECTION + SHOST_DIF_TYPE1_PROTECTION | SHOST_DIF_TYPE2_PROTECTION | SHOST_DIF_TYPE3_PROTECTION | SHOST_DIX_TYPE1_PROTECTION diff --git a/trunk/drivers/scsi/qla2xxx/qla_dbg.c b/trunk/drivers/scsi/qla2xxx/qla_dbg.c index d79cd8a5f831..2155071f3100 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_dbg.c +++ b/trunk/drivers/scsi/qla2xxx/qla_dbg.c @@ -8,24 +8,24 @@ /* * Table for showing the current message id in use for particular level * Change this table for addition of log/debug messages. - * ---------------------------------------------------------------------- - * | Level | Last Value Used | Holes | - * ---------------------------------------------------------------------- - * | Module Init and Probe | 0x0116 | | - * | Mailbox commands | 0x1126 | | - * | Device Discovery | 0x2083 | | - * | Queue Command and IO tracing | 0x302e | 0x3008 | - * | DPC Thread | 0x401c | | - * | Async Events | 0x5059 | | - * | Timer Routines | 0x600d | | - * | User Space Interactions | 0x709d | | - * | Task Management | 0x8041 | | - * | AER/EEH | 0x900f | | - * | Virtual Port | 0xa007 | | - * | ISP82XX Specific | 0xb04f | | - * | MultiQ | 0xc00b | | - * | Misc | 0xd00b | | - * ---------------------------------------------------------------------- + * ----------------------------------------------------- + * | Level | Last Value Used | + * ----------------------------------------------------- + * | Module Init and Probe | 0x0116 | + * | Mailbox commands | 0x111e | + * | Device Discovery | 0x2083 | + * | Queue Command and IO tracing | 0x302e | + * | DPC Thread | 0x401c | + * | Async Events | 0x5059 | + * | Timer Routines | 0x600d | + * | User Space Interactions | 0x709c | + * | Task Management | 0x8043 | + * | AER/EEH | 0x900f | + * | Virtual Port | 0xa007 | + * | ISP82XX Specific | 0xb027 | + * | MultiQ | 0xc00b | + * | Misc | 0xd00b | + * ----------------------------------------------------- */ #include "qla_def.h" diff --git a/trunk/drivers/scsi/qla2xxx/qla_def.h b/trunk/drivers/scsi/qla2xxx/qla_def.h index a03eaf40f377..cc5a79259d33 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_def.h +++ b/trunk/drivers/scsi/qla2xxx/qla_def.h @@ -2529,7 +2529,6 @@ struct qla_hw_data { #define DT_ISP8021 BIT_14 #define DT_ISP_LAST (DT_ISP8021 << 1) -#define DT_T10_PI BIT_25 #define DT_IIDMA BIT_26 #define DT_FWI2 BIT_27 #define DT_ZIO_SUPPORTED BIT_28 @@ -2573,7 +2572,6 @@ struct qla_hw_data { #define IS_NOCACHE_VPD_TYPE(ha) (IS_QLA81XX(ha)) #define IS_ALOGIO_CAPABLE(ha) (IS_QLA23XX(ha) || IS_FWI2_CAPABLE(ha)) -#define IS_T10_PI_CAPABLE(ha) ((ha)->device_type & DT_T10_PI) #define IS_IIDMA_CAPABLE(ha) ((ha)->device_type & DT_IIDMA) #define IS_FWI2_CAPABLE(ha) ((ha)->device_type & DT_FWI2) #define IS_ZIO_SUPPORTED(ha) ((ha)->device_type & DT_ZIO_SUPPORTED) diff --git a/trunk/drivers/scsi/qla2xxx/qla_fw.h b/trunk/drivers/scsi/qla2xxx/qla_fw.h index aa69486dc064..691783abfb69 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_fw.h +++ b/trunk/drivers/scsi/qla2xxx/qla_fw.h @@ -537,11 +537,6 @@ struct sts_entry_24xx { /* * If DIF Error is set in comp_status, these additional fields are * defined: - * - * !!! NOTE: Firmware sends expected/actual DIF data in big endian - * format; but all of the "data" field gets swab32-d in the beginning - * of qla2x00_status_entry(). - * * &data[10] : uint8_t report_runt_bg[2]; - computed guard * &data[12] : uint8_t actual_dif[8]; - DIF Data received * &data[20] : uint8_t expected_dif[8]; - DIF Data computed diff --git a/trunk/drivers/scsi/qla2xxx/qla_init.c b/trunk/drivers/scsi/qla2xxx/qla_init.c index 37da04d3db26..def694271bf7 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_init.c +++ b/trunk/drivers/scsi/qla2xxx/qla_init.c @@ -3838,12 +3838,15 @@ qla2x00_loop_resync(scsi_qla_host_t *vha) req = vha->req; rsp = req->rsp; + atomic_set(&vha->loop_state, LOOP_UPDATE); clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags); if (vha->flags.online) { if (!(rval = qla2x00_fw_ready(vha))) { /* Wait at most MAX_TARGET RSCNs for a stable link. */ wait_time = 256; do { + atomic_set(&vha->loop_state, LOOP_UPDATE); + /* Issue a marker after FW becomes ready. */ qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL); diff --git a/trunk/drivers/scsi/qla2xxx/qla_inline.h b/trunk/drivers/scsi/qla2xxx/qla_inline.h index 9902834e0b74..d2e904bc21c0 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_inline.h +++ b/trunk/drivers/scsi/qla2xxx/qla_inline.h @@ -102,32 +102,3 @@ qla2x00_set_fcport_state(fc_port_t *fcport, int state) fcport->d_id.b.al_pa); } } - -static inline int -qla2x00_hba_err_chk_enabled(srb_t *sp) -{ - /* - * Uncomment when corresponding SCSI changes are done. - * - if (!sp->cmd->prot_chk) - return 0; - * - */ - - switch (scsi_get_prot_op(sp->cmd)) { - case SCSI_PROT_READ_STRIP: - case SCSI_PROT_WRITE_INSERT: - if (ql2xenablehba_err_chk >= 1) - return 1; - break; - case SCSI_PROT_READ_PASS: - case SCSI_PROT_WRITE_PASS: - if (ql2xenablehba_err_chk >= 2) - return 1; - break; - case SCSI_PROT_READ_INSERT: - case SCSI_PROT_WRITE_STRIP: - return 1; - } - return 0; -} diff --git a/trunk/drivers/scsi/qla2xxx/qla_iocb.c b/trunk/drivers/scsi/qla2xxx/qla_iocb.c index dbec89622a0f..49d6906af886 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_iocb.c +++ b/trunk/drivers/scsi/qla2xxx/qla_iocb.c @@ -709,28 +709,20 @@ struct fw_dif_context { * */ static inline void -qla24xx_set_t10dif_tags(srb_t *sp, struct fw_dif_context *pkt, +qla24xx_set_t10dif_tags(struct scsi_cmnd *cmd, struct fw_dif_context *pkt, unsigned int protcnt) { - struct scsi_cmnd *cmd = sp->cmd; + struct sd_dif_tuple *spt; scsi_qla_host_t *vha = shost_priv(cmd->device->host); + unsigned char op = scsi_get_prot_op(cmd); switch (scsi_get_prot_type(cmd)) { + /* For TYPE 0 protection: no checking */ case SCSI_PROT_DIF_TYPE0: - /* - * No check for ql2xenablehba_err_chk, as it would be an - * I/O error if hba tag generation is not done. - */ - pkt->ref_tag = cpu_to_le32((uint32_t) - (0xffffffff & scsi_get_lba(cmd))); - - if (!qla2x00_hba_err_chk_enabled(sp)) - break; - - pkt->ref_tag_mask[0] = 0xff; - pkt->ref_tag_mask[1] = 0xff; - pkt->ref_tag_mask[2] = 0xff; - pkt->ref_tag_mask[3] = 0xff; + pkt->ref_tag_mask[0] = 0x00; + pkt->ref_tag_mask[1] = 0x00; + pkt->ref_tag_mask[2] = 0x00; + pkt->ref_tag_mask[3] = 0x00; break; /* @@ -738,16 +730,20 @@ qla24xx_set_t10dif_tags(srb_t *sp, struct fw_dif_context *pkt, * match LBA in CDB + N */ case SCSI_PROT_DIF_TYPE2: - pkt->app_tag = __constant_cpu_to_le16(0); - pkt->app_tag_mask[0] = 0x0; - pkt->app_tag_mask[1] = 0x0; + if (!ql2xenablehba_err_chk) + break; + + if (scsi_prot_sg_count(cmd)) { + spt = page_address(sg_page(scsi_prot_sglist(cmd))) + + scsi_prot_sglist(cmd)[0].offset; + pkt->app_tag = swab32(spt->app_tag); + pkt->app_tag_mask[0] = 0xff; + pkt->app_tag_mask[1] = 0xff; + } pkt->ref_tag = cpu_to_le32((uint32_t) (0xffffffff & scsi_get_lba(cmd))); - if (!qla2x00_hba_err_chk_enabled(sp)) - break; - /* enable ALL bytes of the ref tag */ pkt->ref_tag_mask[0] = 0xff; pkt->ref_tag_mask[1] = 0xff; @@ -767,15 +763,26 @@ qla24xx_set_t10dif_tags(srb_t *sp, struct fw_dif_context *pkt, * 16 bit app tag. */ case SCSI_PROT_DIF_TYPE1: - pkt->ref_tag = cpu_to_le32((uint32_t) - (0xffffffff & scsi_get_lba(cmd))); - pkt->app_tag = __constant_cpu_to_le16(0); - pkt->app_tag_mask[0] = 0x0; - pkt->app_tag_mask[1] = 0x0; - - if (!qla2x00_hba_err_chk_enabled(sp)) + if (!ql2xenablehba_err_chk) break; + if (protcnt && (op == SCSI_PROT_WRITE_STRIP || + op == SCSI_PROT_WRITE_PASS)) { + spt = page_address(sg_page(scsi_prot_sglist(cmd))) + + scsi_prot_sglist(cmd)[0].offset; + ql_dbg(ql_dbg_io, vha, 0x3008, + "LBA from user %p, lba = 0x%x for cmd=%p.\n", + spt, (int)spt->ref_tag, cmd); + pkt->ref_tag = swab32(spt->ref_tag); + pkt->app_tag_mask[0] = 0x0; + pkt->app_tag_mask[1] = 0x0; + } else { + pkt->ref_tag = cpu_to_le32((uint32_t) + (0xffffffff & scsi_get_lba(cmd))); + pkt->app_tag = __constant_cpu_to_le16(0); + pkt->app_tag_mask[0] = 0x0; + pkt->app_tag_mask[1] = 0x0; + } /* enable ALL bytes of the ref tag */ pkt->ref_tag_mask[0] = 0xff; pkt->ref_tag_mask[1] = 0xff; @@ -791,161 +798,7 @@ qla24xx_set_t10dif_tags(srb_t *sp, struct fw_dif_context *pkt, scsi_get_prot_type(cmd), cmd); } -struct qla2_sgx { - dma_addr_t dma_addr; /* OUT */ - uint32_t dma_len; /* OUT */ - - uint32_t tot_bytes; /* IN */ - struct scatterlist *cur_sg; /* IN */ - - /* for book keeping, bzero on initial invocation */ - uint32_t bytes_consumed; - uint32_t num_bytes; - uint32_t tot_partial; - - /* for debugging */ - uint32_t num_sg; - srb_t *sp; -}; -static int -qla24xx_get_one_block_sg(uint32_t blk_sz, struct qla2_sgx *sgx, - uint32_t *partial) -{ - struct scatterlist *sg; - uint32_t cumulative_partial, sg_len; - dma_addr_t sg_dma_addr; - - if (sgx->num_bytes == sgx->tot_bytes) - return 0; - - sg = sgx->cur_sg; - cumulative_partial = sgx->tot_partial; - - sg_dma_addr = sg_dma_address(sg); - sg_len = sg_dma_len(sg); - - sgx->dma_addr = sg_dma_addr + sgx->bytes_consumed; - - if ((cumulative_partial + (sg_len - sgx->bytes_consumed)) >= blk_sz) { - sgx->dma_len = (blk_sz - cumulative_partial); - sgx->tot_partial = 0; - sgx->num_bytes += blk_sz; - *partial = 0; - } else { - sgx->dma_len = sg_len - sgx->bytes_consumed; - sgx->tot_partial += sgx->dma_len; - *partial = 1; - } - - sgx->bytes_consumed += sgx->dma_len; - - if (sg_len == sgx->bytes_consumed) { - sg = sg_next(sg); - sgx->num_sg++; - sgx->cur_sg = sg; - sgx->bytes_consumed = 0; - } - - return 1; -} - -static int -qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp, - uint32_t *dsd, uint16_t tot_dsds) -{ - void *next_dsd; - uint8_t avail_dsds = 0; - uint32_t dsd_list_len; - struct dsd_dma *dsd_ptr; - struct scatterlist *sg_prot; - uint32_t *cur_dsd = dsd; - uint16_t used_dsds = tot_dsds; - - uint32_t prot_int; - uint32_t partial; - struct qla2_sgx sgx; - dma_addr_t sle_dma; - uint32_t sle_dma_len, tot_prot_dma_len = 0; - struct scsi_cmnd *cmd = sp->cmd; - - prot_int = cmd->device->sector_size; - - memset(&sgx, 0, sizeof(struct qla2_sgx)); - sgx.tot_bytes = scsi_bufflen(sp->cmd); - sgx.cur_sg = scsi_sglist(sp->cmd); - sgx.sp = sp; - - sg_prot = scsi_prot_sglist(sp->cmd); - - while (qla24xx_get_one_block_sg(prot_int, &sgx, &partial)) { - - sle_dma = sgx.dma_addr; - sle_dma_len = sgx.dma_len; -alloc_and_fill: - /* Allocate additional continuation packets? */ - if (avail_dsds == 0) { - avail_dsds = (used_dsds > QLA_DSDS_PER_IOCB) ? - QLA_DSDS_PER_IOCB : used_dsds; - dsd_list_len = (avail_dsds + 1) * 12; - used_dsds -= avail_dsds; - - /* allocate tracking DS */ - dsd_ptr = kzalloc(sizeof(struct dsd_dma), GFP_ATOMIC); - if (!dsd_ptr) - return 1; - - /* allocate new list */ - dsd_ptr->dsd_addr = next_dsd = - dma_pool_alloc(ha->dl_dma_pool, GFP_ATOMIC, - &dsd_ptr->dsd_list_dma); - - if (!next_dsd) { - /* - * Need to cleanup only this dsd_ptr, rest - * will be done by sp_free_dma() - */ - kfree(dsd_ptr); - return 1; - } - - list_add_tail(&dsd_ptr->list, - &((struct crc_context *)sp->ctx)->dsd_list); - - sp->flags |= SRB_CRC_CTX_DSD_VALID; - - /* add new list to cmd iocb or last list */ - *cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma)); - *cur_dsd++ = cpu_to_le32(MSD(dsd_ptr->dsd_list_dma)); - *cur_dsd++ = dsd_list_len; - cur_dsd = (uint32_t *)next_dsd; - } - *cur_dsd++ = cpu_to_le32(LSD(sle_dma)); - *cur_dsd++ = cpu_to_le32(MSD(sle_dma)); - *cur_dsd++ = cpu_to_le32(sle_dma_len); - avail_dsds--; - - if (partial == 0) { - /* Got a full protection interval */ - sle_dma = sg_dma_address(sg_prot) + tot_prot_dma_len; - sle_dma_len = 8; - - tot_prot_dma_len += sle_dma_len; - if (tot_prot_dma_len == sg_dma_len(sg_prot)) { - tot_prot_dma_len = 0; - sg_prot = sg_next(sg_prot); - } - - partial = 1; /* So as to not re-enter this block */ - goto alloc_and_fill; - } - } - /* Null termination */ - *cur_dsd++ = 0; - *cur_dsd++ = 0; - *cur_dsd++ = 0; - return 0; -} static int qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd, uint16_t tot_dsds) @@ -1128,7 +981,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, struct scsi_cmnd *cmd; struct scatterlist *cur_seg; int sgc; - uint32_t total_bytes = 0; + uint32_t total_bytes; uint32_t data_bytes; uint32_t dif_bytes; uint8_t bundling = 1; @@ -1170,10 +1023,8 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, __constant_cpu_to_le16(CF_READ_DATA); } - if ((scsi_get_prot_op(sp->cmd) == SCSI_PROT_READ_INSERT) || - (scsi_get_prot_op(sp->cmd) == SCSI_PROT_WRITE_STRIP) || - (scsi_get_prot_op(sp->cmd) == SCSI_PROT_READ_STRIP) || - (scsi_get_prot_op(sp->cmd) == SCSI_PROT_WRITE_INSERT)) + tot_prot_dsds = scsi_prot_sg_count(cmd); + if (!tot_prot_dsds) bundling = 0; /* Allocate CRC context from global pool */ @@ -1196,7 +1047,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, INIT_LIST_HEAD(&crc_ctx_pkt->dsd_list); - qla24xx_set_t10dif_tags(sp, (struct fw_dif_context *) + qla24xx_set_t10dif_tags(cmd, (struct fw_dif_context *) &crc_ctx_pkt->ref_tag, tot_prot_dsds); cmd_pkt->crc_context_address[0] = cpu_to_le32(LSD(crc_ctx_dma)); @@ -1225,6 +1076,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, fcp_cmnd->additional_cdb_len |= 2; int_to_scsilun(sp->cmd->device->lun, &fcp_cmnd->lun); + host_to_fcp_swap((uint8_t *)&fcp_cmnd->lun, sizeof(fcp_cmnd->lun)); memcpy(fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len); cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(fcp_cmnd_len); cmd_pkt->fcp_cmnd_dseg_address[0] = cpu_to_le32( @@ -1255,28 +1107,15 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, cmd_pkt->fcp_rsp_dseg_len = 0; /* Let response come in status iocb */ /* Compute dif len and adjust data len to incude protection */ + total_bytes = data_bytes; dif_bytes = 0; blk_size = cmd->device->sector_size; - dif_bytes = (data_bytes / blk_size) * 8; - - switch (scsi_get_prot_op(sp->cmd)) { - case SCSI_PROT_READ_INSERT: - case SCSI_PROT_WRITE_STRIP: - total_bytes = data_bytes; - data_bytes += dif_bytes; - break; - - case SCSI_PROT_READ_STRIP: - case SCSI_PROT_WRITE_INSERT: - case SCSI_PROT_READ_PASS: - case SCSI_PROT_WRITE_PASS: - total_bytes = data_bytes + dif_bytes; - break; - default: - BUG(); + if (scsi_get_prot_op(cmd) != SCSI_PROT_NORMAL) { + dif_bytes = (data_bytes / blk_size) * 8; + total_bytes += dif_bytes; } - if (!qla2x00_hba_err_chk_enabled(sp)) + if (!ql2xenablehba_err_chk) fw_prot_opts |= 0x10; /* Disable Guard tag checking */ if (!bundling) { @@ -1312,12 +1151,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, cmd_pkt->control_flags |= __constant_cpu_to_le16(CF_DATA_SEG_DESCR_ENABLE); - - if (!bundling && tot_prot_dsds) { - if (qla24xx_walk_and_build_sglist_no_difb(ha, sp, - cur_dsd, tot_dsds)) - goto crc_queuing_error; - } else if (qla24xx_walk_and_build_sglist(ha, sp, cur_dsd, + if (qla24xx_walk_and_build_sglist(ha, sp, cur_dsd, (tot_dsds - tot_prot_dsds))) goto crc_queuing_error; @@ -1580,22 +1414,6 @@ qla24xx_dif_start_scsi(srb_t *sp) goto queuing_error; else sp->flags |= SRB_DMA_VALID; - - if ((scsi_get_prot_op(cmd) == SCSI_PROT_READ_INSERT) || - (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_STRIP)) { - struct qla2_sgx sgx; - uint32_t partial; - - memset(&sgx, 0, sizeof(struct qla2_sgx)); - sgx.tot_bytes = scsi_bufflen(cmd); - sgx.cur_sg = scsi_sglist(cmd); - sgx.sp = sp; - - nseg = 0; - while (qla24xx_get_one_block_sg( - cmd->device->sector_size, &sgx, &partial)) - nseg++; - } } else nseg = 0; @@ -1610,11 +1428,6 @@ qla24xx_dif_start_scsi(srb_t *sp) goto queuing_error; else sp->flags |= SRB_CRC_PROT_DMA_VALID; - - if ((scsi_get_prot_op(cmd) == SCSI_PROT_READ_INSERT) || - (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_STRIP)) { - nseg = scsi_bufflen(cmd) / cmd->device->sector_size; - } } else { nseg = 0; } @@ -1641,7 +1454,6 @@ qla24xx_dif_start_scsi(srb_t *sp) /* Build header part of command packet (excluding the OPCODE). */ req->current_outstanding_cmd = handle; req->outstanding_cmds[handle] = sp; - sp->handle = handle; sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle; req->cnt -= req_cnt; diff --git a/trunk/drivers/scsi/qla2xxx/qla_isr.c b/trunk/drivers/scsi/qla2xxx/qla_isr.c index 646fc5263d50..b16b7725dee0 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_isr.c +++ b/trunk/drivers/scsi/qla2xxx/qla_isr.c @@ -719,6 +719,7 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb) vha->flags.rscn_queue_overflow = 1; } + atomic_set(&vha->loop_state, LOOP_UPDATE); atomic_set(&vha->loop_down_timer, 0); vha->flags.management_server_logged_in = 0; @@ -1434,27 +1435,25 @@ struct scsi_dif_tuple { * ASC/ASCQ fields in the sense buffer with ILLEGAL_REQUEST * to indicate to the kernel that the HBA detected error. */ -static inline int +static inline void qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24) { struct scsi_qla_host *vha = sp->fcport->vha; struct scsi_cmnd *cmd = sp->cmd; - uint8_t *ap = &sts24->data[12]; - uint8_t *ep = &sts24->data[20]; + struct scsi_dif_tuple *ep = + (struct scsi_dif_tuple *)&sts24->data[20]; + struct scsi_dif_tuple *ap = + (struct scsi_dif_tuple *)&sts24->data[12]; uint32_t e_ref_tag, a_ref_tag; uint16_t e_app_tag, a_app_tag; uint16_t e_guard, a_guard; - /* - * swab32 of the "data" field in the beginning of qla2x00_status_entry() - * would make guard field appear at offset 2 - */ - a_guard = le16_to_cpu(*(uint16_t *)(ap + 2)); - a_app_tag = le16_to_cpu(*(uint16_t *)(ap + 0)); - a_ref_tag = le32_to_cpu(*(uint32_t *)(ap + 4)); - e_guard = le16_to_cpu(*(uint16_t *)(ep + 2)); - e_app_tag = le16_to_cpu(*(uint16_t *)(ep + 0)); - e_ref_tag = le32_to_cpu(*(uint32_t *)(ep + 4)); + e_ref_tag = be32_to_cpu(ep->ref_tag); + a_ref_tag = be32_to_cpu(ap->ref_tag); + e_app_tag = be16_to_cpu(ep->app_tag); + a_app_tag = be16_to_cpu(ap->app_tag); + e_guard = be16_to_cpu(ep->guard); + a_guard = be16_to_cpu(ap->guard); ql_dbg(ql_dbg_io, vha, 0x3023, "iocb(s) %p Returned STATUS.\n", sts24); @@ -1466,63 +1465,6 @@ qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24) cmd->cmnd[0], (u64)scsi_get_lba(cmd), a_ref_tag, e_ref_tag, a_app_tag, e_app_tag, a_guard, e_guard); - /* - * Ignore sector if: - * For type 3: ref & app tag is all 'f's - * For type 0,1,2: app tag is all 'f's - */ - if ((a_app_tag == 0xffff) && - ((scsi_get_prot_type(cmd) != SCSI_PROT_DIF_TYPE3) || - (a_ref_tag == 0xffffffff))) { - uint32_t blocks_done, resid; - sector_t lba_s = scsi_get_lba(cmd); - - /* 2TB boundary case covered automatically with this */ - blocks_done = e_ref_tag - (uint32_t)lba_s + 1; - - resid = scsi_bufflen(cmd) - (blocks_done * - cmd->device->sector_size); - - scsi_set_resid(cmd, resid); - cmd->result = DID_OK << 16; - - /* Update protection tag */ - if (scsi_prot_sg_count(cmd)) { - uint32_t i, j = 0, k = 0, num_ent; - struct scatterlist *sg; - struct sd_dif_tuple *spt; - - /* Patch the corresponding protection tags */ - scsi_for_each_prot_sg(cmd, sg, - scsi_prot_sg_count(cmd), i) { - num_ent = sg_dma_len(sg) / 8; - if (k + num_ent < blocks_done) { - k += num_ent; - continue; - } - j = blocks_done - k - 1; - k = blocks_done; - break; - } - - if (k != blocks_done) { - qla_printk(KERN_WARNING, sp->fcport->vha->hw, - "unexpected tag values tag:lba=%x:%lx)\n", - e_ref_tag, lba_s); - return 1; - } - - spt = page_address(sg_page(sg)) + sg->offset; - spt += j; - - spt->app_tag = 0xffff; - if (scsi_get_prot_type(cmd) == SCSI_PROT_DIF_TYPE3) - spt->ref_tag = 0xffffffff; - } - - return 0; - } - /* check guard */ if (e_guard != a_guard) { scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, @@ -1530,30 +1472,28 @@ qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24) set_driver_byte(cmd, DRIVER_SENSE); set_host_byte(cmd, DID_ABORT); cmd->result |= SAM_STAT_CHECK_CONDITION << 1; - return 1; + return; } - /* check ref tag */ - if (e_ref_tag != a_ref_tag) { + /* check appl tag */ + if (e_app_tag != a_app_tag) { scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, - 0x10, 0x3); + 0x10, 0x2); set_driver_byte(cmd, DRIVER_SENSE); set_host_byte(cmd, DID_ABORT); cmd->result |= SAM_STAT_CHECK_CONDITION << 1; - return 1; + return; } - /* check appl tag */ - if (e_app_tag != a_app_tag) { + /* check ref tag */ + if (e_ref_tag != a_ref_tag) { scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, - 0x10, 0x2); + 0x10, 0x3); set_driver_byte(cmd, DRIVER_SENSE); set_host_byte(cmd, DID_ABORT); cmd->result |= SAM_STAT_CHECK_CONDITION << 1; - return 1; + return; } - - return 1; } /** @@ -1827,7 +1767,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) break; case CS_DIF_ERROR: - logit = qla2x00_handle_dif_error(sp, sts24); + qla2x00_handle_dif_error(sp, sts24); break; default: cp->result = DID_ERROR << 16; @@ -2528,10 +2468,11 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp) goto skip_msi; } - if (IS_QLA2432(ha) && (ha->pdev->revision < QLA_MSIX_CHIP_REV_24XX)) { + if (IS_QLA2432(ha) && (ha->pdev->revision < QLA_MSIX_CHIP_REV_24XX || + !QLA_MSIX_FW_MODE_1(ha->fw_attributes))) { ql_log(ql_log_warn, vha, 0x0035, "MSI-X; Unsupported ISP2432 (0x%X, 0x%X).\n", - ha->pdev->revision, QLA_MSIX_CHIP_REV_24XX); + ha->pdev->revision, ha->fw_attributes); goto skip_msix; } diff --git a/trunk/drivers/scsi/qla2xxx/qla_mid.c b/trunk/drivers/scsi/qla2xxx/qla_mid.c index f488cc69fc79..c706ed370000 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_mid.c +++ b/trunk/drivers/scsi/qla2xxx/qla_mid.c @@ -472,7 +472,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport) host->can_queue = base_vha->req->length + 128; host->this_id = 255; host->cmd_per_lun = 3; - if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) + if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && ql2xenabledif) host->max_cmd_len = 32; else host->max_cmd_len = MAX_CMDSZ; diff --git a/trunk/drivers/scsi/qla2xxx/qla_nx.c b/trunk/drivers/scsi/qla2xxx/qla_nx.c index 049807cda419..5cbf33a50b14 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_nx.c +++ b/trunk/drivers/scsi/qla2xxx/qla_nx.c @@ -2208,7 +2208,6 @@ qla82xx_msix_rsp_q(int irq, void *dev_id) struct qla_hw_data *ha; struct rsp_que *rsp; struct device_reg_82xx __iomem *reg; - unsigned long flags; rsp = (struct rsp_que *) dev_id; if (!rsp) { @@ -2219,11 +2218,11 @@ qla82xx_msix_rsp_q(int irq, void *dev_id) ha = rsp->hw; reg = &ha->iobase->isp82; - spin_lock_irqsave(&ha->hardware_lock, flags); + spin_lock_irq(&ha->hardware_lock); vha = pci_get_drvdata(ha->pdev); qla24xx_process_response_queue(vha, rsp); WRT_REG_DWORD(®->host_int, 0); - spin_unlock_irqrestore(&ha->hardware_lock, flags); + spin_unlock_irq(&ha->hardware_lock); return IRQ_HANDLED; } @@ -2839,16 +2838,6 @@ qla82xx_start_scsi(srb_t *sp) int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun)); - /* build FCP_CMND IU */ - memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd)); - int_to_scsilun(sp->cmd->device->lun, &ctx->fcp_cmnd->lun); - ctx->fcp_cmnd->additional_cdb_len = additional_cdb_len; - - if (cmd->sc_data_direction == DMA_TO_DEVICE) - ctx->fcp_cmnd->additional_cdb_len |= 1; - else if (cmd->sc_data_direction == DMA_FROM_DEVICE) - ctx->fcp_cmnd->additional_cdb_len |= 2; - /* * Update tagged queuing modifier -- default is TSK_SIMPLE (0). */ @@ -2865,6 +2854,16 @@ qla82xx_start_scsi(srb_t *sp) } } + /* build FCP_CMND IU */ + memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd)); + int_to_scsilun(sp->cmd->device->lun, &ctx->fcp_cmnd->lun); + ctx->fcp_cmnd->additional_cdb_len = additional_cdb_len; + + if (cmd->sc_data_direction == DMA_TO_DEVICE) + ctx->fcp_cmnd->additional_cdb_len |= 1; + else if (cmd->sc_data_direction == DMA_FROM_DEVICE) + ctx->fcp_cmnd->additional_cdb_len |= 2; + memcpy(ctx->fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len); fcp_dl = (uint32_t *)(ctx->fcp_cmnd->cdb + 16 + diff --git a/trunk/drivers/scsi/qla2xxx/qla_os.c b/trunk/drivers/scsi/qla2xxx/qla_os.c index 4cace3f20c04..e02df276804e 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_os.c +++ b/trunk/drivers/scsi/qla2xxx/qla_os.c @@ -106,21 +106,17 @@ MODULE_PARM_DESC(ql2xmaxqdepth, "Maximum queue depth to report for target devices."); /* Do not change the value of this after module load */ -int ql2xenabledif = 0; +int ql2xenabledif = 1; module_param(ql2xenabledif, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(ql2xenabledif, " Enable T10-CRC-DIF " - " Default is 0 - No DIF Support. 1 - Enable it" - ", 2 - Enable DIF for all types, except Type 0."); + " Default is 0 - No DIF Support. 1 - Enable it"); -int ql2xenablehba_err_chk = 2; +int ql2xenablehba_err_chk; module_param(ql2xenablehba_err_chk, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(ql2xenablehba_err_chk, - " Enable T10-CRC-DIF Error isolation by HBA:\n" - " Default is 1.\n" - " 0 -- Error isolation disabled\n" - " 1 -- Error isolation enabled only for DIX Type 0\n" - " 2 -- Error isolation enabled for all Types\n"); + " Enable T10-CRC-DIF Error isolation by HBA" + " Default is 0 - Error isolation disabled, 1 - Enable it"); int ql2xiidmaenable=1; module_param(ql2xiidmaenable, int, S_IRUGO); @@ -913,14 +909,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) "Abort command mbx success.\n"); wait = 1; } - - spin_lock_irqsave(&ha->hardware_lock, flags); qla2x00_sp_compl(ha, sp); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - /* Did the command return during mailbox execution? */ - if (ret == FAILED && !CMD_SP(cmd)) - ret = SUCCESS; /* Wait for the command to be returned. */ if (wait) { @@ -2262,7 +2251,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) host->this_id = 255; host->cmd_per_lun = 3; host->unique_id = host->host_no; - if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) + if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && ql2xenabledif) host->max_cmd_len = 32; else host->max_cmd_len = MAX_CMDSZ; @@ -2389,16 +2378,13 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) "Detected hba at address=%p.\n", ha); - if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) { + if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && ql2xenabledif) { if (ha->fw_attributes & BIT_4) { - int prot = 0; base_vha->flags.difdix_supported = 1; ql_dbg(ql_dbg_init, base_vha, 0x00f1, "Registering for DIF/DIX type 1 and 3 protection.\n"); - if (ql2xenabledif == 1) - prot = SHOST_DIX_TYPE0_PROTECTION; scsi_host_set_prot(host, - prot | SHOST_DIF_TYPE1_PROTECTION + SHOST_DIF_TYPE1_PROTECTION | SHOST_DIF_TYPE2_PROTECTION | SHOST_DIF_TYPE3_PROTECTION | SHOST_DIX_TYPE1_PROTECTION diff --git a/trunk/drivers/scsi/qla2xxx/qla_version.h b/trunk/drivers/scsi/qla2xxx/qla_version.h index 13b6357c1fa2..062c97bf62f5 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_version.h +++ b/trunk/drivers/scsi/qla2xxx/qla_version.h @@ -7,7 +7,7 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.03.07.07-k" +#define QLA2XXX_VERSION "8.03.07.03-k" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 3 diff --git a/trunk/drivers/tty/serial/crisv10.c b/trunk/drivers/tty/serial/crisv10.c index 58be715913cd..225123b37f19 100644 --- a/trunk/drivers/tty/serial/crisv10.c +++ b/trunk/drivers/tty/serial/crisv10.c @@ -4450,7 +4450,7 @@ static int __init rs_init(void) #if defined(CONFIG_ETRAX_RS485) #if defined(CONFIG_ETRAX_RS485_ON_PA) - if (cris_io_interface_allocate_pins(if_serial_0, 'a', rs485_pa_bit, + if (cris_io_interface_allocate_pins(if_ser0, 'a', rs485_pa_bit, rs485_pa_bit)) { printk(KERN_CRIT "ETRAX100LX serial: Could not allocate " "RS485 pin\n"); @@ -4459,7 +4459,7 @@ static int __init rs_init(void) } #endif #if defined(CONFIG_ETRAX_RS485_ON_PORT_G) - if (cris_io_interface_allocate_pins(if_serial_0, 'g', rs485_pa_bit, + if (cris_io_interface_allocate_pins(if_ser0, 'g', rs485_pa_bit, rs485_port_g_bit)) { printk(KERN_CRIT "ETRAX100LX serial: Could not allocate " "RS485 pin\n"); diff --git a/trunk/fs/hfsplus/super.c b/trunk/fs/hfsplus/super.c index d24a9b666a23..c106ca22e812 100644 --- a/trunk/fs/hfsplus/super.c +++ b/trunk/fs/hfsplus/super.c @@ -344,7 +344,6 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) struct inode *root, *inode; struct qstr str; struct nls_table *nls = NULL; - u64 last_fs_block, last_fs_page; int err; err = -EINVAL; @@ -400,13 +399,9 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) if (!sbi->rsrc_clump_blocks) sbi->rsrc_clump_blocks = 1; - err = -EFBIG; - last_fs_block = sbi->total_blocks - 1; - last_fs_page = (last_fs_block << sbi->alloc_blksz_shift) >> - PAGE_CACHE_SHIFT; - - if ((last_fs_block > (sector_t)(~0ULL) >> (sbi->alloc_blksz_shift - 9)) || - (last_fs_page > (pgoff_t)(~0ULL))) { + err = generic_check_addressable(sbi->alloc_blksz_shift, + sbi->total_blocks); + if (err) { printk(KERN_ERR "hfs: filesystem size too large.\n"); goto out_free_vhdr; } @@ -530,8 +525,8 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) out_close_ext_tree: hfs_btree_close(sbi->ext_tree); out_free_vhdr: - kfree(sbi->s_vhdr_buf); - kfree(sbi->s_backup_vhdr_buf); + kfree(sbi->s_vhdr); + kfree(sbi->s_backup_vhdr); out_unload_nls: unload_nls(sbi->nls); unload_nls(nls); diff --git a/trunk/fs/hfsplus/wrapper.c b/trunk/fs/hfsplus/wrapper.c index 7daf4b852d1c..10e515a0d452 100644 --- a/trunk/fs/hfsplus/wrapper.c +++ b/trunk/fs/hfsplus/wrapper.c @@ -272,9 +272,9 @@ int hfsplus_read_wrapper(struct super_block *sb) return 0; out_free_backup_vhdr: - kfree(sbi->s_backup_vhdr_buf); + kfree(sbi->s_backup_vhdr); out_free_vhdr: - kfree(sbi->s_vhdr_buf); + kfree(sbi->s_vhdr); out: return error; } diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index f4788365ea22..b52bc685465f 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -2616,7 +2616,6 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) if (!dir->i_op->rmdir) return -EPERM; - dget(dentry); mutex_lock(&dentry->d_inode->i_mutex); error = -EBUSY; @@ -2637,7 +2636,6 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) out: mutex_unlock(&dentry->d_inode->i_mutex); - dput(dentry); if (!error) d_delete(dentry); return error; @@ -3027,7 +3025,6 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, if (error) return error; - dget(new_dentry); if (target) mutex_lock(&target->i_mutex); @@ -3048,7 +3045,6 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, out: if (target) mutex_unlock(&target->i_mutex); - dput(new_dentry); if (!error) if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE)) d_move(old_dentry,new_dentry); diff --git a/trunk/fs/xfs/xfs_aops.c b/trunk/fs/xfs/xfs_aops.c index 8c37dde4c521..63e971e2b837 100644 --- a/trunk/fs/xfs/xfs_aops.c +++ b/trunk/fs/xfs/xfs_aops.c @@ -1300,7 +1300,6 @@ xfs_end_io_direct_write( bool is_async) { struct xfs_ioend *ioend = iocb->private; - struct inode *inode = ioend->io_inode; /* * blockdev_direct_IO can return an error even after the I/O @@ -1332,7 +1331,7 @@ xfs_end_io_direct_write( } /* XXX: probably should move into the real I/O completion handler */ - inode_dio_done(inode); + inode_dio_done(ioend->io_inode); } STATIC ssize_t diff --git a/trunk/include/linux/basic_mmio_gpio.h b/trunk/include/linux/basic_mmio_gpio.h index feb912196745..98999cf107ce 100644 --- a/trunk/include/linux/basic_mmio_gpio.h +++ b/trunk/include/linux/basic_mmio_gpio.h @@ -63,10 +63,15 @@ static inline struct bgpio_chip *to_bgpio_chip(struct gpio_chip *gc) return container_of(gc, struct bgpio_chip, gc); } -int bgpio_remove(struct bgpio_chip *bgc); -int bgpio_init(struct bgpio_chip *bgc, struct device *dev, - unsigned long sz, void __iomem *dat, void __iomem *set, - void __iomem *clr, void __iomem *dirout, void __iomem *dirin, - bool big_endian); +int __devexit bgpio_remove(struct bgpio_chip *bgc); +int __devinit bgpio_init(struct bgpio_chip *bgc, + struct device *dev, + unsigned long sz, + void __iomem *dat, + void __iomem *set, + void __iomem *clr, + void __iomem *dirout, + void __iomem *dirin, + bool big_endian); #endif /* __BASIC_MMIO_GPIO_H */ diff --git a/trunk/include/linux/memcontrol.h b/trunk/include/linux/memcontrol.h index 343bd7661f2a..3b535db00a94 100644 --- a/trunk/include/linux/memcontrol.h +++ b/trunk/include/linux/memcontrol.h @@ -39,6 +39,16 @@ extern unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan, struct mem_cgroup *mem_cont, int active, int file); +struct memcg_scanrecord { + struct mem_cgroup *mem; /* scanend memory cgroup */ + struct mem_cgroup *root; /* scan target hierarchy root */ + int context; /* scanning context (see memcontrol.c) */ + unsigned long nr_scanned[2]; /* the number of scanned pages */ + unsigned long nr_rotated[2]; /* the number of rotated pages */ + unsigned long nr_freed[2]; /* the number of freed pages */ + unsigned long elapsed; /* nsec of time elapsed while scanning */ +}; + #ifdef CONFIG_CGROUP_MEM_RES_CTLR /* * All "charge" functions with gfp_mask should use GFP_KERNEL or @@ -117,6 +127,15 @@ mem_cgroup_get_reclaim_stat_from_page(struct page *page); extern void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p); +extern unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem, + gfp_t gfp_mask, bool noswap, + struct memcg_scanrecord *rec); +extern unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *mem, + gfp_t gfp_mask, bool noswap, + struct zone *zone, + struct memcg_scanrecord *rec, + unsigned long *nr_scanned); + #ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP extern int do_swap_account; #endif diff --git a/trunk/include/linux/swap.h b/trunk/include/linux/swap.h index c71f84bb62ec..14d62490922e 100644 --- a/trunk/include/linux/swap.h +++ b/trunk/include/linux/swap.h @@ -252,12 +252,6 @@ static inline void lru_cache_add_file(struct page *page) extern unsigned long try_to_free_pages(struct zonelist *zonelist, int order, gfp_t gfp_mask, nodemask_t *mask); extern int __isolate_lru_page(struct page *page, int mode, int file); -extern unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem, - gfp_t gfp_mask, bool noswap); -extern unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *mem, - gfp_t gfp_mask, bool noswap, - struct zone *zone, - unsigned long *nr_scanned); extern unsigned long shrink_all_memory(unsigned long nr_pages); extern int vm_swappiness; extern int remove_mapping(struct address_space *mapping, struct page *page); diff --git a/trunk/kernel/workqueue.c b/trunk/kernel/workqueue.c index 1783aabc6128..25fb1b0e53fa 100644 --- a/trunk/kernel/workqueue.c +++ b/trunk/kernel/workqueue.c @@ -2412,13 +2412,8 @@ void drain_workqueue(struct workqueue_struct *wq) for_each_cwq_cpu(cpu, wq) { struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq); - bool drained; - spin_lock_irq(&cwq->gcwq->lock); - drained = !cwq->nr_active && list_empty(&cwq->delayed_works); - spin_unlock_irq(&cwq->gcwq->lock); - - if (drained) + if (!cwq->nr_active && list_empty(&cwq->delayed_works)) continue; if (++flush_cnt == 10 || diff --git a/trunk/lib/sha1.c b/trunk/lib/sha1.c index 1de509a159c8..f33271dd00cb 100644 --- a/trunk/lib/sha1.c +++ b/trunk/lib/sha1.c @@ -8,7 +8,6 @@ #include #include #include -#include #include /* diff --git a/trunk/mm/filemap.c b/trunk/mm/filemap.c index 7771871fa353..645a080ba4df 100644 --- a/trunk/mm/filemap.c +++ b/trunk/mm/filemap.c @@ -827,14 +827,13 @@ unsigned find_get_pages(struct address_space *mapping, pgoff_t start, { unsigned int i; unsigned int ret; - unsigned int nr_found, nr_skip; + unsigned int nr_found; rcu_read_lock(); restart: nr_found = radix_tree_gang_lookup_slot(&mapping->page_tree, (void ***)pages, NULL, start, nr_pages); ret = 0; - nr_skip = 0; for (i = 0; i < nr_found; i++) { struct page *page; repeat: @@ -857,7 +856,6 @@ unsigned find_get_pages(struct address_space *mapping, pgoff_t start, * here as an exceptional entry: so skip over it - * we only reach this from invalidate_mapping_pages(). */ - nr_skip++; continue; } @@ -878,7 +876,7 @@ unsigned find_get_pages(struct address_space *mapping, pgoff_t start, * If all entries were removed before we could secure them, * try again, because callers stop trying once 0 is returned. */ - if (unlikely(!ret && nr_found > nr_skip)) + if (unlikely(!ret && nr_found)) goto restart; rcu_read_unlock(); return ret; diff --git a/trunk/mm/memcontrol.c b/trunk/mm/memcontrol.c index 3508777837c7..ebd1e86bef1c 100644 --- a/trunk/mm/memcontrol.c +++ b/trunk/mm/memcontrol.c @@ -204,6 +204,50 @@ struct mem_cgroup_eventfd_list { static void mem_cgroup_threshold(struct mem_cgroup *mem); static void mem_cgroup_oom_notify(struct mem_cgroup *mem); +enum { + SCAN_BY_LIMIT, + SCAN_BY_SYSTEM, + NR_SCAN_CONTEXT, + SCAN_BY_SHRINK, /* not recorded now */ +}; + +enum { + SCAN, + SCAN_ANON, + SCAN_FILE, + ROTATE, + ROTATE_ANON, + ROTATE_FILE, + FREED, + FREED_ANON, + FREED_FILE, + ELAPSED, + NR_SCANSTATS, +}; + +struct scanstat { + spinlock_t lock; + unsigned long stats[NR_SCAN_CONTEXT][NR_SCANSTATS]; + unsigned long rootstats[NR_SCAN_CONTEXT][NR_SCANSTATS]; +}; + +const char *scanstat_string[NR_SCANSTATS] = { + "scanned_pages", + "scanned_anon_pages", + "scanned_file_pages", + "rotated_pages", + "rotated_anon_pages", + "rotated_file_pages", + "freed_pages", + "freed_anon_pages", + "freed_file_pages", + "elapsed_ns", +}; +#define SCANSTAT_WORD_LIMIT "_by_limit" +#define SCANSTAT_WORD_SYSTEM "_by_system" +#define SCANSTAT_WORD_HIERARCHY "_under_hierarchy" + + /* * The memory controller data structure. The memory controller controls both * page cache and RSS per cgroup. We would eventually like to provide @@ -269,7 +313,8 @@ struct mem_cgroup { /* For oom notifier event fd */ struct list_head oom_notify; - + /* For recording LRU-scan statistics */ + struct scanstat scanstat; /* * Should we move charges of a task when a task is moved into this * mem_cgroup ? And what type of charges should we move ? @@ -1633,6 +1678,44 @@ bool mem_cgroup_reclaimable(struct mem_cgroup *mem, bool noswap) } #endif +static void __mem_cgroup_record_scanstat(unsigned long *stats, + struct memcg_scanrecord *rec) +{ + + stats[SCAN] += rec->nr_scanned[0] + rec->nr_scanned[1]; + stats[SCAN_ANON] += rec->nr_scanned[0]; + stats[SCAN_FILE] += rec->nr_scanned[1]; + + stats[ROTATE] += rec->nr_rotated[0] + rec->nr_rotated[1]; + stats[ROTATE_ANON] += rec->nr_rotated[0]; + stats[ROTATE_FILE] += rec->nr_rotated[1]; + + stats[FREED] += rec->nr_freed[0] + rec->nr_freed[1]; + stats[FREED_ANON] += rec->nr_freed[0]; + stats[FREED_FILE] += rec->nr_freed[1]; + + stats[ELAPSED] += rec->elapsed; +} + +static void mem_cgroup_record_scanstat(struct memcg_scanrecord *rec) +{ + struct mem_cgroup *mem; + int context = rec->context; + + if (context >= NR_SCAN_CONTEXT) + return; + + mem = rec->mem; + spin_lock(&mem->scanstat.lock); + __mem_cgroup_record_scanstat(mem->scanstat.stats[context], rec); + spin_unlock(&mem->scanstat.lock); + + mem = rec->root; + spin_lock(&mem->scanstat.lock); + __mem_cgroup_record_scanstat(mem->scanstat.rootstats[context], rec); + spin_unlock(&mem->scanstat.lock); +} + /* * Scan the hierarchy if needed to reclaim memory. We remember the last child * we reclaimed from, so that we don't end up penalizing one child extensively @@ -1657,8 +1740,9 @@ static int mem_cgroup_hierarchical_reclaim(struct mem_cgroup *root_mem, bool noswap = reclaim_options & MEM_CGROUP_RECLAIM_NOSWAP; bool shrink = reclaim_options & MEM_CGROUP_RECLAIM_SHRINK; bool check_soft = reclaim_options & MEM_CGROUP_RECLAIM_SOFT; + struct memcg_scanrecord rec; unsigned long excess; - unsigned long nr_scanned; + unsigned long scanned; excess = res_counter_soft_limit_excess(&root_mem->res) >> PAGE_SHIFT; @@ -1666,6 +1750,15 @@ static int mem_cgroup_hierarchical_reclaim(struct mem_cgroup *root_mem, if (!check_soft && !shrink && root_mem->memsw_is_minimum) noswap = true; + if (shrink) + rec.context = SCAN_BY_SHRINK; + else if (check_soft) + rec.context = SCAN_BY_SYSTEM; + else + rec.context = SCAN_BY_LIMIT; + + rec.root = root_mem; + while (1) { victim = mem_cgroup_select_victim(root_mem); if (victim == root_mem) { @@ -1706,14 +1799,23 @@ static int mem_cgroup_hierarchical_reclaim(struct mem_cgroup *root_mem, css_put(&victim->css); continue; } + rec.mem = victim; + rec.nr_scanned[0] = 0; + rec.nr_scanned[1] = 0; + rec.nr_rotated[0] = 0; + rec.nr_rotated[1] = 0; + rec.nr_freed[0] = 0; + rec.nr_freed[1] = 0; + rec.elapsed = 0; /* we use swappiness of local cgroup */ if (check_soft) { ret = mem_cgroup_shrink_node_zone(victim, gfp_mask, - noswap, zone, &nr_scanned); - *total_scanned += nr_scanned; + noswap, zone, &rec, &scanned); + *total_scanned += scanned; } else ret = try_to_free_mem_cgroup_pages(victim, gfp_mask, - noswap); + noswap, &rec); + mem_cgroup_record_scanstat(&rec); css_put(&victim->css); /* * At shrinking usage, we can't check we should stop here or @@ -3752,14 +3854,18 @@ static int mem_cgroup_force_empty(struct mem_cgroup *mem, bool free_all) /* try to free all pages in this cgroup */ shrink = 1; while (nr_retries && mem->res.usage > 0) { + struct memcg_scanrecord rec; int progress; if (signal_pending(current)) { ret = -EINTR; goto out; } + rec.context = SCAN_BY_SHRINK; + rec.mem = mem; + rec.root = mem; progress = try_to_free_mem_cgroup_pages(mem, GFP_KERNEL, - false); + false, &rec); if (!progress) { nr_retries--; /* maybe some writeback is necessary */ @@ -4603,6 +4709,54 @@ static int mem_control_numa_stat_open(struct inode *unused, struct file *file) } #endif /* CONFIG_NUMA */ +static int mem_cgroup_vmscan_stat_read(struct cgroup *cgrp, + struct cftype *cft, + struct cgroup_map_cb *cb) +{ + struct mem_cgroup *mem = mem_cgroup_from_cont(cgrp); + char string[64]; + int i; + + for (i = 0; i < NR_SCANSTATS; i++) { + strcpy(string, scanstat_string[i]); + strcat(string, SCANSTAT_WORD_LIMIT); + cb->fill(cb, string, mem->scanstat.stats[SCAN_BY_LIMIT][i]); + } + + for (i = 0; i < NR_SCANSTATS; i++) { + strcpy(string, scanstat_string[i]); + strcat(string, SCANSTAT_WORD_SYSTEM); + cb->fill(cb, string, mem->scanstat.stats[SCAN_BY_SYSTEM][i]); + } + + for (i = 0; i < NR_SCANSTATS; i++) { + strcpy(string, scanstat_string[i]); + strcat(string, SCANSTAT_WORD_LIMIT); + strcat(string, SCANSTAT_WORD_HIERARCHY); + cb->fill(cb, string, mem->scanstat.rootstats[SCAN_BY_LIMIT][i]); + } + for (i = 0; i < NR_SCANSTATS; i++) { + strcpy(string, scanstat_string[i]); + strcat(string, SCANSTAT_WORD_SYSTEM); + strcat(string, SCANSTAT_WORD_HIERARCHY); + cb->fill(cb, string, mem->scanstat.rootstats[SCAN_BY_SYSTEM][i]); + } + return 0; +} + +static int mem_cgroup_reset_vmscan_stat(struct cgroup *cgrp, + unsigned int event) +{ + struct mem_cgroup *mem = mem_cgroup_from_cont(cgrp); + + spin_lock(&mem->scanstat.lock); + memset(&mem->scanstat.stats, 0, sizeof(mem->scanstat.stats)); + memset(&mem->scanstat.rootstats, 0, sizeof(mem->scanstat.rootstats)); + spin_unlock(&mem->scanstat.lock); + return 0; +} + + static struct cftype mem_cgroup_files[] = { { .name = "usage_in_bytes", @@ -4673,6 +4827,11 @@ static struct cftype mem_cgroup_files[] = { .mode = S_IRUGO, }, #endif + { + .name = "vmscan_stat", + .read_map = mem_cgroup_vmscan_stat_read, + .trigger = mem_cgroup_reset_vmscan_stat, + }, }; #ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP @@ -4936,6 +5095,7 @@ mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont) atomic_set(&mem->refcnt, 1); mem->move_charge_at_immigrate = 0; mutex_init(&mem->thresholds_lock); + spin_lock_init(&mem->scanstat.lock); return &mem->css; free_out: __mem_cgroup_free(mem); diff --git a/trunk/mm/mempolicy.c b/trunk/mm/mempolicy.c index 9c51f9f58cac..8b57173c1dd5 100644 --- a/trunk/mm/mempolicy.c +++ b/trunk/mm/mempolicy.c @@ -636,6 +636,7 @@ static int mbind_range(struct mm_struct *mm, unsigned long start, struct vm_area_struct *prev; struct vm_area_struct *vma; int err = 0; + pgoff_t pgoff; unsigned long vmstart; unsigned long vmend; @@ -648,9 +649,9 @@ static int mbind_range(struct mm_struct *mm, unsigned long start, vmstart = max(start, vma->vm_start); vmend = min(end, vma->vm_end); + pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT); prev = vma_merge(mm, prev, vmstart, vmend, vma->vm_flags, - vma->anon_vma, vma->vm_file, vma->vm_pgoff, - new_pol); + vma->anon_vma, vma->vm_file, pgoff, new_pol); if (prev) { vma = prev; next = vma->vm_next; @@ -1411,9 +1412,7 @@ asmlinkage long compat_sys_get_mempolicy(int __user *policy, err = sys_get_mempolicy(policy, nm, nr_bits+1, addr, flags); if (!err && nmask) { - unsigned long copy_size; - copy_size = min_t(unsigned long, sizeof(bm), alloc_size); - err = copy_from_user(bm, nm, copy_size); + err = copy_from_user(bm, nm, alloc_size); /* ensure entire bitmap is zeroed */ err |= clear_user(nmask, ALIGN(maxnode-1, 8) / 8); err |= compat_put_bitmap(nmask, bm, nr_bits); diff --git a/trunk/mm/vmalloc.c b/trunk/mm/vmalloc.c index 5016f19e1661..7ef0903058ee 100644 --- a/trunk/mm/vmalloc.c +++ b/trunk/mm/vmalloc.c @@ -2140,14 +2140,6 @@ struct vm_struct *alloc_vm_area(size_t size) return NULL; } - /* - * If the allocated address space is passed to a hypercall - * before being used then we cannot rely on a page fault to - * trigger an update of the page tables. So sync all the page - * tables here. - */ - vmalloc_sync_all(); - return area; } EXPORT_SYMBOL_GPL(alloc_vm_area); diff --git a/trunk/mm/vmscan.c b/trunk/mm/vmscan.c index b55699cd9067..b7719ec10dc5 100644 --- a/trunk/mm/vmscan.c +++ b/trunk/mm/vmscan.c @@ -105,6 +105,7 @@ struct scan_control { /* Which cgroup do we reclaim from */ struct mem_cgroup *mem_cgroup; + struct memcg_scanrecord *memcg_record; /* * Nodemask of nodes allowed by the caller. If NULL, all nodes @@ -1348,6 +1349,8 @@ putback_lru_pages(struct zone *zone, struct scan_control *sc, int file = is_file_lru(lru); int numpages = hpage_nr_pages(page); reclaim_stat->recent_rotated[file] += numpages; + if (!scanning_global_lru(sc)) + sc->memcg_record->nr_rotated[file] += numpages; } if (!pagevec_add(&pvec, page)) { spin_unlock_irq(&zone->lru_lock); @@ -1391,6 +1394,10 @@ static noinline_for_stack void update_isolated_counts(struct zone *zone, reclaim_stat->recent_scanned[0] += *nr_anon; reclaim_stat->recent_scanned[1] += *nr_file; + if (!scanning_global_lru(sc)) { + sc->memcg_record->nr_scanned[0] += *nr_anon; + sc->memcg_record->nr_scanned[1] += *nr_file; + } } /* @@ -1504,6 +1511,9 @@ shrink_inactive_list(unsigned long nr_to_scan, struct zone *zone, nr_reclaimed += shrink_page_list(&page_list, zone, sc); } + if (!scanning_global_lru(sc)) + sc->memcg_record->nr_freed[file] += nr_reclaimed; + local_irq_disable(); if (current_is_kswapd()) __count_vm_events(KSWAPD_STEAL, nr_reclaimed); @@ -1603,6 +1613,8 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone, } reclaim_stat->recent_scanned[file] += nr_taken; + if (!scanning_global_lru(sc)) + sc->memcg_record->nr_scanned[file] += nr_taken; __count_zone_vm_events(PGREFILL, zone, pgscanned); if (file) @@ -1654,6 +1666,8 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone, * get_scan_ratio. */ reclaim_stat->recent_rotated[file] += nr_rotated; + if (!scanning_global_lru(sc)) + sc->memcg_record->nr_rotated[file] += nr_rotated; move_active_pages_to_lru(zone, &l_active, LRU_ACTIVE + file * LRU_FILE); @@ -1794,15 +1808,23 @@ static void get_scan_count(struct zone *zone, struct scan_control *sc, u64 fraction[2], denominator; enum lru_list l; int noswap = 0; - bool force_scan = false; + int force_scan = 0; unsigned long nr_force_scan[2]; - /* kswapd does zone balancing and needs to scan this zone */ - if (scanning_global_lru(sc) && current_is_kswapd()) - force_scan = true; - /* memcg may have small limit and need to avoid priority drop */ - if (!scanning_global_lru(sc)) - force_scan = true; + + anon = zone_nr_lru_pages(zone, sc, LRU_ACTIVE_ANON) + + zone_nr_lru_pages(zone, sc, LRU_INACTIVE_ANON); + file = zone_nr_lru_pages(zone, sc, LRU_ACTIVE_FILE) + + zone_nr_lru_pages(zone, sc, LRU_INACTIVE_FILE); + + if (((anon + file) >> priority) < SWAP_CLUSTER_MAX) { + /* kswapd does zone balancing and need to scan this zone */ + if (scanning_global_lru(sc) && current_is_kswapd()) + force_scan = 1; + /* memcg may have small limit and need to avoid priority drop */ + if (!scanning_global_lru(sc)) + force_scan = 1; + } /* If we have no swap space, do not bother scanning anon pages. */ if (!sc->may_swap || (nr_swap_pages <= 0)) { @@ -1815,11 +1837,6 @@ static void get_scan_count(struct zone *zone, struct scan_control *sc, goto out; } - anon = zone_nr_lru_pages(zone, sc, LRU_ACTIVE_ANON) + - zone_nr_lru_pages(zone, sc, LRU_INACTIVE_ANON); - file = zone_nr_lru_pages(zone, sc, LRU_ACTIVE_FILE) + - zone_nr_lru_pages(zone, sc, LRU_INACTIVE_FILE); - if (scanning_global_lru(sc)) { free = zone_page_state(zone, NR_FREE_PAGES); /* If we have very few page cache pages, @@ -2251,9 +2268,10 @@ unsigned long try_to_free_pages(struct zonelist *zonelist, int order, #ifdef CONFIG_CGROUP_MEM_RES_CTLR unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *mem, - gfp_t gfp_mask, bool noswap, - struct zone *zone, - unsigned long *nr_scanned) + gfp_t gfp_mask, bool noswap, + struct zone *zone, + struct memcg_scanrecord *rec, + unsigned long *scanned) { struct scan_control sc = { .nr_scanned = 0, @@ -2263,7 +2281,9 @@ unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *mem, .may_swap = !noswap, .order = 0, .mem_cgroup = mem, + .memcg_record = rec, }; + ktime_t start, end; sc.gfp_mask = (gfp_mask & GFP_RECLAIM_MASK) | (GFP_HIGHUSER_MOVABLE & ~GFP_RECLAIM_MASK); @@ -2272,6 +2292,7 @@ unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *mem, sc.may_writepage, sc.gfp_mask); + start = ktime_get(); /* * NOTE: Although we can get the priority field, using it * here is not a good idea, since it limits the pages we can scan. @@ -2280,19 +2301,25 @@ unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *mem, * the priority and make it zero. */ shrink_zone(0, zone, &sc); + end = ktime_get(); + + if (rec) + rec->elapsed += ktime_to_ns(ktime_sub(end, start)); + *scanned = sc.nr_scanned; trace_mm_vmscan_memcg_softlimit_reclaim_end(sc.nr_reclaimed); - *nr_scanned = sc.nr_scanned; return sc.nr_reclaimed; } unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem_cont, gfp_t gfp_mask, - bool noswap) + bool noswap, + struct memcg_scanrecord *rec) { struct zonelist *zonelist; unsigned long nr_reclaimed; + ktime_t start, end; int nid; struct scan_control sc = { .may_writepage = !laptop_mode, @@ -2301,6 +2328,7 @@ unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem_cont, .nr_to_reclaim = SWAP_CLUSTER_MAX, .order = 0, .mem_cgroup = mem_cont, + .memcg_record = rec, .nodemask = NULL, /* we don't care the placement */ .gfp_mask = (gfp_mask & GFP_RECLAIM_MASK) | (GFP_HIGHUSER_MOVABLE & ~GFP_RECLAIM_MASK), @@ -2309,6 +2337,7 @@ unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem_cont, .gfp_mask = sc.gfp_mask, }; + start = ktime_get(); /* * Unlike direct reclaim via alloc_pages(), memcg's reclaim doesn't * take care of from where we get pages. So the node where we start the @@ -2323,6 +2352,9 @@ unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem_cont, sc.gfp_mask); nr_reclaimed = do_try_to_free_pages(zonelist, &sc, &shrink); + end = ktime_get(); + if (rec) + rec->elapsed += ktime_to_ns(ktime_sub(end, start)); trace_mm_vmscan_memcg_reclaim_end(nr_reclaimed); diff --git a/trunk/mm/vmstat.c b/trunk/mm/vmstat.c index d52b13d28e8f..20c18b7694b2 100644 --- a/trunk/mm/vmstat.c +++ b/trunk/mm/vmstat.c @@ -659,7 +659,7 @@ static void walk_zones_in_node(struct seq_file *m, pg_data_t *pgdat, } #endif -#if defined(CONFIG_PROC_FS) || defined(CONFIG_SYSFS) || defined(CONFIG_NUMA) +#if defined(CONFIG_PROC_FS) || defined(CONFIG_SYSFS) #ifdef CONFIG_ZONE_DMA #define TEXT_FOR_DMA(xx) xx "_dma", #else @@ -788,7 +788,7 @@ const char * const vmstat_text[] = { #endif /* CONFIG_VM_EVENTS_COUNTERS */ }; -#endif /* CONFIG_PROC_FS || CONFIG_SYSFS || CONFIG_NUMA */ +#endif /* CONFIG_PROC_FS || CONFIG_SYSFS */ #ifdef CONFIG_PROC_FS