diff options
author | Anthony G. Basile <blueness@gentoo.org> | 2015-09-20 14:42:47 -0400 |
---|---|---|
committer | Anthony G. Basile <blueness@gentoo.org> | 2015-09-20 14:42:47 -0400 |
commit | cf9115c0ed2ec392f3fffea6566d8e1f10e502f8 (patch) | |
tree | e0ebd15d944754273ec6cd7f4f966ace3fac0117 /3.2.71/1024_linux-3.2.25.patch | |
parent | grsecurity-3.1-4.1.7-201509131604 (diff) | |
download | hardened-patchset-cf9115c0ed2ec392f3fffea6566d8e1f10e502f8.tar.gz hardened-patchset-cf9115c0ed2ec392f3fffea6566d8e1f10e502f8.tar.bz2 hardened-patchset-cf9115c0ed2ec392f3fffea6566d8e1f10e502f8.zip |
EOL: 3.2 and 3.14 series.
Diffstat (limited to '3.2.71/1024_linux-3.2.25.patch')
-rw-r--r-- | 3.2.71/1024_linux-3.2.25.patch | 4503 |
1 files changed, 0 insertions, 4503 deletions
diff --git a/3.2.71/1024_linux-3.2.25.patch b/3.2.71/1024_linux-3.2.25.patch deleted file mode 100644 index e95c213..0000000 --- a/3.2.71/1024_linux-3.2.25.patch +++ /dev/null @@ -1,4503 +0,0 @@ -diff --git a/Makefile b/Makefile -index 80bb4fd..e13e4e7 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,6 +1,6 @@ - VERSION = 3 - PATCHLEVEL = 2 --SUBLEVEL = 24 -+SUBLEVEL = 25 - EXTRAVERSION = - NAME = Saber-toothed Squirrel - -diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h -index 559da19..578e5a0 100644 ---- a/arch/powerpc/include/asm/reg.h -+++ b/arch/powerpc/include/asm/reg.h -@@ -1016,7 +1016,8 @@ - /* Macros for setting and retrieving special purpose registers */ - #ifndef __ASSEMBLY__ - #define mfmsr() ({unsigned long rval; \ -- asm volatile("mfmsr %0" : "=r" (rval)); rval;}) -+ asm volatile("mfmsr %0" : "=r" (rval) : \ -+ : "memory"); rval;}) - #ifdef CONFIG_PPC_BOOK3S_64 - #define __mtmsrd(v, l) asm volatile("mtmsrd %0," __stringify(l) \ - : : "r" (v) : "memory") -diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c -index bf99cfa..6324008 100644 ---- a/arch/powerpc/kernel/ftrace.c -+++ b/arch/powerpc/kernel/ftrace.c -@@ -245,9 +245,9 @@ __ftrace_make_nop(struct module *mod, - - /* - * On PPC32 the trampoline looks like: -- * 0x3d, 0x60, 0x00, 0x00 lis r11,sym@ha -- * 0x39, 0x6b, 0x00, 0x00 addi r11,r11,sym@l -- * 0x7d, 0x69, 0x03, 0xa6 mtctr r11 -+ * 0x3d, 0x80, 0x00, 0x00 lis r12,sym@ha -+ * 0x39, 0x8c, 0x00, 0x00 addi r12,r12,sym@l -+ * 0x7d, 0x89, 0x03, 0xa6 mtctr r12 - * 0x4e, 0x80, 0x04, 0x20 bctr - */ - -@@ -262,9 +262,9 @@ __ftrace_make_nop(struct module *mod, - pr_devel(" %08x %08x ", jmp[0], jmp[1]); - - /* verify that this is what we expect it to be */ -- if (((jmp[0] & 0xffff0000) != 0x3d600000) || -- ((jmp[1] & 0xffff0000) != 0x396b0000) || -- (jmp[2] != 0x7d6903a6) || -+ if (((jmp[0] & 0xffff0000) != 0x3d800000) || -+ ((jmp[1] & 0xffff0000) != 0x398c0000) || -+ (jmp[2] != 0x7d8903a6) || - (jmp[3] != 0x4e800420)) { - printk(KERN_ERR "Not a trampoline\n"); - return -EINVAL; -diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c -index 6e0073e..07c7bf4 100644 ---- a/arch/s390/kernel/processor.c -+++ b/arch/s390/kernel/processor.c -@@ -26,12 +26,14 @@ static DEFINE_PER_CPU(struct cpuid, cpu_id); - void __cpuinit cpu_init(void) - { - struct cpuid *id = &per_cpu(cpu_id, smp_processor_id()); -+ struct s390_idle_data *idle = &__get_cpu_var(s390_idle); - - get_cpu_id(id); - atomic_inc(&init_mm.mm_count); - current->active_mm = &init_mm; - BUG_ON(current->mm); - enter_lazy_tlb(&init_mm, current); -+ memset(idle, 0, sizeof(*idle)); - } - - /* -diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c -index 3ea8728..1df64a8 100644 ---- a/arch/s390/kernel/smp.c -+++ b/arch/s390/kernel/smp.c -@@ -1020,14 +1020,11 @@ static int __cpuinit smp_cpu_notify(struct notifier_block *self, - unsigned int cpu = (unsigned int)(long)hcpu; - struct cpu *c = &per_cpu(cpu_devices, cpu); - struct sys_device *s = &c->sysdev; -- struct s390_idle_data *idle; - int err = 0; - - switch (action) { - case CPU_ONLINE: - case CPU_ONLINE_FROZEN: -- idle = &per_cpu(s390_idle, cpu); -- memset(idle, 0, sizeof(struct s390_idle_data)); - err = sysfs_create_group(&s->kobj, &cpu_online_attr_group); - break; - case CPU_DEAD: -diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c -index 563a09d..29c95d7 100644 ---- a/arch/x86/kernel/microcode_core.c -+++ b/arch/x86/kernel/microcode_core.c -@@ -297,20 +297,31 @@ static ssize_t reload_store(struct sys_device *dev, - const char *buf, size_t size) - { - unsigned long val; -- int cpu = dev->id; -- int ret = 0; -- char *end; -+ int cpu; -+ ssize_t ret = 0, tmp_ret; - -- val = simple_strtoul(buf, &end, 0); -- if (end == buf) -+ /* allow reload only from the BSP */ -+ if (boot_cpu_data.cpu_index != dev->id) - return -EINVAL; - -- if (val == 1) { -- get_online_cpus(); -- if (cpu_online(cpu)) -- ret = reload_for_cpu(cpu); -- put_online_cpus(); -+ ret = kstrtoul(buf, 0, &val); -+ if (ret) -+ return ret; -+ -+ if (val != 1) -+ return size; -+ -+ get_online_cpus(); -+ for_each_online_cpu(cpu) { -+ tmp_ret = reload_for_cpu(cpu); -+ if (tmp_ret != 0) -+ pr_warn("Error reloading microcode on CPU %d\n", cpu); -+ -+ /* save retval of the first encountered reload error */ -+ if (!ret) -+ ret = tmp_ret; - } -+ put_online_cpus(); - - if (!ret) - ret = size; -diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c -index 6dd8955..0951b81 100644 ---- a/arch/x86/pci/fixup.c -+++ b/arch/x86/pci/fixup.c -@@ -521,3 +521,20 @@ static void sb600_disable_hpet_bar(struct pci_dev *dev) - } - } - DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x4385, sb600_disable_hpet_bar); -+ -+/* -+ * Twinhead H12Y needs us to block out a region otherwise we map devices -+ * there and any access kills the box. -+ * -+ * See: https://bugzilla.kernel.org/show_bug.cgi?id=10231 -+ * -+ * Match off the LPC and svid/sdid (older kernels lose the bridge subvendor) -+ */ -+static void __devinit twinhead_reserve_killing_zone(struct pci_dev *dev) -+{ -+ if (dev->subsystem_vendor == 0x14FF && dev->subsystem_device == 0xA003) { -+ pr_info("Reserving memory on Twinhead H12Y\n"); -+ request_mem_region(0xFFB00000, 0x100000, "twinhead"); -+ } -+} -+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x27B9, twinhead_reserve_killing_zone); -diff --git a/block/blk-core.c b/block/blk-core.c -index 15de223..49d9e91 100644 ---- a/block/blk-core.c -+++ b/block/blk-core.c -@@ -607,7 +607,7 @@ EXPORT_SYMBOL(blk_init_allocated_queue); - - int blk_get_queue(struct request_queue *q) - { -- if (likely(!test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) { -+ if (likely(!blk_queue_dead(q))) { - kobject_get(&q->kobj); - return 0; - } -@@ -754,7 +754,7 @@ static struct request *get_request(struct request_queue *q, int rw_flags, - const bool is_sync = rw_is_sync(rw_flags) != 0; - int may_queue; - -- if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) -+ if (unlikely(blk_queue_dead(q))) - return NULL; - - may_queue = elv_may_queue(q, rw_flags); -@@ -874,7 +874,7 @@ static struct request *get_request_wait(struct request_queue *q, int rw_flags, - struct io_context *ioc; - struct request_list *rl = &q->rq; - -- if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) -+ if (unlikely(blk_queue_dead(q))) - return NULL; - - prepare_to_wait_exclusive(&rl->wait[is_sync], &wait, -diff --git a/block/blk-exec.c b/block/blk-exec.c -index a1ebceb..6053285 100644 ---- a/block/blk-exec.c -+++ b/block/blk-exec.c -@@ -50,7 +50,7 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk, - { - int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK; - -- if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) { -+ if (unlikely(blk_queue_dead(q))) { - rq->errors = -ENXIO; - if (rq->end_io) - rq->end_io(rq, rq->errors); -diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c -index e7f9f65..f0b2ca8 100644 ---- a/block/blk-sysfs.c -+++ b/block/blk-sysfs.c -@@ -425,7 +425,7 @@ queue_attr_show(struct kobject *kobj, struct attribute *attr, char *page) - if (!entry->show) - return -EIO; - mutex_lock(&q->sysfs_lock); -- if (test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)) { -+ if (blk_queue_dead(q)) { - mutex_unlock(&q->sysfs_lock); - return -ENOENT; - } -@@ -447,7 +447,7 @@ queue_attr_store(struct kobject *kobj, struct attribute *attr, - - q = container_of(kobj, struct request_queue, kobj); - mutex_lock(&q->sysfs_lock); -- if (test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)) { -+ if (blk_queue_dead(q)) { - mutex_unlock(&q->sysfs_lock); - return -ENOENT; - } -diff --git a/block/blk-throttle.c b/block/blk-throttle.c -index 4553245..5eed6a7 100644 ---- a/block/blk-throttle.c -+++ b/block/blk-throttle.c -@@ -310,7 +310,7 @@ static struct throtl_grp * throtl_get_tg(struct throtl_data *td) - struct request_queue *q = td->queue; - - /* no throttling for dead queue */ -- if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) -+ if (unlikely(blk_queue_dead(q))) - return NULL; - - rcu_read_lock(); -@@ -335,7 +335,7 @@ static struct throtl_grp * throtl_get_tg(struct throtl_data *td) - spin_lock_irq(q->queue_lock); - - /* Make sure @q is still alive */ -- if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) { -+ if (unlikely(blk_queue_dead(q))) { - kfree(tg); - return NULL; - } -diff --git a/block/blk.h b/block/blk.h -index 3f6551b..e38691d 100644 ---- a/block/blk.h -+++ b/block/blk.h -@@ -85,7 +85,7 @@ static inline struct request *__elv_next_request(struct request_queue *q) - q->flush_queue_delayed = 1; - return NULL; - } -- if (test_bit(QUEUE_FLAG_DEAD, &q->queue_flags) || -+ if (unlikely(blk_queue_dead(q)) || - !q->elevator->ops->elevator_dispatch_fn(q, 0)) - return NULL; - } -diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c -index 6512b20..d1fcbc0 100644 ---- a/drivers/acpi/ac.c -+++ b/drivers/acpi/ac.c -@@ -292,7 +292,9 @@ static int acpi_ac_add(struct acpi_device *device) - ac->charger.properties = ac_props; - ac->charger.num_properties = ARRAY_SIZE(ac_props); - ac->charger.get_property = get_ac_property; -- power_supply_register(&ac->device->dev, &ac->charger); -+ result = power_supply_register(&ac->device->dev, &ac->charger); -+ if (result) -+ goto end; - - printk(KERN_INFO PREFIX "%s [%s] (%s)\n", - acpi_device_name(device), acpi_device_bid(device), -diff --git a/drivers/gpu/drm/nouveau/nva3_copy.fuc b/drivers/gpu/drm/nouveau/nva3_copy.fuc -index eaf35f8..d894731 100644 ---- a/drivers/gpu/drm/nouveau/nva3_copy.fuc -+++ b/drivers/gpu/drm/nouveau/nva3_copy.fuc -@@ -118,9 +118,9 @@ dispatch_dma: - // mthd 0x030c-0x0340, various stuff - .b16 0xc3 14 - .b32 ctx_src_address_high ~0x000000ff --.b32 ctx_src_address_low ~0xfffffff0 -+.b32 ctx_src_address_low ~0xffffffff - .b32 ctx_dst_address_high ~0x000000ff --.b32 ctx_dst_address_low ~0xfffffff0 -+.b32 ctx_dst_address_low ~0xffffffff - .b32 ctx_src_pitch ~0x0007ffff - .b32 ctx_dst_pitch ~0x0007ffff - .b32 ctx_xcnt ~0x0000ffff -diff --git a/drivers/gpu/drm/nouveau/nva3_copy.fuc.h b/drivers/gpu/drm/nouveau/nva3_copy.fuc.h -index 2731de2..e2a0e88 100644 ---- a/drivers/gpu/drm/nouveau/nva3_copy.fuc.h -+++ b/drivers/gpu/drm/nouveau/nva3_copy.fuc.h -@@ -1,37 +1,72 @@ --uint32_t nva3_pcopy_data[] = { -+u32 nva3_pcopy_data[] = { -+/* 0x0000: ctx_object */ - 0x00000000, -+/* 0x0004: ctx_dma */ -+/* 0x0004: ctx_dma_query */ - 0x00000000, -+/* 0x0008: ctx_dma_src */ - 0x00000000, -+/* 0x000c: ctx_dma_dst */ - 0x00000000, -+/* 0x0010: ctx_query_address_high */ - 0x00000000, -+/* 0x0014: ctx_query_address_low */ - 0x00000000, -+/* 0x0018: ctx_query_counter */ - 0x00000000, -+/* 0x001c: ctx_src_address_high */ - 0x00000000, -+/* 0x0020: ctx_src_address_low */ - 0x00000000, -+/* 0x0024: ctx_src_pitch */ - 0x00000000, -+/* 0x0028: ctx_src_tile_mode */ - 0x00000000, -+/* 0x002c: ctx_src_xsize */ - 0x00000000, -+/* 0x0030: ctx_src_ysize */ - 0x00000000, -+/* 0x0034: ctx_src_zsize */ - 0x00000000, -+/* 0x0038: ctx_src_zoff */ - 0x00000000, -+/* 0x003c: ctx_src_xoff */ - 0x00000000, -+/* 0x0040: ctx_src_yoff */ - 0x00000000, -+/* 0x0044: ctx_src_cpp */ - 0x00000000, -+/* 0x0048: ctx_dst_address_high */ - 0x00000000, -+/* 0x004c: ctx_dst_address_low */ - 0x00000000, -+/* 0x0050: ctx_dst_pitch */ - 0x00000000, -+/* 0x0054: ctx_dst_tile_mode */ - 0x00000000, -+/* 0x0058: ctx_dst_xsize */ - 0x00000000, -+/* 0x005c: ctx_dst_ysize */ - 0x00000000, -+/* 0x0060: ctx_dst_zsize */ - 0x00000000, -+/* 0x0064: ctx_dst_zoff */ - 0x00000000, -+/* 0x0068: ctx_dst_xoff */ - 0x00000000, -+/* 0x006c: ctx_dst_yoff */ - 0x00000000, -+/* 0x0070: ctx_dst_cpp */ - 0x00000000, -+/* 0x0074: ctx_format */ - 0x00000000, -+/* 0x0078: ctx_swz_const0 */ - 0x00000000, -+/* 0x007c: ctx_swz_const1 */ - 0x00000000, -+/* 0x0080: ctx_xcnt */ - 0x00000000, -+/* 0x0084: ctx_ycnt */ - 0x00000000, - 0x00000000, - 0x00000000, -@@ -63,6 +98,7 @@ uint32_t nva3_pcopy_data[] = { - 0x00000000, - 0x00000000, - 0x00000000, -+/* 0x0100: dispatch_table */ - 0x00010000, - 0x00000000, - 0x00000000, -@@ -73,6 +109,7 @@ uint32_t nva3_pcopy_data[] = { - 0x00010162, - 0x00000000, - 0x00030060, -+/* 0x0128: dispatch_dma */ - 0x00010170, - 0x00000000, - 0x00010170, -@@ -118,11 +155,11 @@ uint32_t nva3_pcopy_data[] = { - 0x0000001c, - 0xffffff00, - 0x00000020, -- 0x0000000f, -+ 0x00000000, - 0x00000048, - 0xffffff00, - 0x0000004c, -- 0x0000000f, -+ 0x00000000, - 0x00000024, - 0xfff80000, - 0x00000050, -@@ -146,7 +183,8 @@ uint32_t nva3_pcopy_data[] = { - 0x00000800, - }; - --uint32_t nva3_pcopy_code[] = { -+u32 nva3_pcopy_code[] = { -+/* 0x0000: main */ - 0x04fe04bd, - 0x3517f000, - 0xf10010fe, -@@ -158,23 +196,31 @@ uint32_t nva3_pcopy_code[] = { - 0x17f11031, - 0x27f01200, - 0x0012d003, -+/* 0x002f: spin */ - 0xf40031f4, - 0x0ef40028, -+/* 0x0035: ih */ - 0x8001cffd, - 0xf40812c4, - 0x21f4060b, -+/* 0x0041: ih_no_chsw */ - 0x0412c472, - 0xf4060bf4, -+/* 0x004a: ih_no_cmd */ - 0x11c4c321, - 0x4001d00c, -+/* 0x0052: swctx */ - 0x47f101f8, - 0x4bfe7700, - 0x0007fe00, - 0xf00204b9, - 0x01f40643, - 0x0604fa09, -+/* 0x006b: swctx_load */ - 0xfa060ef4, -+/* 0x006e: swctx_done */ - 0x03f80504, -+/* 0x0072: chsw */ - 0x27f100f8, - 0x23cf1400, - 0x1e3fc800, -@@ -183,18 +229,22 @@ uint32_t nva3_pcopy_code[] = { - 0x1e3af052, - 0xf00023d0, - 0x24d00147, -+/* 0x0093: chsw_no_unload */ - 0xcf00f880, - 0x3dc84023, - 0x220bf41e, - 0xf40131f4, - 0x57f05221, - 0x0367f004, -+/* 0x00a8: chsw_load_ctx_dma */ - 0xa07856bc, - 0xb6018068, - 0x87d00884, - 0x0162b600, -+/* 0x00bb: chsw_finish_load */ - 0xf0f018f4, - 0x23d00237, -+/* 0x00c3: dispatch */ - 0xf100f880, - 0xcf190037, - 0x33cf4032, -@@ -202,6 +252,7 @@ uint32_t nva3_pcopy_code[] = { - 0x1024b607, - 0x010057f1, - 0x74bd64bd, -+/* 0x00dc: dispatch_loop */ - 0x58005658, - 0x50b60157, - 0x0446b804, -@@ -211,6 +262,7 @@ uint32_t nva3_pcopy_code[] = { - 0xb60276bb, - 0x57bb0374, - 0xdf0ef400, -+/* 0x0100: dispatch_valid_mthd */ - 0xb60246bb, - 0x45bb0344, - 0x01459800, -@@ -220,31 +272,41 @@ uint32_t nva3_pcopy_code[] = { - 0xb0014658, - 0x1bf40064, - 0x00538009, -+/* 0x0127: dispatch_cmd */ - 0xf4300ef4, - 0x55f90132, - 0xf40c01f4, -+/* 0x0132: dispatch_invalid_bitfield */ - 0x25f0250e, -+/* 0x0135: dispatch_illegal_mthd */ - 0x0125f002, -+/* 0x0138: dispatch_error */ - 0x100047f1, - 0xd00042d0, - 0x27f04043, - 0x0002d040, -+/* 0x0148: hostirq_wait */ - 0xf08002cf, - 0x24b04024, - 0xf71bf400, -+/* 0x0154: dispatch_done */ - 0x1d0027f1, - 0xd00137f0, - 0x00f80023, -+/* 0x0160: cmd_nop */ -+/* 0x0162: cmd_pm_trigger */ - 0x27f100f8, - 0x34bd2200, - 0xd00233f0, - 0x00f80023, -+/* 0x0170: cmd_dma */ - 0x012842b7, - 0xf00145b6, - 0x43801e39, - 0x0040b701, - 0x0644b606, - 0xf80043d0, -+/* 0x0189: cmd_exec_set_format */ - 0xf030f400, - 0xb00001b0, - 0x01b00101, -@@ -256,20 +318,26 @@ uint32_t nva3_pcopy_code[] = { - 0x70b63847, - 0x0232f401, - 0x94bd84bd, -+/* 0x01b4: ncomp_loop */ - 0xb60f4ac4, - 0xb4bd0445, -+/* 0x01bc: bpc_loop */ - 0xf404a430, - 0xa5ff0f18, - 0x00cbbbc0, - 0xf40231f4, -+/* 0x01ce: cmp_c0 */ - 0x1bf4220e, - 0x10c7f00c, - 0xf400cbbb, -+/* 0x01da: cmp_c1 */ - 0xa430160e, - 0x0c18f406, - 0xbb14c7f0, - 0x0ef400cb, -+/* 0x01e9: cmp_zero */ - 0x80c7f107, -+/* 0x01ed: bpc_next */ - 0x01c83800, - 0xb60180b6, - 0xb5b801b0, -@@ -280,6 +348,7 @@ uint32_t nva3_pcopy_code[] = { - 0x98110680, - 0x68fd2008, - 0x0502f400, -+/* 0x0216: dst_xcnt */ - 0x75fd64bd, - 0x1c078000, - 0xf10078fd, -@@ -304,6 +373,7 @@ uint32_t nva3_pcopy_code[] = { - 0x980056d0, - 0x56d01f06, - 0x1030f440, -+/* 0x0276: cmd_exec_set_surface_tiled */ - 0x579800f8, - 0x6879c70a, - 0xb66478c7, -@@ -311,9 +381,11 @@ uint32_t nva3_pcopy_code[] = { - 0x0e76b060, - 0xf0091bf4, - 0x0ef40477, -+/* 0x0291: xtile64 */ - 0x027cf00f, - 0xfd1170b6, - 0x77f00947, -+/* 0x029d: xtileok */ - 0x0f5a9806, - 0xfd115b98, - 0xb7f000ab, -@@ -371,6 +443,7 @@ uint32_t nva3_pcopy_code[] = { - 0x67d00600, - 0x0060b700, - 0x0068d004, -+/* 0x0382: cmd_exec_set_surface_linear */ - 0x6cf000f8, - 0x0260b702, - 0x0864b602, -@@ -381,13 +454,16 @@ uint32_t nva3_pcopy_code[] = { - 0xb70067d0, - 0x98040060, - 0x67d00957, -+/* 0x03ab: cmd_exec_wait */ - 0xf900f800, - 0xf110f900, - 0xb6080007, -+/* 0x03b6: loop */ - 0x01cf0604, - 0x0114f000, - 0xfcfa1bf4, - 0xf800fc10, -+/* 0x03c5: cmd_exec_query */ - 0x0d34c800, - 0xf5701bf4, - 0xf103ab21, -@@ -417,6 +493,7 @@ uint32_t nva3_pcopy_code[] = { - 0x47f10153, - 0x44b60800, - 0x0045d006, -+/* 0x0438: query_counter */ - 0x03ab21f5, - 0x080c47f1, - 0x980644b6, -@@ -439,11 +516,13 @@ uint32_t nva3_pcopy_code[] = { - 0x47f10153, - 0x44b60800, - 0x0045d006, -+/* 0x0492: cmd_exec */ - 0x21f500f8, - 0x3fc803ab, - 0x0e0bf400, - 0x018921f5, - 0x020047f1, -+/* 0x04a7: cmd_exec_no_format */ - 0xf11e0ef4, - 0xb6081067, - 0x77f00664, -@@ -451,19 +530,24 @@ uint32_t nva3_pcopy_code[] = { - 0x981c0780, - 0x67d02007, - 0x4067d000, -+/* 0x04c2: cmd_exec_init_src_surface */ - 0x32f444bd, - 0xc854bd02, - 0x0bf4043f, - 0x8221f50a, - 0x0a0ef403, -+/* 0x04d4: src_tiled */ - 0x027621f5, -+/* 0x04db: cmd_exec_init_dst_surface */ - 0xf40749f0, - 0x57f00231, - 0x083fc82c, - 0xf50a0bf4, - 0xf4038221, -+/* 0x04ee: dst_tiled */ - 0x21f50a0e, - 0x49f00276, -+/* 0x04f5: cmd_exec_kick */ - 0x0057f108, - 0x0654b608, - 0xd0210698, -@@ -473,6 +557,8 @@ uint32_t nva3_pcopy_code[] = { - 0xc80054d0, - 0x0bf40c3f, - 0xc521f507, -+/* 0x0519: cmd_exec_done */ -+/* 0x051b: cmd_wrcache_flush */ - 0xf100f803, - 0xbd220027, - 0x0133f034, -diff --git a/drivers/gpu/drm/nouveau/nvc0_copy.fuc.h b/drivers/gpu/drm/nouveau/nvc0_copy.fuc.h -index 4199038..9e87036 100644 ---- a/drivers/gpu/drm/nouveau/nvc0_copy.fuc.h -+++ b/drivers/gpu/drm/nouveau/nvc0_copy.fuc.h -@@ -1,34 +1,65 @@ --uint32_t nvc0_pcopy_data[] = { -+u32 nvc0_pcopy_data[] = { -+/* 0x0000: ctx_object */ - 0x00000000, -+/* 0x0004: ctx_query_address_high */ - 0x00000000, -+/* 0x0008: ctx_query_address_low */ - 0x00000000, -+/* 0x000c: ctx_query_counter */ - 0x00000000, -+/* 0x0010: ctx_src_address_high */ - 0x00000000, -+/* 0x0014: ctx_src_address_low */ - 0x00000000, -+/* 0x0018: ctx_src_pitch */ - 0x00000000, -+/* 0x001c: ctx_src_tile_mode */ - 0x00000000, -+/* 0x0020: ctx_src_xsize */ - 0x00000000, -+/* 0x0024: ctx_src_ysize */ - 0x00000000, -+/* 0x0028: ctx_src_zsize */ - 0x00000000, -+/* 0x002c: ctx_src_zoff */ - 0x00000000, -+/* 0x0030: ctx_src_xoff */ - 0x00000000, -+/* 0x0034: ctx_src_yoff */ - 0x00000000, -+/* 0x0038: ctx_src_cpp */ - 0x00000000, -+/* 0x003c: ctx_dst_address_high */ - 0x00000000, -+/* 0x0040: ctx_dst_address_low */ - 0x00000000, -+/* 0x0044: ctx_dst_pitch */ - 0x00000000, -+/* 0x0048: ctx_dst_tile_mode */ - 0x00000000, -+/* 0x004c: ctx_dst_xsize */ - 0x00000000, -+/* 0x0050: ctx_dst_ysize */ - 0x00000000, -+/* 0x0054: ctx_dst_zsize */ - 0x00000000, -+/* 0x0058: ctx_dst_zoff */ - 0x00000000, -+/* 0x005c: ctx_dst_xoff */ - 0x00000000, -+/* 0x0060: ctx_dst_yoff */ - 0x00000000, -+/* 0x0064: ctx_dst_cpp */ - 0x00000000, -+/* 0x0068: ctx_format */ - 0x00000000, -+/* 0x006c: ctx_swz_const0 */ - 0x00000000, -+/* 0x0070: ctx_swz_const1 */ - 0x00000000, -+/* 0x0074: ctx_xcnt */ - 0x00000000, -+/* 0x0078: ctx_ycnt */ - 0x00000000, - 0x00000000, - 0x00000000, -@@ -63,6 +94,7 @@ uint32_t nvc0_pcopy_data[] = { - 0x00000000, - 0x00000000, - 0x00000000, -+/* 0x0100: dispatch_table */ - 0x00010000, - 0x00000000, - 0x00000000, -@@ -111,11 +143,11 @@ uint32_t nvc0_pcopy_data[] = { - 0x00000010, - 0xffffff00, - 0x00000014, -- 0x0000000f, -+ 0x00000000, - 0x0000003c, - 0xffffff00, - 0x00000040, -- 0x0000000f, -+ 0x00000000, - 0x00000018, - 0xfff80000, - 0x00000044, -@@ -139,7 +171,8 @@ uint32_t nvc0_pcopy_data[] = { - 0x00000800, - }; - --uint32_t nvc0_pcopy_code[] = { -+u32 nvc0_pcopy_code[] = { -+/* 0x0000: main */ - 0x04fe04bd, - 0x3517f000, - 0xf10010fe, -@@ -151,15 +184,20 @@ uint32_t nvc0_pcopy_code[] = { - 0x17f11031, - 0x27f01200, - 0x0012d003, -+/* 0x002f: spin */ - 0xf40031f4, - 0x0ef40028, -+/* 0x0035: ih */ - 0x8001cffd, - 0xf40812c4, - 0x21f4060b, -+/* 0x0041: ih_no_chsw */ - 0x0412c4ca, - 0xf5070bf4, -+/* 0x004b: ih_no_cmd */ - 0xc4010221, - 0x01d00c11, -+/* 0x0053: swctx */ - 0xf101f840, - 0xfe770047, - 0x47f1004b, -@@ -188,8 +226,11 @@ uint32_t nvc0_pcopy_code[] = { - 0xf00204b9, - 0x01f40643, - 0x0604fa09, -+/* 0x00c3: swctx_load */ - 0xfa060ef4, -+/* 0x00c6: swctx_done */ - 0x03f80504, -+/* 0x00ca: chsw */ - 0x27f100f8, - 0x23cf1400, - 0x1e3fc800, -@@ -198,18 +239,22 @@ uint32_t nvc0_pcopy_code[] = { - 0x1e3af053, - 0xf00023d0, - 0x24d00147, -+/* 0x00eb: chsw_no_unload */ - 0xcf00f880, - 0x3dc84023, - 0x090bf41e, - 0xf40131f4, -+/* 0x00fa: chsw_finish_load */ - 0x37f05321, - 0x8023d002, -+/* 0x0102: dispatch */ - 0x37f100f8, - 0x32cf1900, - 0x0033cf40, - 0x07ff24e4, - 0xf11024b6, - 0xbd010057, -+/* 0x011b: dispatch_loop */ - 0x5874bd64, - 0x57580056, - 0x0450b601, -@@ -219,6 +264,7 @@ uint32_t nvc0_pcopy_code[] = { - 0xbb0f08f4, - 0x74b60276, - 0x0057bb03, -+/* 0x013f: dispatch_valid_mthd */ - 0xbbdf0ef4, - 0x44b60246, - 0x0045bb03, -@@ -229,24 +275,33 @@ uint32_t nvc0_pcopy_code[] = { - 0x64b00146, - 0x091bf400, - 0xf4005380, -+/* 0x0166: dispatch_cmd */ - 0x32f4300e, - 0xf455f901, - 0x0ef40c01, -+/* 0x0171: dispatch_invalid_bitfield */ - 0x0225f025, -+/* 0x0174: dispatch_illegal_mthd */ -+/* 0x0177: dispatch_error */ - 0xf10125f0, - 0xd0100047, - 0x43d00042, - 0x4027f040, -+/* 0x0187: hostirq_wait */ - 0xcf0002d0, - 0x24f08002, - 0x0024b040, -+/* 0x0193: dispatch_done */ - 0xf1f71bf4, - 0xf01d0027, - 0x23d00137, -+/* 0x019f: cmd_nop */ - 0xf800f800, -+/* 0x01a1: cmd_pm_trigger */ - 0x0027f100, - 0xf034bd22, - 0x23d00233, -+/* 0x01af: cmd_exec_set_format */ - 0xf400f800, - 0x01b0f030, - 0x0101b000, -@@ -258,20 +313,26 @@ uint32_t nvc0_pcopy_code[] = { - 0x3847c701, - 0xf40170b6, - 0x84bd0232, -+/* 0x01da: ncomp_loop */ - 0x4ac494bd, - 0x0445b60f, -+/* 0x01e2: bpc_loop */ - 0xa430b4bd, - 0x0f18f404, - 0xbbc0a5ff, - 0x31f400cb, - 0x220ef402, -+/* 0x01f4: cmp_c0 */ - 0xf00c1bf4, - 0xcbbb10c7, - 0x160ef400, -+/* 0x0200: cmp_c1 */ - 0xf406a430, - 0xc7f00c18, - 0x00cbbb14, -+/* 0x020f: cmp_zero */ - 0xf1070ef4, -+/* 0x0213: bpc_next */ - 0x380080c7, - 0x80b601c8, - 0x01b0b601, -@@ -283,6 +344,7 @@ uint32_t nvc0_pcopy_code[] = { - 0x1d08980e, - 0xf40068fd, - 0x64bd0502, -+/* 0x023c: dst_xcnt */ - 0x800075fd, - 0x78fd1907, - 0x1057f100, -@@ -307,15 +369,18 @@ uint32_t nvc0_pcopy_code[] = { - 0x1c069800, - 0xf44056d0, - 0x00f81030, -+/* 0x029c: cmd_exec_set_surface_tiled */ - 0xc7075798, - 0x78c76879, - 0x0380b664, - 0xb06077c7, - 0x1bf40e76, - 0x0477f009, -+/* 0x02b7: xtile64 */ - 0xf00f0ef4, - 0x70b6027c, - 0x0947fd11, -+/* 0x02c3: xtileok */ - 0x980677f0, - 0x5b980c5a, - 0x00abfd0e, -@@ -374,6 +439,7 @@ uint32_t nvc0_pcopy_code[] = { - 0xb70067d0, - 0xd0040060, - 0x00f80068, -+/* 0x03a8: cmd_exec_set_surface_linear */ - 0xb7026cf0, - 0xb6020260, - 0x57980864, -@@ -384,12 +450,15 @@ uint32_t nvc0_pcopy_code[] = { - 0x0060b700, - 0x06579804, - 0xf80067d0, -+/* 0x03d1: cmd_exec_wait */ - 0xf900f900, - 0x0007f110, - 0x0604b608, -+/* 0x03dc: loop */ - 0xf00001cf, - 0x1bf40114, - 0xfc10fcfa, -+/* 0x03eb: cmd_exec_query */ - 0xc800f800, - 0x1bf40d34, - 0xd121f570, -@@ -419,6 +488,7 @@ uint32_t nvc0_pcopy_code[] = { - 0x0153f026, - 0x080047f1, - 0xd00644b6, -+/* 0x045e: query_counter */ - 0x21f50045, - 0x47f103d1, - 0x44b6080c, -@@ -442,11 +512,13 @@ uint32_t nvc0_pcopy_code[] = { - 0x080047f1, - 0xd00644b6, - 0x00f80045, -+/* 0x04b8: cmd_exec */ - 0x03d121f5, - 0xf4003fc8, - 0x21f50e0b, - 0x47f101af, - 0x0ef40200, -+/* 0x04cd: cmd_exec_no_format */ - 0x1067f11e, - 0x0664b608, - 0x800177f0, -@@ -454,18 +526,23 @@ uint32_t nvc0_pcopy_code[] = { - 0x1d079819, - 0xd00067d0, - 0x44bd4067, -+/* 0x04e8: cmd_exec_init_src_surface */ - 0xbd0232f4, - 0x043fc854, - 0xf50a0bf4, - 0xf403a821, -+/* 0x04fa: src_tiled */ - 0x21f50a0e, - 0x49f0029c, -+/* 0x0501: cmd_exec_init_dst_surface */ - 0x0231f407, - 0xc82c57f0, - 0x0bf4083f, - 0xa821f50a, - 0x0a0ef403, -+/* 0x0514: dst_tiled */ - 0x029c21f5, -+/* 0x051b: cmd_exec_kick */ - 0xf10849f0, - 0xb6080057, - 0x06980654, -@@ -475,7 +552,9 @@ uint32_t nvc0_pcopy_code[] = { - 0x54d00546, - 0x0c3fc800, - 0xf5070bf4, -+/* 0x053f: cmd_exec_done */ - 0xf803eb21, -+/* 0x0541: cmd_wrcache_flush */ - 0x0027f100, - 0xf034bd22, - 0x23d00133, -diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c -index 552b436..3254d51 100644 ---- a/drivers/gpu/drm/radeon/atombios_dp.c -+++ b/drivers/gpu/drm/radeon/atombios_dp.c -@@ -22,6 +22,7 @@ - * - * Authors: Dave Airlie - * Alex Deucher -+ * Jerome Glisse - */ - #include "drmP.h" - #include "radeon_drm.h" -@@ -634,7 +635,6 @@ static bool radeon_dp_get_link_status(struct radeon_connector *radeon_connector, - ret = radeon_dp_aux_native_read(radeon_connector, DP_LANE0_1_STATUS, - link_status, DP_LINK_STATUS_SIZE, 100); - if (ret <= 0) { -- DRM_ERROR("displayport link status failed\n"); - return false; - } - -@@ -812,8 +812,10 @@ static int radeon_dp_link_train_cr(struct radeon_dp_link_train_info *dp_info) - else - mdelay(dp_info->rd_interval * 4); - -- if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) -+ if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) { -+ DRM_ERROR("displayport link status failed\n"); - break; -+ } - - if (dp_clock_recovery_ok(dp_info->link_status, dp_info->dp_lane_count)) { - clock_recovery = true; -@@ -875,8 +877,10 @@ static int radeon_dp_link_train_ce(struct radeon_dp_link_train_info *dp_info) - else - mdelay(dp_info->rd_interval * 4); - -- if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) -+ if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) { -+ DRM_ERROR("displayport link status failed\n"); - break; -+ } - - if (dp_channel_eq_ok(dp_info->link_status, dp_info->dp_lane_count)) { - channel_eq = true; -diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c -index 4a4493f..87d494d 100644 ---- a/drivers/gpu/drm/radeon/radeon_connectors.c -+++ b/drivers/gpu/drm/radeon/radeon_connectors.c -@@ -64,14 +64,33 @@ void radeon_connector_hotplug(struct drm_connector *connector) - - /* just deal with DP (not eDP) here. */ - if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { -- int saved_dpms = connector->dpms; -- -- /* Only turn off the display it it's physically disconnected */ -- if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) -- drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); -- else if (radeon_dp_needs_link_train(radeon_connector)) -- drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); -- connector->dpms = saved_dpms; -+ struct radeon_connector_atom_dig *dig_connector = -+ radeon_connector->con_priv; -+ -+ /* if existing sink type was not DP no need to retrain */ -+ if (dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_DISPLAYPORT) -+ return; -+ -+ /* first get sink type as it may be reset after (un)plug */ -+ dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector); -+ /* don't do anything if sink is not display port, i.e., -+ * passive dp->(dvi|hdmi) adaptor -+ */ -+ if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) { -+ int saved_dpms = connector->dpms; -+ /* Only turn off the display if it's physically disconnected */ -+ if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) { -+ drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); -+ } else if (radeon_dp_needs_link_train(radeon_connector)) { -+ /* set it to OFF so that drm_helper_connector_dpms() -+ * won't return immediately since the current state -+ * is ON at this point. -+ */ -+ connector->dpms = DRM_MODE_DPMS_OFF; -+ drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); -+ } -+ connector->dpms = saved_dpms; -+ } - } - } - -diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c -index 986d608..2132109 100644 ---- a/drivers/gpu/drm/radeon/radeon_cursor.c -+++ b/drivers/gpu/drm/radeon/radeon_cursor.c -@@ -257,8 +257,14 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, - if (!(cursor_end & 0x7f)) - w--; - } -- if (w <= 0) -+ if (w <= 0) { - w = 1; -+ cursor_end = x - xorigin + w; -+ if (!(cursor_end & 0x7f)) { -+ x--; -+ WARN_ON_ONCE(x < 0); -+ } -+ } - } - } - -diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c -index f3ae607..39497c7 100644 ---- a/drivers/gpu/drm/radeon/radeon_object.c -+++ b/drivers/gpu/drm/radeon/radeon_object.c -@@ -117,7 +117,6 @@ int radeon_bo_create(struct radeon_device *rdev, - return -ENOMEM; - } - --retry: - bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); - if (bo == NULL) - return -ENOMEM; -@@ -130,6 +129,8 @@ retry: - bo->gem_base.driver_private = NULL; - bo->surface_reg = -1; - INIT_LIST_HEAD(&bo->list); -+ -+retry: - radeon_ttm_placement_from_domain(bo, domain); - /* Kernel allocation are uninterruptible */ - mutex_lock(&rdev->vram_mutex); -diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c -index a1b8caa..0f074e0 100644 ---- a/drivers/iommu/amd_iommu.c -+++ b/drivers/iommu/amd_iommu.c -@@ -1865,6 +1865,11 @@ static int device_change_notifier(struct notifier_block *nb, - - iommu_init_device(dev); - -+ if (iommu_pass_through) { -+ attach_device(dev, pt_domain); -+ break; -+ } -+ - domain = domain_for_device(dev); - - /* allocate a protection domain if a device is added */ -@@ -1880,10 +1885,7 @@ 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; -+ dev->archdata.dma_ops = &amd_iommu_dma_ops; - - break; - case BUS_NOTIFY_DEL_DEVICE: -diff --git a/drivers/media/video/cx25821/cx25821-core.c b/drivers/media/video/cx25821/cx25821-core.c -index a7fa38f..e572ce5 100644 ---- a/drivers/media/video/cx25821/cx25821-core.c -+++ b/drivers/media/video/cx25821/cx25821-core.c -@@ -914,9 +914,6 @@ static int cx25821_dev_setup(struct cx25821_dev *dev) - list_add_tail(&dev->devlist, &cx25821_devlist); - mutex_unlock(&cx25821_devlist_mutex); - -- strcpy(cx25821_boards[UNKNOWN_BOARD].name, "unknown"); -- strcpy(cx25821_boards[CX25821_BOARD].name, "cx25821"); -- - if (dev->pci->device != 0x8210) { - pr_info("%s(): Exiting. Incorrect Hardware device = 0x%02x\n", - __func__, dev->pci->device); -diff --git a/drivers/media/video/cx25821/cx25821.h b/drivers/media/video/cx25821/cx25821.h -index 2d2d009..bf54360 100644 ---- a/drivers/media/video/cx25821/cx25821.h -+++ b/drivers/media/video/cx25821/cx25821.h -@@ -187,7 +187,7 @@ enum port { - }; - - struct cx25821_board { -- char *name; -+ const char *name; - enum port porta; - enum port portb; - enum port portc; -diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c -index 6878a94..83b51b5 100644 ---- a/drivers/mmc/host/sdhci-pci.c -+++ b/drivers/mmc/host/sdhci-pci.c -@@ -148,6 +148,7 @@ static const struct sdhci_pci_fixes sdhci_ene_714 = { - static const struct sdhci_pci_fixes sdhci_cafe = { - .quirks = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER | - SDHCI_QUIRK_NO_BUSY_IRQ | -+ SDHCI_QUIRK_BROKEN_CARD_DETECTION | - SDHCI_QUIRK_BROKEN_TIMEOUT_VAL, - }; - -diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c -index 9e61d6b..ed1be8a 100644 ---- a/drivers/net/ethernet/realtek/r8169.c -+++ b/drivers/net/ethernet/realtek/r8169.c -@@ -3770,6 +3770,7 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp) - case RTL_GIGA_MAC_VER_22: - case RTL_GIGA_MAC_VER_23: - case RTL_GIGA_MAC_VER_24: -+ case RTL_GIGA_MAC_VER_34: - RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST); - break; - default: -diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c -index 01dcb1a..727c129 100644 ---- a/drivers/net/wireless/mwifiex/cfg80211.c -+++ b/drivers/net/wireless/mwifiex/cfg80211.c -@@ -545,9 +545,9 @@ mwifiex_dump_station_info(struct mwifiex_private *priv, - - /* - * Bit 0 in tx_htinfo indicates that current Tx rate is 11n rate. Valid -- * MCS index values for us are 0 to 7. -+ * MCS index values for us are 0 to 15. - */ -- if ((priv->tx_htinfo & BIT(0)) && (priv->tx_rate < 8)) { -+ if ((priv->tx_htinfo & BIT(0)) && (priv->tx_rate < 16)) { - sinfo->txrate.mcs = priv->tx_rate; - sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; - /* 40MHz rate */ -diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c -index 0ffa111..bdf960b 100644 ---- a/drivers/net/wireless/rt2x00/rt2800usb.c -+++ b/drivers/net/wireless/rt2x00/rt2800usb.c -@@ -876,6 +876,7 @@ static struct usb_device_id rt2800usb_device_table[] = { - { USB_DEVICE(0x1482, 0x3c09) }, - /* AirTies */ - { USB_DEVICE(0x1eda, 0x2012) }, -+ { USB_DEVICE(0x1eda, 0x2210) }, - { USB_DEVICE(0x1eda, 0x2310) }, - /* Allwin */ - { USB_DEVICE(0x8516, 0x2070) }, -@@ -945,6 +946,7 @@ static struct usb_device_id rt2800usb_device_table[] = { - /* DVICO */ - { USB_DEVICE(0x0fe9, 0xb307) }, - /* Edimax */ -+ { USB_DEVICE(0x7392, 0x4085) }, - { USB_DEVICE(0x7392, 0x7711) }, - { USB_DEVICE(0x7392, 0x7717) }, - { USB_DEVICE(0x7392, 0x7718) }, -@@ -1020,6 +1022,7 @@ static struct usb_device_id rt2800usb_device_table[] = { - /* Philips */ - { USB_DEVICE(0x0471, 0x200f) }, - /* Planex */ -+ { USB_DEVICE(0x2019, 0x5201) }, - { USB_DEVICE(0x2019, 0xab25) }, - { USB_DEVICE(0x2019, 0xed06) }, - /* Quanta */ -@@ -1088,6 +1091,12 @@ static struct usb_device_id rt2800usb_device_table[] = { - #ifdef CONFIG_RT2800USB_RT33XX - /* Belkin */ - { USB_DEVICE(0x050d, 0x945b) }, -+ /* D-Link */ -+ { USB_DEVICE(0x2001, 0x3c17) }, -+ /* Panasonic */ -+ { USB_DEVICE(0x083a, 0xb511) }, -+ /* Philips */ -+ { USB_DEVICE(0x0471, 0x20dd) }, - /* Ralink */ - { USB_DEVICE(0x148f, 0x3370) }, - { USB_DEVICE(0x148f, 0x8070) }, -@@ -1099,6 +1108,8 @@ static struct usb_device_id rt2800usb_device_table[] = { - { USB_DEVICE(0x8516, 0x3572) }, - /* Askey */ - { USB_DEVICE(0x1690, 0x0744) }, -+ { USB_DEVICE(0x1690, 0x0761) }, -+ { USB_DEVICE(0x1690, 0x0764) }, - /* Cisco */ - { USB_DEVICE(0x167b, 0x4001) }, - /* EnGenius */ -@@ -1113,6 +1124,9 @@ static struct usb_device_id rt2800usb_device_table[] = { - /* Sitecom */ - { USB_DEVICE(0x0df6, 0x0041) }, - { USB_DEVICE(0x0df6, 0x0062) }, -+ { USB_DEVICE(0x0df6, 0x0065) }, -+ { USB_DEVICE(0x0df6, 0x0066) }, -+ { USB_DEVICE(0x0df6, 0x0068) }, - /* Toshiba */ - { USB_DEVICE(0x0930, 0x0a07) }, - /* Zinwell */ -@@ -1122,6 +1136,9 @@ static struct usb_device_id rt2800usb_device_table[] = { - /* Azurewave */ - { USB_DEVICE(0x13d3, 0x3329) }, - { USB_DEVICE(0x13d3, 0x3365) }, -+ /* D-Link */ -+ { USB_DEVICE(0x2001, 0x3c1c) }, -+ { USB_DEVICE(0x2001, 0x3c1d) }, - /* Ralink */ - { USB_DEVICE(0x148f, 0x5370) }, - { USB_DEVICE(0x148f, 0x5372) }, -@@ -1163,13 +1180,8 @@ static struct usb_device_id rt2800usb_device_table[] = { - /* D-Link */ - { USB_DEVICE(0x07d1, 0x3c0b) }, - { USB_DEVICE(0x07d1, 0x3c17) }, -- { USB_DEVICE(0x2001, 0x3c17) }, -- /* Edimax */ -- { USB_DEVICE(0x7392, 0x4085) }, - /* Encore */ - { USB_DEVICE(0x203d, 0x14a1) }, -- /* Fujitsu Stylistic 550 */ -- { USB_DEVICE(0x1690, 0x0761) }, - /* Gemtek */ - { USB_DEVICE(0x15a9, 0x0010) }, - /* Gigabyte */ -@@ -1190,7 +1202,6 @@ static struct usb_device_id rt2800usb_device_table[] = { - { USB_DEVICE(0x05a6, 0x0101) }, - { USB_DEVICE(0x1d4d, 0x0010) }, - /* Planex */ -- { USB_DEVICE(0x2019, 0x5201) }, - { USB_DEVICE(0x2019, 0xab24) }, - /* Qcom */ - { USB_DEVICE(0x18e8, 0x6259) }, -diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c -index 2cf4c5f..de9faa9 100644 ---- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c -+++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c -@@ -3462,21 +3462,21 @@ void rtl92d_phy_config_macphymode_info(struct ieee80211_hw *hw) - switch (rtlhal->macphymode) { - case DUALMAC_SINGLEPHY: - rtlphy->rf_type = RF_2T2R; -- rtlhal->version |= CHIP_92D_SINGLEPHY; -+ rtlhal->version |= RF_TYPE_2T2R; - rtlhal->bandset = BAND_ON_BOTH; - rtlhal->current_bandtype = BAND_ON_2_4G; - break; - - case SINGLEMAC_SINGLEPHY: - rtlphy->rf_type = RF_2T2R; -- rtlhal->version |= CHIP_92D_SINGLEPHY; -+ rtlhal->version |= RF_TYPE_2T2R; - rtlhal->bandset = BAND_ON_BOTH; - rtlhal->current_bandtype = BAND_ON_2_4G; - break; - - case DUALMAC_DUALPHY: - rtlphy->rf_type = RF_1T1R; -- rtlhal->version &= (~CHIP_92D_SINGLEPHY); -+ rtlhal->version &= RF_TYPE_1T1R; - /* Now we let MAC0 run on 5G band. */ - if (rtlhal->interfaceindex == 0) { - rtlhal->bandset = BAND_ON_5G; -diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c -index 351dc0b..ee77a58 100644 ---- a/drivers/scsi/hosts.c -+++ b/drivers/scsi/hosts.c -@@ -287,6 +287,7 @@ static void scsi_host_dev_release(struct device *dev) - struct Scsi_Host *shost = dev_to_shost(dev); - struct device *parent = dev->parent; - struct request_queue *q; -+ void *queuedata; - - scsi_proc_hostdir_rm(shost->hostt); - -@@ -296,9 +297,9 @@ static void scsi_host_dev_release(struct device *dev) - destroy_workqueue(shost->work_q); - q = shost->uspace_req_q; - if (q) { -- kfree(q->queuedata); -- q->queuedata = NULL; -- scsi_free_queue(q); -+ queuedata = q->queuedata; -+ blk_cleanup_queue(q); -+ kfree(queuedata); - } - - scsi_destroy_command_freelist(shost); -diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c -index e48ba4b..dbe3568 100644 ---- a/drivers/scsi/libsas/sas_expander.c -+++ b/drivers/scsi/libsas/sas_expander.c -@@ -774,7 +774,7 @@ static struct domain_device *sas_ex_discover_end_dev( - } - - /* See if this phy is part of a wide port */ --static int sas_ex_join_wide_port(struct domain_device *parent, int phy_id) -+static bool sas_ex_join_wide_port(struct domain_device *parent, int phy_id) - { - struct ex_phy *phy = &parent->ex_dev.ex_phy[phy_id]; - int i; -@@ -790,11 +790,11 @@ static int sas_ex_join_wide_port(struct domain_device *parent, int phy_id) - sas_port_add_phy(ephy->port, phy->phy); - phy->port = ephy->port; - phy->phy_state = PHY_DEVICE_DISCOVERED; -- return 0; -+ return true; - } - } - -- return -ENODEV; -+ return false; - } - - static struct domain_device *sas_ex_discover_expander( -@@ -932,8 +932,7 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id) - return res; - } - -- res = sas_ex_join_wide_port(dev, phy_id); -- if (!res) { -+ if (sas_ex_join_wide_port(dev, phy_id)) { - SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n", - phy_id, SAS_ADDR(ex_phy->attached_sas_addr)); - return res; -@@ -978,8 +977,7 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id) - if (SAS_ADDR(ex->ex_phy[i].attached_sas_addr) == - SAS_ADDR(child->sas_addr)) { - ex->ex_phy[i].phy_state= PHY_DEVICE_DISCOVERED; -- res = sas_ex_join_wide_port(dev, i); -- if (!res) -+ if (sas_ex_join_wide_port(dev, i)) - SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n", - i, SAS_ADDR(ex->ex_phy[i].attached_sas_addr)); - -@@ -1849,32 +1847,20 @@ static int sas_discover_new(struct domain_device *dev, int phy_id) - { - struct ex_phy *ex_phy = &dev->ex_dev.ex_phy[phy_id]; - struct domain_device *child; -- bool found = false; -- int res, i; -+ int res; - - SAS_DPRINTK("ex %016llx phy%d new device attached\n", - SAS_ADDR(dev->sas_addr), phy_id); - res = sas_ex_phy_discover(dev, phy_id); - if (res) -- goto out; -- /* to support the wide port inserted */ -- for (i = 0; i < dev->ex_dev.num_phys; i++) { -- struct ex_phy *ex_phy_temp = &dev->ex_dev.ex_phy[i]; -- if (i == phy_id) -- continue; -- if (SAS_ADDR(ex_phy_temp->attached_sas_addr) == -- SAS_ADDR(ex_phy->attached_sas_addr)) { -- found = true; -- break; -- } -- } -- if (found) { -- sas_ex_join_wide_port(dev, phy_id); -+ return res; -+ -+ if (sas_ex_join_wide_port(dev, phy_id)) - return 0; -- } -+ - res = sas_ex_discover_devices(dev, phy_id); -- if (!res) -- goto out; -+ if (res) -+ return res; - list_for_each_entry(child, &dev->ex_dev.children, siblings) { - if (SAS_ADDR(child->sas_addr) == - SAS_ADDR(ex_phy->attached_sas_addr)) { -@@ -1884,7 +1870,6 @@ static int sas_discover_new(struct domain_device *dev, int phy_id) - break; - } - } --out: - return res; - } - -@@ -1983,9 +1968,7 @@ int sas_ex_revalidate_domain(struct domain_device *port_dev) - struct domain_device *dev = NULL; - - res = sas_find_bcast_dev(port_dev, &dev); -- if (res) -- goto out; -- if (dev) { -+ while (res == 0 && dev) { - struct expander_device *ex = &dev->ex_dev; - int i = 0, phy_id; - -@@ -1997,8 +1980,10 @@ int sas_ex_revalidate_domain(struct domain_device *port_dev) - res = sas_rediscover(dev, phy_id); - i = phy_id + 1; - } while (i < ex->num_phys); -+ -+ dev = NULL; -+ res = sas_find_bcast_dev(port_dev, &dev); - } --out: - return res; - } - -diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c -index 2aeb2e9..831db24 100644 ---- a/drivers/scsi/scsi.c -+++ b/drivers/scsi/scsi.c -@@ -785,7 +785,13 @@ static void scsi_done(struct scsi_cmnd *cmd) - /* Move this to a header if it becomes more generally useful */ - static struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd) - { -- return *(struct scsi_driver **)cmd->request->rq_disk->private_data; -+ struct scsi_driver **sdp; -+ -+ sdp = (struct scsi_driver **)cmd->request->rq_disk->private_data; -+ if (!sdp) -+ return NULL; -+ -+ return *sdp; - } - - /** -diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c -index dc6131e..456b131 100644 ---- a/drivers/scsi/scsi_error.c -+++ b/drivers/scsi/scsi_error.c -@@ -1673,6 +1673,20 @@ static void scsi_restart_operations(struct Scsi_Host *shost) - * requests are started. - */ - scsi_run_host_queues(shost); -+ -+ /* -+ * if eh is active and host_eh_scheduled is pending we need to re-run -+ * recovery. we do this check after scsi_run_host_queues() to allow -+ * everything pent up since the last eh run a chance to make forward -+ * progress before we sync again. Either we'll immediately re-run -+ * recovery or scsi_device_unbusy() will wake us again when these -+ * pending commands complete. -+ */ -+ spin_lock_irqsave(shost->host_lock, flags); -+ if (shost->host_eh_scheduled) -+ if (scsi_host_set_state(shost, SHOST_RECOVERY)) -+ WARN_ON(scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY)); -+ spin_unlock_irqrestore(shost->host_lock, flags); - } - - /** -diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c -index f0ab58e..6c4b620 100644 ---- a/drivers/scsi/scsi_lib.c -+++ b/drivers/scsi/scsi_lib.c -@@ -406,10 +406,6 @@ static void scsi_run_queue(struct request_queue *q) - LIST_HEAD(starved_list); - unsigned long flags; - -- /* if the device is dead, sdev will be NULL, so no queue to run */ -- if (!sdev) -- return; -- - shost = sdev->host; - if (scsi_target(sdev)->single_lun) - scsi_single_lun_run(sdev); -@@ -483,15 +479,26 @@ void scsi_requeue_run_queue(struct work_struct *work) - */ - static void scsi_requeue_command(struct request_queue *q, struct scsi_cmnd *cmd) - { -+ struct scsi_device *sdev = cmd->device; - struct request *req = cmd->request; - unsigned long flags; - -+ /* -+ * We need to hold a reference on the device to avoid the queue being -+ * killed after the unlock and before scsi_run_queue is invoked which -+ * may happen because scsi_unprep_request() puts the command which -+ * releases its reference on the device. -+ */ -+ get_device(&sdev->sdev_gendev); -+ - spin_lock_irqsave(q->queue_lock, flags); - scsi_unprep_request(req); - blk_requeue_request(q, req); - spin_unlock_irqrestore(q->queue_lock, flags); - - scsi_run_queue(q); -+ -+ put_device(&sdev->sdev_gendev); - } - - void scsi_next_command(struct scsi_cmnd *cmd) -@@ -1374,16 +1381,16 @@ static inline int scsi_host_queue_ready(struct request_queue *q, - * may be changed after request stacking drivers call the function, - * regardless of taking lock or not. - * -- * When scsi can't dispatch I/Os anymore and needs to kill I/Os -- * (e.g. !sdev), scsi needs to return 'not busy'. -- * Otherwise, request stacking drivers may hold requests forever. -+ * When scsi can't dispatch I/Os anymore and needs to kill I/Os scsi -+ * needs to return 'not busy'. Otherwise, request stacking drivers -+ * may hold requests forever. - */ - static int scsi_lld_busy(struct request_queue *q) - { - struct scsi_device *sdev = q->queuedata; - struct Scsi_Host *shost; - -- if (!sdev) -+ if (blk_queue_dead(q)) - return 0; - - shost = sdev->host; -@@ -1494,12 +1501,6 @@ static void scsi_request_fn(struct request_queue *q) - struct scsi_cmnd *cmd; - struct request *req; - -- if (!sdev) { -- while ((req = blk_peek_request(q)) != NULL) -- scsi_kill_request(req, q); -- return; -- } -- - if(!get_device(&sdev->sdev_gendev)) - /* We must be tearing the block queue down already */ - return; -@@ -1701,20 +1702,6 @@ struct request_queue *scsi_alloc_queue(struct scsi_device *sdev) - return q; - } - --void scsi_free_queue(struct request_queue *q) --{ -- unsigned long flags; -- -- WARN_ON(q->queuedata); -- -- /* cause scsi_request_fn() to kill all non-finished requests */ -- spin_lock_irqsave(q->queue_lock, flags); -- q->request_fn(q); -- spin_unlock_irqrestore(q->queue_lock, flags); -- -- blk_cleanup_queue(q); --} -- - /* - * Function: scsi_block_requests() - * -diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h -index 5b475d0..d58adca 100644 ---- a/drivers/scsi/scsi_priv.h -+++ b/drivers/scsi/scsi_priv.h -@@ -85,7 +85,6 @@ extern void scsi_next_command(struct scsi_cmnd *cmd); - extern void scsi_io_completion(struct scsi_cmnd *, unsigned int); - extern void scsi_run_host_queues(struct Scsi_Host *shost); - extern struct request_queue *scsi_alloc_queue(struct scsi_device *sdev); --extern void scsi_free_queue(struct request_queue *q); - extern int scsi_init_queue(void); - extern void scsi_exit_queue(void); - struct request_queue; -diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c -index 6e7ea4a..a48b59c 100644 ---- a/drivers/scsi/scsi_scan.c -+++ b/drivers/scsi/scsi_scan.c -@@ -1710,6 +1710,9 @@ static void scsi_sysfs_add_devices(struct Scsi_Host *shost) - { - struct scsi_device *sdev; - shost_for_each_device(sdev, shost) { -+ /* target removed before the device could be added */ -+ if (sdev->sdev_state == SDEV_DEL) -+ continue; - if (!scsi_host_scan_allowed(shost) || - scsi_sysfs_add_sdev(sdev) != 0) - __scsi_remove_device(sdev); -diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c -index 04c2a27..bb7c482 100644 ---- a/drivers/scsi/scsi_sysfs.c -+++ b/drivers/scsi/scsi_sysfs.c -@@ -971,11 +971,8 @@ void __scsi_remove_device(struct scsi_device *sdev) - sdev->host->hostt->slave_destroy(sdev); - transport_destroy_device(dev); - -- /* cause the request function to reject all I/O requests */ -- sdev->request_queue->queuedata = NULL; -- - /* Freeing the queue signals to block that we're done */ -- scsi_free_queue(sdev->request_queue); -+ blk_cleanup_queue(sdev->request_queue); - put_device(dev); - } - -@@ -1000,7 +997,6 @@ static void __scsi_remove_target(struct scsi_target *starget) - struct scsi_device *sdev; - - spin_lock_irqsave(shost->host_lock, flags); -- starget->reap_ref++; - restart: - list_for_each_entry(sdev, &shost->__devices, siblings) { - if (sdev->channel != starget->channel || -@@ -1014,14 +1010,6 @@ static void __scsi_remove_target(struct scsi_target *starget) - goto restart; - } - spin_unlock_irqrestore(shost->host_lock, flags); -- scsi_target_reap(starget); --} -- --static int __remove_child (struct device * dev, void * data) --{ -- if (scsi_is_target_device(dev)) -- __scsi_remove_target(to_scsi_target(dev)); -- return 0; - } - - /** -@@ -1034,14 +1022,34 @@ static int __remove_child (struct device * dev, void * data) - */ - void scsi_remove_target(struct device *dev) - { -- if (scsi_is_target_device(dev)) { -- __scsi_remove_target(to_scsi_target(dev)); -- return; -+ struct Scsi_Host *shost = dev_to_shost(dev->parent); -+ struct scsi_target *starget, *found; -+ unsigned long flags; -+ -+ restart: -+ found = NULL; -+ spin_lock_irqsave(shost->host_lock, flags); -+ list_for_each_entry(starget, &shost->__targets, siblings) { -+ if (starget->state == STARGET_DEL) -+ continue; -+ if (starget->dev.parent == dev || &starget->dev == dev) { -+ found = starget; -+ found->reap_ref++; -+ break; -+ } - } -+ spin_unlock_irqrestore(shost->host_lock, flags); - -- get_device(dev); -- device_for_each_child(dev, NULL, __remove_child); -- put_device(dev); -+ if (found) { -+ __scsi_remove_target(found); -+ scsi_target_reap(found); -+ /* in the case where @dev has multiple starget children, -+ * continue removing. -+ * -+ * FIXME: does such a case exist? -+ */ -+ goto restart; -+ } - } - EXPORT_SYMBOL(scsi_remove_target); - -diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c -index 0842cc7..2ff1255 100644 ---- a/drivers/target/iscsi/iscsi_target.c -+++ b/drivers/target/iscsi/iscsi_target.c -@@ -427,19 +427,8 @@ int iscsit_reset_np_thread( - - int iscsit_del_np_comm(struct iscsi_np *np) - { -- if (!np->np_socket) -- return 0; -- -- /* -- * Some network transports allocate their own struct sock->file, -- * see if we need to free any additional allocated resources. -- */ -- if (np->np_flags & NPF_SCTP_STRUCT_FILE) { -- kfree(np->np_socket->file); -- np->np_socket->file = NULL; -- } -- -- sock_release(np->np_socket); -+ if (np->np_socket) -+ sock_release(np->np_socket); - return 0; - } - -@@ -4105,13 +4094,8 @@ int iscsit_close_connection( - kfree(conn->conn_ops); - conn->conn_ops = NULL; - -- if (conn->sock) { -- if (conn->conn_flags & CONNFLAG_SCTP_STRUCT_FILE) { -- kfree(conn->sock->file); -- conn->sock->file = NULL; -- } -+ if (conn->sock) - sock_release(conn->sock); -- } - conn->thread_set = NULL; - - pr_debug("Moving to TARG_CONN_STATE_FREE.\n"); -diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h -index 7da2d6a..0f68197 100644 ---- a/drivers/target/iscsi/iscsi_target_core.h -+++ b/drivers/target/iscsi/iscsi_target_core.h -@@ -224,7 +224,6 @@ enum iscsi_timer_flags_table { - /* Used for struct iscsi_np->np_flags */ - enum np_flags_table { - NPF_IP_NETWORK = 0x00, -- NPF_SCTP_STRUCT_FILE = 0x01 /* Bugfix */ - }; - - /* Used for struct iscsi_np->np_thread_state */ -@@ -511,7 +510,6 @@ struct iscsi_conn { - u16 local_port; - int net_size; - u32 auth_id; --#define CONNFLAG_SCTP_STRUCT_FILE 0x01 - u32 conn_flags; - /* Used for iscsi_tx_login_rsp() */ - u32 login_itt; -diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c -index bd2adec..2ec5339 100644 ---- a/drivers/target/iscsi/iscsi_target_login.c -+++ b/drivers/target/iscsi/iscsi_target_login.c -@@ -793,22 +793,6 @@ int iscsi_target_setup_login_socket( - } - np->np_socket = sock; - /* -- * The SCTP stack needs struct socket->file. -- */ -- if ((np->np_network_transport == ISCSI_SCTP_TCP) || -- (np->np_network_transport == ISCSI_SCTP_UDP)) { -- if (!sock->file) { -- sock->file = kzalloc(sizeof(struct file), GFP_KERNEL); -- if (!sock->file) { -- pr_err("Unable to allocate struct" -- " file for SCTP\n"); -- ret = -ENOMEM; -- goto fail; -- } -- np->np_flags |= NPF_SCTP_STRUCT_FILE; -- } -- } -- /* - * Setup the np->np_sockaddr from the passed sockaddr setup - * in iscsi_target_configfs.c code.. - */ -@@ -857,21 +841,15 @@ int iscsi_target_setup_login_socket( - - fail: - np->np_socket = NULL; -- if (sock) { -- if (np->np_flags & NPF_SCTP_STRUCT_FILE) { -- kfree(sock->file); -- sock->file = NULL; -- } -- -+ if (sock) - sock_release(sock); -- } - return ret; - } - - static int __iscsi_target_login_thread(struct iscsi_np *np) - { - u8 buffer[ISCSI_HDR_LEN], iscsi_opcode, zero_tsih = 0; -- int err, ret = 0, ip_proto, sock_type, set_sctp_conn_flag, stop; -+ int err, ret = 0, ip_proto, sock_type, stop; - struct iscsi_conn *conn = NULL; - struct iscsi_login *login; - struct iscsi_portal_group *tpg = NULL; -@@ -882,7 +860,6 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) - struct sockaddr_in6 sock_in6; - - flush_signals(current); -- set_sctp_conn_flag = 0; - sock = np->np_socket; - ip_proto = np->np_ip_proto; - sock_type = np->np_sock_type; -@@ -907,35 +884,12 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) - spin_unlock_bh(&np->np_thread_lock); - goto out; - } -- /* -- * The SCTP stack needs struct socket->file. -- */ -- if ((np->np_network_transport == ISCSI_SCTP_TCP) || -- (np->np_network_transport == ISCSI_SCTP_UDP)) { -- if (!new_sock->file) { -- new_sock->file = kzalloc( -- sizeof(struct file), GFP_KERNEL); -- if (!new_sock->file) { -- pr_err("Unable to allocate struct" -- " file for SCTP\n"); -- sock_release(new_sock); -- /* Get another socket */ -- return 1; -- } -- set_sctp_conn_flag = 1; -- } -- } -- - iscsi_start_login_thread_timer(np); - - conn = kzalloc(sizeof(struct iscsi_conn), GFP_KERNEL); - if (!conn) { - pr_err("Could not allocate memory for" - " new connection\n"); -- if (set_sctp_conn_flag) { -- kfree(new_sock->file); -- new_sock->file = NULL; -- } - sock_release(new_sock); - /* Get another socket */ - return 1; -@@ -945,9 +899,6 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) - conn->conn_state = TARG_CONN_STATE_FREE; - conn->sock = new_sock; - -- if (set_sctp_conn_flag) -- conn->conn_flags |= CONNFLAG_SCTP_STRUCT_FILE; -- - pr_debug("Moving to TARG_CONN_STATE_XPT_UP.\n"); - conn->conn_state = TARG_CONN_STATE_XPT_UP; - -@@ -1195,13 +1146,8 @@ old_sess_out: - iscsi_release_param_list(conn->param_list); - conn->param_list = NULL; - } -- if (conn->sock) { -- if (conn->conn_flags & CONNFLAG_SCTP_STRUCT_FILE) { -- kfree(conn->sock->file); -- conn->sock->file = NULL; -- } -+ if (conn->sock) - sock_release(conn->sock); -- } - kfree(conn); - - if (tpg) { -diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c -index 93b9406..717a8d4 100644 ---- a/drivers/target/target_core_cdb.c -+++ b/drivers/target/target_core_cdb.c -@@ -1114,11 +1114,11 @@ int target_emulate_unmap(struct se_task *task) - struct se_cmd *cmd = task->task_se_cmd; - struct se_device *dev = cmd->se_dev; - unsigned char *buf, *ptr = NULL; -- unsigned char *cdb = &cmd->t_task_cdb[0]; - sector_t lba; -- unsigned int size = cmd->data_length, range; -- int ret = 0, offset; -- unsigned short dl, bd_dl; -+ int size = cmd->data_length; -+ u32 range; -+ int ret = 0; -+ int dl, bd_dl; - - if (!dev->transport->do_discard) { - pr_err("UNMAP emulation not supported for: %s\n", -@@ -1127,24 +1127,41 @@ int target_emulate_unmap(struct se_task *task) - return -ENOSYS; - } - -- /* First UNMAP block descriptor starts at 8 byte offset */ -- offset = 8; -- size -= 8; -- dl = get_unaligned_be16(&cdb[0]); -- bd_dl = get_unaligned_be16(&cdb[2]); -- - buf = transport_kmap_data_sg(cmd); - -- ptr = &buf[offset]; -- pr_debug("UNMAP: Sub: %s Using dl: %hu bd_dl: %hu size: %hu" -+ dl = get_unaligned_be16(&buf[0]); -+ bd_dl = get_unaligned_be16(&buf[2]); -+ -+ size = min(size - 8, bd_dl); -+ if (size / 16 > dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) { -+ cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ /* First UNMAP block descriptor starts at 8 byte offset */ -+ ptr = &buf[8]; -+ pr_debug("UNMAP: Sub: %s Using dl: %u bd_dl: %u size: %u" - " ptr: %p\n", dev->transport->name, dl, bd_dl, size, ptr); - -- while (size) { -+ while (size >= 16) { - lba = get_unaligned_be64(&ptr[0]); - range = get_unaligned_be32(&ptr[8]); - pr_debug("UNMAP: Using lba: %llu and range: %u\n", - (unsigned long long)lba, range); - -+ if (range > dev->se_sub_dev->se_dev_attrib.max_unmap_lba_count) { -+ cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ if (lba + range > dev->transport->get_blocks(dev) + 1) { -+ cmd->scsi_sense_reason = TCM_ADDRESS_OUT_OF_RANGE; -+ ret = -EINVAL; -+ goto err; -+ } -+ - ret = dev->transport->do_discard(dev, lba, range); - if (ret < 0) { - pr_err("blkdev_issue_discard() failed: %d\n", -diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c -index 5660916..94c03d2 100644 ---- a/drivers/target/target_core_transport.c -+++ b/drivers/target/target_core_transport.c -@@ -1820,6 +1820,7 @@ static void transport_generic_request_failure(struct se_cmd *cmd) - case TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE: - case TCM_UNKNOWN_MODE_PAGE: - case TCM_WRITE_PROTECTED: -+ case TCM_ADDRESS_OUT_OF_RANGE: - case TCM_CHECK_CONDITION_ABORT_CMD: - case TCM_CHECK_CONDITION_UNIT_ATTENTION: - case TCM_CHECK_CONDITION_NOT_READY: -@@ -4496,6 +4497,15 @@ int transport_send_check_condition_and_sense( - /* WRITE PROTECTED */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x27; - break; -+ case TCM_ADDRESS_OUT_OF_RANGE: -+ /* CURRENT ERROR */ -+ buffer[offset] = 0x70; -+ buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; -+ /* ILLEGAL REQUEST */ -+ buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; -+ /* LOGICAL BLOCK ADDRESS OUT OF RANGE */ -+ buffer[offset+SPC_ASC_KEY_OFFSET] = 0x21; -+ break; - case TCM_CHECK_CONDITION_UNIT_ATTENTION: - /* CURRENT ERROR */ - buffer[offset] = 0x70; -diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c -index f6ff837..a9df218 100644 ---- a/drivers/usb/core/devio.c -+++ b/drivers/usb/core/devio.c -@@ -1555,10 +1555,14 @@ static int processcompl_compat(struct async *as, void __user * __user *arg) - void __user *addr = as->userurb; - unsigned int i; - -- if (as->userbuffer && urb->actual_length) -- if (copy_to_user(as->userbuffer, urb->transfer_buffer, -- urb->actual_length)) -+ if (as->userbuffer && urb->actual_length) { -+ if (urb->number_of_packets > 0) /* Isochronous */ -+ i = urb->transfer_buffer_length; -+ else /* Non-Isoc */ -+ i = urb->actual_length; -+ if (copy_to_user(as->userbuffer, urb->transfer_buffer, i)) - return -EFAULT; -+ } - if (put_user(as->status, &userurb->status)) - return -EFAULT; - if (put_user(urb->actual_length, &userurb->actual_length)) -diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c -index 29c854b..4e1f0aa 100644 ---- a/drivers/usb/gadget/u_ether.c -+++ b/drivers/usb/gadget/u_ether.c -@@ -796,12 +796,6 @@ int gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN]) - - SET_ETHTOOL_OPS(net, &ops); - -- /* two kinds of host-initiated state changes: -- * - iff DATA transfer is active, carrier is "on" -- * - tx queueing enabled if open *and* carrier is "on" -- */ -- netif_carrier_off(net); -- - dev->gadget = g; - SET_NETDEV_DEV(net, &g->dev); - SET_NETDEV_DEVTYPE(net, &gadget_type); -@@ -815,6 +809,12 @@ int gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN]) - INFO(dev, "HOST MAC %pM\n", dev->host_mac); - - the_dev = dev; -+ -+ /* two kinds of host-initiated state changes: -+ * - iff DATA transfer is active, carrier is "on" -+ * - tx queueing enabled if open *and* carrier is "on" -+ */ -+ netif_carrier_off(net); - } - - return status; -diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c -index 5971c95..d89aac1 100644 ---- a/drivers/usb/serial/option.c -+++ b/drivers/usb/serial/option.c -@@ -932,8 +932,12 @@ static const struct usb_device_id option_ids[] = { - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0165, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0167, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, -- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff) }, -- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff) }, -+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0326, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, -+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, -+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff), -+ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) }, -diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c -index 0b39458..03321e5 100644 ---- a/fs/btrfs/async-thread.c -+++ b/fs/btrfs/async-thread.c -@@ -206,10 +206,17 @@ static noinline int run_ordered_completions(struct btrfs_workers *workers, - - work->ordered_func(work); - -- /* now take the lock again and call the freeing code */ -+ /* now take the lock again and drop our item from the list */ - spin_lock(&workers->order_lock); - list_del(&work->order_list); -+ spin_unlock(&workers->order_lock); -+ -+ /* -+ * we don't want to call the ordered free functions -+ * with the lock held though -+ */ - work->ordered_free(work); -+ spin_lock(&workers->order_lock); - } - - spin_unlock(&workers->order_lock); -diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c -index f44b392..6b2a724 100644 ---- a/fs/btrfs/disk-io.c -+++ b/fs/btrfs/disk-io.c -@@ -872,7 +872,8 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, - - #ifdef CONFIG_MIGRATION - static int btree_migratepage(struct address_space *mapping, -- struct page *newpage, struct page *page) -+ struct page *newpage, struct page *page, -+ enum migrate_mode mode) - { - /* - * we can't safely write a btree page from here, -@@ -887,7 +888,7 @@ static int btree_migratepage(struct address_space *mapping, - if (page_has_private(page) && - !try_to_release_page(page, GFP_KERNEL)) - return -EAGAIN; -- return migrate_page(mapping, newpage, page); -+ return migrate_page(mapping, newpage, page, mode); - } - #endif - -diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c -index 6aa7457..c858a29 100644 ---- a/fs/cifs/cifssmb.c -+++ b/fs/cifs/cifssmb.c -@@ -89,6 +89,32 @@ static struct { - /* Forward declarations */ - static void cifs_readv_complete(struct work_struct *work); - -+#ifdef CONFIG_HIGHMEM -+/* -+ * On arches that have high memory, kmap address space is limited. By -+ * serializing the kmap operations on those arches, we ensure that we don't -+ * end up with a bunch of threads in writeback with partially mapped page -+ * arrays, stuck waiting for kmap to come back. That situation prevents -+ * progress and can deadlock. -+ */ -+static DEFINE_MUTEX(cifs_kmap_mutex); -+ -+static inline void -+cifs_kmap_lock(void) -+{ -+ mutex_lock(&cifs_kmap_mutex); -+} -+ -+static inline void -+cifs_kmap_unlock(void) -+{ -+ mutex_unlock(&cifs_kmap_mutex); -+} -+#else /* !CONFIG_HIGHMEM */ -+#define cifs_kmap_lock() do { ; } while(0) -+#define cifs_kmap_unlock() do { ; } while(0) -+#endif /* CONFIG_HIGHMEM */ -+ - /* Mark as invalid, all open files on tree connections since they - were closed when session to server was lost */ - static void mark_open_files_invalid(struct cifs_tcon *pTcon) -@@ -1540,6 +1566,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) - eof_index = eof ? (eof - 1) >> PAGE_CACHE_SHIFT : 0; - cFYI(1, "eof=%llu eof_index=%lu", eof, eof_index); - -+ cifs_kmap_lock(); - list_for_each_entry_safe(page, tpage, &rdata->pages, lru) { - if (remaining >= PAGE_CACHE_SIZE) { - /* enough data to fill the page */ -@@ -1589,6 +1616,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) - page_cache_release(page); - } - } -+ cifs_kmap_unlock(); - - /* issue the read if we have any iovecs left to fill */ - if (rdata->nr_iov > 1) { -@@ -2171,6 +2199,7 @@ cifs_async_writev(struct cifs_writedata *wdata) - iov[0].iov_base = smb; - - /* marshal up the pages into iov array */ -+ cifs_kmap_lock(); - wdata->bytes = 0; - for (i = 0; i < wdata->nr_pages; i++) { - iov[i + 1].iov_len = min(inode->i_size - -@@ -2179,6 +2208,7 @@ cifs_async_writev(struct cifs_writedata *wdata) - iov[i + 1].iov_base = kmap(wdata->pages[i]); - wdata->bytes += iov[i + 1].iov_len; - } -+ cifs_kmap_unlock(); - - cFYI(1, "async write at %llu %u bytes", wdata->offset, wdata->bytes); - -diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c -index 914bf9e..d6970f7 100644 ---- a/fs/ext4/balloc.c -+++ b/fs/ext4/balloc.c -@@ -557,7 +557,8 @@ ext4_fsblk_t ext4_count_free_clusters(struct super_block *sb) - if (bitmap_bh == NULL) - continue; - -- x = ext4_count_free(bitmap_bh, sb->s_blocksize); -+ x = ext4_count_free(bitmap_bh->b_data, -+ EXT4_BLOCKS_PER_GROUP(sb) / 8); - printk(KERN_DEBUG "group %u: stored = %d, counted = %u\n", - i, ext4_free_group_clusters(sb, gdp), x); - bitmap_count += x; -diff --git a/fs/ext4/bitmap.c b/fs/ext4/bitmap.c -index fa3af81..bbde5d5 100644 ---- a/fs/ext4/bitmap.c -+++ b/fs/ext4/bitmap.c -@@ -11,21 +11,15 @@ - #include <linux/jbd2.h> - #include "ext4.h" - --#ifdef EXT4FS_DEBUG -- - static const int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0}; - --unsigned int ext4_count_free(struct buffer_head *map, unsigned int numchars) -+unsigned int ext4_count_free(char *bitmap, unsigned int numchars) - { - unsigned int i, sum = 0; - -- if (!map) -- return 0; - for (i = 0; i < numchars; i++) -- sum += nibblemap[map->b_data[i] & 0xf] + -- nibblemap[(map->b_data[i] >> 4) & 0xf]; -+ sum += nibblemap[bitmap[i] & 0xf] + -+ nibblemap[(bitmap[i] >> 4) & 0xf]; - return sum; - } - --#endif /* EXT4FS_DEBUG */ -- -diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h -index 7b1cd5c..8cb184c 100644 ---- a/fs/ext4/ext4.h -+++ b/fs/ext4/ext4.h -@@ -1123,8 +1123,7 @@ struct ext4_sb_info { - unsigned long s_desc_per_block; /* Number of group descriptors per block */ - ext4_group_t s_groups_count; /* Number of groups in the fs */ - ext4_group_t s_blockfile_groups;/* Groups acceptable for non-extent files */ -- unsigned long s_overhead_last; /* Last calculated overhead */ -- unsigned long s_blocks_last; /* Last seen block count */ -+ unsigned long s_overhead; /* # of fs overhead clusters */ - unsigned int s_cluster_ratio; /* Number of blocks per cluster */ - unsigned int s_cluster_bits; /* log2 of s_cluster_ratio */ - loff_t s_bitmap_maxbytes; /* max bytes for bitmap files */ -@@ -1757,7 +1756,7 @@ struct mmpd_data { - # define NORET_AND noreturn, - - /* bitmap.c */ --extern unsigned int ext4_count_free(struct buffer_head *, unsigned); -+extern unsigned int ext4_count_free(char *bitmap, unsigned numchars); - - /* balloc.c */ - extern unsigned int ext4_block_group(struct super_block *sb, -@@ -1925,6 +1924,7 @@ extern int ext4_group_extend(struct super_block *sb, - ext4_fsblk_t n_blocks_count); - - /* super.c */ -+extern int ext4_calculate_overhead(struct super_block *sb); - extern void *ext4_kvmalloc(size_t size, gfp_t flags); - extern void *ext4_kvzalloc(size_t size, gfp_t flags); - extern void ext4_kvfree(void *ptr); -diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c -index 8fb6844..6266799 100644 ---- a/fs/ext4/ialloc.c -+++ b/fs/ext4/ialloc.c -@@ -1057,7 +1057,8 @@ unsigned long ext4_count_free_inodes(struct super_block *sb) - if (!bitmap_bh) - continue; - -- x = ext4_count_free(bitmap_bh, EXT4_INODES_PER_GROUP(sb) / 8); -+ x = ext4_count_free(bitmap_bh->b_data, -+ EXT4_INODES_PER_GROUP(sb) / 8); - printk(KERN_DEBUG "group %lu: stored = %d, counted = %lu\n", - (unsigned long) i, ext4_free_inodes_count(sb, gdp), x); - bitmap_count += x; -diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c -index 3ce7613..8b01f9f 100644 ---- a/fs/ext4/inode.c -+++ b/fs/ext4/inode.c -@@ -277,6 +277,15 @@ void ext4_da_update_reserve_space(struct inode *inode, - used = ei->i_reserved_data_blocks; - } - -+ if (unlikely(ei->i_allocated_meta_blocks > ei->i_reserved_meta_blocks)) { -+ ext4_msg(inode->i_sb, KERN_NOTICE, "%s: ino %lu, allocated %d " -+ "with only %d reserved metadata blocks\n", __func__, -+ inode->i_ino, ei->i_allocated_meta_blocks, -+ ei->i_reserved_meta_blocks); -+ WARN_ON(1); -+ ei->i_allocated_meta_blocks = ei->i_reserved_meta_blocks; -+ } -+ - /* Update per-inode reservations */ - ei->i_reserved_data_blocks -= used; - ei->i_reserved_meta_blocks -= ei->i_allocated_meta_blocks; -@@ -1102,6 +1111,17 @@ static int ext4_da_reserve_space(struct inode *inode, ext4_lblk_t lblock) - struct ext4_inode_info *ei = EXT4_I(inode); - unsigned int md_needed; - int ret; -+ ext4_lblk_t save_last_lblock; -+ int save_len; -+ -+ /* -+ * We will charge metadata quota at writeout time; this saves -+ * us from metadata over-estimation, though we may go over by -+ * a small amount in the end. Here we just reserve for data. -+ */ -+ ret = dquot_reserve_block(inode, EXT4_C2B(sbi, 1)); -+ if (ret) -+ return ret; - - /* - * recalculate the amount of metadata blocks to reserve -@@ -1110,32 +1130,31 @@ static int ext4_da_reserve_space(struct inode *inode, ext4_lblk_t lblock) - */ - repeat: - spin_lock(&ei->i_block_reservation_lock); -+ /* -+ * ext4_calc_metadata_amount() has side effects, which we have -+ * to be prepared undo if we fail to claim space. -+ */ -+ save_len = ei->i_da_metadata_calc_len; -+ save_last_lblock = ei->i_da_metadata_calc_last_lblock; - md_needed = EXT4_NUM_B2C(sbi, - ext4_calc_metadata_amount(inode, lblock)); - trace_ext4_da_reserve_space(inode, md_needed); -- spin_unlock(&ei->i_block_reservation_lock); - - /* -- * We will charge metadata quota at writeout time; this saves -- * us from metadata over-estimation, though we may go over by -- * a small amount in the end. Here we just reserve for data. -- */ -- ret = dquot_reserve_block(inode, EXT4_C2B(sbi, 1)); -- if (ret) -- return ret; -- /* - * We do still charge estimated metadata to the sb though; - * we cannot afford to run out of free blocks. - */ - if (ext4_claim_free_clusters(sbi, md_needed + 1, 0)) { -- dquot_release_reservation_block(inode, EXT4_C2B(sbi, 1)); -+ ei->i_da_metadata_calc_len = save_len; -+ ei->i_da_metadata_calc_last_lblock = save_last_lblock; -+ spin_unlock(&ei->i_block_reservation_lock); - if (ext4_should_retry_alloc(inode->i_sb, &retries)) { - yield(); - goto repeat; - } -+ dquot_release_reservation_block(inode, EXT4_C2B(sbi, 1)); - return -ENOSPC; - } -- spin_lock(&ei->i_block_reservation_lock); - ei->i_reserved_data_blocks++; - ei->i_reserved_meta_blocks += md_needed; - spin_unlock(&ei->i_block_reservation_lock); -diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c -index 996780a..4eac337 100644 ---- a/fs/ext4/resize.c -+++ b/fs/ext4/resize.c -@@ -952,6 +952,11 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) - &sbi->s_flex_groups[flex_group].free_inodes); - } - -+ /* -+ * Update the fs overhead information -+ */ -+ ext4_calculate_overhead(sb); -+ - ext4_handle_dirty_super(handle, sb); - - exit_journal: -diff --git a/fs/ext4/super.c b/fs/ext4/super.c -index a93486e..a071348 100644 ---- a/fs/ext4/super.c -+++ b/fs/ext4/super.c -@@ -3083,6 +3083,114 @@ static void ext4_destroy_lazyinit_thread(void) - kthread_stop(ext4_lazyinit_task); - } - -+/* -+ * Note: calculating the overhead so we can be compatible with -+ * historical BSD practice is quite difficult in the face of -+ * clusters/bigalloc. This is because multiple metadata blocks from -+ * different block group can end up in the same allocation cluster. -+ * Calculating the exact overhead in the face of clustered allocation -+ * requires either O(all block bitmaps) in memory or O(number of block -+ * groups**2) in time. We will still calculate the superblock for -+ * older file systems --- and if we come across with a bigalloc file -+ * system with zero in s_overhead_clusters the estimate will be close to -+ * correct especially for very large cluster sizes --- but for newer -+ * file systems, it's better to calculate this figure once at mkfs -+ * time, and store it in the superblock. If the superblock value is -+ * present (even for non-bigalloc file systems), we will use it. -+ */ -+static int count_overhead(struct super_block *sb, ext4_group_t grp, -+ char *buf) -+{ -+ struct ext4_sb_info *sbi = EXT4_SB(sb); -+ struct ext4_group_desc *gdp; -+ ext4_fsblk_t first_block, last_block, b; -+ ext4_group_t i, ngroups = ext4_get_groups_count(sb); -+ int s, j, count = 0; -+ -+ first_block = le32_to_cpu(sbi->s_es->s_first_data_block) + -+ (grp * EXT4_BLOCKS_PER_GROUP(sb)); -+ last_block = first_block + EXT4_BLOCKS_PER_GROUP(sb) - 1; -+ for (i = 0; i < ngroups; i++) { -+ gdp = ext4_get_group_desc(sb, i, NULL); -+ b = ext4_block_bitmap(sb, gdp); -+ if (b >= first_block && b <= last_block) { -+ ext4_set_bit(EXT4_B2C(sbi, b - first_block), buf); -+ count++; -+ } -+ b = ext4_inode_bitmap(sb, gdp); -+ if (b >= first_block && b <= last_block) { -+ ext4_set_bit(EXT4_B2C(sbi, b - first_block), buf); -+ count++; -+ } -+ b = ext4_inode_table(sb, gdp); -+ if (b >= first_block && b + sbi->s_itb_per_group <= last_block) -+ for (j = 0; j < sbi->s_itb_per_group; j++, b++) { -+ int c = EXT4_B2C(sbi, b - first_block); -+ ext4_set_bit(c, buf); -+ count++; -+ } -+ if (i != grp) -+ continue; -+ s = 0; -+ if (ext4_bg_has_super(sb, grp)) { -+ ext4_set_bit(s++, buf); -+ count++; -+ } -+ for (j = ext4_bg_num_gdb(sb, grp); j > 0; j--) { -+ ext4_set_bit(EXT4_B2C(sbi, s++), buf); -+ count++; -+ } -+ } -+ if (!count) -+ return 0; -+ return EXT4_CLUSTERS_PER_GROUP(sb) - -+ ext4_count_free(buf, EXT4_CLUSTERS_PER_GROUP(sb) / 8); -+} -+ -+/* -+ * Compute the overhead and stash it in sbi->s_overhead -+ */ -+int ext4_calculate_overhead(struct super_block *sb) -+{ -+ struct ext4_sb_info *sbi = EXT4_SB(sb); -+ struct ext4_super_block *es = sbi->s_es; -+ ext4_group_t i, ngroups = ext4_get_groups_count(sb); -+ ext4_fsblk_t overhead = 0; -+ char *buf = (char *) get_zeroed_page(GFP_KERNEL); -+ -+ memset(buf, 0, PAGE_SIZE); -+ if (!buf) -+ return -ENOMEM; -+ -+ /* -+ * Compute the overhead (FS structures). This is constant -+ * for a given filesystem unless the number of block groups -+ * changes so we cache the previous value until it does. -+ */ -+ -+ /* -+ * All of the blocks before first_data_block are overhead -+ */ -+ overhead = EXT4_B2C(sbi, le32_to_cpu(es->s_first_data_block)); -+ -+ /* -+ * Add the overhead found in each block group -+ */ -+ for (i = 0; i < ngroups; i++) { -+ int blks; -+ -+ blks = count_overhead(sb, i, buf); -+ overhead += blks; -+ if (blks) -+ memset(buf, 0, PAGE_SIZE); -+ cond_resched(); -+ } -+ sbi->s_overhead = overhead; -+ smp_wmb(); -+ free_page((unsigned long) buf); -+ return 0; -+} -+ - static int ext4_fill_super(struct super_block *sb, void *data, int silent) - { - char *orig_data = kstrdup(data, GFP_KERNEL); -@@ -3695,6 +3803,18 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) - - no_journal: - /* -+ * Get the # of file system overhead blocks from the -+ * superblock if present. -+ */ -+ if (es->s_overhead_clusters) -+ sbi->s_overhead = le32_to_cpu(es->s_overhead_clusters); -+ else { -+ ret = ext4_calculate_overhead(sb); -+ if (ret) -+ goto failed_mount_wq; -+ } -+ -+ /* - * The maximum number of concurrent works can be high and - * concurrency isn't really necessary. Limit it to 1. - */ -@@ -4568,67 +4688,21 @@ restore_opts: - return err; - } - --/* -- * Note: calculating the overhead so we can be compatible with -- * historical BSD practice is quite difficult in the face of -- * clusters/bigalloc. This is because multiple metadata blocks from -- * different block group can end up in the same allocation cluster. -- * Calculating the exact overhead in the face of clustered allocation -- * requires either O(all block bitmaps) in memory or O(number of block -- * groups**2) in time. We will still calculate the superblock for -- * older file systems --- and if we come across with a bigalloc file -- * system with zero in s_overhead_clusters the estimate will be close to -- * correct especially for very large cluster sizes --- but for newer -- * file systems, it's better to calculate this figure once at mkfs -- * time, and store it in the superblock. If the superblock value is -- * present (even for non-bigalloc file systems), we will use it. -- */ - static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf) - { - struct super_block *sb = dentry->d_sb; - struct ext4_sb_info *sbi = EXT4_SB(sb); - struct ext4_super_block *es = sbi->s_es; -- struct ext4_group_desc *gdp; -+ ext4_fsblk_t overhead = 0; - u64 fsid; - s64 bfree; - -- if (test_opt(sb, MINIX_DF)) { -- sbi->s_overhead_last = 0; -- } else if (es->s_overhead_clusters) { -- sbi->s_overhead_last = le32_to_cpu(es->s_overhead_clusters); -- } else if (sbi->s_blocks_last != ext4_blocks_count(es)) { -- ext4_group_t i, ngroups = ext4_get_groups_count(sb); -- ext4_fsblk_t overhead = 0; -- -- /* -- * Compute the overhead (FS structures). This is constant -- * for a given filesystem unless the number of block groups -- * changes so we cache the previous value until it does. -- */ -- -- /* -- * All of the blocks before first_data_block are -- * overhead -- */ -- overhead = EXT4_B2C(sbi, le32_to_cpu(es->s_first_data_block)); -- -- /* -- * Add the overhead found in each block group -- */ -- for (i = 0; i < ngroups; i++) { -- gdp = ext4_get_group_desc(sb, i, NULL); -- overhead += ext4_num_overhead_clusters(sb, i, gdp); -- cond_resched(); -- } -- sbi->s_overhead_last = overhead; -- smp_wmb(); -- sbi->s_blocks_last = ext4_blocks_count(es); -- } -+ if (!test_opt(sb, MINIX_DF)) -+ overhead = sbi->s_overhead; - - buf->f_type = EXT4_SUPER_MAGIC; - buf->f_bsize = sb->s_blocksize; -- buf->f_blocks = (ext4_blocks_count(es) - -- EXT4_C2B(sbi, sbi->s_overhead_last)); -+ buf->f_blocks = ext4_blocks_count(es) - EXT4_C2B(sbi, sbi->s_overhead); - bfree = percpu_counter_sum_positive(&sbi->s_freeclusters_counter) - - percpu_counter_sum_positive(&sbi->s_dirtyclusters_counter); - /* prevent underflow in case that few free space is available */ -diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c -index ebc2f4d..0aa424a 100644 ---- a/fs/hugetlbfs/inode.c -+++ b/fs/hugetlbfs/inode.c -@@ -569,7 +569,8 @@ static int hugetlbfs_set_page_dirty(struct page *page) - } - - static int hugetlbfs_migrate_page(struct address_space *mapping, -- struct page *newpage, struct page *page) -+ struct page *newpage, struct page *page, -+ enum migrate_mode mode) - { - int rc; - -diff --git a/fs/locks.c b/fs/locks.c -index 6a64f15..fcc50ab 100644 ---- a/fs/locks.c -+++ b/fs/locks.c -@@ -308,7 +308,7 @@ static int flock_make_lock(struct file *filp, struct file_lock **lock, - return 0; - } - --static int assign_type(struct file_lock *fl, int type) -+static int assign_type(struct file_lock *fl, long type) - { - switch (type) { - case F_RDLCK: -@@ -445,7 +445,7 @@ static const struct lock_manager_operations lease_manager_ops = { - /* - * Initialize a lease, use the default lock manager operations - */ --static int lease_init(struct file *filp, int type, struct file_lock *fl) -+static int lease_init(struct file *filp, long type, struct file_lock *fl) - { - if (assign_type(fl, type) != 0) - return -EINVAL; -@@ -463,7 +463,7 @@ static int lease_init(struct file *filp, int type, struct file_lock *fl) - } - - /* Allocate a file_lock initialised to this type of lease */ --static struct file_lock *lease_alloc(struct file *filp, int type) -+static struct file_lock *lease_alloc(struct file *filp, long type) - { - struct file_lock *fl = locks_alloc_lock(); - int error = -ENOMEM; -diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h -index 3f4d957..68b3f20 100644 ---- a/fs/nfs/internal.h -+++ b/fs/nfs/internal.h -@@ -330,7 +330,7 @@ void nfs_commit_release_pages(struct nfs_write_data *data); - - #ifdef CONFIG_MIGRATION - extern int nfs_migrate_page(struct address_space *, -- struct page *, struct page *); -+ struct page *, struct page *, enum migrate_mode); - #else - #define nfs_migrate_page NULL - #endif -diff --git a/fs/nfs/write.c b/fs/nfs/write.c -index 4efd421..c6e523a 100644 ---- a/fs/nfs/write.c -+++ b/fs/nfs/write.c -@@ -1711,7 +1711,7 @@ out_error: - - #ifdef CONFIG_MIGRATION - int nfs_migrate_page(struct address_space *mapping, struct page *newpage, -- struct page *page) -+ struct page *page, enum migrate_mode mode) - { - /* - * If PagePrivate is set, then the page is currently associated with -@@ -1726,7 +1726,7 @@ int nfs_migrate_page(struct address_space *mapping, struct page *newpage, - - nfs_fscache_release_page(page, GFP_KERNEL); - -- return migrate_page(mapping, newpage, page); -+ return migrate_page(mapping, newpage, page, mode); - } - #endif - -diff --git a/fs/udf/super.c b/fs/udf/super.c -index 270e135..516b7f0 100644 ---- a/fs/udf/super.c -+++ b/fs/udf/super.c -@@ -1285,7 +1285,7 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block, - BUG_ON(ident != TAG_IDENT_LVD); - lvd = (struct logicalVolDesc *)bh->b_data; - table_len = le32_to_cpu(lvd->mapTableLength); -- if (sizeof(*lvd) + table_len > sb->s_blocksize) { -+ if (table_len > sb->s_blocksize - sizeof(*lvd)) { - udf_err(sb, "error loading logical volume descriptor: " - "Partition table too long (%u > %lu)\n", table_len, - sb->s_blocksize - sizeof(*lvd)); -diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h -index 0ed1eb0..ff039f0 100644 ---- a/include/linux/blkdev.h -+++ b/include/linux/blkdev.h -@@ -481,6 +481,7 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q) - - #define blk_queue_tagged(q) test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags) - #define blk_queue_stopped(q) test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags) -+#define blk_queue_dead(q) test_bit(QUEUE_FLAG_DEAD, &(q)->queue_flags) - #define blk_queue_nomerges(q) test_bit(QUEUE_FLAG_NOMERGES, &(q)->queue_flags) - #define blk_queue_noxmerges(q) \ - test_bit(QUEUE_FLAG_NOXMERGES, &(q)->queue_flags) -diff --git a/include/linux/cpu.h b/include/linux/cpu.h -index 6cb60fd..c692acc 100644 ---- a/include/linux/cpu.h -+++ b/include/linux/cpu.h -@@ -66,8 +66,9 @@ enum { - /* migration should happen before other stuff but after perf */ - CPU_PRI_PERF = 20, - CPU_PRI_MIGRATION = 10, -- /* prepare workqueues for other notifiers */ -- CPU_PRI_WORKQUEUE = 5, -+ /* bring up workqueues before normal notifiers and down after */ -+ CPU_PRI_WORKQUEUE_UP = 5, -+ CPU_PRI_WORKQUEUE_DOWN = -5, - }; - - #define CPU_ONLINE 0x0002 /* CPU (unsigned)v is up */ -diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h -index e9eaec5..7a7e5fd 100644 ---- a/include/linux/cpuset.h -+++ b/include/linux/cpuset.h -@@ -89,42 +89,33 @@ extern void rebuild_sched_domains(void); - extern void cpuset_print_task_mems_allowed(struct task_struct *p); - - /* -- * reading current mems_allowed and mempolicy in the fastpath must protected -- * by get_mems_allowed() -+ * get_mems_allowed is required when making decisions involving mems_allowed -+ * such as during page allocation. mems_allowed can be updated in parallel -+ * and depending on the new value an operation can fail potentially causing -+ * process failure. A retry loop with get_mems_allowed and put_mems_allowed -+ * prevents these artificial failures. - */ --static inline void get_mems_allowed(void) -+static inline unsigned int get_mems_allowed(void) - { -- current->mems_allowed_change_disable++; -- -- /* -- * ensure that reading mems_allowed and mempolicy happens after the -- * update of ->mems_allowed_change_disable. -- * -- * the write-side task finds ->mems_allowed_change_disable is not 0, -- * and knows the read-side task is reading mems_allowed or mempolicy, -- * so it will clear old bits lazily. -- */ -- smp_mb(); -+ return read_seqcount_begin(¤t->mems_allowed_seq); - } - --static inline void put_mems_allowed(void) -+/* -+ * If this returns false, the operation that took place after get_mems_allowed -+ * may have failed. It is up to the caller to retry the operation if -+ * appropriate. -+ */ -+static inline bool put_mems_allowed(unsigned int seq) - { -- /* -- * ensure that reading mems_allowed and mempolicy before reducing -- * mems_allowed_change_disable. -- * -- * the write-side task will know that the read-side task is still -- * reading mems_allowed or mempolicy, don't clears old bits in the -- * nodemask. -- */ -- smp_mb(); -- --ACCESS_ONCE(current->mems_allowed_change_disable); -+ return !read_seqcount_retry(¤t->mems_allowed_seq, seq); - } - - static inline void set_mems_allowed(nodemask_t nodemask) - { - task_lock(current); -+ write_seqcount_begin(¤t->mems_allowed_seq); - current->mems_allowed = nodemask; -+ write_seqcount_end(¤t->mems_allowed_seq); - task_unlock(current); - } - -@@ -234,12 +225,14 @@ static inline void set_mems_allowed(nodemask_t nodemask) - { - } - --static inline void get_mems_allowed(void) -+static inline unsigned int get_mems_allowed(void) - { -+ return 0; - } - --static inline void put_mems_allowed(void) -+static inline bool put_mems_allowed(unsigned int seq) - { -+ return true; - } - - #endif /* !CONFIG_CPUSETS */ -diff --git a/include/linux/fs.h b/include/linux/fs.h -index 43d36b7..29b6353 100644 ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -525,6 +525,7 @@ enum positive_aop_returns { - struct page; - struct address_space; - struct writeback_control; -+enum migrate_mode; - - struct iov_iter { - const struct iovec *iov; -@@ -609,9 +610,12 @@ struct address_space_operations { - loff_t offset, unsigned long nr_segs); - int (*get_xip_mem)(struct address_space *, pgoff_t, int, - void **, unsigned long *); -- /* migrate the contents of a page to the specified target */ -+ /* -+ * migrate the contents of a page to the specified target. If sync -+ * is false, it must not block. -+ */ - int (*migratepage) (struct address_space *, -- struct page *, struct page *); -+ struct page *, struct page *, enum migrate_mode); - int (*launder_page) (struct page *); - int (*is_partially_uptodate) (struct page *, read_descriptor_t *, - unsigned long); -@@ -2586,7 +2590,8 @@ extern int generic_check_addressable(unsigned, u64); - - #ifdef CONFIG_MIGRATION - extern int buffer_migrate_page(struct address_space *, -- struct page *, struct page *); -+ struct page *, struct page *, -+ enum migrate_mode); - #else - #define buffer_migrate_page NULL - #endif -diff --git a/include/linux/init_task.h b/include/linux/init_task.h -index 32574ee..df53fdf 100644 ---- a/include/linux/init_task.h -+++ b/include/linux/init_task.h -@@ -30,6 +30,13 @@ extern struct fs_struct init_fs; - #define INIT_THREADGROUP_FORK_LOCK(sig) - #endif - -+#ifdef CONFIG_CPUSETS -+#define INIT_CPUSET_SEQ \ -+ .mems_allowed_seq = SEQCNT_ZERO, -+#else -+#define INIT_CPUSET_SEQ -+#endif -+ - #define INIT_SIGNALS(sig) { \ - .nr_threads = 1, \ - .wait_chldexit = __WAIT_QUEUE_HEAD_INITIALIZER(sig.wait_chldexit),\ -@@ -193,6 +200,7 @@ extern struct cred init_cred; - INIT_FTRACE_GRAPH \ - INIT_TRACE_RECURSION \ - INIT_TASK_RCU_PREEMPT(tsk) \ -+ INIT_CPUSET_SEQ \ - } - - -diff --git a/include/linux/migrate.h b/include/linux/migrate.h -index e39aeec..eaf8674 100644 ---- a/include/linux/migrate.h -+++ b/include/linux/migrate.h -@@ -6,18 +6,31 @@ - - typedef struct page *new_page_t(struct page *, unsigned long private, int **); - -+/* -+ * MIGRATE_ASYNC means never block -+ * MIGRATE_SYNC_LIGHT in the current implementation means to allow blocking -+ * on most operations but not ->writepage as the potential stall time -+ * is too significant -+ * MIGRATE_SYNC will block when migrating pages -+ */ -+enum migrate_mode { -+ MIGRATE_ASYNC, -+ MIGRATE_SYNC_LIGHT, -+ MIGRATE_SYNC, -+}; -+ - #ifdef CONFIG_MIGRATION - #define PAGE_MIGRATION 1 - - extern void putback_lru_pages(struct list_head *l); - extern int migrate_page(struct address_space *, -- struct page *, struct page *); -+ struct page *, struct page *, enum migrate_mode); - extern int migrate_pages(struct list_head *l, new_page_t x, - unsigned long private, bool offlining, -- bool sync); -+ enum migrate_mode mode); - extern int migrate_huge_pages(struct list_head *l, new_page_t x, - unsigned long private, bool offlining, -- bool sync); -+ enum migrate_mode mode); - - extern int fail_migrate_page(struct address_space *, - struct page *, struct page *); -@@ -36,10 +49,10 @@ extern int migrate_huge_page_move_mapping(struct address_space *mapping, - static inline void putback_lru_pages(struct list_head *l) {} - static inline int migrate_pages(struct list_head *l, new_page_t x, - unsigned long private, bool offlining, -- bool sync) { return -ENOSYS; } -+ enum migrate_mode mode) { return -ENOSYS; } - static inline int migrate_huge_pages(struct list_head *l, new_page_t x, - unsigned long private, bool offlining, -- bool sync) { return -ENOSYS; } -+ enum migrate_mode mode) { return -ENOSYS; } - - static inline int migrate_prep(void) { return -ENOSYS; } - static inline int migrate_prep_local(void) { return -ENOSYS; } -diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h -index 905b1e1..25842b6 100644 ---- a/include/linux/mmzone.h -+++ b/include/linux/mmzone.h -@@ -173,6 +173,8 @@ static inline int is_unevictable_lru(enum lru_list l) - #define ISOLATE_CLEAN ((__force isolate_mode_t)0x4) - /* Isolate unmapped file */ - #define ISOLATE_UNMAPPED ((__force isolate_mode_t)0x8) -+/* Isolate for asynchronous migration */ -+#define ISOLATE_ASYNC_MIGRATE ((__force isolate_mode_t)0x10) - - /* LRU Isolation modes. */ - typedef unsigned __bitwise__ isolate_mode_t; -diff --git a/include/linux/sched.h b/include/linux/sched.h -index 5afa2a3..d336c35 100644 ---- a/include/linux/sched.h -+++ b/include/linux/sched.h -@@ -145,6 +145,7 @@ extern unsigned long this_cpu_load(void); - - - extern void calc_global_load(unsigned long ticks); -+extern void update_cpu_load_nohz(void); - - extern unsigned long get_parent_ip(unsigned long addr); - -@@ -1481,7 +1482,7 @@ struct task_struct { - #endif - #ifdef CONFIG_CPUSETS - nodemask_t mems_allowed; /* Protected by alloc_lock */ -- int mems_allowed_change_disable; -+ seqcount_t mems_allowed_seq; /* Seqence no to catch updates */ - int cpuset_mem_spread_rotor; - int cpuset_slab_spread_rotor; - #endif -diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h -index 94bbec3..6ee550e 100644 ---- a/include/target/target_core_base.h -+++ b/include/target/target_core_base.h -@@ -157,6 +157,7 @@ enum tcm_sense_reason_table { - TCM_CHECK_CONDITION_UNIT_ATTENTION = 0x0e, - TCM_CHECK_CONDITION_NOT_READY = 0x0f, - TCM_RESERVATION_CONFLICT = 0x10, -+ TCM_ADDRESS_OUT_OF_RANGE = 0x11, - }; - - struct se_obj { -diff --git a/kernel/cpuset.c b/kernel/cpuset.c -index 0b1712d..46a1d3c 100644 ---- a/kernel/cpuset.c -+++ b/kernel/cpuset.c -@@ -964,7 +964,6 @@ static void cpuset_change_task_nodemask(struct task_struct *tsk, - { - bool need_loop; - --repeat: - /* - * Allow tasks that have access to memory reserves because they have - * been OOM killed to get memory anywhere. -@@ -983,45 +982,19 @@ repeat: - */ - need_loop = task_has_mempolicy(tsk) || - !nodes_intersects(*newmems, tsk->mems_allowed); -- nodes_or(tsk->mems_allowed, tsk->mems_allowed, *newmems); -- mpol_rebind_task(tsk, newmems, MPOL_REBIND_STEP1); - -- /* -- * ensure checking ->mems_allowed_change_disable after setting all new -- * allowed nodes. -- * -- * the read-side task can see an nodemask with new allowed nodes and -- * old allowed nodes. and if it allocates page when cpuset clears newly -- * disallowed ones continuous, it can see the new allowed bits. -- * -- * And if setting all new allowed nodes is after the checking, setting -- * all new allowed nodes and clearing newly disallowed ones will be done -- * continuous, and the read-side task may find no node to alloc page. -- */ -- smp_mb(); -+ if (need_loop) -+ write_seqcount_begin(&tsk->mems_allowed_seq); - -- /* -- * Allocation of memory is very fast, we needn't sleep when waiting -- * for the read-side. -- */ -- while (need_loop && ACCESS_ONCE(tsk->mems_allowed_change_disable)) { -- task_unlock(tsk); -- if (!task_curr(tsk)) -- yield(); -- goto repeat; -- } -- -- /* -- * ensure checking ->mems_allowed_change_disable before clearing all new -- * disallowed nodes. -- * -- * if clearing newly disallowed bits before the checking, the read-side -- * task may find no node to alloc page. -- */ -- smp_mb(); -+ nodes_or(tsk->mems_allowed, tsk->mems_allowed, *newmems); -+ mpol_rebind_task(tsk, newmems, MPOL_REBIND_STEP1); - - mpol_rebind_task(tsk, newmems, MPOL_REBIND_STEP2); - tsk->mems_allowed = *newmems; -+ -+ if (need_loop) -+ write_seqcount_end(&tsk->mems_allowed_seq); -+ - task_unlock(tsk); - } - -diff --git a/kernel/fork.c b/kernel/fork.c -index 79ee71f..222457a 100644 ---- a/kernel/fork.c -+++ b/kernel/fork.c -@@ -979,6 +979,9 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) - #ifdef CONFIG_CGROUPS - init_rwsem(&sig->threadgroup_fork_lock); - #endif -+#ifdef CONFIG_CPUSETS -+ seqcount_init(&tsk->mems_allowed_seq); -+#endif - - sig->oom_adj = current->signal->oom_adj; - sig->oom_score_adj = current->signal->oom_score_adj; -diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c -index 7c0d578..013bd2e 100644 ---- a/kernel/power/hibernate.c -+++ b/kernel/power/hibernate.c -@@ -367,6 +367,7 @@ int hibernation_snapshot(int platform_mode) - } - - suspend_console(); -+ ftrace_stop(); - pm_restrict_gfp_mask(); - error = dpm_suspend(PMSG_FREEZE); - if (error) -@@ -392,6 +393,7 @@ int hibernation_snapshot(int platform_mode) - if (error || !in_suspend) - pm_restore_gfp_mask(); - -+ ftrace_start(); - resume_console(); - dpm_complete(msg); - -@@ -496,6 +498,7 @@ int hibernation_restore(int platform_mode) - - pm_prepare_console(); - suspend_console(); -+ ftrace_stop(); - pm_restrict_gfp_mask(); - error = dpm_suspend_start(PMSG_QUIESCE); - if (!error) { -@@ -503,6 +506,7 @@ int hibernation_restore(int platform_mode) - dpm_resume_end(PMSG_RECOVER); - } - pm_restore_gfp_mask(); -+ ftrace_start(); - resume_console(); - pm_restore_console(); - return error; -@@ -529,6 +533,7 @@ int hibernation_platform_enter(void) - - entering_platform_hibernation = true; - suspend_console(); -+ ftrace_stop(); - error = dpm_suspend_start(PMSG_HIBERNATE); - if (error) { - if (hibernation_ops->recover) -@@ -572,6 +577,7 @@ int hibernation_platform_enter(void) - Resume_devices: - entering_platform_hibernation = false; - dpm_resume_end(PMSG_RESTORE); -+ ftrace_start(); - resume_console(); - - Close: -diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c -index 4953dc0..af48faa 100644 ---- a/kernel/power/suspend.c -+++ b/kernel/power/suspend.c -@@ -25,6 +25,7 @@ - #include <linux/export.h> - #include <linux/suspend.h> - #include <linux/syscore_ops.h> -+#include <linux/ftrace.h> - #include <trace/events/power.h> - - #include "power.h" -@@ -220,6 +221,7 @@ int suspend_devices_and_enter(suspend_state_t state) - goto Close; - } - suspend_console(); -+ ftrace_stop(); - suspend_test_start(); - error = dpm_suspend_start(PMSG_SUSPEND); - if (error) { -@@ -239,6 +241,7 @@ int suspend_devices_and_enter(suspend_state_t state) - suspend_test_start(); - dpm_resume_end(PMSG_RESUME); - suspend_test_finish("resume devices"); -+ ftrace_start(); - resume_console(); - Close: - if (suspend_ops->end) -diff --git a/kernel/sched.c b/kernel/sched.c -index 52ac69b..9cd8ca7 100644 ---- a/kernel/sched.c -+++ b/kernel/sched.c -@@ -1887,7 +1887,7 @@ static void double_rq_unlock(struct rq *rq1, struct rq *rq2) - - static void update_sysctl(void); - static int get_update_sysctl_factor(void); --static void update_cpu_load(struct rq *this_rq); -+static void update_idle_cpu_load(struct rq *this_rq); - - static inline void __set_task_cpu(struct task_struct *p, unsigned int cpu) - { -@@ -3855,22 +3855,13 @@ decay_load_missed(unsigned long load, unsigned long missed_updates, int idx) - * scheduler tick (TICK_NSEC). With tickless idle this will not be called - * every tick. We fix it up based on jiffies. - */ --static void update_cpu_load(struct rq *this_rq) -+static void __update_cpu_load(struct rq *this_rq, unsigned long this_load, -+ unsigned long pending_updates) - { -- unsigned long this_load = this_rq->load.weight; -- unsigned long curr_jiffies = jiffies; -- unsigned long pending_updates; - int i, scale; - - this_rq->nr_load_updates++; - -- /* Avoid repeated calls on same jiffy, when moving in and out of idle */ -- if (curr_jiffies == this_rq->last_load_update_tick) -- return; -- -- pending_updates = curr_jiffies - this_rq->last_load_update_tick; -- this_rq->last_load_update_tick = curr_jiffies; -- - /* Update our load: */ - this_rq->cpu_load[0] = this_load; /* Fasttrack for idx 0 */ - for (i = 1, scale = 2; i < CPU_LOAD_IDX_MAX; i++, scale += scale) { -@@ -3895,9 +3886,78 @@ static void update_cpu_load(struct rq *this_rq) - sched_avg_update(this_rq); - } - -+#ifdef CONFIG_NO_HZ -+/* -+ * There is no sane way to deal with nohz on smp when using jiffies because the -+ * cpu doing the jiffies update might drift wrt the cpu doing the jiffy reading -+ * causing off-by-one errors in observed deltas; {0,2} instead of {1,1}. -+ * -+ * Therefore we cannot use the delta approach from the regular tick since that -+ * would seriously skew the load calculation. However we'll make do for those -+ * updates happening while idle (nohz_idle_balance) or coming out of idle -+ * (tick_nohz_idle_exit). -+ * -+ * This means we might still be one tick off for nohz periods. -+ */ -+ -+/* -+ * Called from nohz_idle_balance() to update the load ratings before doing the -+ * idle balance. -+ */ -+static void update_idle_cpu_load(struct rq *this_rq) -+{ -+ unsigned long curr_jiffies = ACCESS_ONCE(jiffies); -+ unsigned long load = this_rq->load.weight; -+ unsigned long pending_updates; -+ -+ /* -+ * bail if there's load or we're actually up-to-date. -+ */ -+ if (load || curr_jiffies == this_rq->last_load_update_tick) -+ return; -+ -+ pending_updates = curr_jiffies - this_rq->last_load_update_tick; -+ this_rq->last_load_update_tick = curr_jiffies; -+ -+ __update_cpu_load(this_rq, load, pending_updates); -+} -+ -+/* -+ * Called from tick_nohz_idle_exit() -- try and fix up the ticks we missed. -+ */ -+void update_cpu_load_nohz(void) -+{ -+ struct rq *this_rq = this_rq(); -+ unsigned long curr_jiffies = ACCESS_ONCE(jiffies); -+ unsigned long pending_updates; -+ -+ if (curr_jiffies == this_rq->last_load_update_tick) -+ return; -+ -+ raw_spin_lock(&this_rq->lock); -+ pending_updates = curr_jiffies - this_rq->last_load_update_tick; -+ if (pending_updates) { -+ this_rq->last_load_update_tick = curr_jiffies; -+ /* -+ * We were idle, this means load 0, the current load might be -+ * !0 due to remote wakeups and the sort. -+ */ -+ __update_cpu_load(this_rq, 0, pending_updates); -+ } -+ raw_spin_unlock(&this_rq->lock); -+} -+#endif /* CONFIG_NO_HZ */ -+ -+/* -+ * Called from scheduler_tick() -+ */ - static void update_cpu_load_active(struct rq *this_rq) - { -- update_cpu_load(this_rq); -+ /* -+ * See the mess around update_idle_cpu_load() / update_cpu_load_nohz(). -+ */ -+ this_rq->last_load_update_tick = jiffies; -+ __update_cpu_load(this_rq, this_rq->load.weight, 1); - - calc_load_account_active(this_rq); - } -diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c -index 8a39fa3..66e4576 100644 ---- a/kernel/sched_fair.c -+++ b/kernel/sched_fair.c -@@ -4735,7 +4735,7 @@ static void nohz_idle_balance(int this_cpu, enum cpu_idle_type idle) - - raw_spin_lock_irq(&this_rq->lock); - update_rq_clock(this_rq); -- update_cpu_load(this_rq); -+ update_idle_cpu_load(this_rq); - raw_spin_unlock_irq(&this_rq->lock); - - rebalance_domains(balance_cpu, CPU_IDLE); -diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c -index 9955ebd..793548c 100644 ---- a/kernel/time/tick-sched.c -+++ b/kernel/time/tick-sched.c -@@ -549,6 +549,7 @@ void tick_nohz_restart_sched_tick(void) - /* Update jiffies first */ - select_nohz_load_balancer(0); - tick_do_update_jiffies64(now); -+ update_cpu_load_nohz(); - - #ifndef CONFIG_VIRT_CPU_ACCOUNTING - /* -diff --git a/kernel/workqueue.c b/kernel/workqueue.c -index 7947e16..a650bee 100644 ---- a/kernel/workqueue.c -+++ b/kernel/workqueue.c -@@ -3586,6 +3586,41 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb, - return notifier_from_errno(0); - } - -+/* -+ * Workqueues should be brought up before normal priority CPU notifiers. -+ * This will be registered high priority CPU notifier. -+ */ -+static int __devinit workqueue_cpu_up_callback(struct notifier_block *nfb, -+ unsigned long action, -+ void *hcpu) -+{ -+ switch (action & ~CPU_TASKS_FROZEN) { -+ case CPU_UP_PREPARE: -+ case CPU_UP_CANCELED: -+ case CPU_DOWN_FAILED: -+ case CPU_ONLINE: -+ return workqueue_cpu_callback(nfb, action, hcpu); -+ } -+ return NOTIFY_OK; -+} -+ -+/* -+ * Workqueues should be brought down after normal priority CPU notifiers. -+ * This will be registered as low priority CPU notifier. -+ */ -+static int __devinit workqueue_cpu_down_callback(struct notifier_block *nfb, -+ unsigned long action, -+ void *hcpu) -+{ -+ switch (action & ~CPU_TASKS_FROZEN) { -+ case CPU_DOWN_PREPARE: -+ case CPU_DYING: -+ case CPU_POST_DEAD: -+ return workqueue_cpu_callback(nfb, action, hcpu); -+ } -+ return NOTIFY_OK; -+} -+ - #ifdef CONFIG_SMP - - struct work_for_cpu { -@@ -3779,7 +3814,8 @@ static int __init init_workqueues(void) - unsigned int cpu; - int i; - -- cpu_notifier(workqueue_cpu_callback, CPU_PRI_WORKQUEUE); -+ cpu_notifier(workqueue_cpu_up_callback, CPU_PRI_WORKQUEUE_UP); -+ cpu_notifier(workqueue_cpu_down_callback, CPU_PRI_WORKQUEUE_DOWN); - - /* initialize gcwqs */ - for_each_gcwq_cpu(cpu) { -diff --git a/mm/compaction.c b/mm/compaction.c -index 50f1c60..46973fb 100644 ---- a/mm/compaction.c -+++ b/mm/compaction.c -@@ -372,7 +372,7 @@ static isolate_migrate_t isolate_migratepages(struct zone *zone, - } - - if (!cc->sync) -- mode |= ISOLATE_CLEAN; -+ mode |= ISOLATE_ASYNC_MIGRATE; - - /* Try isolate the page */ - if (__isolate_lru_page(page, mode, 0) != 0) -@@ -577,7 +577,7 @@ static int compact_zone(struct zone *zone, struct compact_control *cc) - nr_migrate = cc->nr_migratepages; - err = migrate_pages(&cc->migratepages, compaction_alloc, - (unsigned long)cc, false, -- cc->sync); -+ cc->sync ? MIGRATE_SYNC_LIGHT : MIGRATE_ASYNC); - update_nr_listpages(cc); - nr_remaining = cc->nr_migratepages; - -diff --git a/mm/filemap.c b/mm/filemap.c -index 03c5b0e..556858c 100644 ---- a/mm/filemap.c -+++ b/mm/filemap.c -@@ -500,10 +500,13 @@ struct page *__page_cache_alloc(gfp_t gfp) - struct page *page; - - if (cpuset_do_page_mem_spread()) { -- get_mems_allowed(); -- n = cpuset_mem_spread_node(); -- page = alloc_pages_exact_node(n, gfp, 0); -- put_mems_allowed(); -+ unsigned int cpuset_mems_cookie; -+ do { -+ cpuset_mems_cookie = get_mems_allowed(); -+ n = cpuset_mem_spread_node(); -+ page = alloc_pages_exact_node(n, gfp, 0); -+ } while (!put_mems_allowed(cpuset_mems_cookie) && !page); -+ - return page; - } - return alloc_pages(gfp, 0); -diff --git a/mm/hugetlb.c b/mm/hugetlb.c -index 7c535b0..b1e1bad 100644 ---- a/mm/hugetlb.c -+++ b/mm/hugetlb.c -@@ -538,8 +538,10 @@ static struct page *dequeue_huge_page_vma(struct hstate *h, - struct zonelist *zonelist; - struct zone *zone; - struct zoneref *z; -+ unsigned int cpuset_mems_cookie; - -- get_mems_allowed(); -+retry_cpuset: -+ cpuset_mems_cookie = get_mems_allowed(); - zonelist = huge_zonelist(vma, address, - htlb_alloc_mask, &mpol, &nodemask); - /* -@@ -566,10 +568,15 @@ static struct page *dequeue_huge_page_vma(struct hstate *h, - } - } - } --err: -+ - mpol_cond_put(mpol); -- put_mems_allowed(); -+ if (unlikely(!put_mems_allowed(cpuset_mems_cookie) && !page)) -+ goto retry_cpuset; - return page; -+ -+err: -+ mpol_cond_put(mpol); -+ return NULL; - } - - static void update_and_free_page(struct hstate *h, struct page *page) -diff --git a/mm/memory-failure.c b/mm/memory-failure.c -index 06d3479..5bd5bb1 100644 ---- a/mm/memory-failure.c -+++ b/mm/memory-failure.c -@@ -1427,8 +1427,8 @@ static int soft_offline_huge_page(struct page *page, int flags) - /* Keep page count to indicate a given hugepage is isolated. */ - - list_add(&hpage->lru, &pagelist); -- ret = migrate_huge_pages(&pagelist, new_page, MPOL_MF_MOVE_ALL, 0, -- true); -+ ret = migrate_huge_pages(&pagelist, new_page, MPOL_MF_MOVE_ALL, false, -+ MIGRATE_SYNC); - if (ret) { - struct page *page1, *page2; - list_for_each_entry_safe(page1, page2, &pagelist, lru) -@@ -1557,7 +1557,7 @@ int soft_offline_page(struct page *page, int flags) - page_is_file_cache(page)); - list_add(&page->lru, &pagelist); - ret = migrate_pages(&pagelist, new_page, MPOL_MF_MOVE_ALL, -- 0, true); -+ false, MIGRATE_SYNC); - if (ret) { - putback_lru_pages(&pagelist); - pr_info("soft offline: %#lx: migration failed %d, type %lx\n", -diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c -index 2168489..6629faf 100644 ---- a/mm/memory_hotplug.c -+++ b/mm/memory_hotplug.c -@@ -809,7 +809,7 @@ do_migrate_range(unsigned long start_pfn, unsigned long end_pfn) - } - /* this function returns # of failed pages */ - ret = migrate_pages(&source, hotremove_migrate_alloc, 0, -- true, true); -+ true, MIGRATE_SYNC); - if (ret) - putback_lru_pages(&source); - } -diff --git a/mm/mempolicy.c b/mm/mempolicy.c -index b26aae2..c0007f9 100644 ---- a/mm/mempolicy.c -+++ b/mm/mempolicy.c -@@ -942,7 +942,7 @@ static int migrate_to_node(struct mm_struct *mm, int source, int dest, - - if (!list_empty(&pagelist)) { - err = migrate_pages(&pagelist, new_node_page, dest, -- false, true); -+ false, MIGRATE_SYNC); - if (err) - putback_lru_pages(&pagelist); - } -@@ -1843,18 +1843,24 @@ struct page * - alloc_pages_vma(gfp_t gfp, int order, struct vm_area_struct *vma, - unsigned long addr, int node) - { -- struct mempolicy *pol = get_vma_policy(current, vma, addr); -+ struct mempolicy *pol; - struct zonelist *zl; - struct page *page; -+ unsigned int cpuset_mems_cookie; -+ -+retry_cpuset: -+ pol = get_vma_policy(current, vma, addr); -+ cpuset_mems_cookie = get_mems_allowed(); - -- get_mems_allowed(); - if (unlikely(pol->mode == MPOL_INTERLEAVE)) { - unsigned nid; - - nid = interleave_nid(pol, vma, addr, PAGE_SHIFT + order); - mpol_cond_put(pol); - page = alloc_page_interleave(gfp, order, nid); -- put_mems_allowed(); -+ if (unlikely(!put_mems_allowed(cpuset_mems_cookie) && !page)) -+ goto retry_cpuset; -+ - return page; - } - zl = policy_zonelist(gfp, pol, node); -@@ -1865,7 +1871,8 @@ alloc_pages_vma(gfp_t gfp, int order, struct vm_area_struct *vma, - struct page *page = __alloc_pages_nodemask(gfp, order, - zl, policy_nodemask(gfp, pol)); - __mpol_put(pol); -- put_mems_allowed(); -+ if (unlikely(!put_mems_allowed(cpuset_mems_cookie) && !page)) -+ goto retry_cpuset; - return page; - } - /* -@@ -1873,7 +1880,8 @@ alloc_pages_vma(gfp_t gfp, int order, struct vm_area_struct *vma, - */ - page = __alloc_pages_nodemask(gfp, order, zl, - policy_nodemask(gfp, pol)); -- put_mems_allowed(); -+ if (unlikely(!put_mems_allowed(cpuset_mems_cookie) && !page)) -+ goto retry_cpuset; - return page; - } - -@@ -1900,11 +1908,14 @@ struct page *alloc_pages_current(gfp_t gfp, unsigned order) - { - struct mempolicy *pol = current->mempolicy; - struct page *page; -+ unsigned int cpuset_mems_cookie; - - if (!pol || in_interrupt() || (gfp & __GFP_THISNODE)) - pol = &default_policy; - -- get_mems_allowed(); -+retry_cpuset: -+ cpuset_mems_cookie = get_mems_allowed(); -+ - /* - * No reference counting needed for current->mempolicy - * nor system default_policy -@@ -1915,7 +1926,10 @@ struct page *alloc_pages_current(gfp_t gfp, unsigned order) - page = __alloc_pages_nodemask(gfp, order, - policy_zonelist(gfp, pol, numa_node_id()), - policy_nodemask(gfp, pol)); -- put_mems_allowed(); -+ -+ if (unlikely(!put_mems_allowed(cpuset_mems_cookie) && !page)) -+ goto retry_cpuset; -+ - return page; - } - EXPORT_SYMBOL(alloc_pages_current); -diff --git a/mm/migrate.c b/mm/migrate.c -index 177aca4..180d97f 100644 ---- a/mm/migrate.c -+++ b/mm/migrate.c -@@ -220,6 +220,56 @@ out: - pte_unmap_unlock(ptep, ptl); - } - -+#ifdef CONFIG_BLOCK -+/* Returns true if all buffers are successfully locked */ -+static bool buffer_migrate_lock_buffers(struct buffer_head *head, -+ enum migrate_mode mode) -+{ -+ struct buffer_head *bh = head; -+ -+ /* Simple case, sync compaction */ -+ if (mode != MIGRATE_ASYNC) { -+ do { -+ get_bh(bh); -+ lock_buffer(bh); -+ bh = bh->b_this_page; -+ -+ } while (bh != head); -+ -+ return true; -+ } -+ -+ /* async case, we cannot block on lock_buffer so use trylock_buffer */ -+ do { -+ get_bh(bh); -+ if (!trylock_buffer(bh)) { -+ /* -+ * We failed to lock the buffer and cannot stall in -+ * async migration. Release the taken locks -+ */ -+ struct buffer_head *failed_bh = bh; -+ put_bh(failed_bh); -+ bh = head; -+ while (bh != failed_bh) { -+ unlock_buffer(bh); -+ put_bh(bh); -+ bh = bh->b_this_page; -+ } -+ return false; -+ } -+ -+ bh = bh->b_this_page; -+ } while (bh != head); -+ return true; -+} -+#else -+static inline bool buffer_migrate_lock_buffers(struct buffer_head *head, -+ enum migrate_mode mode) -+{ -+ return true; -+} -+#endif /* CONFIG_BLOCK */ -+ - /* - * Replace the page in the mapping. - * -@@ -229,7 +279,8 @@ out: - * 3 for pages with a mapping and PagePrivate/PagePrivate2 set. - */ - static int migrate_page_move_mapping(struct address_space *mapping, -- struct page *newpage, struct page *page) -+ struct page *newpage, struct page *page, -+ struct buffer_head *head, enum migrate_mode mode) - { - int expected_count; - void **pslot; -@@ -259,6 +310,20 @@ static int migrate_page_move_mapping(struct address_space *mapping, - } - - /* -+ * In the async migration case of moving a page with buffers, lock the -+ * buffers using trylock before the mapping is moved. If the mapping -+ * was moved, we later failed to lock the buffers and could not move -+ * the mapping back due to an elevated page count, we would have to -+ * block waiting on other references to be dropped. -+ */ -+ if (mode == MIGRATE_ASYNC && head && -+ !buffer_migrate_lock_buffers(head, mode)) { -+ page_unfreeze_refs(page, expected_count); -+ spin_unlock_irq(&mapping->tree_lock); -+ return -EAGAIN; -+ } -+ -+ /* - * Now we know that no one else is looking at the page. - */ - get_page(newpage); /* add cache reference */ -@@ -415,13 +480,14 @@ EXPORT_SYMBOL(fail_migrate_page); - * Pages are locked upon entry and exit. - */ - int migrate_page(struct address_space *mapping, -- struct page *newpage, struct page *page) -+ struct page *newpage, struct page *page, -+ enum migrate_mode mode) - { - int rc; - - BUG_ON(PageWriteback(page)); /* Writeback must be complete */ - -- rc = migrate_page_move_mapping(mapping, newpage, page); -+ rc = migrate_page_move_mapping(mapping, newpage, page, NULL, mode); - - if (rc) - return rc; -@@ -438,28 +504,28 @@ EXPORT_SYMBOL(migrate_page); - * exist. - */ - int buffer_migrate_page(struct address_space *mapping, -- struct page *newpage, struct page *page) -+ struct page *newpage, struct page *page, enum migrate_mode mode) - { - struct buffer_head *bh, *head; - int rc; - - if (!page_has_buffers(page)) -- return migrate_page(mapping, newpage, page); -+ return migrate_page(mapping, newpage, page, mode); - - head = page_buffers(page); - -- rc = migrate_page_move_mapping(mapping, newpage, page); -+ rc = migrate_page_move_mapping(mapping, newpage, page, head, mode); - - if (rc) - return rc; - -- bh = head; -- do { -- get_bh(bh); -- lock_buffer(bh); -- bh = bh->b_this_page; -- -- } while (bh != head); -+ /* -+ * In the async case, migrate_page_move_mapping locked the buffers -+ * with an IRQ-safe spinlock held. In the sync case, the buffers -+ * need to be locked now -+ */ -+ if (mode != MIGRATE_ASYNC) -+ BUG_ON(!buffer_migrate_lock_buffers(head, mode)); - - ClearPagePrivate(page); - set_page_private(newpage, page_private(page)); -@@ -536,10 +602,14 @@ static int writeout(struct address_space *mapping, struct page *page) - * Default handling if a filesystem does not provide a migration function. - */ - static int fallback_migrate_page(struct address_space *mapping, -- struct page *newpage, struct page *page) -+ struct page *newpage, struct page *page, enum migrate_mode mode) - { -- if (PageDirty(page)) -+ if (PageDirty(page)) { -+ /* Only writeback pages in full synchronous migration */ -+ if (mode != MIGRATE_SYNC) -+ return -EBUSY; - return writeout(mapping, page); -+ } - - /* - * Buffers may be managed in a filesystem specific way. -@@ -549,7 +619,7 @@ static int fallback_migrate_page(struct address_space *mapping, - !try_to_release_page(page, GFP_KERNEL)) - return -EAGAIN; - -- return migrate_page(mapping, newpage, page); -+ return migrate_page(mapping, newpage, page, mode); - } - - /* -@@ -564,7 +634,7 @@ static int fallback_migrate_page(struct address_space *mapping, - * == 0 - success - */ - static int move_to_new_page(struct page *newpage, struct page *page, -- int remap_swapcache, bool sync) -+ int remap_swapcache, enum migrate_mode mode) - { - struct address_space *mapping; - int rc; -@@ -585,29 +655,18 @@ static int move_to_new_page(struct page *newpage, struct page *page, - - mapping = page_mapping(page); - if (!mapping) -- rc = migrate_page(mapping, newpage, page); -- else { -+ rc = migrate_page(mapping, newpage, page, mode); -+ else if (mapping->a_ops->migratepage) - /* -- * Do not writeback pages if !sync and migratepage is -- * not pointing to migrate_page() which is nonblocking -- * (swapcache/tmpfs uses migratepage = migrate_page). -+ * Most pages have a mapping and most filesystems provide a -+ * migratepage callback. Anonymous pages are part of swap -+ * space which also has its own migratepage callback. This -+ * is the most common path for page migration. - */ -- if (PageDirty(page) && !sync && -- mapping->a_ops->migratepage != migrate_page) -- rc = -EBUSY; -- else if (mapping->a_ops->migratepage) -- /* -- * Most pages have a mapping and most filesystems -- * should provide a migration function. Anonymous -- * pages are part of swap space which also has its -- * own migration function. This is the most common -- * path for page migration. -- */ -- rc = mapping->a_ops->migratepage(mapping, -- newpage, page); -- else -- rc = fallback_migrate_page(mapping, newpage, page); -- } -+ rc = mapping->a_ops->migratepage(mapping, -+ newpage, page, mode); -+ else -+ rc = fallback_migrate_page(mapping, newpage, page, mode); - - if (rc) { - newpage->mapping = NULL; -@@ -622,7 +681,7 @@ static int move_to_new_page(struct page *newpage, struct page *page, - } - - static int __unmap_and_move(struct page *page, struct page *newpage, -- int force, bool offlining, bool sync) -+ int force, bool offlining, enum migrate_mode mode) - { - int rc = -EAGAIN; - int remap_swapcache = 1; -@@ -631,7 +690,7 @@ static int __unmap_and_move(struct page *page, struct page *newpage, - struct anon_vma *anon_vma = NULL; - - if (!trylock_page(page)) { -- if (!force || !sync) -+ if (!force || mode == MIGRATE_ASYNC) - goto out; - - /* -@@ -677,10 +736,12 @@ static int __unmap_and_move(struct page *page, struct page *newpage, - - if (PageWriteback(page)) { - /* -- * For !sync, there is no point retrying as the retry loop -- * is expected to be too short for PageWriteback to be cleared -+ * Only in the case of a full syncronous migration is it -+ * necessary to wait for PageWriteback. In the async case, -+ * the retry loop is too short and in the sync-light case, -+ * the overhead of stalling is too much - */ -- if (!sync) { -+ if (mode != MIGRATE_SYNC) { - rc = -EBUSY; - goto uncharge; - } -@@ -751,7 +812,7 @@ static int __unmap_and_move(struct page *page, struct page *newpage, - - skip_unmap: - if (!page_mapped(page)) -- rc = move_to_new_page(newpage, page, remap_swapcache, sync); -+ rc = move_to_new_page(newpage, page, remap_swapcache, mode); - - if (rc && remap_swapcache) - remove_migration_ptes(page, page); -@@ -774,7 +835,8 @@ out: - * to the newly allocated page in newpage. - */ - static int unmap_and_move(new_page_t get_new_page, unsigned long private, -- struct page *page, int force, bool offlining, bool sync) -+ struct page *page, int force, bool offlining, -+ enum migrate_mode mode) - { - int rc = 0; - int *result = NULL; -@@ -792,7 +854,7 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private, - if (unlikely(split_huge_page(page))) - goto out; - -- rc = __unmap_and_move(page, newpage, force, offlining, sync); -+ rc = __unmap_and_move(page, newpage, force, offlining, mode); - out: - if (rc != -EAGAIN) { - /* -@@ -840,7 +902,8 @@ out: - */ - static int unmap_and_move_huge_page(new_page_t get_new_page, - unsigned long private, struct page *hpage, -- int force, bool offlining, bool sync) -+ int force, bool offlining, -+ enum migrate_mode mode) - { - int rc = 0; - int *result = NULL; -@@ -853,7 +916,7 @@ static int unmap_and_move_huge_page(new_page_t get_new_page, - rc = -EAGAIN; - - if (!trylock_page(hpage)) { -- if (!force || !sync) -+ if (!force || mode != MIGRATE_SYNC) - goto out; - lock_page(hpage); - } -@@ -864,7 +927,7 @@ static int unmap_and_move_huge_page(new_page_t get_new_page, - try_to_unmap(hpage, TTU_MIGRATION|TTU_IGNORE_MLOCK|TTU_IGNORE_ACCESS); - - if (!page_mapped(hpage)) -- rc = move_to_new_page(new_hpage, hpage, 1, sync); -+ rc = move_to_new_page(new_hpage, hpage, 1, mode); - - if (rc) - remove_migration_ptes(hpage, hpage); -@@ -907,7 +970,7 @@ out: - */ - int migrate_pages(struct list_head *from, - new_page_t get_new_page, unsigned long private, bool offlining, -- bool sync) -+ enum migrate_mode mode) - { - int retry = 1; - int nr_failed = 0; -@@ -928,7 +991,7 @@ int migrate_pages(struct list_head *from, - - rc = unmap_and_move(get_new_page, private, - page, pass > 2, offlining, -- sync); -+ mode); - - switch(rc) { - case -ENOMEM: -@@ -958,7 +1021,7 @@ out: - - int migrate_huge_pages(struct list_head *from, - new_page_t get_new_page, unsigned long private, bool offlining, -- bool sync) -+ enum migrate_mode mode) - { - int retry = 1; - int nr_failed = 0; -@@ -975,7 +1038,7 @@ int migrate_huge_pages(struct list_head *from, - - rc = unmap_and_move_huge_page(get_new_page, - private, page, pass > 2, offlining, -- sync); -+ mode); - - switch(rc) { - case -ENOMEM: -@@ -1104,7 +1167,7 @@ set_status: - err = 0; - if (!list_empty(&pagelist)) { - err = migrate_pages(&pagelist, new_page_node, -- (unsigned long)pm, 0, true); -+ (unsigned long)pm, 0, MIGRATE_SYNC); - if (err) - putback_lru_pages(&pagelist); - } -diff --git a/mm/page_alloc.c b/mm/page_alloc.c -index 485be89..065dbe8 100644 ---- a/mm/page_alloc.c -+++ b/mm/page_alloc.c -@@ -1886,14 +1886,20 @@ static struct page * - __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, - struct zonelist *zonelist, enum zone_type high_zoneidx, - nodemask_t *nodemask, int alloc_flags, struct zone *preferred_zone, -- int migratetype, unsigned long *did_some_progress, -- bool sync_migration) -+ int migratetype, bool sync_migration, -+ bool *deferred_compaction, -+ unsigned long *did_some_progress) - { - struct page *page; - -- if (!order || compaction_deferred(preferred_zone)) -+ if (!order) - return NULL; - -+ if (compaction_deferred(preferred_zone)) { -+ *deferred_compaction = true; -+ return NULL; -+ } -+ - current->flags |= PF_MEMALLOC; - *did_some_progress = try_to_compact_pages(zonelist, order, gfp_mask, - nodemask, sync_migration); -@@ -1921,7 +1927,13 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, - * but not enough to satisfy watermarks. - */ - count_vm_event(COMPACTFAIL); -- defer_compaction(preferred_zone); -+ -+ /* -+ * As async compaction considers a subset of pageblocks, only -+ * defer if the failure was a sync compaction failure. -+ */ -+ if (sync_migration) -+ defer_compaction(preferred_zone); - - cond_resched(); - } -@@ -1933,8 +1945,9 @@ static inline struct page * - __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, - struct zonelist *zonelist, enum zone_type high_zoneidx, - nodemask_t *nodemask, int alloc_flags, struct zone *preferred_zone, -- int migratetype, unsigned long *did_some_progress, -- bool sync_migration) -+ int migratetype, bool sync_migration, -+ bool *deferred_compaction, -+ unsigned long *did_some_progress) - { - return NULL; - } -@@ -2084,6 +2097,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, - unsigned long pages_reclaimed = 0; - unsigned long did_some_progress; - bool sync_migration = false; -+ bool deferred_compaction = false; - - /* - * In the slowpath, we sanity check order to avoid ever trying to -@@ -2164,12 +2178,22 @@ rebalance: - zonelist, high_zoneidx, - nodemask, - alloc_flags, preferred_zone, -- migratetype, &did_some_progress, -- sync_migration); -+ migratetype, sync_migration, -+ &deferred_compaction, -+ &did_some_progress); - if (page) - goto got_pg; - sync_migration = true; - -+ /* -+ * If compaction is deferred for high-order allocations, it is because -+ * sync compaction recently failed. In this is the case and the caller -+ * has requested the system not be heavily disrupted, fail the -+ * allocation now instead of entering direct reclaim -+ */ -+ if (deferred_compaction && (gfp_mask & __GFP_NO_KSWAPD)) -+ goto nopage; -+ - /* Try direct reclaim and then allocating */ - page = __alloc_pages_direct_reclaim(gfp_mask, order, - zonelist, high_zoneidx, -@@ -2232,8 +2256,9 @@ rebalance: - zonelist, high_zoneidx, - nodemask, - alloc_flags, preferred_zone, -- migratetype, &did_some_progress, -- sync_migration); -+ migratetype, sync_migration, -+ &deferred_compaction, -+ &did_some_progress); - if (page) - goto got_pg; - } -@@ -2257,8 +2282,9 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, - { - enum zone_type high_zoneidx = gfp_zone(gfp_mask); - struct zone *preferred_zone; -- struct page *page; -+ struct page *page = NULL; - int migratetype = allocflags_to_migratetype(gfp_mask); -+ unsigned int cpuset_mems_cookie; - - gfp_mask &= gfp_allowed_mask; - -@@ -2277,15 +2303,15 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, - if (unlikely(!zonelist->_zonerefs->zone)) - return NULL; - -- get_mems_allowed(); -+retry_cpuset: -+ cpuset_mems_cookie = get_mems_allowed(); -+ - /* The preferred zone is used for statistics later */ - first_zones_zonelist(zonelist, high_zoneidx, - nodemask ? : &cpuset_current_mems_allowed, - &preferred_zone); -- if (!preferred_zone) { -- put_mems_allowed(); -- return NULL; -- } -+ if (!preferred_zone) -+ goto out; - - /* First allocation attempt */ - page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, nodemask, order, -@@ -2295,9 +2321,19 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, - page = __alloc_pages_slowpath(gfp_mask, order, - zonelist, high_zoneidx, nodemask, - preferred_zone, migratetype); -- put_mems_allowed(); - - trace_mm_page_alloc(page, order, gfp_mask, migratetype); -+ -+out: -+ /* -+ * When updating a task's mems_allowed, it is possible to race with -+ * parallel threads in such a way that an allocation can fail while -+ * the mask is being updated. If a page allocation is about to fail, -+ * check if the cpuset changed during allocation and if so, retry. -+ */ -+ if (unlikely(!put_mems_allowed(cpuset_mems_cookie) && !page)) -+ goto retry_cpuset; -+ - return page; - } - EXPORT_SYMBOL(__alloc_pages_nodemask); -@@ -2521,13 +2557,15 @@ void si_meminfo_node(struct sysinfo *val, int nid) - bool skip_free_areas_node(unsigned int flags, int nid) - { - bool ret = false; -+ unsigned int cpuset_mems_cookie; - - if (!(flags & SHOW_MEM_FILTER_NODES)) - goto out; - -- get_mems_allowed(); -- ret = !node_isset(nid, cpuset_current_mems_allowed); -- put_mems_allowed(); -+ do { -+ cpuset_mems_cookie = get_mems_allowed(); -+ ret = !node_isset(nid, cpuset_current_mems_allowed); -+ } while (!put_mems_allowed(cpuset_mems_cookie)); - out: - return ret; - } -@@ -3407,25 +3445,33 @@ static void setup_zone_migrate_reserve(struct zone *zone) - if (page_to_nid(page) != zone_to_nid(zone)) - continue; - -- /* Blocks with reserved pages will never free, skip them. */ -- block_end_pfn = min(pfn + pageblock_nr_pages, end_pfn); -- if (pageblock_is_reserved(pfn, block_end_pfn)) -- continue; -- - block_migratetype = get_pageblock_migratetype(page); - -- /* If this block is reserved, account for it */ -- if (reserve > 0 && block_migratetype == MIGRATE_RESERVE) { -- reserve--; -- continue; -- } -+ /* Only test what is necessary when the reserves are not met */ -+ if (reserve > 0) { -+ /* -+ * Blocks with reserved pages will never free, skip -+ * them. -+ */ -+ block_end_pfn = min(pfn + pageblock_nr_pages, end_pfn); -+ if (pageblock_is_reserved(pfn, block_end_pfn)) -+ continue; - -- /* Suitable for reserving if this block is movable */ -- if (reserve > 0 && block_migratetype == MIGRATE_MOVABLE) { -- set_pageblock_migratetype(page, MIGRATE_RESERVE); -- move_freepages_block(zone, page, MIGRATE_RESERVE); -- reserve--; -- continue; -+ /* If this block is reserved, account for it */ -+ if (block_migratetype == MIGRATE_RESERVE) { -+ reserve--; -+ continue; -+ } -+ -+ /* Suitable for reserving if this block is movable */ -+ if (block_migratetype == MIGRATE_MOVABLE) { -+ set_pageblock_migratetype(page, -+ MIGRATE_RESERVE); -+ move_freepages_block(zone, page, -+ MIGRATE_RESERVE); -+ reserve--; -+ continue; -+ } - } - - /* -diff --git a/mm/slab.c b/mm/slab.c -index 83311c9a..cd3ab93 100644 ---- a/mm/slab.c -+++ b/mm/slab.c -@@ -3267,12 +3267,10 @@ static void *alternate_node_alloc(struct kmem_cache *cachep, gfp_t flags) - if (in_interrupt() || (flags & __GFP_THISNODE)) - return NULL; - nid_alloc = nid_here = numa_mem_id(); -- get_mems_allowed(); - if (cpuset_do_slab_mem_spread() && (cachep->flags & SLAB_MEM_SPREAD)) - nid_alloc = cpuset_slab_spread_node(); - else if (current->mempolicy) - nid_alloc = slab_node(current->mempolicy); -- put_mems_allowed(); - if (nid_alloc != nid_here) - return ____cache_alloc_node(cachep, flags, nid_alloc); - return NULL; -@@ -3295,14 +3293,17 @@ static void *fallback_alloc(struct kmem_cache *cache, gfp_t flags) - enum zone_type high_zoneidx = gfp_zone(flags); - void *obj = NULL; - int nid; -+ unsigned int cpuset_mems_cookie; - - if (flags & __GFP_THISNODE) - return NULL; - -- get_mems_allowed(); -- zonelist = node_zonelist(slab_node(current->mempolicy), flags); - local_flags = flags & (GFP_CONSTRAINT_MASK|GFP_RECLAIM_MASK); - -+retry_cpuset: -+ cpuset_mems_cookie = get_mems_allowed(); -+ zonelist = node_zonelist(slab_node(current->mempolicy), flags); -+ - retry: - /* - * Look through allowed nodes for objects available -@@ -3355,7 +3356,9 @@ retry: - } - } - } -- put_mems_allowed(); -+ -+ if (unlikely(!put_mems_allowed(cpuset_mems_cookie) && !obj)) -+ goto retry_cpuset; - return obj; - } - -diff --git a/mm/slub.c b/mm/slub.c -index af47188..5710788 100644 ---- a/mm/slub.c -+++ b/mm/slub.c -@@ -1582,6 +1582,7 @@ static struct page *get_any_partial(struct kmem_cache *s, gfp_t flags, - struct zone *zone; - enum zone_type high_zoneidx = gfp_zone(flags); - void *object; -+ unsigned int cpuset_mems_cookie; - - /* - * The defrag ratio allows a configuration of the tradeoffs between -@@ -1605,23 +1606,32 @@ static struct page *get_any_partial(struct kmem_cache *s, gfp_t flags, - get_cycles() % 1024 > s->remote_node_defrag_ratio) - return NULL; - -- get_mems_allowed(); -- zonelist = node_zonelist(slab_node(current->mempolicy), flags); -- for_each_zone_zonelist(zone, z, zonelist, high_zoneidx) { -- struct kmem_cache_node *n; -- -- n = get_node(s, zone_to_nid(zone)); -- -- if (n && cpuset_zone_allowed_hardwall(zone, flags) && -- n->nr_partial > s->min_partial) { -- object = get_partial_node(s, n, c); -- if (object) { -- put_mems_allowed(); -- return object; -+ do { -+ cpuset_mems_cookie = get_mems_allowed(); -+ zonelist = node_zonelist(slab_node(current->mempolicy), flags); -+ for_each_zone_zonelist(zone, z, zonelist, high_zoneidx) { -+ struct kmem_cache_node *n; -+ -+ n = get_node(s, zone_to_nid(zone)); -+ -+ if (n && cpuset_zone_allowed_hardwall(zone, flags) && -+ n->nr_partial > s->min_partial) { -+ object = get_partial_node(s, n, c); -+ if (object) { -+ /* -+ * Return the object even if -+ * put_mems_allowed indicated that -+ * the cpuset mems_allowed was -+ * updated in parallel. It's a -+ * harmless race between the alloc -+ * and the cpuset update. -+ */ -+ put_mems_allowed(cpuset_mems_cookie); -+ return object; -+ } - } - } -- } -- put_mems_allowed(); -+ } while (!put_mems_allowed(cpuset_mems_cookie)); - #endif - return NULL; - } -diff --git a/mm/vmscan.c b/mm/vmscan.c -index 8342119..48febd7 100644 ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -715,7 +715,13 @@ static enum page_references page_check_references(struct page *page, - */ - SetPageReferenced(page); - -- if (referenced_page) -+ if (referenced_page || referenced_ptes > 1) -+ return PAGEREF_ACTIVATE; -+ -+ /* -+ * Activate file-backed executable pages after first usage. -+ */ -+ if (vm_flags & VM_EXEC) - return PAGEREF_ACTIVATE; - - return PAGEREF_KEEP; -@@ -1061,8 +1067,39 @@ int __isolate_lru_page(struct page *page, isolate_mode_t mode, int file) - - ret = -EBUSY; - -- if ((mode & ISOLATE_CLEAN) && (PageDirty(page) || PageWriteback(page))) -- return ret; -+ /* -+ * To minimise LRU disruption, the caller can indicate that it only -+ * wants to isolate pages it will be able to operate on without -+ * blocking - clean pages for the most part. -+ * -+ * ISOLATE_CLEAN means that only clean pages should be isolated. This -+ * is used by reclaim when it is cannot write to backing storage -+ * -+ * ISOLATE_ASYNC_MIGRATE is used to indicate that it only wants to pages -+ * that it is possible to migrate without blocking -+ */ -+ if (mode & (ISOLATE_CLEAN|ISOLATE_ASYNC_MIGRATE)) { -+ /* All the caller can do on PageWriteback is block */ -+ if (PageWriteback(page)) -+ return ret; -+ -+ if (PageDirty(page)) { -+ struct address_space *mapping; -+ -+ /* ISOLATE_CLEAN means only clean pages */ -+ if (mode & ISOLATE_CLEAN) -+ return ret; -+ -+ /* -+ * Only pages without mappings or that have a -+ * ->migratepage callback are possible to migrate -+ * without blocking -+ */ -+ mapping = page_mapping(page); -+ if (mapping && !mapping->a_ops->migratepage) -+ return ret; -+ } -+ } - - if ((mode & ISOLATE_UNMAPPED) && page_mapped(page)) - return ret; -@@ -1178,7 +1215,7 @@ static unsigned long isolate_lru_pages(unsigned long nr_to_scan, - * anon page which don't already have a swap slot is - * pointless. - */ -- if (nr_swap_pages <= 0 && PageAnon(cursor_page) && -+ if (nr_swap_pages <= 0 && PageSwapBacked(cursor_page) && - !PageSwapCache(cursor_page)) - break; - -@@ -1874,7 +1911,8 @@ static void get_scan_count(struct zone *zone, struct scan_control *sc, - * latencies, so it's better to scan a minimum amount there as - * well. - */ -- if (scanning_global_lru(sc) && current_is_kswapd()) -+ if (scanning_global_lru(sc) && current_is_kswapd() && -+ zone->all_unreclaimable) - force_scan = true; - if (!scanning_global_lru(sc)) - force_scan = true; -@@ -2012,8 +2050,9 @@ static inline bool should_continue_reclaim(struct zone *zone, - * inactive lists are large enough, continue reclaiming - */ - pages_for_compaction = (2UL << sc->order); -- inactive_lru_pages = zone_nr_lru_pages(zone, sc, LRU_INACTIVE_ANON) + -- zone_nr_lru_pages(zone, sc, LRU_INACTIVE_FILE); -+ inactive_lru_pages = zone_nr_lru_pages(zone, sc, LRU_INACTIVE_FILE); -+ if (nr_swap_pages > 0) -+ inactive_lru_pages += zone_nr_lru_pages(zone, sc, LRU_INACTIVE_ANON); - if (sc->nr_reclaimed < pages_for_compaction && - inactive_lru_pages > pages_for_compaction) - return true; -@@ -2088,6 +2127,42 @@ restart: - throttle_vm_writeout(sc->gfp_mask); - } - -+/* Returns true if compaction should go ahead for a high-order request */ -+static inline bool compaction_ready(struct zone *zone, struct scan_control *sc) -+{ -+ unsigned long balance_gap, watermark; -+ bool watermark_ok; -+ -+ /* Do not consider compaction for orders reclaim is meant to satisfy */ -+ if (sc->order <= PAGE_ALLOC_COSTLY_ORDER) -+ return false; -+ -+ /* -+ * Compaction takes time to run and there are potentially other -+ * callers using the pages just freed. Continue reclaiming until -+ * there is a buffer of free pages available to give compaction -+ * a reasonable chance of completing and allocating the page -+ */ -+ balance_gap = min(low_wmark_pages(zone), -+ (zone->present_pages + KSWAPD_ZONE_BALANCE_GAP_RATIO-1) / -+ KSWAPD_ZONE_BALANCE_GAP_RATIO); -+ watermark = high_wmark_pages(zone) + balance_gap + (2UL << sc->order); -+ watermark_ok = zone_watermark_ok_safe(zone, 0, watermark, 0, 0); -+ -+ /* -+ * If compaction is deferred, reclaim up to a point where -+ * compaction will have a chance of success when re-enabled -+ */ -+ if (compaction_deferred(zone)) -+ return watermark_ok; -+ -+ /* If compaction is not ready to start, keep reclaiming */ -+ if (!compaction_suitable(zone, sc->order)) -+ return false; -+ -+ return watermark_ok; -+} -+ - /* - * This is the direct reclaim path, for page-allocating processes. We only - * try to reclaim pages from zones which will satisfy the caller's allocation -@@ -2105,8 +2180,9 @@ restart: - * scan then give up on it. - * - * This function returns true if a zone is being reclaimed for a costly -- * high-order allocation and compaction is either ready to begin or deferred. -- * This indicates to the caller that it should retry the allocation or fail. -+ * high-order allocation and compaction is ready to begin. This indicates to -+ * the caller that it should consider retrying the allocation instead of -+ * further reclaim. - */ - static bool shrink_zones(int priority, struct zonelist *zonelist, - struct scan_control *sc) -@@ -2115,7 +2191,7 @@ static bool shrink_zones(int priority, struct zonelist *zonelist, - struct zone *zone; - unsigned long nr_soft_reclaimed; - unsigned long nr_soft_scanned; -- bool should_abort_reclaim = false; -+ bool aborted_reclaim = false; - - for_each_zone_zonelist_nodemask(zone, z, zonelist, - gfp_zone(sc->gfp_mask), sc->nodemask) { -@@ -2140,10 +2216,8 @@ static bool shrink_zones(int priority, struct zonelist *zonelist, - * noticable problem, like transparent huge page - * allocations. - */ -- if (sc->order > PAGE_ALLOC_COSTLY_ORDER && -- (compaction_suitable(zone, sc->order) || -- compaction_deferred(zone))) { -- should_abort_reclaim = true; -+ if (compaction_ready(zone, sc)) { -+ aborted_reclaim = true; - continue; - } - } -@@ -2165,7 +2239,7 @@ static bool shrink_zones(int priority, struct zonelist *zonelist, - shrink_zone(priority, zone, sc); - } - -- return should_abort_reclaim; -+ return aborted_reclaim; - } - - static bool zone_reclaimable(struct zone *zone) -@@ -2219,8 +2293,8 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, - struct zoneref *z; - struct zone *zone; - unsigned long writeback_threshold; -+ bool aborted_reclaim; - -- get_mems_allowed(); - delayacct_freepages_start(); - - if (scanning_global_lru(sc)) -@@ -2230,8 +2304,7 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, - sc->nr_scanned = 0; - if (!priority) - disable_swap_token(sc->mem_cgroup); -- if (shrink_zones(priority, zonelist, sc)) -- break; -+ aborted_reclaim = shrink_zones(priority, zonelist, sc); - - /* - * Don't shrink slabs when reclaiming memory from -@@ -2285,7 +2358,6 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, - - out: - delayacct_freepages_end(); -- put_mems_allowed(); - - if (sc->nr_reclaimed) - return sc->nr_reclaimed; -@@ -2298,6 +2370,10 @@ out: - if (oom_killer_disabled) - return 0; - -+ /* Aborted reclaim to try compaction? don't OOM, then */ -+ if (aborted_reclaim) -+ return 1; -+ - /* top priority shrink_zones still had more to do? don't OOM, then */ - if (scanning_global_lru(sc) && !all_unreclaimable(zonelist, sc)) - return 1; -diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c -index c505fd5..c119f33 100644 ---- a/sound/pci/hda/patch_hdmi.c -+++ b/sound/pci/hda/patch_hdmi.c -@@ -868,7 +868,6 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, - struct hdmi_spec_per_pin *per_pin; - struct hdmi_eld *eld; - struct hdmi_spec_per_cvt *per_cvt = NULL; -- int pinctl; - - /* Validate hinfo */ - pin_idx = hinfo_to_pin_index(spec, hinfo); -@@ -904,11 +903,6 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, - snd_hda_codec_write(codec, per_pin->pin_nid, 0, - AC_VERB_SET_CONNECT_SEL, - mux_idx); -- pinctl = snd_hda_codec_read(codec, per_pin->pin_nid, 0, -- AC_VERB_GET_PIN_WIDGET_CONTROL, 0); -- snd_hda_codec_write(codec, per_pin->pin_nid, 0, -- AC_VERB_SET_PIN_WIDGET_CONTROL, -- pinctl | PIN_OUT); - snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid); - - /* Initially set the converter's capabilities */ -@@ -1147,11 +1141,17 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, - struct hdmi_spec *spec = codec->spec; - int pin_idx = hinfo_to_pin_index(spec, hinfo); - hda_nid_t pin_nid = spec->pins[pin_idx].pin_nid; -+ int pinctl; - - hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels); - - hdmi_setup_audio_infoframe(codec, pin_idx, substream); - -+ pinctl = snd_hda_codec_read(codec, pin_nid, 0, -+ AC_VERB_GET_PIN_WIDGET_CONTROL, 0); -+ snd_hda_codec_write(codec, pin_nid, 0, -+ AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl | PIN_OUT); -+ - return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format); - } - -diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c -index 5f096a5..191fd78 100644 ---- a/sound/pci/hda/patch_realtek.c -+++ b/sound/pci/hda/patch_realtek.c -@@ -5989,6 +5989,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { - { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, - { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 }, - { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 }, -+ { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 }, - { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", - .patch = patch_alc861 }, - { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, -diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c -index 90e93bf..0dc441c 100644 ---- a/sound/soc/soc-dapm.c -+++ b/sound/soc/soc-dapm.c -@@ -1381,7 +1381,15 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) - } - - list_for_each_entry(w, &card->widgets, list) { -- list_del_init(&w->dirty); -+ switch (w->id) { -+ case snd_soc_dapm_pre: -+ case snd_soc_dapm_post: -+ /* These widgets always need to be powered */ -+ break; -+ default: -+ list_del_init(&w->dirty); -+ break; -+ } - - if (w->power) { - d = w->dapm; |