diff options
Diffstat (limited to '1023_linux-3.2.24.patch')
-rw-r--r-- | 1023_linux-3.2.24.patch | 4684 |
1 files changed, 4684 insertions, 0 deletions
diff --git a/1023_linux-3.2.24.patch b/1023_linux-3.2.24.patch new file mode 100644 index 00000000..4692eb4d --- /dev/null +++ b/1023_linux-3.2.24.patch @@ -0,0 +1,4684 @@ +diff --git a/Makefile b/Makefile +index 40d1e3b..80bb4fd 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 2 +-SUBLEVEL = 23 ++SUBLEVEL = 24 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/plat-samsung/adc.c +index 33ecd0c..b1e05cc 100644 +--- a/arch/arm/plat-samsung/adc.c ++++ b/arch/arm/plat-samsung/adc.c +@@ -157,11 +157,13 @@ int s3c_adc_start(struct s3c_adc_client *client, + return -EINVAL; + } + +- if (client->is_ts && adc->ts_pend) +- return -EAGAIN; +- + spin_lock_irqsave(&adc->lock, flags); + ++ if (client->is_ts && adc->ts_pend) { ++ spin_unlock_irqrestore(&adc->lock, flags); ++ return -EAGAIN; ++ } ++ + client->channel = channel; + client->nr_samples = nr_samples; + +diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h +index 97f8bf6..adda036 100644 +--- a/arch/mips/include/asm/thread_info.h ++++ b/arch/mips/include/asm/thread_info.h +@@ -60,6 +60,8 @@ struct thread_info { + register struct thread_info *__current_thread_info __asm__("$28"); + #define current_thread_info() __current_thread_info + ++#endif /* !__ASSEMBLY__ */ ++ + /* thread information allocation */ + #if defined(CONFIG_PAGE_SIZE_4KB) && defined(CONFIG_32BIT) + #define THREAD_SIZE_ORDER (1) +@@ -97,8 +99,6 @@ register struct thread_info *__current_thread_info __asm__("$28"); + + #define free_thread_info(info) kfree(info) + +-#endif /* !__ASSEMBLY__ */ +- + #define PREEMPT_ACTIVE 0x10000000 + + /* +diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S +index a81176f..be281c6 100644 +--- a/arch/mips/kernel/vmlinux.lds.S ++++ b/arch/mips/kernel/vmlinux.lds.S +@@ -1,5 +1,6 @@ + #include <asm/asm-offsets.h> + #include <asm/page.h> ++#include <asm/thread_info.h> + #include <asm-generic/vmlinux.lds.h> + + #undef mips +@@ -73,7 +74,7 @@ SECTIONS + .data : { /* Data */ + . = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */ + +- INIT_TASK_DATA(PAGE_SIZE) ++ INIT_TASK_DATA(THREAD_SIZE) + NOSAVE_DATA + CACHELINE_ALIGNED_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT) + READ_MOSTLY_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT) +diff --git a/arch/powerpc/include/asm/cputime.h b/arch/powerpc/include/asm/cputime.h +index 98b7c4b..fa3f921 100644 +--- a/arch/powerpc/include/asm/cputime.h ++++ b/arch/powerpc/include/asm/cputime.h +@@ -126,11 +126,11 @@ static inline u64 cputime64_to_jiffies64(const cputime_t ct) + /* + * Convert cputime <-> microseconds + */ +-extern u64 __cputime_msec_factor; ++extern u64 __cputime_usec_factor; + + static inline unsigned long cputime_to_usecs(const cputime_t ct) + { +- return mulhdu(ct, __cputime_msec_factor) * USEC_PER_MSEC; ++ return mulhdu(ct, __cputime_usec_factor); + } + + static inline cputime_t usecs_to_cputime(const unsigned long us) +@@ -143,7 +143,7 @@ static inline cputime_t usecs_to_cputime(const unsigned long us) + sec = us / 1000000; + if (ct) { + ct *= tb_ticks_per_sec; +- do_div(ct, 1000); ++ do_div(ct, 1000000); + } + if (sec) + ct += (cputime_t) sec * tb_ticks_per_sec; +diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c +index 5db163c..ec8affe 100644 +--- a/arch/powerpc/kernel/time.c ++++ b/arch/powerpc/kernel/time.c +@@ -168,13 +168,13 @@ EXPORT_SYMBOL_GPL(ppc_tb_freq); + #ifdef CONFIG_VIRT_CPU_ACCOUNTING + /* + * Factors for converting from cputime_t (timebase ticks) to +- * jiffies, milliseconds, seconds, and clock_t (1/USER_HZ seconds). ++ * jiffies, microseconds, seconds, and clock_t (1/USER_HZ seconds). + * These are all stored as 0.64 fixed-point binary fractions. + */ + u64 __cputime_jiffies_factor; + EXPORT_SYMBOL(__cputime_jiffies_factor); +-u64 __cputime_msec_factor; +-EXPORT_SYMBOL(__cputime_msec_factor); ++u64 __cputime_usec_factor; ++EXPORT_SYMBOL(__cputime_usec_factor); + u64 __cputime_sec_factor; + EXPORT_SYMBOL(__cputime_sec_factor); + u64 __cputime_clockt_factor; +@@ -192,8 +192,8 @@ static void calc_cputime_factors(void) + + div128_by_32(HZ, 0, tb_ticks_per_sec, &res); + __cputime_jiffies_factor = res.result_low; +- div128_by_32(1000, 0, tb_ticks_per_sec, &res); +- __cputime_msec_factor = res.result_low; ++ div128_by_32(1000000, 0, tb_ticks_per_sec, &res); ++ __cputime_usec_factor = res.result_low; + div128_by_32(1, 0, tb_ticks_per_sec, &res); + __cputime_sec_factor = res.result_low; + div128_by_32(USER_HZ, 0, tb_ticks_per_sec, &res); +diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c +index 4558f0d..479d03c 100644 +--- a/arch/x86/kernel/acpi/boot.c ++++ b/arch/x86/kernel/acpi/boot.c +@@ -416,12 +416,14 @@ acpi_parse_int_src_ovr(struct acpi_subtable_header * header, + return 0; + } + +- if (intsrc->source_irq == 0 && intsrc->global_irq == 2) { ++ if (intsrc->source_irq == 0) { + if (acpi_skip_timer_override) { +- printk(PREFIX "BIOS IRQ0 pin2 override ignored.\n"); ++ printk(PREFIX "BIOS IRQ0 override ignored.\n"); + return 0; + } +- if (acpi_fix_pin2_polarity && (intsrc->inti_flags & ACPI_MADT_POLARITY_MASK)) { ++ ++ if ((intsrc->global_irq == 2) && acpi_fix_pin2_polarity ++ && (intsrc->inti_flags & ACPI_MADT_POLARITY_MASK)) { + intsrc->inti_flags &= ~ACPI_MADT_POLARITY_MASK; + printk(PREFIX "BIOS IRQ0 pin2 override: forcing polarity to high active.\n"); + } +@@ -1327,17 +1329,12 @@ static int __init dmi_disable_acpi(const struct dmi_system_id *d) + } + + /* +- * Force ignoring BIOS IRQ0 pin2 override ++ * Force ignoring BIOS IRQ0 override + */ + static int __init dmi_ignore_irq0_timer_override(const struct dmi_system_id *d) + { +- /* +- * The ati_ixp4x0_rev() early PCI quirk should have set +- * the acpi_skip_timer_override flag already: +- */ + if (!acpi_skip_timer_override) { +- WARN(1, KERN_ERR "ati_ixp4x0 quirk not complete.\n"); +- pr_notice("%s detected: Ignoring BIOS IRQ0 pin2 override\n", ++ pr_notice("%s detected: Ignoring BIOS IRQ0 override\n", + d->ident); + acpi_skip_timer_override = 1; + } +@@ -1431,7 +1428,7 @@ static struct dmi_system_id __initdata acpi_dmi_table_late[] = { + * is enabled. This input is incorrectly designated the + * ISA IRQ 0 via an interrupt source override even though + * it is wired to the output of the master 8259A and INTIN0 +- * is not connected at all. Force ignoring BIOS IRQ0 pin2 ++ * is not connected at all. Force ignoring BIOS IRQ0 + * override in that cases. + */ + { +@@ -1466,6 +1463,14 @@ static struct dmi_system_id __initdata acpi_dmi_table_late[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6715b"), + }, + }, ++ { ++ .callback = dmi_ignore_irq0_timer_override, ++ .ident = "FUJITSU SIEMENS", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"), ++ }, ++ }, + {} + }; + +diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c +index 37a458b..e61f79c 100644 +--- a/arch/x86/kernel/reboot.c ++++ b/arch/x86/kernel/reboot.c +@@ -460,6 +460,14 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 990"), + }, + }, ++ { /* Handle problems with rebooting on the Precision M6600. */ ++ .callback = set_pci_reboot, ++ .ident = "Dell OptiPlex 990", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Precision M6600"), ++ }, ++ }, + { } + }; + +diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c +index 688be8a..9e76a32 100644 +--- a/block/scsi_ioctl.c ++++ b/block/scsi_ioctl.c +@@ -721,11 +721,14 @@ int scsi_verify_blk_ioctl(struct block_device *bd, unsigned int cmd) + break; + } + ++ if (capable(CAP_SYS_RAWIO)) ++ return 0; ++ + /* In particular, rule out all resets and host-specific ioctls. */ + printk_ratelimited(KERN_WARNING + "%s: sending ioctl %x to a partition!\n", current->comm, cmd); + +- return capable(CAP_SYS_RAWIO) ? 0 : -ENOTTY; ++ return -ENOTTY; + } + EXPORT_SYMBOL(scsi_verify_blk_ioctl); + +diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c +index c850de4..eff7222 100644 +--- a/drivers/acpi/processor_core.c ++++ b/drivers/acpi/processor_core.c +@@ -189,10 +189,12 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) + * Processor (CPU3, 0x03, 0x00000410, 0x06) {} + * } + * +- * Ignores apic_id and always return 0 for CPU0's handle. ++ * Ignores apic_id and always returns 0 for the processor ++ * handle with acpi id 0 if nr_cpu_ids is 1. ++ * This should be the case if SMP tables are not found. + * Return -1 for other CPU's handle. + */ +- if (acpi_id == 0) ++ if (nr_cpu_ids <= 1 && acpi_id == 0) + return acpi_id; + else + return apic_id; +diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c +index ca191ff..ed6bc52 100644 +--- a/drivers/acpi/sleep.c ++++ b/drivers/acpi/sleep.c +@@ -702,8 +702,8 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p) + * can wake the system. _S0W may be valid, too. + */ + if (acpi_target_sleep_state == ACPI_STATE_S0 || +- (device_may_wakeup(dev) && +- adev->wakeup.sleep_state <= acpi_target_sleep_state)) { ++ (device_may_wakeup(dev) && adev->wakeup.flags.valid && ++ adev->wakeup.sleep_state >= acpi_target_sleep_state)) { + acpi_status status; + + acpi_method[3] = 'W'; +diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c +index 9f66181..240a244 100644 +--- a/drivers/acpi/sysfs.c ++++ b/drivers/acpi/sysfs.c +@@ -173,7 +173,7 @@ static int param_set_trace_state(const char *val, struct kernel_param *kp) + { + int result = 0; + +- if (!strncmp(val, "enable", strlen("enable") - 1)) { ++ if (!strncmp(val, "enable", strlen("enable"))) { + result = acpi_debug_trace(trace_method_name, trace_debug_level, + trace_debug_layer, 0); + if (result) +@@ -181,7 +181,7 @@ static int param_set_trace_state(const char *val, struct kernel_param *kp) + goto exit; + } + +- if (!strncmp(val, "disable", strlen("disable") - 1)) { ++ if (!strncmp(val, "disable", strlen("disable"))) { + int name = 0; + result = acpi_debug_trace((char *)&name, trace_debug_level, + trace_debug_layer, 0); +diff --git a/drivers/gpio/gpio-wm8994.c b/drivers/gpio/gpio-wm8994.c +index 96198f3..a2da8f2 100644 +--- a/drivers/gpio/gpio-wm8994.c ++++ b/drivers/gpio/gpio-wm8994.c +@@ -89,8 +89,11 @@ static int wm8994_gpio_direction_out(struct gpio_chip *chip, + struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip); + struct wm8994 *wm8994 = wm8994_gpio->wm8994; + ++ if (value) ++ value = WM8994_GPN_LVL; ++ + return wm8994_set_bits(wm8994, WM8994_GPIO_1 + offset, +- WM8994_GPN_DIR, 0); ++ WM8994_GPN_DIR | WM8994_GPN_LVL, value); + } + + static void wm8994_gpio_set(struct gpio_chip *chip, unsigned offset, int value) +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 6aa7716..cc75c4b 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -8043,8 +8043,8 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) + I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */ + + if (intel_enable_rc6(dev_priv->dev)) +- rc6_mask = GEN6_RC_CTL_RC6p_ENABLE | +- GEN6_RC_CTL_RC6_ENABLE; ++ rc6_mask = GEN6_RC_CTL_RC6_ENABLE | ++ ((IS_GEN7(dev_priv->dev)) ? GEN6_RC_CTL_RC6p_ENABLE : 0); + + I915_WRITE(GEN6_RC_CONTROL, + rc6_mask | +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index 299d238..899c712 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -514,6 +514,12 @@ static const struct hid_device_id apple_devices[] = { + .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS), + .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI), ++ .driver_data = APPLE_HAS_FN }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO), ++ .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS), ++ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), + .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index c27b402..95430a0 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1374,6 +1374,9 @@ static const struct hid_device_id hid_have_special_driver[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, +@@ -1884,6 +1887,7 @@ static const struct hid_device_id hid_ignore_list[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MCT) }, + { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_HYBRID) }, + { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_HEATCONTROL) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_BEATPAD) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT1) }, +@@ -1968,6 +1972,9 @@ static const struct hid_device_id hid_mouse_ignore_list[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, + { } +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index fba3fc4..7db934d 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -125,6 +125,9 @@ + #define USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI 0x024c + #define USB_DEVICE_ID_APPLE_WELLSPRING6_ISO 0x024d + #define USB_DEVICE_ID_APPLE_WELLSPRING6_JIS 0x024e ++#define USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI 0x0262 ++#define USB_DEVICE_ID_APPLE_WELLSPRING7_ISO 0x0263 ++#define USB_DEVICE_ID_APPLE_WELLSPRING7_JIS 0x0264 + #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI 0x0239 + #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a + #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b +@@ -491,6 +494,9 @@ + #define USB_DEVICE_ID_CRYSTALTOUCH 0x0006 + #define USB_DEVICE_ID_CRYSTALTOUCH_DUAL 0x0007 + ++#define USB_VENDOR_ID_MADCATZ 0x0738 ++#define USB_DEVICE_ID_MADCATZ_BEATPAD 0x4540 ++ + #define USB_VENDOR_ID_MCC 0x09db + #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 + #define USB_DEVICE_ID_MCC_PMD1208LS 0x007a +diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c +index d912649..1ba7af2 100644 +--- a/drivers/hwmon/it87.c ++++ b/drivers/hwmon/it87.c +@@ -2086,7 +2086,7 @@ static void __devinit it87_init_device(struct platform_device *pdev) + + /* Start monitoring */ + it87_write_value(data, IT87_REG_CONFIG, +- (it87_read_value(data, IT87_REG_CONFIG) & 0x36) ++ (it87_read_value(data, IT87_REG_CONFIG) & 0x3e) + | (update_vbat ? 0x41 : 0x01)); + } + +diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c +index 61c9cf1..1201a15 100644 +--- a/drivers/hwspinlock/hwspinlock_core.c ++++ b/drivers/hwspinlock/hwspinlock_core.c +@@ -345,7 +345,7 @@ int hwspin_lock_register(struct hwspinlock_device *bank, struct device *dev, + spin_lock_init(&hwlock->lock); + hwlock->bank = bank; + +- ret = hwspin_lock_register_single(hwlock, i); ++ ret = hwspin_lock_register_single(hwlock, base_id + i); + if (ret) + goto reg_failed; + } +@@ -354,7 +354,7 @@ int hwspin_lock_register(struct hwspinlock_device *bank, struct device *dev, + + reg_failed: + while (--i >= 0) +- hwspin_lock_unregister_single(i); ++ hwspin_lock_unregister_single(base_id + i); + return ret; + } + EXPORT_SYMBOL_GPL(hwspin_lock_register); +diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c +index d728875..2189cbf 100644 +--- a/drivers/input/joystick/xpad.c ++++ b/drivers/input/joystick/xpad.c +@@ -142,6 +142,7 @@ static const struct xpad_device { + { 0x0c12, 0x880a, "Pelican Eclipse PL-2023", 0, XTYPE_XBOX }, + { 0x0c12, 0x8810, "Zeroplus Xbox Controller", 0, XTYPE_XBOX }, + { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", 0, XTYPE_XBOX }, ++ { 0x0d2f, 0x0002, "Andamiro Pump It Up pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, + { 0x0e4c, 0x1097, "Radica Gamester Controller", 0, XTYPE_XBOX }, + { 0x0e4c, 0x2390, "Radica Games Jtech Controller", 0, XTYPE_XBOX }, + { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", 0, XTYPE_XBOX }, +@@ -164,6 +165,7 @@ static const struct xpad_device { + { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, + { 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, + { 0x0f0d, 0x000d, "Hori Fighting Stick EX2", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, ++ { 0x1689, 0xfd00, "Razer Onza Tournament Edition", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, + { 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX }, + { 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN } + }; +@@ -238,12 +240,14 @@ static struct usb_device_id xpad_table [] = { + XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */ + XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */ + XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */ ++ { USB_DEVICE(0x0738, 0x4540) }, /* Mad Catz Beat Pad */ + XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f X-Box 360 controllers */ + XPAD_XBOX360_VENDOR(0x12ab), /* X-Box 360 dance pads */ + XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */ + XPAD_XBOX360_VENDOR(0x146b), /* BigBen Interactive Controllers */ + XPAD_XBOX360_VENDOR(0x1bad), /* Harminix Rock Band Guitar and Drums */ +- XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */ ++ XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */ ++ XPAD_XBOX360_VENDOR(0x1689), /* Razer Onza */ + { } + }; + +diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c +index 5ec617e..ec58f48 100644 +--- a/drivers/input/mouse/bcm5974.c ++++ b/drivers/input/mouse/bcm5974.c +@@ -79,6 +79,10 @@ + #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI 0x0252 + #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO 0x0253 + #define USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS 0x0254 ++/* MacbookPro10,1 (unibody, June 2012) */ ++#define USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI 0x0262 ++#define USB_DEVICE_ID_APPLE_WELLSPRING7_ISO 0x0263 ++#define USB_DEVICE_ID_APPLE_WELLSPRING7_JIS 0x0264 + + #define BCM5974_DEVICE(prod) { \ + .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ +@@ -128,6 +132,10 @@ static const struct usb_device_id bcm5974_table[] = { + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI), + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO), + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS), ++ /* MacbookPro10,1 */ ++ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI), ++ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_ISO), ++ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_JIS), + /* Terminating entry */ + {} + }; +@@ -354,6 +362,18 @@ static const struct bcm5974_config bcm5974_config_table[] = { + { DIM_X, DIM_X / SN_COORD, -4620, 5140 }, + { DIM_Y, DIM_Y / SN_COORD, -150, 6600 } + }, ++ { ++ USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI, ++ USB_DEVICE_ID_APPLE_WELLSPRING7_ISO, ++ USB_DEVICE_ID_APPLE_WELLSPRING7_JIS, ++ HAS_INTEGRATED_BUTTON, ++ 0x84, sizeof(struct bt_data), ++ 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, ++ { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, ++ { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, ++ { DIM_X, DIM_X / SN_COORD, -4750, 5280 }, ++ { DIM_Y, DIM_Y / SN_COORD, -150, 6730 } ++ }, + {} + }; + +diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c +index f1d5408..a1b8caa 100644 +--- a/drivers/iommu/amd_iommu.c ++++ b/drivers/iommu/amd_iommu.c +@@ -59,6 +59,8 @@ static struct protection_domain *pt_domain; + + static struct iommu_ops amd_iommu_ops; + ++static struct dma_map_ops amd_iommu_dma_ops; ++ + /* + * general struct to manage commands send to an IOMMU + */ +@@ -1878,6 +1880,11 @@ static int device_change_notifier(struct notifier_block *nb, + list_add_tail(&dma_domain->list, &iommu_pd_list); + spin_unlock_irqrestore(&iommu_pd_list_lock, flags); + ++ if (!iommu_pass_through) ++ dev->archdata.dma_ops = &amd_iommu_dma_ops; ++ else ++ dev->archdata.dma_ops = &nommu_dma_ops; ++ + break; + case BUS_NOTIFY_DEL_DEVICE: + +diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c +index 6269eb0..ef2d493 100644 +--- a/drivers/iommu/amd_iommu_init.c ++++ b/drivers/iommu/amd_iommu_init.c +@@ -1468,6 +1468,8 @@ static int __init amd_iommu_init(void) + + register_syscore_ops(&amd_iommu_syscore_ops); + ++ x86_platform.iommu_shutdown = disable_iommus; ++ + if (iommu_pass_through) + goto out; + +@@ -1476,7 +1478,6 @@ static int __init amd_iommu_init(void) + else + printk(KERN_INFO "AMD-Vi: Lazy IO/TLB flushing enabled\n"); + +- x86_platform.iommu_shutdown = disable_iommus; + out: + return ret; + +diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c +index 9bfd057..dae2b7a 100644 +--- a/drivers/md/dm-raid1.c ++++ b/drivers/md/dm-raid1.c +@@ -1080,6 +1080,7 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) + ti->split_io = dm_rh_get_region_size(ms->rh); + ti->num_flush_requests = 1; + ti->num_discard_requests = 1; ++ ti->discard_zeroes_data_unsupported = 1; + + ms->kmirrord_wq = alloc_workqueue("kmirrord", + WQ_NON_REENTRANT | WQ_MEM_RECLAIM, 0); +@@ -1210,7 +1211,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, + * We need to dec pending if this was a write. + */ + if (rw == WRITE) { +- if (!(bio->bi_rw & REQ_FLUSH)) ++ if (!(bio->bi_rw & (REQ_FLUSH | REQ_DISCARD))) + dm_rh_dec(ms->rh, map_context->ll); + return error; + } +diff --git a/drivers/md/dm-region-hash.c b/drivers/md/dm-region-hash.c +index 7771ed2..69732e0 100644 +--- a/drivers/md/dm-region-hash.c ++++ b/drivers/md/dm-region-hash.c +@@ -404,6 +404,9 @@ void dm_rh_mark_nosync(struct dm_region_hash *rh, struct bio *bio) + return; + } + ++ if (bio->bi_rw & REQ_DISCARD) ++ return; ++ + /* We must inform the log that the sync count has changed. */ + log->type->set_region_sync(log, region, 0); + +@@ -524,7 +527,7 @@ void dm_rh_inc_pending(struct dm_region_hash *rh, struct bio_list *bios) + struct bio *bio; + + for (bio = bios->head; bio; bio = bio->bi_next) { +- if (bio->bi_rw & REQ_FLUSH) ++ if (bio->bi_rw & (REQ_FLUSH | REQ_DISCARD)) + continue; + rh_inc(rh, dm_rh_bio_to_region(rh, bio)); + } +diff --git a/drivers/md/md.c b/drivers/md/md.c +index 700ecae..d8646d7 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -3700,8 +3700,8 @@ array_state_show(struct mddev *mddev, char *page) + return sprintf(page, "%s\n", array_states[st]); + } + +-static int do_md_stop(struct mddev * mddev, int ro, int is_open); +-static int md_set_readonly(struct mddev * mddev, int is_open); ++static int do_md_stop(struct mddev * mddev, int ro, struct block_device *bdev); ++static int md_set_readonly(struct mddev * mddev, struct block_device *bdev); + static int do_md_run(struct mddev * mddev); + static int restart_array(struct mddev *mddev); + +@@ -3717,14 +3717,14 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len) + /* stopping an active array */ + if (atomic_read(&mddev->openers) > 0) + return -EBUSY; +- err = do_md_stop(mddev, 0, 0); ++ err = do_md_stop(mddev, 0, NULL); + break; + case inactive: + /* stopping an active array */ + if (mddev->pers) { + if (atomic_read(&mddev->openers) > 0) + return -EBUSY; +- err = do_md_stop(mddev, 2, 0); ++ err = do_md_stop(mddev, 2, NULL); + } else + err = 0; /* already inactive */ + break; +@@ -3732,7 +3732,7 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len) + break; /* not supported yet */ + case readonly: + if (mddev->pers) +- err = md_set_readonly(mddev, 0); ++ err = md_set_readonly(mddev, NULL); + else { + mddev->ro = 1; + set_disk_ro(mddev->gendisk, 1); +@@ -3742,7 +3742,7 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len) + case read_auto: + if (mddev->pers) { + if (mddev->ro == 0) +- err = md_set_readonly(mddev, 0); ++ err = md_set_readonly(mddev, NULL); + else if (mddev->ro == 1) + err = restart_array(mddev); + if (err == 0) { +@@ -5078,15 +5078,17 @@ void md_stop(struct mddev *mddev) + } + EXPORT_SYMBOL_GPL(md_stop); + +-static int md_set_readonly(struct mddev *mddev, int is_open) ++static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) + { + int err = 0; + mutex_lock(&mddev->open_mutex); +- if (atomic_read(&mddev->openers) > is_open) { ++ if (atomic_read(&mddev->openers) > !!bdev) { + printk("md: %s still in use.\n",mdname(mddev)); + err = -EBUSY; + goto out; + } ++ if (bdev) ++ sync_blockdev(bdev); + if (mddev->pers) { + __md_stop_writes(mddev); + +@@ -5108,18 +5110,26 @@ out: + * 0 - completely stop and dis-assemble array + * 2 - stop but do not disassemble array + */ +-static int do_md_stop(struct mddev * mddev, int mode, int is_open) ++static int do_md_stop(struct mddev * mddev, int mode, ++ struct block_device *bdev) + { + struct gendisk *disk = mddev->gendisk; + struct md_rdev *rdev; + + mutex_lock(&mddev->open_mutex); +- if (atomic_read(&mddev->openers) > is_open || ++ if (atomic_read(&mddev->openers) > !!bdev || + mddev->sysfs_active) { + printk("md: %s still in use.\n",mdname(mddev)); + mutex_unlock(&mddev->open_mutex); + return -EBUSY; + } ++ if (bdev) ++ /* It is possible IO was issued on some other ++ * open file which was closed before we took ->open_mutex. ++ * As that was not the last close __blkdev_put will not ++ * have called sync_blockdev, so we must. ++ */ ++ sync_blockdev(bdev); + + if (mddev->pers) { + if (mddev->ro) +@@ -5193,7 +5203,7 @@ static void autorun_array(struct mddev *mddev) + err = do_md_run(mddev); + if (err) { + printk(KERN_WARNING "md: do_md_run() returned %d\n", err); +- do_md_stop(mddev, 0, 0); ++ do_md_stop(mddev, 0, NULL); + } + } + +@@ -6184,11 +6194,11 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode, + goto done_unlock; + + case STOP_ARRAY: +- err = do_md_stop(mddev, 0, 1); ++ err = do_md_stop(mddev, 0, bdev); + goto done_unlock; + + case STOP_ARRAY_RO: +- err = md_set_readonly(mddev, 1); ++ err = md_set_readonly(mddev, bdev); + goto done_unlock; + + case BLKROSET: +diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c +index 7af60ec..2d97bf0 100644 +--- a/drivers/md/raid1.c ++++ b/drivers/md/raid1.c +@@ -1713,8 +1713,14 @@ static void sync_request_write(struct mddev *mddev, struct r1bio *r1_bio) + + if (atomic_dec_and_test(&r1_bio->remaining)) { + /* if we're here, all write(s) have completed, so clean up */ +- md_done_sync(mddev, r1_bio->sectors, 1); +- put_buf(r1_bio); ++ int s = r1_bio->sectors; ++ if (test_bit(R1BIO_MadeGood, &r1_bio->state) || ++ test_bit(R1BIO_WriteError, &r1_bio->state)) ++ reschedule_retry(r1_bio); ++ else { ++ put_buf(r1_bio); ++ md_done_sync(mddev, s, 1); ++ } + } + } + +@@ -2378,9 +2384,10 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, int *skipp + */ + if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { + atomic_set(&r1_bio->remaining, read_targets); +- for (i=0; i<conf->raid_disks; i++) { ++ for (i = 0; i < conf->raid_disks && read_targets; i++) { + bio = r1_bio->bios[i]; + if (bio->bi_end_io == end_sync_read) { ++ read_targets--; + md_sync_acct(bio->bi_bdev, nr_sectors); + generic_make_request(bio); + } +diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c +index 6ba4954..26ef63a 100644 +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -196,12 +196,14 @@ static void __release_stripe(struct r5conf *conf, struct stripe_head *sh) + BUG_ON(!list_empty(&sh->lru)); + BUG_ON(atomic_read(&conf->active_stripes)==0); + if (test_bit(STRIPE_HANDLE, &sh->state)) { +- if (test_bit(STRIPE_DELAYED, &sh->state)) ++ if (test_bit(STRIPE_DELAYED, &sh->state) && ++ !test_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) + list_add_tail(&sh->lru, &conf->delayed_list); + else if (test_bit(STRIPE_BIT_DELAY, &sh->state) && + sh->bm_seq - conf->seq_write > 0) + list_add_tail(&sh->lru, &conf->bitmap_list); + else { ++ clear_bit(STRIPE_DELAYED, &sh->state); + clear_bit(STRIPE_BIT_DELAY, &sh->state); + list_add_tail(&sh->lru, &conf->handle_list); + } +diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c +index f732877..d5cda35 100644 +--- a/drivers/media/dvb/dvb-core/dvbdev.c ++++ b/drivers/media/dvb/dvb-core/dvbdev.c +@@ -243,6 +243,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, + if (minor == MAX_DVB_MINORS) { + kfree(dvbdevfops); + kfree(dvbdev); ++ up_write(&minor_rwsem); + mutex_unlock(&dvbdev_register_lock); + return -EINVAL; + } +diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c +index 34c03be..83e8e1b 100644 +--- a/drivers/mtd/nand/nandsim.c ++++ b/drivers/mtd/nand/nandsim.c +@@ -28,7 +28,7 @@ + #include <linux/module.h> + #include <linux/moduleparam.h> + #include <linux/vmalloc.h> +-#include <asm/div64.h> ++#include <linux/math64.h> + #include <linux/slab.h> + #include <linux/errno.h> + #include <linux/string.h> +@@ -547,12 +547,6 @@ static char *get_partition_name(int i) + return kstrdup(buf, GFP_KERNEL); + } + +-static uint64_t divide(uint64_t n, uint32_t d) +-{ +- do_div(n, d); +- return n; +-} +- + /* + * Initialize the nandsim structure. + * +@@ -581,7 +575,7 @@ static int init_nandsim(struct mtd_info *mtd) + ns->geom.oobsz = mtd->oobsize; + ns->geom.secsz = mtd->erasesize; + ns->geom.pgszoob = ns->geom.pgsz + ns->geom.oobsz; +- ns->geom.pgnum = divide(ns->geom.totsz, ns->geom.pgsz); ++ ns->geom.pgnum = div_u64(ns->geom.totsz, ns->geom.pgsz); + ns->geom.totszoob = ns->geom.totsz + (uint64_t)ns->geom.pgnum * ns->geom.oobsz; + ns->geom.secshift = ffs(ns->geom.secsz) - 1; + ns->geom.pgshift = chip->page_shift; +@@ -924,7 +918,7 @@ static int setup_wear_reporting(struct mtd_info *mtd) + + if (!rptwear) + return 0; +- wear_eb_count = divide(mtd->size, mtd->erasesize); ++ wear_eb_count = div_u64(mtd->size, mtd->erasesize); + mem = wear_eb_count * sizeof(unsigned long); + if (mem / sizeof(unsigned long) != wear_eb_count) { + NS_ERR("Too many erase blocks for wear reporting\n"); +diff --git a/drivers/net/bonding/bond_debugfs.c b/drivers/net/bonding/bond_debugfs.c +index 3680aa2..2cf084e 100644 +--- a/drivers/net/bonding/bond_debugfs.c ++++ b/drivers/net/bonding/bond_debugfs.c +@@ -6,7 +6,7 @@ + #include "bonding.h" + #include "bond_alb.h" + +-#ifdef CONFIG_DEBUG_FS ++#if defined(CONFIG_DEBUG_FS) && !defined(CONFIG_NET_NS) + + #include <linux/debugfs.h> + #include <linux/seq_file.h> +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 1a88e38..6c284d1 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -3184,6 +3184,12 @@ static int bond_master_netdev_event(unsigned long event, + switch (event) { + case NETDEV_CHANGENAME: + return bond_event_changename(event_bond); ++ case NETDEV_UNREGISTER: ++ bond_remove_proc_entry(event_bond); ++ break; ++ case NETDEV_REGISTER: ++ bond_create_proc_entry(event_bond); ++ break; + default: + break; + } +@@ -4391,8 +4397,6 @@ static void bond_uninit(struct net_device *bond_dev) + + bond_work_cancel_all(bond); + +- bond_remove_proc_entry(bond); +- + bond_debug_unregister(bond); + + __hw_addr_flush(&bond->mc_list); +@@ -4794,7 +4798,6 @@ static int bond_init(struct net_device *bond_dev) + + bond_set_lockdep_class(bond_dev); + +- bond_create_proc_entry(bond); + list_add_tail(&bond->bond_list, &bn->dev_list); + + bond_prepare_sysfs_group(bond); +diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +index eccdcff..5ae7df7 100644 +--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c ++++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +@@ -267,7 +267,6 @@ static void atl1c_check_link_status(struct atl1c_adapter *adapter) + dev_warn(&pdev->dev, "stop mac failed\n"); + atl1c_set_aspm(hw, false); + netif_carrier_off(netdev); +- netif_stop_queue(netdev); + atl1c_phy_reset(hw); + atl1c_phy_init(&adapter->hw); + } else { +diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +index aec7212..8dda46a 100644 +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +@@ -723,21 +723,6 @@ struct bnx2x_fastpath { + + #define ETH_RX_ERROR_FALGS ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG + +-#define BNX2X_IP_CSUM_ERR(cqe) \ +- (!((cqe)->fast_path_cqe.status_flags & \ +- ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG) && \ +- ((cqe)->fast_path_cqe.type_error_flags & \ +- ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG)) +- +-#define BNX2X_L4_CSUM_ERR(cqe) \ +- (!((cqe)->fast_path_cqe.status_flags & \ +- ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG) && \ +- ((cqe)->fast_path_cqe.type_error_flags & \ +- ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG)) +- +-#define BNX2X_RX_CSUM_OK(cqe) \ +- (!(BNX2X_L4_CSUM_ERR(cqe) || BNX2X_IP_CSUM_ERR(cqe))) +- + #define BNX2X_PRS_FLAG_OVERETH_IPV4(flags) \ + (((le16_to_cpu(flags) & \ + PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) >> \ +diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +index 580b44e..2c1a5c0 100644 +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +@@ -220,7 +220,7 @@ int bnx2x_tx_int(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata) + + if ((netif_tx_queue_stopped(txq)) && + (bp->state == BNX2X_STATE_OPEN) && +- (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 3)) ++ (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 4)) + netif_tx_wake_queue(txq); + + __netif_tx_unlock(txq); +@@ -551,6 +551,26 @@ static inline void bnx2x_set_skb_rxhash(struct bnx2x *bp, union eth_rx_cqe *cqe, + le32_to_cpu(cqe->fast_path_cqe.rss_hash_result); + } + ++static void bnx2x_csum_validate(struct sk_buff *skb, union eth_rx_cqe *cqe, ++ struct bnx2x_fastpath *fp) ++{ ++ /* Do nothing if no IP/L4 csum validation was done */ ++ ++ if (cqe->fast_path_cqe.status_flags & ++ (ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG | ++ ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG)) ++ return; ++ ++ /* If both IP/L4 validation were done, check if an error was found. */ ++ ++ if (cqe->fast_path_cqe.type_error_flags & ++ (ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG | ++ ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG)) ++ fp->eth_q_stats.hw_csum_err++; ++ else ++ skb->ip_summed = CHECKSUM_UNNECESSARY; ++} ++ + int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) + { + struct bnx2x *bp = fp->bp; +@@ -746,13 +766,9 @@ reuse_rx: + + skb_checksum_none_assert(skb); + +- if (bp->dev->features & NETIF_F_RXCSUM) { ++ if (bp->dev->features & NETIF_F_RXCSUM) ++ bnx2x_csum_validate(skb, cqe, fp); + +- if (likely(BNX2X_RX_CSUM_OK(cqe))) +- skb->ip_summed = CHECKSUM_UNNECESSARY; +- else +- fp->eth_q_stats.hw_csum_err++; +- } + } + + skb_record_rx_queue(skb, fp->index); +@@ -2238,8 +2254,6 @@ int bnx2x_poll(struct napi_struct *napi, int budget) + /* we split the first BD into headers and data BDs + * to ease the pain of our fellow microcode engineers + * we use one mapping for both BDs +- * So far this has only been observed to happen +- * in Other Operating Systems(TM) + */ + static noinline u16 bnx2x_tx_split(struct bnx2x *bp, + struct bnx2x_fp_txdata *txdata, +@@ -2890,7 +2904,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) + + txdata->tx_bd_prod += nbd; + +- if (unlikely(bnx2x_tx_avail(bp, txdata) < MAX_SKB_FRAGS + 3)) { ++ if (unlikely(bnx2x_tx_avail(bp, txdata) < MAX_SKB_FRAGS + 4)) { + netif_tx_stop_queue(txq); + + /* paired memory barrier is in bnx2x_tx_int(), we have to keep +@@ -2899,7 +2913,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) + smp_mb(); + + fp->eth_q_stats.driver_xoff++; +- if (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 3) ++ if (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 4) + netif_tx_wake_queue(txq); + } + txdata->tx_pkt++; +diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c +index 2dcac28..6b258d9 100644 +--- a/drivers/net/ethernet/broadcom/tg3.c ++++ b/drivers/net/ethernet/broadcom/tg3.c +@@ -14046,7 +14046,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) + } + } + +- if (tg3_flag(tp, 5755_PLUS)) ++ if (tg3_flag(tp, 5755_PLUS) || ++ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) + tg3_flag_set(tp, SHORT_DMA_BUG); + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) +diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c +index e556fc3..3072d35 100644 +--- a/drivers/net/ethernet/intel/e1000e/82571.c ++++ b/drivers/net/ethernet/intel/e1000e/82571.c +@@ -1571,6 +1571,9 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) + ctrl = er32(CTRL); + status = er32(STATUS); + rxcw = er32(RXCW); ++ /* SYNCH bit and IV bit are sticky */ ++ udelay(10); ++ rxcw = er32(RXCW); + + if ((rxcw & E1000_RXCW_SYNCH) && !(rxcw & E1000_RXCW_IV)) { + +diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c +index cc2565c..9e61d6b 100644 +--- a/drivers/net/ethernet/realtek/r8169.c ++++ b/drivers/net/ethernet/realtek/r8169.c +@@ -4185,6 +4185,7 @@ out: + return rc; + + err_out_msi_4: ++ netif_napi_del(&tp->napi); + rtl_disable_msi(pdev, tp); + iounmap(ioaddr); + err_out_free_res_3: +@@ -4210,6 +4211,8 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) + + cancel_delayed_work_sync(&tp->task); + ++ netif_napi_del(&tp->napi); ++ + unregister_netdev(dev); + + rtl_release_firmware(tp); +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 72cd190..d4d2bc1 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -1174,6 +1174,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) + priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion); + wmb(); + priv->hw->desc->set_tx_owner(desc); ++ wmb(); + } + + /* Interrupt on completition only for the latest segment */ +@@ -1189,6 +1190,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) + + /* To avoid raise condition */ + priv->hw->desc->set_tx_owner(first); ++ wmb(); + + priv->cur_tx++; + +@@ -1252,6 +1254,7 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv) + } + wmb(); + priv->hw->desc->set_rx_owner(p + entry); ++ wmb(); + } + } + +diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c +index 1b7082d..26106c0 100644 +--- a/drivers/net/macvtap.c ++++ b/drivers/net/macvtap.c +@@ -504,10 +504,11 @@ static int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *from, + if (copy > size) { + ++from; + --count; +- } ++ offset = 0; ++ } else ++ offset += size; + copy -= size; + offset1 += size; +- offset = 0; + } + + if (len == offset1) +@@ -517,24 +518,29 @@ static int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *from, + struct page *page[MAX_SKB_FRAGS]; + int num_pages; + unsigned long base; ++ unsigned long truesize; + +- len = from->iov_len - offset1; ++ len = from->iov_len - offset; + if (!len) { +- offset1 = 0; ++ offset = 0; + ++from; + continue; + } +- base = (unsigned long)from->iov_base + offset1; ++ base = (unsigned long)from->iov_base + offset; + size = ((base & ~PAGE_MASK) + len + ~PAGE_MASK) >> PAGE_SHIFT; ++ if (i + size > MAX_SKB_FRAGS) ++ return -EMSGSIZE; + num_pages = get_user_pages_fast(base, size, 0, &page[i]); +- if ((num_pages != size) || +- (num_pages > MAX_SKB_FRAGS - skb_shinfo(skb)->nr_frags)) +- /* put_page is in skb free */ ++ if (num_pages != size) { ++ for (i = 0; i < num_pages; i++) ++ put_page(page[i]); + return -EFAULT; ++ } ++ truesize = size * PAGE_SIZE; + skb->data_len += len; + skb->len += len; +- skb->truesize += len; +- atomic_add(len, &skb->sk->sk_wmem_alloc); ++ skb->truesize += truesize; ++ atomic_add(truesize, &skb->sk->sk_wmem_alloc); + while (len) { + int off = base & ~PAGE_MASK; + int size = min_t(int, len, PAGE_SIZE - off); +@@ -545,7 +551,7 @@ static int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *from, + len -= size; + i++; + } +- offset1 = 0; ++ offset = 0; + ++from; + } + return 0; +@@ -645,7 +651,7 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, + int err; + struct virtio_net_hdr vnet_hdr = { 0 }; + int vnet_hdr_len = 0; +- int copylen; ++ int copylen = 0; + bool zerocopy = false; + + if (q->flags & IFF_VNET_HDR) { +@@ -674,15 +680,31 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, + if (unlikely(len < ETH_HLEN)) + goto err; + ++ err = -EMSGSIZE; ++ if (unlikely(count > UIO_MAXIOV)) ++ goto err; ++ + if (m && m->msg_control && sock_flag(&q->sk, SOCK_ZEROCOPY)) + zerocopy = true; + + if (zerocopy) { ++ /* Userspace may produce vectors with count greater than ++ * MAX_SKB_FRAGS, so we need to linearize parts of the skb ++ * to let the rest of data to be fit in the frags. ++ */ ++ if (count > MAX_SKB_FRAGS) { ++ copylen = iov_length(iv, count - MAX_SKB_FRAGS); ++ if (copylen < vnet_hdr_len) ++ copylen = 0; ++ else ++ copylen -= vnet_hdr_len; ++ } + /* There are 256 bytes to be copied in skb, so there is enough + * room for skb expand head in case it is used. + * The rest buffer is mapped from userspace. + */ +- copylen = vnet_hdr.hdr_len; ++ if (copylen < vnet_hdr.hdr_len) ++ copylen = vnet_hdr.hdr_len; + if (!copylen) + copylen = GOODCOPY_LEN; + } else +@@ -693,10 +715,9 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, + if (!skb) + goto err; + +- if (zerocopy) { ++ if (zerocopy) + err = zerocopy_sg_from_iovec(skb, iv, vnet_hdr_len, count); +- skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY; +- } else ++ else + err = skb_copy_datagram_from_iovec(skb, 0, iv, vnet_hdr_len, + len); + if (err) +@@ -715,8 +736,10 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, + rcu_read_lock_bh(); + vlan = rcu_dereference_bh(q->vlan); + /* copy skb_ubuf_info for callback when skb has no error */ +- if (zerocopy) ++ if (zerocopy) { + skb_shinfo(skb)->destructor_arg = m->msg_control; ++ skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY; ++ } + if (vlan) + macvlan_start_xmit(skb, vlan->dev); + else +diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c +index ad96164..00ed9c1 100644 +--- a/drivers/net/usb/ipheth.c ++++ b/drivers/net/usb/ipheth.c +@@ -59,6 +59,7 @@ + #define USB_PRODUCT_IPHONE_3G 0x1292 + #define USB_PRODUCT_IPHONE_3GS 0x1294 + #define USB_PRODUCT_IPHONE_4 0x1297 ++#define USB_PRODUCT_IPAD 0x129a + #define USB_PRODUCT_IPHONE_4_VZW 0x129c + #define USB_PRODUCT_IPHONE_4S 0x12a0 + +@@ -101,6 +102,10 @@ static struct usb_device_id ipheth_table[] = { + IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, + IPHETH_USBINTF_PROTO) }, + { USB_DEVICE_AND_INTERFACE_INFO( ++ USB_VENDOR_APPLE, USB_PRODUCT_IPAD, ++ IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, ++ IPHETH_USBINTF_PROTO) }, ++ { USB_DEVICE_AND_INTERFACE_INFO( + USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4_VZW, + IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, + IPHETH_USBINTF_PROTO) }, +diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c +index 833cbef..8a40ff9 100644 +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c +@@ -900,8 +900,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) + */ + if (!(txs->status & TX_STATUS_AMPDU) + && (txs->status & TX_STATUS_INTERMEDIATE)) { +- wiphy_err(wlc->wiphy, "%s: INTERMEDIATE but not AMPDU\n", +- __func__); ++ BCMMSG(wlc->wiphy, "INTERMEDIATE but not AMPDU\n"); + return false; + } + +diff --git a/drivers/net/wireless/ipw2x00/ipw.h b/drivers/net/wireless/ipw2x00/ipw.h +new file mode 100644 +index 0000000..4007bf5 +--- /dev/null ++++ b/drivers/net/wireless/ipw2x00/ipw.h +@@ -0,0 +1,23 @@ ++/* ++ * Intel Pro/Wireless 2100, 2200BG, 2915ABG network connection driver ++ * ++ * Copyright 2012 Stanislav Yakovlev <stas.yakovlev@gmail.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#ifndef __IPW_H__ ++#define __IPW_H__ ++ ++#include <linux/ieee80211.h> ++ ++static const u32 ipw_cipher_suites[] = { ++ WLAN_CIPHER_SUITE_WEP40, ++ WLAN_CIPHER_SUITE_WEP104, ++ WLAN_CIPHER_SUITE_TKIP, ++ WLAN_CIPHER_SUITE_CCMP, ++}; ++ ++#endif +diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c +index 127e9c6..10862d4 100644 +--- a/drivers/net/wireless/ipw2x00/ipw2100.c ++++ b/drivers/net/wireless/ipw2x00/ipw2100.c +@@ -166,6 +166,7 @@ that only one external action is invoked at a time. + #include <net/lib80211.h> + + #include "ipw2100.h" ++#include "ipw.h" + + #define IPW2100_VERSION "git-1.2.2" + +@@ -1955,6 +1956,9 @@ static int ipw2100_wdev_init(struct net_device *dev) + wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = bg_band; + } + ++ wdev->wiphy->cipher_suites = ipw_cipher_suites; ++ wdev->wiphy->n_cipher_suites = ARRAY_SIZE(ipw_cipher_suites); ++ + set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev); + if (wiphy_register(wdev->wiphy)) { + ipw2100_down(priv); +diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c +index 827889b..56bd370 100644 +--- a/drivers/net/wireless/ipw2x00/ipw2200.c ++++ b/drivers/net/wireless/ipw2x00/ipw2200.c +@@ -34,6 +34,7 @@ + #include <linux/slab.h> + #include <net/cfg80211-wext.h> + #include "ipw2200.h" ++#include "ipw.h" + + + #ifndef KBUILD_EXTMOD +@@ -11535,6 +11536,9 @@ static int ipw_wdev_init(struct net_device *dev) + wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = a_band; + } + ++ wdev->wiphy->cipher_suites = ipw_cipher_suites; ++ wdev->wiphy->n_cipher_suites = ARRAY_SIZE(ipw_cipher_suites); ++ + set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev); + + /* With that information in place, we can now register the wiphy... */ +diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-sta.c b/drivers/net/wireless/iwlegacy/iwl-4965-sta.c +index a262c23..0116ca8 100644 +--- a/drivers/net/wireless/iwlegacy/iwl-4965-sta.c ++++ b/drivers/net/wireless/iwlegacy/iwl-4965-sta.c +@@ -466,7 +466,7 @@ int iwl4965_remove_dynamic_key(struct iwl_priv *priv, + return 0; + } + +- if (priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) { ++ if (priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_INVALID) { + IWL_WARN(priv, "Removing wrong key %d 0x%x\n", + keyconf->keyidx, key_flags); + spin_unlock_irqrestore(&priv->sta_lock, flags); +@@ -483,7 +483,7 @@ int iwl4965_remove_dynamic_key(struct iwl_priv *priv, + sizeof(struct iwl4965_keyinfo)); + priv->stations[sta_id].sta.key.key_flags = + STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID; +- priv->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET; ++ priv->stations[sta_id].sta.key.key_offset = keyconf->hw_key_idx; + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + +diff --git a/drivers/net/wireless/iwlegacy/iwl-core.c b/drivers/net/wireless/iwlegacy/iwl-core.c +index 2bd5659..1bb64c9 100644 +--- a/drivers/net/wireless/iwlegacy/iwl-core.c ++++ b/drivers/net/wireless/iwlegacy/iwl-core.c +@@ -1884,14 +1884,12 @@ void iwl_legacy_bg_watchdog(unsigned long data) + return; + + /* monitor and check for other stuck queues */ +- if (iwl_legacy_is_any_associated(priv)) { +- for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) { +- /* skip as we already checked the command queue */ +- if (cnt == priv->cmd_queue) +- continue; +- if (iwl_legacy_check_stuck_queue(priv, cnt)) +- return; +- } ++ for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) { ++ /* skip as we already checked the command queue */ ++ if (cnt == priv->cmd_queue) ++ continue; ++ if (iwl_legacy_check_stuck_queue(priv, cnt)) ++ return; + } + + mod_timer(&priv->watchdog, jiffies + +diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c +index 1e31050..ba28807 100644 +--- a/drivers/net/wireless/rt2x00/rt2x00usb.c ++++ b/drivers/net/wireless/rt2x00/rt2x00usb.c +@@ -426,8 +426,8 @@ void rt2x00usb_kick_queue(struct data_queue *queue) + case QID_RX: + if (!rt2x00queue_full(queue)) + rt2x00queue_for_each_entry(queue, +- Q_INDEX_DONE, + Q_INDEX, ++ Q_INDEX_DONE, + NULL, + rt2x00usb_kick_rx_entry); + break; +diff --git a/drivers/net/wireless/rtl818x/rtl8187/leds.c b/drivers/net/wireless/rtl818x/rtl8187/leds.c +index 2e0de2f..c2d5b49 100644 +--- a/drivers/net/wireless/rtl818x/rtl8187/leds.c ++++ b/drivers/net/wireless/rtl818x/rtl8187/leds.c +@@ -117,7 +117,7 @@ static void rtl8187_led_brightness_set(struct led_classdev *led_dev, + radio_on = true; + } else if (radio_on) { + radio_on = false; +- cancel_delayed_work_sync(&priv->led_on); ++ cancel_delayed_work(&priv->led_on); + ieee80211_queue_delayed_work(hw, &priv->led_off, 0); + } + } else if (radio_on) { +diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c +index 12d1e81..d024f83 100644 +--- a/drivers/pci/pci-driver.c ++++ b/drivers/pci/pci-driver.c +@@ -742,6 +742,18 @@ static int pci_pm_suspend_noirq(struct device *dev) + + pci_pm_set_unknown_state(pci_dev); + ++ /* ++ * Some BIOSes from ASUS have a bug: If a USB EHCI host controller's ++ * PCI COMMAND register isn't 0, the BIOS assumes that the controller ++ * hasn't been quiesced and tries to turn it off. If the controller ++ * is already in D3, this can hang or cause memory corruption. ++ * ++ * Since the value of the COMMAND register doesn't matter once the ++ * device has been suspended, we can safely set it to 0 here. ++ */ ++ if (pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI) ++ pci_write_config_word(pci_dev, PCI_COMMAND, 0); ++ + return 0; + } + +diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c +index e5b75eb..6d4a531 100644 +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -1689,11 +1689,6 @@ int pci_prepare_to_sleep(struct pci_dev *dev) + if (target_state == PCI_POWER_ERROR) + return -EIO; + +- /* Some devices mustn't be in D3 during system sleep */ +- if (target_state == PCI_D3hot && +- (dev->dev_flags & PCI_DEV_FLAGS_NO_D3_DURING_SLEEP)) +- return 0; +- + pci_enable_wake(dev, target_state, device_may_wakeup(&dev->dev)); + + error = pci_set_power_state(dev, target_state); +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index 3c56fec..78fda9c 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -2940,32 +2940,6 @@ static void __devinit disable_igfx_irq(struct pci_dev *dev) + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0102, disable_igfx_irq); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq); + +-/* +- * The Intel 6 Series/C200 Series chipset's EHCI controllers on many +- * ASUS motherboards will cause memory corruption or a system crash +- * if they are in D3 while the system is put into S3 sleep. +- */ +-static void __devinit asus_ehci_no_d3(struct pci_dev *dev) +-{ +- const char *sys_info; +- static const char good_Asus_board[] = "P8Z68-V"; +- +- if (dev->dev_flags & PCI_DEV_FLAGS_NO_D3_DURING_SLEEP) +- return; +- if (dev->subsystem_vendor != PCI_VENDOR_ID_ASUSTEK) +- return; +- sys_info = dmi_get_system_info(DMI_BOARD_NAME); +- if (sys_info && memcmp(sys_info, good_Asus_board, +- sizeof(good_Asus_board) - 1) == 0) +- return; +- +- dev_info(&dev->dev, "broken D3 during system sleep on ASUS\n"); +- dev->dev_flags |= PCI_DEV_FLAGS_NO_D3_DURING_SLEEP; +- device_set_wakeup_capable(&dev->dev, false); +-} +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1c26, asus_ehci_no_d3); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1c2d, asus_ehci_no_d3); +- + static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, + struct pci_fixup *end) + { +diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c +index 809a3ae..b46ec11 100644 +--- a/drivers/platform/x86/intel_ips.c ++++ b/drivers/platform/x86/intel_ips.c +@@ -72,6 +72,7 @@ + #include <linux/string.h> + #include <linux/tick.h> + #include <linux/timer.h> ++#include <linux/dmi.h> + #include <drm/i915_drm.h> + #include <asm/msr.h> + #include <asm/processor.h> +@@ -1505,6 +1506,24 @@ static DEFINE_PCI_DEVICE_TABLE(ips_id_table) = { + + MODULE_DEVICE_TABLE(pci, ips_id_table); + ++static int ips_blacklist_callback(const struct dmi_system_id *id) ++{ ++ pr_info("Blacklisted intel_ips for %s\n", id->ident); ++ return 1; ++} ++ ++static const struct dmi_system_id ips_blacklist[] = { ++ { ++ .callback = ips_blacklist_callback, ++ .ident = "HP ProBook", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook"), ++ }, ++ }, ++ { } /* terminating entry */ ++}; ++ + static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) + { + u64 platform_info; +@@ -1514,6 +1533,9 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) + u16 htshi, trc, trc_required_mask; + u8 tse; + ++ if (dmi_check_system(ips_blacklist)) ++ return -ENODEV; ++ + ips = kzalloc(sizeof(struct ips_driver), GFP_KERNEL); + if (!ips) + return -ENOMEM; +diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c +index 09e26bf..af1e296 100644 +--- a/drivers/platform/x86/samsung-laptop.c ++++ b/drivers/platform/x86/samsung-laptop.c +@@ -540,245 +540,34 @@ static DEVICE_ATTR(performance_level, S_IWUSR | S_IRUGO, + get_performance_level, set_performance_level); + + +-static int __init dmi_check_cb(const struct dmi_system_id *id) +-{ +- pr_info("found laptop model '%s'\n", +- id->ident); +- return 1; +-} +- + static struct dmi_system_id __initdata samsung_dmi_table[] = { + { +- .ident = "N128", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, +- "SAMSUNG ELECTRONICS CO., LTD."), +- DMI_MATCH(DMI_PRODUCT_NAME, "N128"), +- DMI_MATCH(DMI_BOARD_NAME, "N128"), +- }, +- .callback = dmi_check_cb, +- }, +- { +- .ident = "N130", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, + "SAMSUNG ELECTRONICS CO., LTD."), +- DMI_MATCH(DMI_PRODUCT_NAME, "N130"), +- DMI_MATCH(DMI_BOARD_NAME, "N130"), ++ DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ + }, +- .callback = dmi_check_cb, + }, + { +- .ident = "N510", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, + "SAMSUNG ELECTRONICS CO., LTD."), +- DMI_MATCH(DMI_PRODUCT_NAME, "N510"), +- DMI_MATCH(DMI_BOARD_NAME, "N510"), ++ DMI_MATCH(DMI_CHASSIS_TYPE, "9"), /* Laptop */ + }, +- .callback = dmi_check_cb, + }, + { +- .ident = "X125", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, + "SAMSUNG ELECTRONICS CO., LTD."), +- DMI_MATCH(DMI_PRODUCT_NAME, "X125"), +- DMI_MATCH(DMI_BOARD_NAME, "X125"), ++ DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */ + }, +- .callback = dmi_check_cb, + }, + { +- .ident = "X120/X170", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, + "SAMSUNG ELECTRONICS CO., LTD."), +- DMI_MATCH(DMI_PRODUCT_NAME, "X120/X170"), +- DMI_MATCH(DMI_BOARD_NAME, "X120/X170"), +- }, +- .callback = dmi_check_cb, +- }, +- { +- .ident = "NC10", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, +- "SAMSUNG ELECTRONICS CO., LTD."), +- DMI_MATCH(DMI_PRODUCT_NAME, "NC10"), +- DMI_MATCH(DMI_BOARD_NAME, "NC10"), +- }, +- .callback = dmi_check_cb, +- }, +- { +- .ident = "NP-Q45", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, +- "SAMSUNG ELECTRONICS CO., LTD."), +- DMI_MATCH(DMI_PRODUCT_NAME, "SQ45S70S"), +- DMI_MATCH(DMI_BOARD_NAME, "SQ45S70S"), +- }, +- .callback = dmi_check_cb, +- }, +- { +- .ident = "X360", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, +- "SAMSUNG ELECTRONICS CO., LTD."), +- DMI_MATCH(DMI_PRODUCT_NAME, "X360"), +- DMI_MATCH(DMI_BOARD_NAME, "X360"), +- }, +- .callback = dmi_check_cb, +- }, +- { +- .ident = "R410 Plus", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, +- "SAMSUNG ELECTRONICS CO., LTD."), +- DMI_MATCH(DMI_PRODUCT_NAME, "R410P"), +- DMI_MATCH(DMI_BOARD_NAME, "R460"), +- }, +- .callback = dmi_check_cb, +- }, +- { +- .ident = "R518", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, +- "SAMSUNG ELECTRONICS CO., LTD."), +- DMI_MATCH(DMI_PRODUCT_NAME, "R518"), +- DMI_MATCH(DMI_BOARD_NAME, "R518"), +- }, +- .callback = dmi_check_cb, +- }, +- { +- .ident = "R519/R719", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, +- "SAMSUNG ELECTRONICS CO., LTD."), +- DMI_MATCH(DMI_PRODUCT_NAME, "R519/R719"), +- DMI_MATCH(DMI_BOARD_NAME, "R519/R719"), +- }, +- .callback = dmi_check_cb, +- }, +- { +- .ident = "N150/N210/N220", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, +- "SAMSUNG ELECTRONICS CO., LTD."), +- DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220"), +- DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220"), +- }, +- .callback = dmi_check_cb, +- }, +- { +- .ident = "N220", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, +- "SAMSUNG ELECTRONICS CO., LTD."), +- DMI_MATCH(DMI_PRODUCT_NAME, "N220"), +- DMI_MATCH(DMI_BOARD_NAME, "N220"), +- }, +- .callback = dmi_check_cb, +- }, +- { +- .ident = "N150/N210/N220/N230", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, +- "SAMSUNG ELECTRONICS CO., LTD."), +- DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220/N230"), +- DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220/N230"), +- }, +- .callback = dmi_check_cb, +- }, +- { +- .ident = "N150P/N210P/N220P", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, +- "SAMSUNG ELECTRONICS CO., LTD."), +- DMI_MATCH(DMI_PRODUCT_NAME, "N150P/N210P/N220P"), +- DMI_MATCH(DMI_BOARD_NAME, "N150P/N210P/N220P"), +- }, +- .callback = dmi_check_cb, +- }, +- { +- .ident = "R700", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), +- DMI_MATCH(DMI_PRODUCT_NAME, "SR700"), +- DMI_MATCH(DMI_BOARD_NAME, "SR700"), +- }, +- .callback = dmi_check_cb, +- }, +- { +- .ident = "R530/R730", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), +- DMI_MATCH(DMI_PRODUCT_NAME, "R530/R730"), +- DMI_MATCH(DMI_BOARD_NAME, "R530/R730"), +- }, +- .callback = dmi_check_cb, +- }, +- { +- .ident = "NF110/NF210/NF310", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), +- DMI_MATCH(DMI_PRODUCT_NAME, "NF110/NF210/NF310"), +- DMI_MATCH(DMI_BOARD_NAME, "NF110/NF210/NF310"), +- }, +- .callback = dmi_check_cb, +- }, +- { +- .ident = "N145P/N250P/N260P", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), +- DMI_MATCH(DMI_PRODUCT_NAME, "N145P/N250P/N260P"), +- DMI_MATCH(DMI_BOARD_NAME, "N145P/N250P/N260P"), +- }, +- .callback = dmi_check_cb, +- }, +- { +- .ident = "R70/R71", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, +- "SAMSUNG ELECTRONICS CO., LTD."), +- DMI_MATCH(DMI_PRODUCT_NAME, "R70/R71"), +- DMI_MATCH(DMI_BOARD_NAME, "R70/R71"), +- }, +- .callback = dmi_check_cb, +- }, +- { +- .ident = "P460", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), +- DMI_MATCH(DMI_PRODUCT_NAME, "P460"), +- DMI_MATCH(DMI_BOARD_NAME, "P460"), +- }, +- .callback = dmi_check_cb, +- }, +- { +- .ident = "R528/R728", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), +- DMI_MATCH(DMI_PRODUCT_NAME, "R528/R728"), +- DMI_MATCH(DMI_BOARD_NAME, "R528/R728"), +- }, +- .callback = dmi_check_cb, +- }, +- { +- .ident = "NC210/NC110", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), +- DMI_MATCH(DMI_PRODUCT_NAME, "NC210/NC110"), +- DMI_MATCH(DMI_BOARD_NAME, "NC210/NC110"), +- }, +- .callback = dmi_check_cb, +- }, +- { +- .ident = "X520", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), +- DMI_MATCH(DMI_PRODUCT_NAME, "X520"), +- DMI_MATCH(DMI_BOARD_NAME, "X520"), ++ DMI_MATCH(DMI_CHASSIS_TYPE, "14"), /* Sub-Notebook */ + }, +- .callback = dmi_check_cb, + }, + { }, + }; +@@ -819,7 +608,8 @@ static int __init samsung_init(void) + + f0000_segment = ioremap_nocache(0xf0000, 0xffff); + if (!f0000_segment) { +- pr_err("Can't map the segment at 0xf0000\n"); ++ if (debug || force) ++ pr_err("Can't map the segment at 0xf0000\n"); + return -EINVAL; + } + +@@ -832,7 +622,8 @@ static int __init samsung_init(void) + } + + if (loca == 0xffff) { +- pr_err("This computer does not support SABI\n"); ++ if (debug || force) ++ pr_err("This computer does not support SABI\n"); + goto error_no_signature; + } + +diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c +index 39e41fb..5160354 100644 +--- a/drivers/rtc/rtc-mxc.c ++++ b/drivers/rtc/rtc-mxc.c +@@ -191,10 +191,11 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id) + struct platform_device *pdev = dev_id; + struct rtc_plat_data *pdata = platform_get_drvdata(pdev); + void __iomem *ioaddr = pdata->ioaddr; ++ unsigned long flags; + u32 status; + u32 events = 0; + +- spin_lock_irq(&pdata->rtc->irq_lock); ++ spin_lock_irqsave(&pdata->rtc->irq_lock, flags); + status = readw(ioaddr + RTC_RTCISR) & readw(ioaddr + RTC_RTCIENR); + /* clear interrupt sources */ + writew(status, ioaddr + RTC_RTCISR); +@@ -217,7 +218,7 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id) + rtc_update_alarm(&pdev->dev, &pdata->g_rtc_alarm); + + rtc_update_irq(pdata->rtc, 1, events); +- spin_unlock_irq(&pdata->rtc->irq_lock); ++ spin_unlock_irqrestore(&pdata->rtc->irq_lock, flags); + + return IRQ_HANDLED; + } +diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c +index 532d212..393e7ce 100644 +--- a/drivers/scsi/aic94xx/aic94xx_task.c ++++ b/drivers/scsi/aic94xx/aic94xx_task.c +@@ -201,7 +201,7 @@ static void asd_get_response_tasklet(struct asd_ascb *ascb, + + if (SAS_STATUS_BUF_SIZE >= sizeof(*resp)) { + resp->frame_len = le16_to_cpu(*(__le16 *)(r+6)); +- memcpy(&resp->ending_fis[0], r+16, 24); ++ memcpy(&resp->ending_fis[0], r+16, ATA_RESP_FIS_SIZE); + ts->buf_valid_size = sizeof(*resp); + } + } +diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c +index db9238f..4868fc9 100644 +--- a/drivers/scsi/libsas/sas_ata.c ++++ b/drivers/scsi/libsas/sas_ata.c +@@ -112,12 +112,12 @@ static void sas_ata_task_done(struct sas_task *task) + if (stat->stat == SAS_PROTO_RESPONSE || stat->stat == SAM_STAT_GOOD || + ((stat->stat == SAM_STAT_CHECK_CONDITION && + dev->sata_dev.command_set == ATAPI_COMMAND_SET))) { +- ata_tf_from_fis(resp->ending_fis, &dev->sata_dev.tf); ++ memcpy(dev->sata_dev.fis, resp->ending_fis, ATA_RESP_FIS_SIZE); + + if (!link->sactive) { +- qc->err_mask |= ac_err_mask(dev->sata_dev.tf.command); ++ qc->err_mask |= ac_err_mask(dev->sata_dev.fis[2]); + } else { +- link->eh_info.err_mask |= ac_err_mask(dev->sata_dev.tf.command); ++ link->eh_info.err_mask |= ac_err_mask(dev->sata_dev.fis[2]); + if (unlikely(link->eh_info.err_mask)) + qc->flags |= ATA_QCFLAG_FAILED; + } +@@ -138,8 +138,8 @@ static void sas_ata_task_done(struct sas_task *task) + qc->flags |= ATA_QCFLAG_FAILED; + } + +- dev->sata_dev.tf.feature = 0x04; /* status err */ +- dev->sata_dev.tf.command = ATA_ERR; ++ dev->sata_dev.fis[3] = 0x04; /* status err */ ++ dev->sata_dev.fis[2] = ATA_ERR; + } + } + +@@ -252,7 +252,7 @@ static bool sas_ata_qc_fill_rtf(struct ata_queued_cmd *qc) + { + struct domain_device *dev = qc->ap->private_data; + +- memcpy(&qc->result_tf, &dev->sata_dev.tf, sizeof(qc->result_tf)); ++ ata_tf_from_fis(dev->sata_dev.fis, &qc->result_tf); + return true; + } + +diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c +index 65ea65a..93b9406 100644 +--- a/drivers/target/target_core_cdb.c ++++ b/drivers/target/target_core_cdb.c +@@ -1199,7 +1199,7 @@ int target_emulate_write_same(struct se_task *task) + if (num_blocks != 0) + range = num_blocks; + else +- range = (dev->transport->get_blocks(dev) - lba); ++ range = (dev->transport->get_blocks(dev) - lba) + 1; + + pr_debug("WRITE_SAME UNMAP: LBA: %llu Range: %llu\n", + (unsigned long long)lba, (unsigned long long)range); +diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c +index b75bc92..9145141 100644 +--- a/drivers/target/target_core_pr.c ++++ b/drivers/target/target_core_pr.c +@@ -2042,7 +2042,7 @@ static int __core_scsi3_write_aptpl_to_file( + if (IS_ERR(file) || !file || !file->f_dentry) { + pr_err("filp_open(%s) for APTPL metadata" + " failed\n", path); +- return (PTR_ERR(file) < 0 ? PTR_ERR(file) : -ENOENT); ++ return IS_ERR(file) ? PTR_ERR(file) : -ENOENT; + } + + iov[0].iov_base = &buf[0]; +@@ -3853,7 +3853,7 @@ int target_scsi3_emulate_pr_out(struct se_task *task) + " SPC-2 reservation is held, returning" + " RESERVATION_CONFLICT\n"); + cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; +- ret = EINVAL; ++ ret = -EINVAL; + goto out; + } + +@@ -3863,7 +3863,8 @@ int target_scsi3_emulate_pr_out(struct se_task *task) + */ + if (!cmd->se_sess) { + cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; +- return -EINVAL; ++ ret = -EINVAL; ++ goto out; + } + + if (cmd->data_length < 24) { +diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c +index d95cfe2..278819c 100644 +--- a/drivers/target/tcm_fc/tfc_cmd.c ++++ b/drivers/target/tcm_fc/tfc_cmd.c +@@ -249,6 +249,8 @@ u32 ft_get_task_tag(struct se_cmd *se_cmd) + { + struct ft_cmd *cmd = container_of(se_cmd, struct ft_cmd, se_cmd); + ++ if (cmd->aborted) ++ return ~0; + return fc_seq_exch(cmd->seq)->rxid; + } + +diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c +index 19fb5fa..9aaed0d 100644 +--- a/drivers/usb/class/cdc-wdm.c ++++ b/drivers/usb/class/cdc-wdm.c +@@ -473,6 +473,8 @@ retry: + goto retry; + } + if (!desc->reslength) { /* zero length read */ ++ dev_dbg(&desc->intf->dev, "%s: zero length - clearing WDM_READ\n", __func__); ++ clear_bit(WDM_READ, &desc->flags); + spin_unlock_irq(&desc->iuspin); + goto retry; + } +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index 52d27ed..175b6bb 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -2039,12 +2039,16 @@ static unsigned hub_is_wusb(struct usb_hub *hub) + static int hub_port_reset(struct usb_hub *hub, int port1, + struct usb_device *udev, unsigned int delay, bool warm); + +-/* Is a USB 3.0 port in the Inactive state? */ +-static bool hub_port_inactive(struct usb_hub *hub, u16 portstatus) ++/* Is a USB 3.0 port in the Inactive or Complinance Mode state? ++ * Port worm reset is required to recover ++ */ ++static bool hub_port_warm_reset_required(struct usb_hub *hub, u16 portstatus) + { + return hub_is_superspeed(hub->hdev) && +- (portstatus & USB_PORT_STAT_LINK_STATE) == +- USB_SS_PORT_LS_SS_INACTIVE; ++ (((portstatus & USB_PORT_STAT_LINK_STATE) == ++ USB_SS_PORT_LS_SS_INACTIVE) || ++ ((portstatus & USB_PORT_STAT_LINK_STATE) == ++ USB_SS_PORT_LS_COMP_MOD)) ; + } + + static int hub_port_wait_reset(struct usb_hub *hub, int port1, +@@ -2080,7 +2084,7 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1, + * + * See https://bugzilla.kernel.org/show_bug.cgi?id=41752 + */ +- if (hub_port_inactive(hub, portstatus)) { ++ if (hub_port_warm_reset_required(hub, portstatus)) { + int ret; + + if ((portchange & USB_PORT_STAT_C_CONNECTION)) +@@ -3646,9 +3650,7 @@ static void hub_events(void) + /* Warm reset a USB3 protocol port if it's in + * SS.Inactive state. + */ +- if (hub_is_superspeed(hub->hdev) && +- (portstatus & USB_PORT_STAT_LINK_STATE) +- == USB_SS_PORT_LS_SS_INACTIVE) { ++ if (hub_port_warm_reset_required(hub, portstatus)) { + dev_dbg(hub_dev, "warm reset port %d\n", i); + hub_port_reset(hub, i, NULL, + HUB_BH_RESET_TIME, true); +diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c +index a8b2980..fd8a2c2 100644 +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -438,6 +438,42 @@ void xhci_test_and_clear_bit(struct xhci_hcd *xhci, __le32 __iomem **port_array, + } + } + ++/* Updates Link Status for super Speed port */ ++static void xhci_hub_report_link_state(u32 *status, u32 status_reg) ++{ ++ u32 pls = status_reg & PORT_PLS_MASK; ++ ++ /* resume state is a xHCI internal state. ++ * Do not report it to usb core. ++ */ ++ if (pls == XDEV_RESUME) ++ return; ++ ++ /* When the CAS bit is set then warm reset ++ * should be performed on port ++ */ ++ if (status_reg & PORT_CAS) { ++ /* The CAS bit can be set while the port is ++ * in any link state. ++ * Only roothubs have CAS bit, so we ++ * pretend to be in compliance mode ++ * unless we're already in compliance ++ * or the inactive state. ++ */ ++ if (pls != USB_SS_PORT_LS_COMP_MOD && ++ pls != USB_SS_PORT_LS_SS_INACTIVE) { ++ pls = USB_SS_PORT_LS_COMP_MOD; ++ } ++ /* Return also connection bit - ++ * hub state machine resets port ++ * when this bit is set. ++ */ ++ pls |= USB_PORT_STAT_CONNECTION; ++ } ++ /* update status field */ ++ *status |= pls; ++} ++ + int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + u16 wIndex, char *buf, u16 wLength) + { +@@ -579,13 +615,9 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + else + status |= USB_PORT_STAT_POWER; + } +- /* Port Link State */ ++ /* Update Port Link State for super speed ports*/ + if (hcd->speed == HCD_USB3) { +- /* resume state is a xHCI internal state. +- * Do not report it to usb core. +- */ +- if ((temp & PORT_PLS_MASK) != XDEV_RESUME) +- status |= (temp & PORT_PLS_MASK); ++ xhci_hub_report_link_state(&status, temp); + } + if (bus_state->port_c_suspend & (1 << wIndex)) + status |= 1 << USB_PORT_FEAT_C_SUSPEND; +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index 363b141..7a56805 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -341,7 +341,11 @@ struct xhci_op_regs { + #define PORT_PLC (1 << 22) + /* port configure error change - port failed to configure its link partner */ + #define PORT_CEC (1 << 23) +-/* bit 24 reserved */ ++/* Cold Attach Status - xHC can set this bit to report device attached during ++ * Sx state. Warm port reset should be perfomed to clear this bit and move port ++ * to connected state. ++ */ ++#define PORT_CAS (1 << 24) + /* wake on connect (enable) */ + #define PORT_WKCONN_E (1 << 25) + /* wake on disconnect (enable) */ +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 21a4734..5971c95 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -496,6 +496,15 @@ static void option_instat_callback(struct urb *urb); + + /* MediaTek products */ + #define MEDIATEK_VENDOR_ID 0x0e8d ++#define MEDIATEK_PRODUCT_DC_1COM 0x00a0 ++#define MEDIATEK_PRODUCT_DC_4COM 0x00a5 ++#define MEDIATEK_PRODUCT_DC_5COM 0x00a4 ++#define MEDIATEK_PRODUCT_7208_1COM 0x7101 ++#define MEDIATEK_PRODUCT_7208_2COM 0x7102 ++#define MEDIATEK_PRODUCT_FP_1COM 0x0003 ++#define MEDIATEK_PRODUCT_FP_2COM 0x0023 ++#define MEDIATEK_PRODUCT_FPDC_1COM 0x0043 ++#define MEDIATEK_PRODUCT_FPDC_2COM 0x0033 + + /* Cellient products */ + #define CELLIENT_VENDOR_ID 0x2692 +@@ -553,6 +562,10 @@ static const struct option_blacklist_info net_intf1_blacklist = { + .reserved = BIT(1), + }; + ++static const struct option_blacklist_info net_intf2_blacklist = { ++ .reserved = BIT(2), ++}; ++ + static const struct option_blacklist_info net_intf3_blacklist = { + .reserved = BIT(3), + }; +@@ -1093,6 +1106,8 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1298, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1299, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1300, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1402, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, + 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, +@@ -1234,6 +1249,17 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a1, 0xff, 0x02, 0x01) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a2, 0xff, 0x00, 0x00) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a2, 0xff, 0x02, 0x01) }, /* MediaTek MT6276M modem & app port */ ++ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_1COM, 0x0a, 0x00, 0x00) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_5COM, 0xff, 0x02, 0x01) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_5COM, 0xff, 0x00, 0x00) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_4COM, 0xff, 0x02, 0x01) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_4COM, 0xff, 0x00, 0x00) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_7208_1COM, 0x02, 0x00, 0x00) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_7208_2COM, 0x02, 0x02, 0x01) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FP_1COM, 0x0a, 0x00, 0x00) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FP_2COM, 0x0a, 0x00, 0x00) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FPDC_1COM, 0x0a, 0x00, 0x00) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FPDC_2COM, 0x0a, 0x00, 0x00) }, + { USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) }, + { } /* Terminating entry */ + }; +diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c +index c14c42b..ae66278 100644 +--- a/drivers/vhost/vhost.c ++++ b/drivers/vhost/vhost.c +@@ -222,6 +222,8 @@ static int vhost_worker(void *data) + if (work) { + __set_current_state(TASK_RUNNING); + work->fn(work); ++ if (need_resched()) ++ schedule(); + } else + schedule(); + +diff --git a/fs/buffer.c b/fs/buffer.c +index c807931..4115eca 100644 +--- a/fs/buffer.c ++++ b/fs/buffer.c +@@ -1087,6 +1087,9 @@ grow_buffers(struct block_device *bdev, sector_t block, int size) + static struct buffer_head * + __getblk_slow(struct block_device *bdev, sector_t block, int size) + { ++ int ret; ++ struct buffer_head *bh; ++ + /* Size must be multiple of hard sectorsize */ + if (unlikely(size & (bdev_logical_block_size(bdev)-1) || + (size < 512 || size > PAGE_SIZE))) { +@@ -1099,20 +1102,21 @@ __getblk_slow(struct block_device *bdev, sector_t block, int size) + return NULL; + } + +- for (;;) { +- struct buffer_head * bh; +- int ret; ++retry: ++ bh = __find_get_block(bdev, block, size); ++ if (bh) ++ return bh; + ++ ret = grow_buffers(bdev, block, size); ++ if (ret == 0) { ++ free_more_memory(); ++ goto retry; ++ } else if (ret > 0) { + bh = __find_get_block(bdev, block, size); + if (bh) + return bh; +- +- ret = grow_buffers(bdev, block, size); +- if (ret < 0) +- return NULL; +- if (ret == 0) +- free_more_memory(); + } ++ return NULL; + } + + /* +diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c +index b21670c..56c152d 100644 +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -2925,6 +2925,18 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, + #define CIFS_DEFAULT_NON_POSIX_RSIZE (60 * 1024) + #define CIFS_DEFAULT_NON_POSIX_WSIZE (65536) + ++/* ++ * On hosts with high memory, we can't currently support wsize/rsize that are ++ * larger than we can kmap at once. Cap the rsize/wsize at ++ * LAST_PKMAP * PAGE_SIZE. We'll never be able to fill a read or write request ++ * larger than that anyway. ++ */ ++#ifdef CONFIG_HIGHMEM ++#define CIFS_KMAP_SIZE_LIMIT (LAST_PKMAP * PAGE_CACHE_SIZE) ++#else /* CONFIG_HIGHMEM */ ++#define CIFS_KMAP_SIZE_LIMIT (1<<24) ++#endif /* CONFIG_HIGHMEM */ ++ + static unsigned int + cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) + { +@@ -2955,6 +2967,9 @@ cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) + wsize = min_t(unsigned int, wsize, + server->maxBuf - sizeof(WRITE_REQ) + 4); + ++ /* limit to the amount that we can kmap at once */ ++ wsize = min_t(unsigned int, wsize, CIFS_KMAP_SIZE_LIMIT); ++ + /* hard limit of CIFS_MAX_WSIZE */ + wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE); + +@@ -2996,6 +3011,9 @@ cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) + if (!(server->capabilities & CAP_LARGE_READ_X)) + rsize = min_t(unsigned int, CIFSMaxBufSize, rsize); + ++ /* limit to the amount that we can kmap at once */ ++ rsize = min_t(unsigned int, rsize, CIFS_KMAP_SIZE_LIMIT); ++ + /* hard limit of CIFS_MAX_RSIZE */ + rsize = min_t(unsigned int, rsize, CIFS_MAX_RSIZE); + +diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c +index db4a138..4c37ed4 100644 +--- a/fs/cifs/readdir.c ++++ b/fs/cifs/readdir.c +@@ -86,9 +86,12 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name, + + dentry = d_lookup(parent, name); + if (dentry) { +- /* FIXME: check for inode number changes? */ +- if (dentry->d_inode != NULL) ++ inode = dentry->d_inode; ++ /* update inode in place if i_ino didn't change */ ++ if (inode && CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) { ++ cifs_fattr_to_inode(inode, fattr); + return dentry; ++ } + d_drop(dentry); + dput(dentry); + } +diff --git a/fs/ecryptfs/kthread.c b/fs/ecryptfs/kthread.c +index 69f994a..0dbe58a 100644 +--- a/fs/ecryptfs/kthread.c ++++ b/fs/ecryptfs/kthread.c +@@ -149,7 +149,7 @@ int ecryptfs_privileged_open(struct file **lower_file, + (*lower_file) = dentry_open(lower_dentry, lower_mnt, flags, cred); + if (!IS_ERR(*lower_file)) + goto out; +- if (flags & O_RDONLY) { ++ if ((flags & O_ACCMODE) == O_RDONLY) { + rc = PTR_ERR((*lower_file)); + goto out; + } +diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c +index 0dc5a3d..de42310 100644 +--- a/fs/ecryptfs/miscdev.c ++++ b/fs/ecryptfs/miscdev.c +@@ -49,7 +49,10 @@ ecryptfs_miscdev_poll(struct file *file, poll_table *pt) + mutex_lock(&ecryptfs_daemon_hash_mux); + /* TODO: Just use file->private_data? */ + rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); +- BUG_ON(rc || !daemon); ++ if (rc || !daemon) { ++ mutex_unlock(&ecryptfs_daemon_hash_mux); ++ return -EINVAL; ++ } + mutex_lock(&daemon->mux); + mutex_unlock(&ecryptfs_daemon_hash_mux); + if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { +@@ -122,6 +125,7 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file) + goto out_unlock_daemon; + } + daemon->flags |= ECRYPTFS_DAEMON_MISCDEV_OPEN; ++ file->private_data = daemon; + atomic_inc(&ecryptfs_num_miscdev_opens); + out_unlock_daemon: + mutex_unlock(&daemon->mux); +@@ -152,9 +156,9 @@ ecryptfs_miscdev_release(struct inode *inode, struct file *file) + + mutex_lock(&ecryptfs_daemon_hash_mux); + rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); +- BUG_ON(rc || !daemon); ++ if (rc || !daemon) ++ daemon = file->private_data; + mutex_lock(&daemon->mux); +- BUG_ON(daemon->pid != task_pid(current)); + BUG_ON(!(daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN)); + daemon->flags &= ~ECRYPTFS_DAEMON_MISCDEV_OPEN; + atomic_dec(&ecryptfs_num_miscdev_opens); +@@ -191,31 +195,32 @@ int ecryptfs_send_miscdev(char *data, size_t data_size, + struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type, + u16 msg_flags, struct ecryptfs_daemon *daemon) + { +- int rc = 0; ++ struct ecryptfs_message *msg; + +- mutex_lock(&msg_ctx->mux); +- msg_ctx->msg = kmalloc((sizeof(*msg_ctx->msg) + data_size), +- GFP_KERNEL); +- if (!msg_ctx->msg) { +- rc = -ENOMEM; ++ msg = kmalloc((sizeof(*msg) + data_size), GFP_KERNEL); ++ if (!msg) { + printk(KERN_ERR "%s: Out of memory whilst attempting " + "to kmalloc(%zd, GFP_KERNEL)\n", __func__, +- (sizeof(*msg_ctx->msg) + data_size)); +- goto out_unlock; ++ (sizeof(*msg) + data_size)); ++ return -ENOMEM; + } ++ ++ mutex_lock(&msg_ctx->mux); ++ msg_ctx->msg = msg; + msg_ctx->msg->index = msg_ctx->index; + msg_ctx->msg->data_len = data_size; + msg_ctx->type = msg_type; + memcpy(msg_ctx->msg->data, data, data_size); + msg_ctx->msg_size = (sizeof(*msg_ctx->msg) + data_size); +- mutex_lock(&daemon->mux); + list_add_tail(&msg_ctx->daemon_out_list, &daemon->msg_ctx_out_queue); ++ mutex_unlock(&msg_ctx->mux); ++ ++ mutex_lock(&daemon->mux); + daemon->num_queued_msg_ctx++; + wake_up_interruptible(&daemon->wait); + mutex_unlock(&daemon->mux); +-out_unlock: +- mutex_unlock(&msg_ctx->mux); +- return rc; ++ ++ return 0; + } + + /** +@@ -246,8 +251,16 @@ ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count, + mutex_lock(&ecryptfs_daemon_hash_mux); + /* TODO: Just use file->private_data? */ + rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); +- BUG_ON(rc || !daemon); ++ if (rc || !daemon) { ++ mutex_unlock(&ecryptfs_daemon_hash_mux); ++ return -EINVAL; ++ } + mutex_lock(&daemon->mux); ++ if (task_pid(current) != daemon->pid) { ++ mutex_unlock(&daemon->mux); ++ mutex_unlock(&ecryptfs_daemon_hash_mux); ++ return -EPERM; ++ } + if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { + rc = 0; + mutex_unlock(&ecryptfs_daemon_hash_mux); +@@ -284,9 +297,6 @@ check_list: + * message from the queue; try again */ + goto check_list; + } +- BUG_ON(euid != daemon->euid); +- BUG_ON(current_user_ns() != daemon->user_ns); +- BUG_ON(task_pid(current) != daemon->pid); + msg_ctx = list_first_entry(&daemon->msg_ctx_out_queue, + struct ecryptfs_msg_ctx, daemon_out_list); + BUG_ON(!msg_ctx); +diff --git a/fs/eventpoll.c b/fs/eventpoll.c +index 4d9d3a4..a6f3763 100644 +--- a/fs/eventpoll.c ++++ b/fs/eventpoll.c +@@ -1629,8 +1629,10 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd, + if (op == EPOLL_CTL_ADD) { + if (is_file_epoll(tfile)) { + error = -ELOOP; +- if (ep_loop_check(ep, tfile) != 0) ++ if (ep_loop_check(ep, tfile) != 0) { ++ clear_tfile_check_list(); + goto error_tgt_fput; ++ } + } else + list_add(&tfile->f_tfile_llink, &tfile_check_list); + } +diff --git a/fs/exofs/ore.c b/fs/exofs/ore.c +index 49cf230..24a49d4 100644 +--- a/fs/exofs/ore.c ++++ b/fs/exofs/ore.c +@@ -735,13 +735,7 @@ static int _prepare_for_striping(struct ore_io_state *ios) + out: + ios->numdevs = devs_in_group; + ios->pages_consumed = cur_pg; +- if (unlikely(ret)) { +- if (length == ios->length) +- return ret; +- else +- ios->length -= length; +- } +- return 0; ++ return ret; + } + + int ore_create(struct ore_io_state *ios) +diff --git a/fs/exofs/ore_raid.c b/fs/exofs/ore_raid.c +index d222c77..fff2070 100644 +--- a/fs/exofs/ore_raid.c ++++ b/fs/exofs/ore_raid.c +@@ -461,16 +461,12 @@ static void _mark_read4write_pages_uptodate(struct ore_io_state *ios, int ret) + * ios->sp2d[p][*], xor is calculated the same way. These pages are + * allocated/freed and don't go through cache + */ +-static int _read_4_write(struct ore_io_state *ios) ++static int _read_4_write_first_stripe(struct ore_io_state *ios) + { +- struct ore_io_state *ios_read; + struct ore_striping_info read_si; + struct __stripe_pages_2d *sp2d = ios->sp2d; + u64 offset = ios->si.first_stripe_start; +- u64 last_stripe_end; +- unsigned bytes_in_stripe = ios->si.bytes_in_stripe; +- unsigned i, c, p, min_p = sp2d->pages_in_unit, max_p = -1; +- int ret; ++ unsigned c, p, min_p = sp2d->pages_in_unit, max_p = -1; + + if (offset == ios->offset) /* Go to start collect $200 */ + goto read_last_stripe; +@@ -478,6 +474,9 @@ static int _read_4_write(struct ore_io_state *ios) + min_p = _sp2d_min_pg(sp2d); + max_p = _sp2d_max_pg(sp2d); + ++ ORE_DBGMSG("stripe_start=0x%llx ios->offset=0x%llx min_p=%d max_p=%d\n", ++ offset, ios->offset, min_p, max_p); ++ + for (c = 0; ; c++) { + ore_calc_stripe_info(ios->layout, offset, 0, &read_si); + read_si.obj_offset += min_p * PAGE_SIZE; +@@ -512,6 +511,18 @@ static int _read_4_write(struct ore_io_state *ios) + } + + read_last_stripe: ++ return 0; ++} ++ ++static int _read_4_write_last_stripe(struct ore_io_state *ios) ++{ ++ struct ore_striping_info read_si; ++ struct __stripe_pages_2d *sp2d = ios->sp2d; ++ u64 offset; ++ u64 last_stripe_end; ++ unsigned bytes_in_stripe = ios->si.bytes_in_stripe; ++ unsigned c, p, min_p = sp2d->pages_in_unit, max_p = -1; ++ + offset = ios->offset + ios->length; + if (offset % PAGE_SIZE) + _add_to_r4w_last_page(ios, &offset); +@@ -527,15 +538,15 @@ read_last_stripe: + c = _dev_order(ios->layout->group_width * ios->layout->mirrors_p1, + ios->layout->mirrors_p1, read_si.par_dev, read_si.dev); + +- BUG_ON(ios->si.first_stripe_start + bytes_in_stripe != last_stripe_end); +- /* unaligned IO must be within a single stripe */ +- + if (min_p == sp2d->pages_in_unit) { + /* Didn't do it yet */ + min_p = _sp2d_min_pg(sp2d); + max_p = _sp2d_max_pg(sp2d); + } + ++ ORE_DBGMSG("offset=0x%llx stripe_end=0x%llx min_p=%d max_p=%d\n", ++ offset, last_stripe_end, min_p, max_p); ++ + while (offset < last_stripe_end) { + struct __1_page_stripe *_1ps = &sp2d->_1p_stripes[p]; + +@@ -568,6 +579,15 @@ read_last_stripe: + } + + read_it: ++ return 0; ++} ++ ++static int _read_4_write_execute(struct ore_io_state *ios) ++{ ++ struct ore_io_state *ios_read; ++ unsigned i; ++ int ret; ++ + ios_read = ios->ios_read_4_write; + if (!ios_read) + return 0; +@@ -591,6 +611,8 @@ read_it: + } + + _mark_read4write_pages_uptodate(ios_read, ret); ++ ore_put_io_state(ios_read); ++ ios->ios_read_4_write = NULL; /* Might need a reuse at last stripe */ + return 0; + } + +@@ -626,8 +648,11 @@ int _ore_add_parity_unit(struct ore_io_state *ios, + /* If first stripe, Read in all read4write pages + * (if needed) before we calculate the first parity. + */ +- _read_4_write(ios); ++ _read_4_write_first_stripe(ios); + } ++ if (!cur_len) /* If last stripe r4w pages of last stripe */ ++ _read_4_write_last_stripe(ios); ++ _read_4_write_execute(ios); + + for (i = 0; i < num_pages; i++) { + pages[i] = _raid_page_alloc(); +@@ -654,34 +679,14 @@ int _ore_add_parity_unit(struct ore_io_state *ios, + + int _ore_post_alloc_raid_stuff(struct ore_io_state *ios) + { +- struct ore_layout *layout = ios->layout; +- + if (ios->parity_pages) { ++ struct ore_layout *layout = ios->layout; + unsigned pages_in_unit = layout->stripe_unit / PAGE_SIZE; +- unsigned stripe_size = ios->si.bytes_in_stripe; +- u64 last_stripe, first_stripe; + + if (_sp2d_alloc(pages_in_unit, layout->group_width, + layout->parity, &ios->sp2d)) { + return -ENOMEM; + } +- +- /* Round io down to last full strip */ +- first_stripe = div_u64(ios->offset, stripe_size); +- last_stripe = div_u64(ios->offset + ios->length, stripe_size); +- +- /* If an IO spans more then a single stripe it must end at +- * a stripe boundary. The reminder at the end is pushed into the +- * next IO. +- */ +- if (last_stripe != first_stripe) { +- ios->length = last_stripe * stripe_size - ios->offset; +- +- BUG_ON(!ios->length); +- ios->nr_pages = (ios->length + PAGE_SIZE - 1) / +- PAGE_SIZE; +- ios->si.length = ios->length; /*make it consistent */ +- } + } + return 0; + } +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index ab7aa3f..a93486e 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -1097,7 +1097,7 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) + } + if (sbi->s_max_batch_time != EXT4_DEF_MAX_BATCH_TIME) { + seq_printf(seq, ",max_batch_time=%u", +- (unsigned) sbi->s_min_batch_time); ++ (unsigned) sbi->s_max_batch_time); + } + + /* +diff --git a/fs/fifo.c b/fs/fifo.c +index b1a524d..cf6f434 100644 +--- a/fs/fifo.c ++++ b/fs/fifo.c +@@ -14,7 +14,7 @@ + #include <linux/sched.h> + #include <linux/pipe_fs_i.h> + +-static void wait_for_partner(struct inode* inode, unsigned int *cnt) ++static int wait_for_partner(struct inode* inode, unsigned int *cnt) + { + int cur = *cnt; + +@@ -23,6 +23,7 @@ static void wait_for_partner(struct inode* inode, unsigned int *cnt) + if (signal_pending(current)) + break; + } ++ return cur == *cnt ? -ERESTARTSYS : 0; + } + + static void wake_up_partner(struct inode* inode) +@@ -67,8 +68,7 @@ static int fifo_open(struct inode *inode, struct file *filp) + * seen a writer */ + filp->f_version = pipe->w_counter; + } else { +- wait_for_partner(inode, &pipe->w_counter); +- if(signal_pending(current)) ++ if (wait_for_partner(inode, &pipe->w_counter)) + goto err_rd; + } + } +@@ -90,8 +90,7 @@ static int fifo_open(struct inode *inode, struct file *filp) + wake_up_partner(inode); + + if (!pipe->readers) { +- wait_for_partner(inode, &pipe->r_counter); +- if (signal_pending(current)) ++ if (wait_for_partner(inode, &pipe->r_counter)) + goto err_wr; + } + break; +diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c +index 2d0ca24..ebc2f4d 100644 +--- a/fs/hugetlbfs/inode.c ++++ b/fs/hugetlbfs/inode.c +@@ -592,9 +592,15 @@ static int hugetlbfs_statfs(struct dentry *dentry, struct kstatfs *buf) + spin_lock(&sbinfo->stat_lock); + /* If no limits set, just report 0 for max/free/used + * blocks, like simple_statfs() */ +- if (sbinfo->max_blocks >= 0) { +- buf->f_blocks = sbinfo->max_blocks; +- buf->f_bavail = buf->f_bfree = sbinfo->free_blocks; ++ if (sbinfo->spool) { ++ long free_pages; ++ ++ spin_lock(&sbinfo->spool->lock); ++ buf->f_blocks = sbinfo->spool->max_hpages; ++ free_pages = sbinfo->spool->max_hpages ++ - sbinfo->spool->used_hpages; ++ buf->f_bavail = buf->f_bfree = free_pages; ++ spin_unlock(&sbinfo->spool->lock); + buf->f_files = sbinfo->max_inodes; + buf->f_ffree = sbinfo->free_inodes; + } +@@ -610,6 +616,10 @@ static void hugetlbfs_put_super(struct super_block *sb) + + if (sbi) { + sb->s_fs_info = NULL; ++ ++ if (sbi->spool) ++ hugepage_put_subpool(sbi->spool); ++ + kfree(sbi); + } + } +@@ -841,10 +851,14 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent) + sb->s_fs_info = sbinfo; + sbinfo->hstate = config.hstate; + spin_lock_init(&sbinfo->stat_lock); +- sbinfo->max_blocks = config.nr_blocks; +- sbinfo->free_blocks = config.nr_blocks; + sbinfo->max_inodes = config.nr_inodes; + sbinfo->free_inodes = config.nr_inodes; ++ sbinfo->spool = NULL; ++ if (config.nr_blocks != -1) { ++ sbinfo->spool = hugepage_new_subpool(config.nr_blocks); ++ if (!sbinfo->spool) ++ goto out_free; ++ } + sb->s_maxbytes = MAX_LFS_FILESIZE; + sb->s_blocksize = huge_page_size(config.hstate); + sb->s_blocksize_bits = huge_page_shift(config.hstate); +@@ -864,38 +878,12 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent) + sb->s_root = root; + return 0; + out_free: ++ if (sbinfo->spool) ++ kfree(sbinfo->spool); + kfree(sbinfo); + return -ENOMEM; + } + +-int hugetlb_get_quota(struct address_space *mapping, long delta) +-{ +- int ret = 0; +- struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(mapping->host->i_sb); +- +- if (sbinfo->free_blocks > -1) { +- spin_lock(&sbinfo->stat_lock); +- if (sbinfo->free_blocks - delta >= 0) +- sbinfo->free_blocks -= delta; +- else +- ret = -ENOMEM; +- spin_unlock(&sbinfo->stat_lock); +- } +- +- return ret; +-} +- +-void hugetlb_put_quota(struct address_space *mapping, long delta) +-{ +- struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(mapping->host->i_sb); +- +- if (sbinfo->free_blocks > -1) { +- spin_lock(&sbinfo->stat_lock); +- sbinfo->free_blocks += delta; +- spin_unlock(&sbinfo->stat_lock); +- } +-} +- + static struct dentry *hugetlbfs_mount(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data) + { +diff --git a/fs/locks.c b/fs/locks.c +index 0d68f1f..6a64f15 100644 +--- a/fs/locks.c ++++ b/fs/locks.c +@@ -1465,7 +1465,7 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp) + case F_WRLCK: + return generic_add_lease(filp, arg, flp); + default: +- BUG(); ++ return -EINVAL; + } + } + EXPORT_SYMBOL(generic_setlease); +diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c +index 47d1c6f..b122af8 100644 +--- a/fs/nfs/idmap.c ++++ b/fs/nfs/idmap.c +@@ -318,12 +318,12 @@ struct idmap_hashent { + unsigned long ih_expires; + __u32 ih_id; + size_t ih_namelen; +- char ih_name[IDMAP_NAMESZ]; ++ const char *ih_name; + }; + + struct idmap_hashtable { + __u8 h_type; +- struct idmap_hashent h_entries[IDMAP_HASH_SZ]; ++ struct idmap_hashent *h_entries; + }; + + struct idmap { +@@ -378,6 +378,28 @@ nfs_idmap_new(struct nfs_client *clp) + return 0; + } + ++static void ++idmap_alloc_hashtable(struct idmap_hashtable *h) ++{ ++ if (h->h_entries != NULL) ++ return; ++ h->h_entries = kcalloc(IDMAP_HASH_SZ, ++ sizeof(*h->h_entries), ++ GFP_KERNEL); ++} ++ ++static void ++idmap_free_hashtable(struct idmap_hashtable *h) ++{ ++ int i; ++ ++ if (h->h_entries == NULL) ++ return; ++ for (i = 0; i < IDMAP_HASH_SZ; i++) ++ kfree(h->h_entries[i].ih_name); ++ kfree(h->h_entries); ++} ++ + void + nfs_idmap_delete(struct nfs_client *clp) + { +@@ -387,6 +409,8 @@ nfs_idmap_delete(struct nfs_client *clp) + return; + rpc_unlink(idmap->idmap_dentry); + clp->cl_idmap = NULL; ++ idmap_free_hashtable(&idmap->idmap_user_hash); ++ idmap_free_hashtable(&idmap->idmap_group_hash); + kfree(idmap); + } + +@@ -396,6 +420,8 @@ nfs_idmap_delete(struct nfs_client *clp) + static inline struct idmap_hashent * + idmap_name_hash(struct idmap_hashtable* h, const char *name, size_t len) + { ++ if (h->h_entries == NULL) ++ return NULL; + return &h->h_entries[fnvhash32(name, len) % IDMAP_HASH_SZ]; + } + +@@ -404,6 +430,8 @@ idmap_lookup_name(struct idmap_hashtable *h, const char *name, size_t len) + { + struct idmap_hashent *he = idmap_name_hash(h, name, len); + ++ if (he == NULL) ++ return NULL; + if (he->ih_namelen != len || memcmp(he->ih_name, name, len) != 0) + return NULL; + if (time_after(jiffies, he->ih_expires)) +@@ -414,6 +442,8 @@ idmap_lookup_name(struct idmap_hashtable *h, const char *name, size_t len) + static inline struct idmap_hashent * + idmap_id_hash(struct idmap_hashtable* h, __u32 id) + { ++ if (h->h_entries == NULL) ++ return NULL; + return &h->h_entries[fnvhash32(&id, sizeof(id)) % IDMAP_HASH_SZ]; + } + +@@ -421,6 +451,9 @@ static struct idmap_hashent * + idmap_lookup_id(struct idmap_hashtable *h, __u32 id) + { + struct idmap_hashent *he = idmap_id_hash(h, id); ++ ++ if (he == NULL) ++ return NULL; + if (he->ih_id != id || he->ih_namelen == 0) + return NULL; + if (time_after(jiffies, he->ih_expires)) +@@ -436,12 +469,14 @@ idmap_lookup_id(struct idmap_hashtable *h, __u32 id) + static inline struct idmap_hashent * + idmap_alloc_name(struct idmap_hashtable *h, char *name, size_t len) + { ++ idmap_alloc_hashtable(h); + return idmap_name_hash(h, name, len); + } + + static inline struct idmap_hashent * + idmap_alloc_id(struct idmap_hashtable *h, __u32 id) + { ++ idmap_alloc_hashtable(h); + return idmap_id_hash(h, id); + } + +@@ -449,9 +484,14 @@ static void + idmap_update_entry(struct idmap_hashent *he, const char *name, + size_t namelen, __u32 id) + { ++ char *str = kmalloc(namelen + 1, GFP_KERNEL); ++ if (str == NULL) ++ return; ++ kfree(he->ih_name); + he->ih_id = id; +- memcpy(he->ih_name, name, namelen); +- he->ih_name[namelen] = '\0'; ++ memcpy(str, name, namelen); ++ str[namelen] = '\0'; ++ he->ih_name = str; + he->ih_namelen = namelen; + he->ih_expires = jiffies + nfs_idmap_cache_timeout; + } +diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c +index 66020ac..07354b7 100644 +--- a/fs/nfs/nfs4state.c ++++ b/fs/nfs/nfs4state.c +@@ -1186,8 +1186,9 @@ restart: + spin_lock(&state->state_lock); + list_for_each_entry(lock, &state->lock_states, ls_locks) { + if (!(lock->ls_flags & NFS_LOCK_INITIALIZED)) +- printk("%s: Lock reclaim failed!\n", +- __func__); ++ pr_warn_ratelimited("NFS: " ++ "%s: Lock reclaim " ++ "failed!\n", __func__); + } + spin_unlock(&state->state_lock); + nfs4_put_open_state(state); +diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c +index 55d0128..a03ee52 100644 +--- a/fs/nfs/objlayout/objio_osd.c ++++ b/fs/nfs/objlayout/objio_osd.c +@@ -433,7 +433,10 @@ int objio_read_pagelist(struct nfs_read_data *rdata) + objios->ios->done = _read_done; + dprintk("%s: offset=0x%llx length=0x%x\n", __func__, + rdata->args.offset, rdata->args.count); +- return ore_read(objios->ios); ++ ret = ore_read(objios->ios); ++ if (unlikely(ret)) ++ objio_free_result(&objios->oir); ++ return ret; + } + + /* +@@ -464,8 +467,16 @@ static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate) + struct objio_state *objios = priv; + struct nfs_write_data *wdata = objios->oir.rpcdata; + pgoff_t index = offset / PAGE_SIZE; +- struct page *page = find_get_page(wdata->inode->i_mapping, index); ++ struct page *page; ++ loff_t i_size = i_size_read(wdata->inode); ++ ++ if (offset >= i_size) { ++ *uptodate = true; ++ dprintk("%s: g_zero_page index=0x%lx\n", __func__, index); ++ return ZERO_PAGE(0); ++ } + ++ page = find_get_page(wdata->inode->i_mapping, index); + if (!page) { + page = find_or_create_page(wdata->inode->i_mapping, + index, GFP_NOFS); +@@ -486,8 +497,10 @@ static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate) + + static void __r4w_put_page(void *priv, struct page *page) + { +- dprintk("%s: index=0x%lx\n", __func__, page->index); +- page_cache_release(page); ++ dprintk("%s: index=0x%lx\n", __func__, ++ (page == ZERO_PAGE(0)) ? -1UL : page->index); ++ if (ZERO_PAGE(0) != page) ++ page_cache_release(page); + return; + } + +@@ -517,8 +530,10 @@ int objio_write_pagelist(struct nfs_write_data *wdata, int how) + dprintk("%s: offset=0x%llx length=0x%x\n", __func__, + wdata->args.offset, wdata->args.count); + ret = ore_write(objios->ios); +- if (unlikely(ret)) ++ if (unlikely(ret)) { ++ objio_free_result(&objios->oir); + return ret; ++ } + + if (objios->sync) + _write_done(objios->ios, objios); +diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c +index 07ee5b4..1c7d45e 100644 +--- a/fs/ocfs2/file.c ++++ b/fs/ocfs2/file.c +@@ -1950,7 +1950,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, + if (ret < 0) + mlog_errno(ret); + +- if (file->f_flags & O_SYNC) ++ if (file && (file->f_flags & O_SYNC)) + handle->h_sync = 1; + + ocfs2_commit_trans(osb, handle); +diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c +index fbb0b47..d5378d0 100644 +--- a/fs/ramfs/file-nommu.c ++++ b/fs/ramfs/file-nommu.c +@@ -110,6 +110,7 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) + + /* prevent the page from being discarded on memory pressure */ + SetPageDirty(page); ++ SetPageUptodate(page); + + unlock_page(page); + put_page(page); +diff --git a/fs/ubifs/sb.c b/fs/ubifs/sb.c +index 6094c5a..b73ecd8 100644 +--- a/fs/ubifs/sb.c ++++ b/fs/ubifs/sb.c +@@ -715,8 +715,12 @@ static int fixup_free_space(struct ubifs_info *c) + lnum = ubifs_next_log_lnum(c, lnum); + } + +- /* Fixup the current log head */ +- err = fixup_leb(c, c->lhead_lnum, c->lhead_offs); ++ /* ++ * Fixup the log head which contains the only a CS node at the ++ * beginning. ++ */ ++ err = fixup_leb(c, c->lhead_lnum, ++ ALIGN(UBIFS_CS_NODE_SZ, c->min_io_size)); + if (err) + goto out; + +diff --git a/include/linux/Kbuild b/include/linux/Kbuild +index bd21ecd..a3ce901 100644 +--- a/include/linux/Kbuild ++++ b/include/linux/Kbuild +@@ -268,6 +268,7 @@ header-y += netfilter_ipv4.h + header-y += netfilter_ipv6.h + header-y += netlink.h + header-y += netrom.h ++header-y += nfc.h + header-y += nfs.h + header-y += nfs2.h + header-y += nfs3.h +diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h +index fd0dc30..cc07d27 100644 +--- a/include/linux/hrtimer.h ++++ b/include/linux/hrtimer.h +@@ -165,6 +165,7 @@ enum hrtimer_base_type { + * @lock: lock protecting the base and associated clock bases + * and timers + * @active_bases: Bitfield to mark bases with active timers ++ * @clock_was_set: Indicates that clock was set from irq context. + * @expires_next: absolute time of the next event which was scheduled + * via clock_set_next_event() + * @hres_active: State of high resolution mode +@@ -177,7 +178,8 @@ enum hrtimer_base_type { + */ + struct hrtimer_cpu_base { + raw_spinlock_t lock; +- unsigned long active_bases; ++ unsigned int active_bases; ++ unsigned int clock_was_set; + #ifdef CONFIG_HIGH_RES_TIMERS + ktime_t expires_next; + int hres_active; +@@ -286,6 +288,8 @@ extern void hrtimer_peek_ahead_timers(void); + # define MONOTONIC_RES_NSEC HIGH_RES_NSEC + # define KTIME_MONOTONIC_RES KTIME_HIGH_RES + ++extern void clock_was_set_delayed(void); ++ + #else + + # define MONOTONIC_RES_NSEC LOW_RES_NSEC +@@ -306,6 +310,9 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer) + { + return 0; + } ++ ++static inline void clock_was_set_delayed(void) { } ++ + #endif + + extern void clock_was_set(void); +@@ -320,6 +327,7 @@ extern ktime_t ktime_get(void); + extern ktime_t ktime_get_real(void); + extern ktime_t ktime_get_boottime(void); + extern ktime_t ktime_get_monotonic_offset(void); ++extern ktime_t ktime_get_update_offsets(ktime_t *offs_real, ktime_t *offs_boot); + + DECLARE_PER_CPU(struct tick_device, tick_cpu_device); + +diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h +index d9d6c86..c5ed2f1 100644 +--- a/include/linux/hugetlb.h ++++ b/include/linux/hugetlb.h +@@ -14,6 +14,15 @@ struct user_struct; + #include <linux/shm.h> + #include <asm/tlbflush.h> + ++struct hugepage_subpool { ++ spinlock_t lock; ++ long count; ++ long max_hpages, used_hpages; ++}; ++ ++struct hugepage_subpool *hugepage_new_subpool(long nr_blocks); ++void hugepage_put_subpool(struct hugepage_subpool *spool); ++ + int PageHuge(struct page *page); + + void reset_vma_resv_huge_pages(struct vm_area_struct *vma); +@@ -138,12 +147,11 @@ struct hugetlbfs_config { + }; + + struct hugetlbfs_sb_info { +- long max_blocks; /* blocks allowed */ +- long free_blocks; /* blocks free */ + long max_inodes; /* inodes allowed */ + long free_inodes; /* inodes free */ + spinlock_t stat_lock; + struct hstate *hstate; ++ struct hugepage_subpool *spool; + }; + + +@@ -166,8 +174,6 @@ extern const struct file_operations hugetlbfs_file_operations; + extern const struct vm_operations_struct hugetlb_vm_ops; + struct file *hugetlb_file_setup(const char *name, size_t size, vm_flags_t acct, + struct user_struct **user, int creat_flags); +-int hugetlb_get_quota(struct address_space *mapping, long delta); +-void hugetlb_put_quota(struct address_space *mapping, long delta); + + static inline int is_file_hugepages(struct file *file) + { +diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h +index 188cb2f..905b1e1 100644 +--- a/include/linux/mmzone.h ++++ b/include/linux/mmzone.h +@@ -652,7 +652,7 @@ typedef struct pglist_data { + range, including holes */ + int node_id; + wait_queue_head_t kswapd_wait; +- struct task_struct *kswapd; ++ struct task_struct *kswapd; /* Protected by lock_memory_hotplug() */ + int kswapd_max_order; + enum zone_type classzone_idx; + } pg_data_t; +diff --git a/include/linux/pci.h b/include/linux/pci.h +index c0cfa0d..7cda65b 100644 +--- a/include/linux/pci.h ++++ b/include/linux/pci.h +@@ -176,8 +176,6 @@ enum pci_dev_flags { + PCI_DEV_FLAGS_NO_D3 = (__force pci_dev_flags_t) 2, + /* Provide indication device is assigned by a Virtual Machine Manager */ + PCI_DEV_FLAGS_ASSIGNED = (__force pci_dev_flags_t) 4, +- /* Device causes system crash if in D3 during S3 sleep */ +- PCI_DEV_FLAGS_NO_D3_DURING_SLEEP = (__force pci_dev_flags_t) 8, + }; + + enum pci_irq_reroute_variant { +diff --git a/include/linux/sched.h b/include/linux/sched.h +index 1c4f3e9..5afa2a3 100644 +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -1892,6 +1892,14 @@ static inline int set_cpus_allowed_ptr(struct task_struct *p, + } + #endif + ++#ifdef CONFIG_NO_HZ ++void calc_load_enter_idle(void); ++void calc_load_exit_idle(void); ++#else ++static inline void calc_load_enter_idle(void) { } ++static inline void calc_load_exit_idle(void) { } ++#endif /* CONFIG_NO_HZ */ ++ + #ifndef CONFIG_CPUMASK_OFFSTACK + static inline int set_cpus_allowed(struct task_struct *p, cpumask_t new_mask) + { +diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h +index bdb4590..53dc7e7 100644 +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -213,11 +213,8 @@ enum { + /* device driver is going to provide hardware time stamp */ + SKBTX_IN_PROGRESS = 1 << 2, + +- /* ensure the originating sk reference is available on driver level */ +- SKBTX_DRV_NEEDS_SK_REF = 1 << 3, +- + /* device driver supports TX zero-copy buffers */ +- SKBTX_DEV_ZEROCOPY = 1 << 4, ++ SKBTX_DEV_ZEROCOPY = 1 << 3, + }; + + /* +diff --git a/include/linux/timex.h b/include/linux/timex.h +index aa60fe7..08e90fb 100644 +--- a/include/linux/timex.h ++++ b/include/linux/timex.h +@@ -266,7 +266,7 @@ static inline int ntp_synced(void) + /* Returns how long ticks are at present, in ns / 2^NTP_SCALE_SHIFT. */ + extern u64 tick_length; + +-extern void second_overflow(void); ++extern int second_overflow(unsigned long secs); + extern void update_ntp_one_tick(void); + extern int do_adjtimex(struct timex *); + extern void hardpps(const struct timespec *, const struct timespec *); +diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h +index 6a308d4..1e100c6 100644 +--- a/include/scsi/libsas.h ++++ b/include/scsi/libsas.h +@@ -159,6 +159,8 @@ enum ata_command_set { + ATAPI_COMMAND_SET = 1, + }; + ++#define ATA_RESP_FIS_SIZE 24 ++ + struct sata_device { + enum ata_command_set command_set; + struct smp_resp rps_resp; /* report_phy_sata_resp */ +@@ -170,7 +172,7 @@ struct sata_device { + + struct ata_port *ap; + struct ata_host ata_host; +- struct ata_taskfile tf; ++ u8 fis[ATA_RESP_FIS_SIZE]; + u32 sstatus; + u32 serror; + u32 scontrol; +@@ -486,7 +488,7 @@ enum exec_status { + */ + struct ata_task_resp { + u16 frame_len; +- u8 ending_fis[24]; /* dev to host or data-in */ ++ u8 ending_fis[ATA_RESP_FIS_SIZE]; /* dev to host or data-in */ + u32 sstatus; + u32 serror; + u32 scontrol; +diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c +index ae34bf5..6db7a5e 100644 +--- a/kernel/hrtimer.c ++++ b/kernel/hrtimer.c +@@ -657,6 +657,14 @@ static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer, + return 0; + } + ++static inline ktime_t hrtimer_update_base(struct hrtimer_cpu_base *base) ++{ ++ ktime_t *offs_real = &base->clock_base[HRTIMER_BASE_REALTIME].offset; ++ ktime_t *offs_boot = &base->clock_base[HRTIMER_BASE_BOOTTIME].offset; ++ ++ return ktime_get_update_offsets(offs_real, offs_boot); ++} ++ + /* + * Retrigger next event is called after clock was set + * +@@ -665,22 +673,12 @@ static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer, + static void retrigger_next_event(void *arg) + { + struct hrtimer_cpu_base *base = &__get_cpu_var(hrtimer_bases); +- struct timespec realtime_offset, xtim, wtm, sleep; + + if (!hrtimer_hres_active()) + return; + +- /* Optimized out for !HIGH_RES */ +- get_xtime_and_monotonic_and_sleep_offset(&xtim, &wtm, &sleep); +- set_normalized_timespec(&realtime_offset, -wtm.tv_sec, -wtm.tv_nsec); +- +- /* Adjust CLOCK_REALTIME offset */ + raw_spin_lock(&base->lock); +- base->clock_base[HRTIMER_BASE_REALTIME].offset = +- timespec_to_ktime(realtime_offset); +- base->clock_base[HRTIMER_BASE_BOOTTIME].offset = +- timespec_to_ktime(sleep); +- ++ hrtimer_update_base(base); + hrtimer_force_reprogram(base, 0); + raw_spin_unlock(&base->lock); + } +@@ -710,13 +708,25 @@ static int hrtimer_switch_to_hres(void) + base->clock_base[i].resolution = KTIME_HIGH_RES; + + tick_setup_sched_timer(); +- + /* "Retrigger" the interrupt to get things going */ + retrigger_next_event(NULL); + local_irq_restore(flags); + return 1; + } + ++/* ++ * Called from timekeeping code to reprogramm the hrtimer interrupt ++ * device. If called from the timer interrupt context we defer it to ++ * softirq context. ++ */ ++void clock_was_set_delayed(void) ++{ ++ struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases); ++ ++ cpu_base->clock_was_set = 1; ++ __raise_softirq_irqoff(HRTIMER_SOFTIRQ); ++} ++ + #else + + static inline int hrtimer_hres_active(void) { return 0; } +@@ -1250,11 +1260,10 @@ void hrtimer_interrupt(struct clock_event_device *dev) + cpu_base->nr_events++; + dev->next_event.tv64 = KTIME_MAX; + +- entry_time = now = ktime_get(); ++ raw_spin_lock(&cpu_base->lock); ++ entry_time = now = hrtimer_update_base(cpu_base); + retry: + expires_next.tv64 = KTIME_MAX; +- +- raw_spin_lock(&cpu_base->lock); + /* + * We set expires_next to KTIME_MAX here with cpu_base->lock + * held to prevent that a timer is enqueued in our queue via +@@ -1330,8 +1339,12 @@ retry: + * We need to prevent that we loop forever in the hrtimer + * interrupt routine. We give it 3 attempts to avoid + * overreacting on some spurious event. ++ * ++ * Acquire base lock for updating the offsets and retrieving ++ * the current time. + */ +- now = ktime_get(); ++ raw_spin_lock(&cpu_base->lock); ++ now = hrtimer_update_base(cpu_base); + cpu_base->nr_retries++; + if (++retries < 3) + goto retry; +@@ -1343,6 +1356,7 @@ retry: + */ + cpu_base->nr_hangs++; + cpu_base->hang_detected = 1; ++ raw_spin_unlock(&cpu_base->lock); + delta = ktime_sub(now, entry_time); + if (delta.tv64 > cpu_base->max_hang_time.tv64) + cpu_base->max_hang_time = delta; +@@ -1395,6 +1409,13 @@ void hrtimer_peek_ahead_timers(void) + + static void run_hrtimer_softirq(struct softirq_action *h) + { ++ struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases); ++ ++ if (cpu_base->clock_was_set) { ++ cpu_base->clock_was_set = 0; ++ clock_was_set(); ++ } ++ + hrtimer_peek_ahead_timers(); + } + +diff --git a/kernel/power/swap.c b/kernel/power/swap.c +index b313086..64f8f97 100644 +--- a/kernel/power/swap.c ++++ b/kernel/power/swap.c +@@ -6,7 +6,7 @@ + * + * Copyright (C) 1998,2001-2005 Pavel Machek <pavel@ucw.cz> + * Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl> +- * Copyright (C) 2010 Bojan Smojver <bojan@rexursive.com> ++ * Copyright (C) 2010-2012 Bojan Smojver <bojan@rexursive.com> + * + * This file is released under the GPLv2. + * +@@ -283,14 +283,17 @@ static int write_page(void *buf, sector_t offset, struct bio **bio_chain) + return -ENOSPC; + + if (bio_chain) { +- src = (void *)__get_free_page(__GFP_WAIT | __GFP_HIGH); ++ src = (void *)__get_free_page(__GFP_WAIT | __GFP_NOWARN | ++ __GFP_NORETRY); + if (src) { + copy_page(src, buf); + } else { + ret = hib_wait_on_bio_chain(bio_chain); /* Free pages */ + if (ret) + return ret; +- src = (void *)__get_free_page(__GFP_WAIT | __GFP_HIGH); ++ src = (void *)__get_free_page(__GFP_WAIT | ++ __GFP_NOWARN | ++ __GFP_NORETRY); + if (src) { + copy_page(src, buf); + } else { +@@ -368,12 +371,17 @@ static int swap_write_page(struct swap_map_handle *handle, void *buf, + clear_page(handle->cur); + handle->cur_swap = offset; + handle->k = 0; +- } +- if (bio_chain && low_free_pages() <= handle->reqd_free_pages) { +- error = hib_wait_on_bio_chain(bio_chain); +- if (error) +- goto out; +- handle->reqd_free_pages = reqd_free_pages(); ++ ++ if (bio_chain && low_free_pages() <= handle->reqd_free_pages) { ++ error = hib_wait_on_bio_chain(bio_chain); ++ if (error) ++ goto out; ++ /* ++ * Recalculate the number of required free pages, to ++ * make sure we never take more than half. ++ */ ++ handle->reqd_free_pages = reqd_free_pages(); ++ } + } + out: + return error; +@@ -420,8 +428,9 @@ static int swap_writer_finish(struct swap_map_handle *handle, + /* Maximum number of threads for compression/decompression. */ + #define LZO_THREADS 3 + +-/* Maximum number of pages for read buffering. */ +-#define LZO_READ_PAGES (MAP_PAGE_ENTRIES * 8) ++/* Minimum/maximum number of pages for read buffering. */ ++#define LZO_MIN_RD_PAGES 1024 ++#define LZO_MAX_RD_PAGES 8192 + + + /** +@@ -632,12 +641,6 @@ static int save_image_lzo(struct swap_map_handle *handle, + } + + /* +- * Adjust number of free pages after all allocations have been done. +- * We don't want to run out of pages when writing. +- */ +- handle->reqd_free_pages = reqd_free_pages(); +- +- /* + * Start the CRC32 thread. + */ + init_waitqueue_head(&crc->go); +@@ -658,6 +661,12 @@ static int save_image_lzo(struct swap_map_handle *handle, + goto out_clean; + } + ++ /* ++ * Adjust the number of required free pages after all allocations have ++ * been done. We don't want to run out of pages when writing. ++ */ ++ handle->reqd_free_pages = reqd_free_pages(); ++ + printk(KERN_INFO + "PM: Using %u thread(s) for compression.\n" + "PM: Compressing and saving image data (%u pages) ... ", +@@ -1067,7 +1076,7 @@ static int load_image_lzo(struct swap_map_handle *handle, + unsigned i, thr, run_threads, nr_threads; + unsigned ring = 0, pg = 0, ring_size = 0, + have = 0, want, need, asked = 0; +- unsigned long read_pages; ++ unsigned long read_pages = 0; + unsigned char **page = NULL; + struct dec_data *data = NULL; + struct crc_data *crc = NULL; +@@ -1079,7 +1088,7 @@ static int load_image_lzo(struct swap_map_handle *handle, + nr_threads = num_online_cpus() - 1; + nr_threads = clamp_val(nr_threads, 1, LZO_THREADS); + +- page = vmalloc(sizeof(*page) * LZO_READ_PAGES); ++ page = vmalloc(sizeof(*page) * LZO_MAX_RD_PAGES); + if (!page) { + printk(KERN_ERR "PM: Failed to allocate LZO page\n"); + ret = -ENOMEM; +@@ -1144,15 +1153,22 @@ static int load_image_lzo(struct swap_map_handle *handle, + } + + /* +- * Adjust number of pages for read buffering, in case we are short. ++ * Set the number of pages for read buffering. ++ * This is complete guesswork, because we'll only know the real ++ * picture once prepare_image() is called, which is much later on ++ * during the image load phase. We'll assume the worst case and ++ * say that none of the image pages are from high memory. + */ +- read_pages = (nr_free_pages() - snapshot_get_image_size()) >> 1; +- read_pages = clamp_val(read_pages, LZO_CMP_PAGES, LZO_READ_PAGES); ++ if (low_free_pages() > snapshot_get_image_size()) ++ read_pages = (low_free_pages() - snapshot_get_image_size()) / 2; ++ read_pages = clamp_val(read_pages, LZO_MIN_RD_PAGES, LZO_MAX_RD_PAGES); + + for (i = 0; i < read_pages; i++) { + page[i] = (void *)__get_free_page(i < LZO_CMP_PAGES ? + __GFP_WAIT | __GFP_HIGH : +- __GFP_WAIT); ++ __GFP_WAIT | __GFP_NOWARN | ++ __GFP_NORETRY); ++ + if (!page[i]) { + if (i < LZO_CMP_PAGES) { + ring_size = i; +diff --git a/kernel/sched.c b/kernel/sched.c +index 576a27f..52ac69b 100644 +--- a/kernel/sched.c ++++ b/kernel/sched.c +@@ -1885,7 +1885,6 @@ static void double_rq_unlock(struct rq *rq1, struct rq *rq2) + + #endif + +-static void calc_load_account_idle(struct rq *this_rq); + static void update_sysctl(void); + static int get_update_sysctl_factor(void); + static void update_cpu_load(struct rq *this_rq); +@@ -3401,11 +3400,73 @@ unsigned long this_cpu_load(void) + } + + ++/* ++ * Global load-average calculations ++ * ++ * We take a distributed and async approach to calculating the global load-avg ++ * in order to minimize overhead. ++ * ++ * The global load average is an exponentially decaying average of nr_running + ++ * nr_uninterruptible. ++ * ++ * Once every LOAD_FREQ: ++ * ++ * nr_active = 0; ++ * for_each_possible_cpu(cpu) ++ * nr_active += cpu_of(cpu)->nr_running + cpu_of(cpu)->nr_uninterruptible; ++ * ++ * avenrun[n] = avenrun[0] * exp_n + nr_active * (1 - exp_n) ++ * ++ * Due to a number of reasons the above turns in the mess below: ++ * ++ * - for_each_possible_cpu() is prohibitively expensive on machines with ++ * serious number of cpus, therefore we need to take a distributed approach ++ * to calculating nr_active. ++ * ++ * \Sum_i x_i(t) = \Sum_i x_i(t) - x_i(t_0) | x_i(t_0) := 0 ++ * = \Sum_i { \Sum_j=1 x_i(t_j) - x_i(t_j-1) } ++ * ++ * So assuming nr_active := 0 when we start out -- true per definition, we ++ * can simply take per-cpu deltas and fold those into a global accumulate ++ * to obtain the same result. See calc_load_fold_active(). ++ * ++ * Furthermore, in order to avoid synchronizing all per-cpu delta folding ++ * across the machine, we assume 10 ticks is sufficient time for every ++ * cpu to have completed this task. ++ * ++ * This places an upper-bound on the IRQ-off latency of the machine. Then ++ * again, being late doesn't loose the delta, just wrecks the sample. ++ * ++ * - cpu_rq()->nr_uninterruptible isn't accurately tracked per-cpu because ++ * this would add another cross-cpu cacheline miss and atomic operation ++ * to the wakeup path. Instead we increment on whatever cpu the task ran ++ * when it went into uninterruptible state and decrement on whatever cpu ++ * did the wakeup. This means that only the sum of nr_uninterruptible over ++ * all cpus yields the correct result. ++ * ++ * This covers the NO_HZ=n code, for extra head-aches, see the comment below. ++ */ ++ + /* Variables and functions for calc_load */ + static atomic_long_t calc_load_tasks; + static unsigned long calc_load_update; + unsigned long avenrun[3]; +-EXPORT_SYMBOL(avenrun); ++EXPORT_SYMBOL(avenrun); /* should be removed */ ++ ++/** ++ * get_avenrun - get the load average array ++ * @loads: pointer to dest load array ++ * @offset: offset to add ++ * @shift: shift count to shift the result left ++ * ++ * These values are estimates at best, so no need for locking. ++ */ ++void get_avenrun(unsigned long *loads, unsigned long offset, int shift) ++{ ++ loads[0] = (avenrun[0] + offset) << shift; ++ loads[1] = (avenrun[1] + offset) << shift; ++ loads[2] = (avenrun[2] + offset) << shift; ++} + + static long calc_load_fold_active(struct rq *this_rq) + { +@@ -3422,6 +3483,9 @@ static long calc_load_fold_active(struct rq *this_rq) + return delta; + } + ++/* ++ * a1 = a0 * e + a * (1 - e) ++ */ + static unsigned long + calc_load(unsigned long load, unsigned long exp, unsigned long active) + { +@@ -3433,30 +3497,118 @@ calc_load(unsigned long load, unsigned long exp, unsigned long active) + + #ifdef CONFIG_NO_HZ + /* +- * For NO_HZ we delay the active fold to the next LOAD_FREQ update. ++ * Handle NO_HZ for the global load-average. ++ * ++ * Since the above described distributed algorithm to compute the global ++ * load-average relies on per-cpu sampling from the tick, it is affected by ++ * NO_HZ. ++ * ++ * The basic idea is to fold the nr_active delta into a global idle-delta upon ++ * entering NO_HZ state such that we can include this as an 'extra' cpu delta ++ * when we read the global state. ++ * ++ * Obviously reality has to ruin such a delightfully simple scheme: ++ * ++ * - When we go NO_HZ idle during the window, we can negate our sample ++ * contribution, causing under-accounting. ++ * ++ * We avoid this by keeping two idle-delta counters and flipping them ++ * when the window starts, thus separating old and new NO_HZ load. ++ * ++ * The only trick is the slight shift in index flip for read vs write. ++ * ++ * 0s 5s 10s 15s ++ * +10 +10 +10 +10 ++ * |-|-----------|-|-----------|-|-----------|-| ++ * r:0 0 1 1 0 0 1 1 0 ++ * w:0 1 1 0 0 1 1 0 0 ++ * ++ * This ensures we'll fold the old idle contribution in this window while ++ * accumlating the new one. ++ * ++ * - When we wake up from NO_HZ idle during the window, we push up our ++ * contribution, since we effectively move our sample point to a known ++ * busy state. ++ * ++ * This is solved by pushing the window forward, and thus skipping the ++ * sample, for this cpu (effectively using the idle-delta for this cpu which ++ * was in effect at the time the window opened). This also solves the issue ++ * of having to deal with a cpu having been in NOHZ idle for multiple ++ * LOAD_FREQ intervals. + * + * When making the ILB scale, we should try to pull this in as well. + */ +-static atomic_long_t calc_load_tasks_idle; ++static atomic_long_t calc_load_idle[2]; ++static int calc_load_idx; + +-static void calc_load_account_idle(struct rq *this_rq) ++static inline int calc_load_write_idx(void) + { ++ int idx = calc_load_idx; ++ ++ /* ++ * See calc_global_nohz(), if we observe the new index, we also ++ * need to observe the new update time. ++ */ ++ smp_rmb(); ++ ++ /* ++ * If the folding window started, make sure we start writing in the ++ * next idle-delta. ++ */ ++ if (!time_before(jiffies, calc_load_update)) ++ idx++; ++ ++ return idx & 1; ++} ++ ++static inline int calc_load_read_idx(void) ++{ ++ return calc_load_idx & 1; ++} ++ ++void calc_load_enter_idle(void) ++{ ++ struct rq *this_rq = this_rq(); + long delta; + ++ /* ++ * We're going into NOHZ mode, if there's any pending delta, fold it ++ * into the pending idle delta. ++ */ + delta = calc_load_fold_active(this_rq); +- if (delta) +- atomic_long_add(delta, &calc_load_tasks_idle); ++ if (delta) { ++ int idx = calc_load_write_idx(); ++ atomic_long_add(delta, &calc_load_idle[idx]); ++ } + } + +-static long calc_load_fold_idle(void) ++void calc_load_exit_idle(void) + { +- long delta = 0; ++ struct rq *this_rq = this_rq(); ++ ++ /* ++ * If we're still before the sample window, we're done. ++ */ ++ if (time_before(jiffies, this_rq->calc_load_update)) ++ return; + + /* +- * Its got a race, we don't care... ++ * We woke inside or after the sample window, this means we're already ++ * accounted through the nohz accounting, so skip the entire deal and ++ * sync up for the next window. + */ +- if (atomic_long_read(&calc_load_tasks_idle)) +- delta = atomic_long_xchg(&calc_load_tasks_idle, 0); ++ this_rq->calc_load_update = calc_load_update; ++ if (time_before(jiffies, this_rq->calc_load_update + 10)) ++ this_rq->calc_load_update += LOAD_FREQ; ++} ++ ++static long calc_load_fold_idle(void) ++{ ++ int idx = calc_load_read_idx(); ++ long delta = 0; ++ ++ if (atomic_long_read(&calc_load_idle[idx])) ++ delta = atomic_long_xchg(&calc_load_idle[idx], 0); + + return delta; + } +@@ -3542,66 +3694,39 @@ static void calc_global_nohz(void) + { + long delta, active, n; + +- /* +- * If we crossed a calc_load_update boundary, make sure to fold +- * any pending idle changes, the respective CPUs might have +- * missed the tick driven calc_load_account_active() update +- * due to NO_HZ. +- */ +- delta = calc_load_fold_idle(); +- if (delta) +- atomic_long_add(delta, &calc_load_tasks); +- +- /* +- * It could be the one fold was all it took, we done! +- */ +- if (time_before(jiffies, calc_load_update + 10)) +- return; +- +- /* +- * Catch-up, fold however many we are behind still +- */ +- delta = jiffies - calc_load_update - 10; +- n = 1 + (delta / LOAD_FREQ); ++ if (!time_before(jiffies, calc_load_update + 10)) { ++ /* ++ * Catch-up, fold however many we are behind still ++ */ ++ delta = jiffies - calc_load_update - 10; ++ n = 1 + (delta / LOAD_FREQ); + +- active = atomic_long_read(&calc_load_tasks); +- active = active > 0 ? active * FIXED_1 : 0; ++ active = atomic_long_read(&calc_load_tasks); ++ active = active > 0 ? active * FIXED_1 : 0; + +- avenrun[0] = calc_load_n(avenrun[0], EXP_1, active, n); +- avenrun[1] = calc_load_n(avenrun[1], EXP_5, active, n); +- avenrun[2] = calc_load_n(avenrun[2], EXP_15, active, n); ++ avenrun[0] = calc_load_n(avenrun[0], EXP_1, active, n); ++ avenrun[1] = calc_load_n(avenrun[1], EXP_5, active, n); ++ avenrun[2] = calc_load_n(avenrun[2], EXP_15, active, n); + +- calc_load_update += n * LOAD_FREQ; +-} +-#else +-static void calc_load_account_idle(struct rq *this_rq) +-{ +-} ++ calc_load_update += n * LOAD_FREQ; ++ } + +-static inline long calc_load_fold_idle(void) +-{ +- return 0; ++ /* ++ * Flip the idle index... ++ * ++ * Make sure we first write the new time then flip the index, so that ++ * calc_load_write_idx() will see the new time when it reads the new ++ * index, this avoids a double flip messing things up. ++ */ ++ smp_wmb(); ++ calc_load_idx++; + } ++#else /* !CONFIG_NO_HZ */ + +-static void calc_global_nohz(void) +-{ +-} +-#endif ++static inline long calc_load_fold_idle(void) { return 0; } ++static inline void calc_global_nohz(void) { } + +-/** +- * get_avenrun - get the load average array +- * @loads: pointer to dest load array +- * @offset: offset to add +- * @shift: shift count to shift the result left +- * +- * These values are estimates at best, so no need for locking. +- */ +-void get_avenrun(unsigned long *loads, unsigned long offset, int shift) +-{ +- loads[0] = (avenrun[0] + offset) << shift; +- loads[1] = (avenrun[1] + offset) << shift; +- loads[2] = (avenrun[2] + offset) << shift; +-} ++#endif /* CONFIG_NO_HZ */ + + /* + * calc_load - update the avenrun load estimates 10 ticks after the +@@ -3609,11 +3734,18 @@ void get_avenrun(unsigned long *loads, unsigned long offset, int shift) + */ + void calc_global_load(unsigned long ticks) + { +- long active; ++ long active, delta; + + if (time_before(jiffies, calc_load_update + 10)) + return; + ++ /* ++ * Fold the 'old' idle-delta to include all NO_HZ cpus. ++ */ ++ delta = calc_load_fold_idle(); ++ if (delta) ++ atomic_long_add(delta, &calc_load_tasks); ++ + active = atomic_long_read(&calc_load_tasks); + active = active > 0 ? active * FIXED_1 : 0; + +@@ -3624,12 +3756,7 @@ void calc_global_load(unsigned long ticks) + calc_load_update += LOAD_FREQ; + + /* +- * Account one period with whatever state we found before +- * folding in the nohz state and ageing the entire idle period. +- * +- * This avoids loosing a sample when we go idle between +- * calc_load_account_active() (10 ticks ago) and now and thus +- * under-accounting. ++ * In case we idled for multiple LOAD_FREQ intervals, catch up in bulk. + */ + calc_global_nohz(); + } +@@ -3646,7 +3773,6 @@ static void calc_load_account_active(struct rq *this_rq) + return; + + delta = calc_load_fold_active(this_rq); +- delta += calc_load_fold_idle(); + if (delta) + atomic_long_add(delta, &calc_load_tasks); + +@@ -3654,6 +3780,10 @@ static void calc_load_account_active(struct rq *this_rq) + } + + /* ++ * End of global load-average stuff ++ */ ++ ++/* + * The exact cpuload at various idx values, calculated at every tick would be + * load = (2^idx - 1) / 2^idx * load + 1 / 2^idx * cur_load + * +diff --git a/kernel/sched_idletask.c b/kernel/sched_idletask.c +index 0a51882..be92bfe 100644 +--- a/kernel/sched_idletask.c ++++ b/kernel/sched_idletask.c +@@ -23,7 +23,6 @@ static void check_preempt_curr_idle(struct rq *rq, struct task_struct *p, int fl + static struct task_struct *pick_next_task_idle(struct rq *rq) + { + schedstat_inc(rq, sched_goidle); +- calc_load_account_idle(rq); + return rq->idle; + } + +diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c +index 4b85a7a..f1eb182 100644 +--- a/kernel/time/ntp.c ++++ b/kernel/time/ntp.c +@@ -31,8 +31,6 @@ unsigned long tick_nsec; + u64 tick_length; + static u64 tick_length_base; + +-static struct hrtimer leap_timer; +- + #define MAX_TICKADJ 500LL /* usecs */ + #define MAX_TICKADJ_SCALED \ + (((MAX_TICKADJ * NSEC_PER_USEC) << NTP_SCALE_SHIFT) / NTP_INTERVAL_FREQ) +@@ -350,60 +348,60 @@ void ntp_clear(void) + } + + /* +- * Leap second processing. If in leap-insert state at the end of the +- * day, the system clock is set back one second; if in leap-delete +- * state, the system clock is set ahead one second. ++ * this routine handles the overflow of the microsecond field ++ * ++ * The tricky bits of code to handle the accurate clock support ++ * were provided by Dave Mills (Mills@UDEL.EDU) of NTP fame. ++ * They were originally developed for SUN and DEC kernels. ++ * All the kudos should go to Dave for this stuff. ++ * ++ * Also handles leap second processing, and returns leap offset + */ +-static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer) ++int second_overflow(unsigned long secs) + { +- enum hrtimer_restart res = HRTIMER_NORESTART; +- +- write_seqlock(&xtime_lock); ++ int leap = 0; ++ s64 delta; + ++ /* ++ * Leap second processing. If in leap-insert state at the end of the ++ * day, the system clock is set back one second; if in leap-delete ++ * state, the system clock is set ahead one second. ++ */ + switch (time_state) { + case TIME_OK: ++ if (time_status & STA_INS) ++ time_state = TIME_INS; ++ else if (time_status & STA_DEL) ++ time_state = TIME_DEL; + break; + case TIME_INS: +- timekeeping_leap_insert(-1); +- time_state = TIME_OOP; +- printk(KERN_NOTICE +- "Clock: inserting leap second 23:59:60 UTC\n"); +- hrtimer_add_expires_ns(&leap_timer, NSEC_PER_SEC); +- res = HRTIMER_RESTART; ++ if (secs % 86400 == 0) { ++ leap = -1; ++ time_state = TIME_OOP; ++ time_tai++; ++ printk(KERN_NOTICE ++ "Clock: inserting leap second 23:59:60 UTC\n"); ++ } + break; + case TIME_DEL: +- timekeeping_leap_insert(1); +- time_tai--; +- time_state = TIME_WAIT; +- printk(KERN_NOTICE +- "Clock: deleting leap second 23:59:59 UTC\n"); ++ if ((secs + 1) % 86400 == 0) { ++ leap = 1; ++ time_tai--; ++ time_state = TIME_WAIT; ++ printk(KERN_NOTICE ++ "Clock: deleting leap second 23:59:59 UTC\n"); ++ } + break; + case TIME_OOP: +- time_tai++; + time_state = TIME_WAIT; +- /* fall through */ ++ break; ++ + case TIME_WAIT: + if (!(time_status & (STA_INS | STA_DEL))) + time_state = TIME_OK; + break; + } + +- write_sequnlock(&xtime_lock); +- +- return res; +-} +- +-/* +- * this routine handles the overflow of the microsecond field +- * +- * The tricky bits of code to handle the accurate clock support +- * were provided by Dave Mills (Mills@UDEL.EDU) of NTP fame. +- * They were originally developed for SUN and DEC kernels. +- * All the kudos should go to Dave for this stuff. +- */ +-void second_overflow(void) +-{ +- s64 delta; + + /* Bump the maxerror field */ + time_maxerror += MAXFREQ / NSEC_PER_USEC; +@@ -423,23 +421,25 @@ void second_overflow(void) + pps_dec_valid(); + + if (!time_adjust) +- return; ++ goto out; + + if (time_adjust > MAX_TICKADJ) { + time_adjust -= MAX_TICKADJ; + tick_length += MAX_TICKADJ_SCALED; +- return; ++ goto out; + } + + if (time_adjust < -MAX_TICKADJ) { + time_adjust += MAX_TICKADJ; + tick_length -= MAX_TICKADJ_SCALED; +- return; ++ goto out; + } + + tick_length += (s64)(time_adjust * NSEC_PER_USEC / NTP_INTERVAL_FREQ) + << NTP_SCALE_SHIFT; + time_adjust = 0; ++out: ++ return leap; + } + + #ifdef CONFIG_GENERIC_CMOS_UPDATE +@@ -501,27 +501,6 @@ static void notify_cmos_timer(void) + static inline void notify_cmos_timer(void) { } + #endif + +-/* +- * Start the leap seconds timer: +- */ +-static inline void ntp_start_leap_timer(struct timespec *ts) +-{ +- long now = ts->tv_sec; +- +- if (time_status & STA_INS) { +- time_state = TIME_INS; +- now += 86400 - now % 86400; +- hrtimer_start(&leap_timer, ktime_set(now, 0), HRTIMER_MODE_ABS); +- +- return; +- } +- +- if (time_status & STA_DEL) { +- time_state = TIME_DEL; +- now += 86400 - (now + 1) % 86400; +- hrtimer_start(&leap_timer, ktime_set(now, 0), HRTIMER_MODE_ABS); +- } +-} + + /* + * Propagate a new txc->status value into the NTP state: +@@ -546,22 +525,6 @@ static inline void process_adj_status(struct timex *txc, struct timespec *ts) + time_status &= STA_RONLY; + time_status |= txc->status & ~STA_RONLY; + +- switch (time_state) { +- case TIME_OK: +- ntp_start_leap_timer(ts); +- break; +- case TIME_INS: +- case TIME_DEL: +- time_state = TIME_OK; +- ntp_start_leap_timer(ts); +- case TIME_WAIT: +- if (!(time_status & (STA_INS | STA_DEL))) +- time_state = TIME_OK; +- break; +- case TIME_OOP: +- hrtimer_restart(&leap_timer); +- break; +- } + } + /* + * Called with the xtime lock held, so we can access and modify +@@ -643,9 +606,6 @@ int do_adjtimex(struct timex *txc) + (txc->tick < 900000/USER_HZ || + txc->tick > 1100000/USER_HZ)) + return -EINVAL; +- +- if (txc->modes & ADJ_STATUS && time_state != TIME_OK) +- hrtimer_cancel(&leap_timer); + } + + if (txc->modes & ADJ_SETOFFSET) { +@@ -967,6 +927,4 @@ __setup("ntp_tick_adj=", ntp_tick_adj_setup); + void __init ntp_init(void) + { + ntp_clear(); +- hrtimer_init(&leap_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS); +- leap_timer.function = ntp_leap_second; + } +diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c +index c923640..9955ebd 100644 +--- a/kernel/time/tick-sched.c ++++ b/kernel/time/tick-sched.c +@@ -430,6 +430,7 @@ void tick_nohz_stop_sched_tick(int inidle) + */ + if (!ts->tick_stopped) { + select_nohz_load_balancer(1); ++ calc_load_enter_idle(); + + ts->idle_tick = hrtimer_get_expires(&ts->sched_timer); + ts->tick_stopped = 1; +@@ -563,6 +564,7 @@ void tick_nohz_restart_sched_tick(void) + account_idle_ticks(ticks); + #endif + ++ calc_load_exit_idle(); + touch_softlockup_watchdog(); + /* + * Cancel the scheduled timer and restore the tick +diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c +index 2378413..03e67d4 100644 +--- a/kernel/time/timekeeping.c ++++ b/kernel/time/timekeeping.c +@@ -161,23 +161,43 @@ static struct timespec xtime __attribute__ ((aligned (16))); + static struct timespec wall_to_monotonic __attribute__ ((aligned (16))); + static struct timespec total_sleep_time; + ++/* Offset clock monotonic -> clock realtime */ ++static ktime_t offs_real; ++ ++/* Offset clock monotonic -> clock boottime */ ++static ktime_t offs_boot; ++ + /* + * The raw monotonic time for the CLOCK_MONOTONIC_RAW posix clock. + */ + static struct timespec raw_time; + +-/* flag for if timekeeping is suspended */ +-int __read_mostly timekeeping_suspended; ++/* must hold write on xtime_lock */ ++static void update_rt_offset(void) ++{ ++ struct timespec tmp, *wtm = &wall_to_monotonic; + +-/* must hold xtime_lock */ +-void timekeeping_leap_insert(int leapsecond) ++ set_normalized_timespec(&tmp, -wtm->tv_sec, -wtm->tv_nsec); ++ offs_real = timespec_to_ktime(tmp); ++} ++ ++/* must hold write on xtime_lock */ ++static void timekeeping_update(bool clearntp) + { +- xtime.tv_sec += leapsecond; +- wall_to_monotonic.tv_sec -= leapsecond; +- update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock, +- timekeeper.mult); ++ if (clearntp) { ++ timekeeper.ntp_error = 0; ++ ntp_clear(); ++ } ++ update_rt_offset(); ++ update_vsyscall(&xtime, &wall_to_monotonic, ++ timekeeper.clock, timekeeper.mult); + } + ++ ++ ++/* flag for if timekeeping is suspended */ ++int __read_mostly timekeeping_suspended; ++ + /** + * timekeeping_forward_now - update clock to the current time + * +@@ -375,11 +395,7 @@ int do_settimeofday(const struct timespec *tv) + + xtime = *tv; + +- timekeeper.ntp_error = 0; +- ntp_clear(); +- +- update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock, +- timekeeper.mult); ++ timekeeping_update(true); + + write_sequnlock_irqrestore(&xtime_lock, flags); + +@@ -412,11 +428,7 @@ int timekeeping_inject_offset(struct timespec *ts) + xtime = timespec_add(xtime, *ts); + wall_to_monotonic = timespec_sub(wall_to_monotonic, *ts); + +- timekeeper.ntp_error = 0; +- ntp_clear(); +- +- update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock, +- timekeeper.mult); ++ timekeeping_update(true); + + write_sequnlock_irqrestore(&xtime_lock, flags); + +@@ -591,6 +603,7 @@ void __init timekeeping_init(void) + } + set_normalized_timespec(&wall_to_monotonic, + -boot.tv_sec, -boot.tv_nsec); ++ update_rt_offset(); + total_sleep_time.tv_sec = 0; + total_sleep_time.tv_nsec = 0; + write_sequnlock_irqrestore(&xtime_lock, flags); +@@ -599,6 +612,12 @@ void __init timekeeping_init(void) + /* time in seconds when suspend began */ + static struct timespec timekeeping_suspend_time; + ++static void update_sleep_time(struct timespec t) ++{ ++ total_sleep_time = t; ++ offs_boot = timespec_to_ktime(t); ++} ++ + /** + * __timekeeping_inject_sleeptime - Internal function to add sleep interval + * @delta: pointer to a timespec delta value +@@ -616,7 +635,7 @@ static void __timekeeping_inject_sleeptime(struct timespec *delta) + + xtime = timespec_add(xtime, *delta); + wall_to_monotonic = timespec_sub(wall_to_monotonic, *delta); +- total_sleep_time = timespec_add(total_sleep_time, *delta); ++ update_sleep_time(timespec_add(total_sleep_time, *delta)); + } + + +@@ -645,10 +664,7 @@ void timekeeping_inject_sleeptime(struct timespec *delta) + + __timekeeping_inject_sleeptime(delta); + +- timekeeper.ntp_error = 0; +- ntp_clear(); +- update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock, +- timekeeper.mult); ++ timekeeping_update(true); + + write_sequnlock_irqrestore(&xtime_lock, flags); + +@@ -683,6 +699,7 @@ static void timekeeping_resume(void) + timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock); + timekeeper.ntp_error = 0; + timekeeping_suspended = 0; ++ timekeeping_update(false); + write_sequnlock_irqrestore(&xtime_lock, flags); + + touch_softlockup_watchdog(); +@@ -942,9 +959,14 @@ static cycle_t logarithmic_accumulation(cycle_t offset, int shift) + + timekeeper.xtime_nsec += timekeeper.xtime_interval << shift; + while (timekeeper.xtime_nsec >= nsecps) { ++ int leap; + timekeeper.xtime_nsec -= nsecps; + xtime.tv_sec++; +- second_overflow(); ++ leap = second_overflow(xtime.tv_sec); ++ xtime.tv_sec += leap; ++ wall_to_monotonic.tv_sec -= leap; ++ if (leap) ++ clock_was_set_delayed(); + } + + /* Accumulate raw time */ +@@ -1050,14 +1072,17 @@ static void update_wall_time(void) + * xtime.tv_nsec isn't larger then NSEC_PER_SEC + */ + if (unlikely(xtime.tv_nsec >= NSEC_PER_SEC)) { ++ int leap; + xtime.tv_nsec -= NSEC_PER_SEC; + xtime.tv_sec++; +- second_overflow(); ++ leap = second_overflow(xtime.tv_sec); ++ xtime.tv_sec += leap; ++ wall_to_monotonic.tv_sec -= leap; ++ if (leap) ++ clock_was_set_delayed(); + } + +- /* check to see if there is a new clocksource to use */ +- update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock, +- timekeeper.mult); ++ timekeeping_update(false); + } + + /** +@@ -1216,6 +1241,40 @@ void get_xtime_and_monotonic_and_sleep_offset(struct timespec *xtim, + } while (read_seqretry(&xtime_lock, seq)); + } + ++#ifdef CONFIG_HIGH_RES_TIMERS ++/** ++ * ktime_get_update_offsets - hrtimer helper ++ * @real: pointer to storage for monotonic -> realtime offset ++ * @_boot: pointer to storage for monotonic -> boottime offset ++ * ++ * Returns current monotonic time and updates the offsets ++ * Called from hrtimer_interupt() or retrigger_next_event() ++ */ ++ktime_t ktime_get_update_offsets(ktime_t *real, ktime_t *boot) ++{ ++ ktime_t now; ++ unsigned int seq; ++ u64 secs, nsecs; ++ ++ do { ++ seq = read_seqbegin(&xtime_lock); ++ ++ secs = xtime.tv_sec; ++ nsecs = xtime.tv_nsec; ++ nsecs += timekeeping_get_ns(); ++ /* If arch requires, add in gettimeoffset() */ ++ nsecs += arch_gettimeoffset(); ++ ++ *real = offs_real; ++ *boot = offs_boot; ++ } while (read_seqretry(&xtime_lock, seq)); ++ ++ now = ktime_add_ns(ktime_set(secs, 0), nsecs); ++ now = ktime_sub(now, *real); ++ return now; ++} ++#endif ++ + /** + * ktime_get_monotonic_offset() - get wall_to_monotonic in ktime_t format + */ +diff --git a/mm/compaction.c b/mm/compaction.c +index 8fb8a40..50f1c60 100644 +--- a/mm/compaction.c ++++ b/mm/compaction.c +@@ -592,8 +592,11 @@ static int compact_zone(struct zone *zone, struct compact_control *cc) + if (err) { + putback_lru_pages(&cc->migratepages); + cc->nr_migratepages = 0; ++ if (err == -ENOMEM) { ++ ret = COMPACT_PARTIAL; ++ goto out; ++ } + } +- + } + + out: +diff --git a/mm/hugetlb.c b/mm/hugetlb.c +index 5f5c545..7c535b0 100644 +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -53,6 +53,84 @@ static unsigned long __initdata default_hstate_size; + */ + static DEFINE_SPINLOCK(hugetlb_lock); + ++static inline void unlock_or_release_subpool(struct hugepage_subpool *spool) ++{ ++ bool free = (spool->count == 0) && (spool->used_hpages == 0); ++ ++ spin_unlock(&spool->lock); ++ ++ /* If no pages are used, and no other handles to the subpool ++ * remain, free the subpool the subpool remain */ ++ if (free) ++ kfree(spool); ++} ++ ++struct hugepage_subpool *hugepage_new_subpool(long nr_blocks) ++{ ++ struct hugepage_subpool *spool; ++ ++ spool = kmalloc(sizeof(*spool), GFP_KERNEL); ++ if (!spool) ++ return NULL; ++ ++ spin_lock_init(&spool->lock); ++ spool->count = 1; ++ spool->max_hpages = nr_blocks; ++ spool->used_hpages = 0; ++ ++ return spool; ++} ++ ++void hugepage_put_subpool(struct hugepage_subpool *spool) ++{ ++ spin_lock(&spool->lock); ++ BUG_ON(!spool->count); ++ spool->count--; ++ unlock_or_release_subpool(spool); ++} ++ ++static int hugepage_subpool_get_pages(struct hugepage_subpool *spool, ++ long delta) ++{ ++ int ret = 0; ++ ++ if (!spool) ++ return 0; ++ ++ spin_lock(&spool->lock); ++ if ((spool->used_hpages + delta) <= spool->max_hpages) { ++ spool->used_hpages += delta; ++ } else { ++ ret = -ENOMEM; ++ } ++ spin_unlock(&spool->lock); ++ ++ return ret; ++} ++ ++static void hugepage_subpool_put_pages(struct hugepage_subpool *spool, ++ long delta) ++{ ++ if (!spool) ++ return; ++ ++ spin_lock(&spool->lock); ++ spool->used_hpages -= delta; ++ /* If hugetlbfs_put_super couldn't free spool due to ++ * an outstanding quota reference, free it now. */ ++ unlock_or_release_subpool(spool); ++} ++ ++static inline struct hugepage_subpool *subpool_inode(struct inode *inode) ++{ ++ return HUGETLBFS_SB(inode->i_sb)->spool; ++} ++ ++static inline struct hugepage_subpool *subpool_vma(struct vm_area_struct *vma) ++{ ++ return subpool_inode(vma->vm_file->f_dentry->d_inode); ++} ++ + /* + * Region tracking -- allows tracking of reservations and instantiated pages + * across the pages in a mapping. +@@ -533,9 +611,9 @@ static void free_huge_page(struct page *page) + */ + struct hstate *h = page_hstate(page); + int nid = page_to_nid(page); +- struct address_space *mapping; ++ struct hugepage_subpool *spool = ++ (struct hugepage_subpool *)page_private(page); + +- mapping = (struct address_space *) page_private(page); + set_page_private(page, 0); + page->mapping = NULL; + BUG_ON(page_count(page)); +@@ -551,8 +629,7 @@ static void free_huge_page(struct page *page) + enqueue_huge_page(h, page); + } + spin_unlock(&hugetlb_lock); +- if (mapping) +- hugetlb_put_quota(mapping, 1); ++ hugepage_subpool_put_pages(spool, 1); + } + + static void prep_new_huge_page(struct hstate *h, struct page *page, int nid) +@@ -966,11 +1043,12 @@ static void return_unused_surplus_pages(struct hstate *h, + /* + * Determine if the huge page at addr within the vma has an associated + * reservation. Where it does not we will need to logically increase +- * reservation and actually increase quota before an allocation can occur. +- * Where any new reservation would be required the reservation change is +- * prepared, but not committed. Once the page has been quota'd allocated +- * an instantiated the change should be committed via vma_commit_reservation. +- * No action is required on failure. ++ * reservation and actually increase subpool usage before an allocation ++ * can occur. Where any new reservation would be required the ++ * reservation change is prepared, but not committed. Once the page ++ * has been allocated from the subpool and instantiated the change should ++ * be committed via vma_commit_reservation. No action is required on ++ * failure. + */ + static long vma_needs_reservation(struct hstate *h, + struct vm_area_struct *vma, unsigned long addr) +@@ -1019,24 +1097,24 @@ static void vma_commit_reservation(struct hstate *h, + static struct page *alloc_huge_page(struct vm_area_struct *vma, + unsigned long addr, int avoid_reserve) + { ++ struct hugepage_subpool *spool = subpool_vma(vma); + struct hstate *h = hstate_vma(vma); + struct page *page; +- struct address_space *mapping = vma->vm_file->f_mapping; +- struct inode *inode = mapping->host; + long chg; + + /* +- * Processes that did not create the mapping will have no reserves and +- * will not have accounted against quota. Check that the quota can be +- * made before satisfying the allocation +- * MAP_NORESERVE mappings may also need pages and quota allocated +- * if no reserve mapping overlaps. ++ * Processes that did not create the mapping will have no ++ * reserves and will not have accounted against subpool ++ * limit. Check that the subpool limit can be made before ++ * satisfying the allocation MAP_NORESERVE mappings may also ++ * need pages and subpool limit allocated allocated if no reserve ++ * mapping overlaps. + */ + chg = vma_needs_reservation(h, vma, addr); + if (chg < 0) + return ERR_PTR(-VM_FAULT_OOM); + if (chg) +- if (hugetlb_get_quota(inode->i_mapping, chg)) ++ if (hugepage_subpool_get_pages(spool, chg)) + return ERR_PTR(-VM_FAULT_SIGBUS); + + spin_lock(&hugetlb_lock); +@@ -1046,12 +1124,12 @@ static struct page *alloc_huge_page(struct vm_area_struct *vma, + if (!page) { + page = alloc_buddy_huge_page(h, NUMA_NO_NODE); + if (!page) { +- hugetlb_put_quota(inode->i_mapping, chg); ++ hugepage_subpool_put_pages(spool, chg); + return ERR_PTR(-VM_FAULT_SIGBUS); + } + } + +- set_page_private(page, (unsigned long) mapping); ++ set_page_private(page, (unsigned long)spool); + + vma_commit_reservation(h, vma, addr); + +@@ -2081,6 +2159,7 @@ static void hugetlb_vm_op_close(struct vm_area_struct *vma) + { + struct hstate *h = hstate_vma(vma); + struct resv_map *reservations = vma_resv_map(vma); ++ struct hugepage_subpool *spool = subpool_vma(vma); + unsigned long reserve; + unsigned long start; + unsigned long end; +@@ -2096,7 +2175,7 @@ static void hugetlb_vm_op_close(struct vm_area_struct *vma) + + if (reserve) { + hugetlb_acct_memory(h, -reserve); +- hugetlb_put_quota(vma->vm_file->f_mapping, reserve); ++ hugepage_subpool_put_pages(spool, reserve); + } + } + } +@@ -2326,7 +2405,7 @@ static int unmap_ref_private(struct mm_struct *mm, struct vm_area_struct *vma, + address = address & huge_page_mask(h); + pgoff = ((address - vma->vm_start) >> PAGE_SHIFT) + + (vma->vm_pgoff >> PAGE_SHIFT); +- mapping = (struct address_space *)page_private(page); ++ mapping = vma->vm_file->f_dentry->d_inode->i_mapping; + + /* + * Take the mapping lock for the duration of the table walk. As +@@ -2865,11 +2944,12 @@ int hugetlb_reserve_pages(struct inode *inode, + { + long ret, chg; + struct hstate *h = hstate_inode(inode); ++ struct hugepage_subpool *spool = subpool_inode(inode); + + /* + * Only apply hugepage reservation if asked. At fault time, an + * attempt will be made for VM_NORESERVE to allocate a page +- * and filesystem quota without using reserves ++ * without using reserves + */ + if (vm_flags & VM_NORESERVE) + return 0; +@@ -2898,19 +2978,19 @@ int hugetlb_reserve_pages(struct inode *inode, + goto out_err; + } + +- /* There must be enough filesystem quota for the mapping */ +- if (hugetlb_get_quota(inode->i_mapping, chg)) { ++ /* There must be enough pages in the subpool for the mapping */ ++ if (hugepage_subpool_get_pages(spool, chg)) { + ret = -ENOSPC; + goto out_err; + } + + /* + * Check enough hugepages are available for the reservation. +- * Hand back the quota if there are not ++ * Hand the pages back to the subpool if there are not + */ + ret = hugetlb_acct_memory(h, chg); + if (ret < 0) { +- hugetlb_put_quota(inode->i_mapping, chg); ++ hugepage_subpool_put_pages(spool, chg); + goto out_err; + } + +@@ -2938,12 +3018,13 @@ void hugetlb_unreserve_pages(struct inode *inode, long offset, long freed) + { + struct hstate *h = hstate_inode(inode); + long chg = region_truncate(&inode->i_mapping->private_list, offset); ++ struct hugepage_subpool *spool = subpool_inode(inode); + + spin_lock(&inode->i_lock); + inode->i_blocks -= (blocks_per_huge_page(h) * freed); + spin_unlock(&inode->i_lock); + +- hugetlb_put_quota(inode->i_mapping, (chg - freed)); ++ hugepage_subpool_put_pages(spool, (chg - freed)); + hugetlb_acct_memory(h, -(chg - freed)); + } + +diff --git a/mm/vmscan.c b/mm/vmscan.c +index fbe2d2c..8342119 100644 +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -2824,7 +2824,10 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, int classzone_idx) + * them before going back to sleep. + */ + set_pgdat_percpu_threshold(pgdat, calculate_normal_threshold); +- schedule(); ++ ++ if (!kthread_should_stop()) ++ schedule(); ++ + set_pgdat_percpu_threshold(pgdat, calculate_pressure_threshold); + } else { + if (remaining) +@@ -3090,14 +3093,17 @@ int kswapd_run(int nid) + } + + /* +- * Called by memory hotplug when all memory in a node is offlined. ++ * Called by memory hotplug when all memory in a node is offlined. Caller must ++ * hold lock_memory_hotplug(). + */ + void kswapd_stop(int nid) + { + struct task_struct *kswapd = NODE_DATA(nid)->kswapd; + +- if (kswapd) ++ if (kswapd) { + kthread_stop(kswapd); ++ NODE_DATA(nid)->kswapd = NULL; ++ } + } + + static int __init kswapd_init(void) +diff --git a/net/can/raw.c b/net/can/raw.c +index cde1b4a..46cca3a 100644 +--- a/net/can/raw.c ++++ b/net/can/raw.c +@@ -681,9 +681,6 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock, + if (err < 0) + goto free_skb; + +- /* to be able to check the received tx sock reference in raw_rcv() */ +- skb_shinfo(skb)->tx_flags |= SKBTX_DRV_NEEDS_SK_REF; +- + skb->dev = dev; + skb->sk = sk; + +diff --git a/net/core/dev.c b/net/core/dev.c +index 1cbddc9..5738654 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -2079,25 +2079,6 @@ static int dev_gso_segment(struct sk_buff *skb, int features) + return 0; + } + +-/* +- * Try to orphan skb early, right before transmission by the device. +- * We cannot orphan skb if tx timestamp is requested or the sk-reference +- * is needed on driver level for other reasons, e.g. see net/can/raw.c +- */ +-static inline void skb_orphan_try(struct sk_buff *skb) +-{ +- struct sock *sk = skb->sk; +- +- if (sk && !skb_shinfo(skb)->tx_flags) { +- /* skb_tx_hash() wont be able to get sk. +- * We copy sk_hash into skb->rxhash +- */ +- if (!skb->rxhash) +- skb->rxhash = sk->sk_hash; +- skb_orphan(skb); +- } +-} +- + static bool can_checksum_protocol(unsigned long features, __be16 protocol) + { + return ((features & NETIF_F_GEN_CSUM) || +@@ -2182,8 +2163,6 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, + if (!list_empty(&ptype_all)) + dev_queue_xmit_nit(skb, dev); + +- skb_orphan_try(skb); +- + features = netif_skb_features(skb); + + if (vlan_tx_tag_present(skb) && +@@ -2293,7 +2272,7 @@ u16 __skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb, + if (skb->sk && skb->sk->sk_hash) + hash = skb->sk->sk_hash; + else +- hash = (__force u16) skb->protocol ^ skb->rxhash; ++ hash = (__force u16) skb->protocol; + hash = jhash_1word(hash, hashrnd); + + return (u16) (((u64) hash * qcount) >> 32) + qoffset; +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index 9726927..32e6ca2 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -5836,6 +5836,8 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, + goto discard; + + if (th->syn) { ++ if (th->fin) ++ goto discard; + if (icsk->icsk_af_ops->conn_request(sk, skb) < 0) + return 1; + +diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c +index 274d150..cf98d62 100644 +--- a/net/iucv/af_iucv.c ++++ b/net/iucv/af_iucv.c +@@ -380,7 +380,6 @@ static int afiucv_hs_send(struct iucv_message *imsg, struct sock *sock, + skb_trim(skb, skb->dev->mtu); + } + skb->protocol = ETH_P_AF_IUCV; +- skb_shinfo(skb)->tx_flags |= SKBTX_DRV_NEEDS_SK_REF; + nskb = skb_clone(skb, GFP_ATOMIC); + if (!nskb) + return -ENOMEM; +diff --git a/net/wireless/util.c b/net/wireless/util.c +index d38815d..74d5292 100644 +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -813,7 +813,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, + ntype == NL80211_IFTYPE_P2P_CLIENT)) + return -EBUSY; + +- if (ntype != otype) { ++ if (ntype != otype && netif_running(dev)) { + err = cfg80211_can_change_interface(rdev, dev->ieee80211_ptr, + ntype); + if (err) +diff --git a/scripts/depmod.sh b/scripts/depmod.sh +index a272356..2ae4817 100755 +--- a/scripts/depmod.sh ++++ b/scripts/depmod.sh +@@ -9,12 +9,6 @@ fi + DEPMOD=$1 + KERNELRELEASE=$2 + +-if ! "$DEPMOD" -V 2>/dev/null | grep -q module-init-tools; then +- echo "Warning: you may need to install module-init-tools" >&2 +- echo "See http://www.codemonkey.org.uk/docs/post-halloween-2.6.txt" >&2 +- sleep 1 +-fi +- + if ! test -r System.map -a -x "$DEPMOD"; then + exit 0 + fi +diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c +index 9f614b4..272407c 100644 +--- a/virt/kvm/irq_comm.c ++++ b/virt/kvm/irq_comm.c +@@ -318,6 +318,7 @@ static int setup_routing_entry(struct kvm_irq_routing_table *rt, + */ + hlist_for_each_entry(ei, n, &rt->map[ue->gsi], link) + if (ei->type == KVM_IRQ_ROUTING_MSI || ++ ue->type == KVM_IRQ_ROUTING_MSI || + ue->u.irqchip.irqchip == ei->irqchip.irqchip) + return r; + |