From: Greg Kroah-Hartman Date: Tue, 1 Nov 2011 23:31:16 +0000 (-0700) Subject: 3.1 patches X-Git-Tag: v3.0.9~44 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a3337f9868ae697b18ab65b4185bf40657d49107;p=thirdparty%2Fkernel%2Fstable-queue.git 3.1 patches --- diff --git a/queue-3.1/apic-i386-bigsmp-fix-false-warnings-regarding-logical-apic-id-mismatches.patch b/queue-3.1/apic-i386-bigsmp-fix-false-warnings-regarding-logical-apic-id-mismatches.patch new file mode 100644 index 00000000000..610ab3d187f --- /dev/null +++ b/queue-3.1/apic-i386-bigsmp-fix-false-warnings-regarding-logical-apic-id-mismatches.patch @@ -0,0 +1,111 @@ +From 838312be46f3abfbdc175f81c3e54a857994476d Mon Sep 17 00:00:00 2001 +From: Jan Beulich +Date: Wed, 28 Sep 2011 16:44:54 +0100 +Subject: apic, i386/bigsmp: Fix false warnings regarding logical APIC ID mismatches + +From: Jan Beulich + +commit 838312be46f3abfbdc175f81c3e54a857994476d upstream. + +These warnings (generally one per CPU) are a result of +initializing x86_cpu_to_logical_apicid while apic_default is +still in use, but the check in setup_local_APIC() being done +when apic_bigsmp was already used as an override in +default_setup_apic_routing(): + + Overriding APIC driver with bigsmp + Enabling APIC mode: Physflat. Using 5 I/O APICs + ------------[ cut here ]------------ + WARNING: at .../arch/x86/kernel/apic/apic.c:1239 + ... + CPU 1 irqstacks, hard=f1c9a000 soft=f1c9c000 + Booting Node 0, Processors #1 + smpboot cpu 1: start_ip = 9e000 + Initializing CPU#1 + ------------[ cut here ]------------ + WARNING: at .../arch/x86/kernel/apic/apic.c:1239 + setup_local_APIC+0x137/0x46b() Hardware name: ... + CPU1 logical APIC ID: 2 != 8 + ... + +Fix this (for the time being, i.e. until +x86_32_early_logical_apicid() will get removed again, as Tejun +says ought to be possible) by overriding the previously stored +values at the point where the APIC driver gets overridden. + +v2: Move this and the pre-existing override logic into + arch/x86/kernel/apic/bigsmp_32.c. + +Signed-off-by: Jan Beulich +Acked-by: Tejun Heo +Link: http://lkml.kernel.org/r/4E835D16020000780005844C@nat28.tlf.novell.com +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/include/asm/apic.h | 2 +- + arch/x86/kernel/apic/bigsmp_32.c | 20 ++++++++++++++++---- + arch/x86/kernel/apic/probe_32.c | 10 ++-------- + 3 files changed, 19 insertions(+), 13 deletions(-) + +--- a/arch/x86/include/asm/apic.h ++++ b/arch/x86/include/asm/apic.h +@@ -495,7 +495,7 @@ static inline void default_wait_for_init + return; + } + +-extern struct apic *generic_bigsmp_probe(void); ++extern void generic_bigsmp_probe(void); + + + #ifdef CONFIG_X86_LOCAL_APIC +--- a/arch/x86/kernel/apic/bigsmp_32.c ++++ b/arch/x86/kernel/apic/bigsmp_32.c +@@ -255,12 +255,24 @@ static struct apic apic_bigsmp = { + .x86_32_early_logical_apicid = bigsmp_early_logical_apicid, + }; + +-struct apic * __init generic_bigsmp_probe(void) ++void __init generic_bigsmp_probe(void) + { +- if (probe_bigsmp()) +- return &apic_bigsmp; ++ unsigned int cpu; + +- return NULL; ++ if (!probe_bigsmp()) ++ return; ++ ++ apic = &apic_bigsmp; ++ ++ for_each_possible_cpu(cpu) { ++ if (early_per_cpu(x86_cpu_to_logical_apicid, ++ cpu) == BAD_APICID) ++ continue; ++ early_per_cpu(x86_cpu_to_logical_apicid, cpu) = ++ bigsmp_early_logical_apicid(cpu); ++ } ++ ++ pr_info("Overriding APIC driver with %s\n", apic_bigsmp.name); + } + + apic_driver(apic_bigsmp); +--- a/arch/x86/kernel/apic/probe_32.c ++++ b/arch/x86/kernel/apic/probe_32.c +@@ -200,14 +200,8 @@ void __init default_setup_apic_routing(v + * - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support + */ + +- if (!cmdline_apic && apic == &apic_default) { +- struct apic *bigsmp = generic_bigsmp_probe(); +- if (bigsmp) { +- apic = bigsmp; +- printk(KERN_INFO "Overriding APIC driver with %s\n", +- apic->name); +- } +- } ++ if (!cmdline_apic && apic == &apic_default) ++ generic_bigsmp_probe(); + #endif + + if (apic->setup_apic_routing) diff --git a/queue-3.1/ata_piix-make-dvd-drive-recognisable-on-systems-with-intel-sandybridge-chipsets-v2.patch b/queue-3.1/ata_piix-make-dvd-drive-recognisable-on-systems-with-intel-sandybridge-chipsets-v2.patch new file mode 100644 index 00000000000..cb253598aeb --- /dev/null +++ b/queue-3.1/ata_piix-make-dvd-drive-recognisable-on-systems-with-intel-sandybridge-chipsets-v2.patch @@ -0,0 +1,145 @@ +From 5e5a4f5d5a08c9c504fe956391ac3dae2c66556d Mon Sep 17 00:00:00 2001 +From: Ming Lei +Date: Fri, 7 Oct 2011 11:50:22 +0800 +Subject: ata_piix: make DVD Drive recognisable on systems with Intel Sandybridge chipsets(v2) + +From: Ming Lei + +commit 5e5a4f5d5a08c9c504fe956391ac3dae2c66556d upstream. + +This quirk patch fixes one kind of bug inside some Intel Sandybridge +chipsets, see reports from + + https://bugzilla.kernel.org/show_bug.cgi?id=40592. + +Many guys also have reported the problem before: + + https://bugs.launchpad.net/bugs/737388 + https://bugs.launchpad.net/bugs/794642 + https://bugs.launchpad.net/bugs/782389 + ...... + +With help from Tejun, the problem is found to be caused by 32bit PIO +mode, so introduce the quirk patch to disable 32bit PIO on SATA piix +for some Sandybridge CPT chipsets. + +Seth also tested the patch on all five affected chipsets +(pci device ID: 0x1c00, 0x1c01, 0x1d00, 0x1e00, 0x1e01), and found +the patch does fix the problem. + +Tested-by: Heasley, Seth +Cc: Alan Cox +Signed-off-by: Ming Lei +Acked-by: Tejun Heo +Signed-off-by: Jeff Garzik +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/ata/ata_piix.c | 37 ++++++++++++++++++++++++++++++++----- + 1 file changed, 32 insertions(+), 5 deletions(-) + +--- a/drivers/ata/ata_piix.c ++++ b/drivers/ata/ata_piix.c +@@ -113,6 +113,8 @@ enum { + PIIX_PATA_FLAGS = ATA_FLAG_SLAVE_POSS, + PIIX_SATA_FLAGS = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR, + ++ PIIX_FLAG_PIO16 = (1 << 30), /*support 16bit PIO only*/ ++ + PIIX_80C_PRI = (1 << 5) | (1 << 4), + PIIX_80C_SEC = (1 << 7) | (1 << 6), + +@@ -147,6 +149,7 @@ enum piix_controller_ids { + ich8m_apple_sata, /* locks up on second port enable */ + tolapai_sata, + piix_pata_vmw, /* PIIX4 for VMware, spurious DMA_ERR */ ++ ich8_sata_snb, + }; + + struct piix_map_db { +@@ -177,6 +180,7 @@ static int piix_sidpr_scr_write(struct a + static int piix_sidpr_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, + unsigned hints); + static bool piix_irq_check(struct ata_port *ap); ++static int piix_port_start(struct ata_port *ap); + #ifdef CONFIG_PM + static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); + static int piix_pci_device_resume(struct pci_dev *pdev); +@@ -298,21 +302,21 @@ static const struct pci_device_id piix_p + /* SATA Controller IDE (PCH) */ + { 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, + /* SATA Controller IDE (CPT) */ +- { 0x8086, 0x1c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, ++ { 0x8086, 0x1c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, + /* SATA Controller IDE (CPT) */ +- { 0x8086, 0x1c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, ++ { 0x8086, 0x1c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, + /* SATA Controller IDE (CPT) */ + { 0x8086, 0x1c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, + /* SATA Controller IDE (CPT) */ + { 0x8086, 0x1c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, + /* SATA Controller IDE (PBG) */ +- { 0x8086, 0x1d00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, ++ { 0x8086, 0x1d00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, + /* SATA Controller IDE (PBG) */ + { 0x8086, 0x1d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, + /* SATA Controller IDE (Panther Point) */ +- { 0x8086, 0x1e00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, ++ { 0x8086, 0x1e00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, + /* SATA Controller IDE (Panther Point) */ +- { 0x8086, 0x1e01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, ++ { 0x8086, 0x1e01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, + /* SATA Controller IDE (Panther Point) */ + { 0x8086, 0x1e08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, + /* SATA Controller IDE (Panther Point) */ +@@ -338,6 +342,7 @@ static struct scsi_host_template piix_sh + static struct ata_port_operations piix_sata_ops = { + .inherits = &ata_bmdma32_port_ops, + .sff_irq_check = piix_irq_check, ++ .port_start = piix_port_start, + }; + + static struct ata_port_operations piix_pata_ops = { +@@ -478,6 +483,7 @@ static const struct piix_map_db *piix_ma + [ich8_2port_sata] = &ich8_2port_map_db, + [ich8m_apple_sata] = &ich8m_apple_map_db, + [tolapai_sata] = &tolapai_map_db, ++ [ich8_sata_snb] = &ich8_map_db, + }; + + static struct ata_port_info piix_port_info[] = { +@@ -606,6 +612,19 @@ static struct ata_port_info piix_port_in + .port_ops = &piix_vmw_ops, + }, + ++ /* ++ * some Sandybridge chipsets have broken 32 mode up to now, ++ * see https://bugzilla.kernel.org/show_bug.cgi?id=40592 ++ */ ++ [ich8_sata_snb] = ++ { ++ .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR | PIIX_FLAG_PIO16, ++ .pio_mask = ATA_PIO4, ++ .mwdma_mask = ATA_MWDMA2, ++ .udma_mask = ATA_UDMA6, ++ .port_ops = &piix_sata_ops, ++ }, ++ + }; + + static struct pci_bits piix_enable_bits[] = { +@@ -649,6 +668,14 @@ static const struct ich_laptop ich_lapto + { 0, } + }; + ++static int piix_port_start(struct ata_port *ap) ++{ ++ if (!(ap->flags & PIIX_FLAG_PIO16)) ++ ap->pflags |= ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE; ++ ++ return ata_bmdma_port_start(ap); ++} ++ + /** + * ich_pata_cable_detect - Probe host controller cable detect info + * @ap: Port for which cable detect info is desired diff --git a/queue-3.1/dp83640-free-packet-queues-on-remove.patch b/queue-3.1/dp83640-free-packet-queues-on-remove.patch new file mode 100644 index 00000000000..c52ce55eefe --- /dev/null +++ b/queue-3.1/dp83640-free-packet-queues-on-remove.patch @@ -0,0 +1,48 @@ +From 8b3408f8ee994973869d8ba32c5bf482bc4ddca4 Mon Sep 17 00:00:00 2001 +From: Richard Cochran +Date: Fri, 21 Oct 2011 00:49:17 +0000 +Subject: dp83640: free packet queues on remove + +From: Richard Cochran + +commit 8b3408f8ee994973869d8ba32c5bf482bc4ddca4 upstream. + +If the PHY should disappear (for example, on an USB Ethernet MAC), then +the driver would leak any undelivered time stamp packets. This commit +fixes the issue by calling the appropriate functions to free any packets +left in the transmit and receive queues. + +The driver first appeared in v3.0. + +Signed-off-by: Richard Cochran +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/phy/dp83640.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/net/phy/dp83640.c ++++ b/drivers/net/phy/dp83640.c +@@ -875,6 +875,7 @@ static void dp83640_remove(struct phy_de + struct dp83640_clock *clock; + struct list_head *this, *next; + struct dp83640_private *tmp, *dp83640 = phydev->priv; ++ struct sk_buff *skb; + + if (phydev->addr == BROADCAST_ADDR) + return; +@@ -882,6 +883,12 @@ static void dp83640_remove(struct phy_de + enable_status_frames(phydev, false); + cancel_work_sync(&dp83640->ts_work); + ++ while ((skb = skb_dequeue(&dp83640->rx_queue)) != NULL) ++ kfree_skb(skb); ++ ++ while ((skb = skb_dequeue(&dp83640->tx_queue)) != NULL) ++ skb_complete_tx_timestamp(skb, NULL); ++ + clock = dp83640_clock_get(dp83640->clock); + + if (dp83640 == clock->chosen) { diff --git a/queue-3.1/ftrace-kprobes-fix-not-to-delete-probes-if-in-use.patch b/queue-3.1/ftrace-kprobes-fix-not-to-delete-probes-if-in-use.patch new file mode 100644 index 00000000000..b95402b01b5 --- /dev/null +++ b/queue-3.1/ftrace-kprobes-fix-not-to-delete-probes-if-in-use.patch @@ -0,0 +1,173 @@ +From 02ca1521ad404cf566e0075848f80d064c0a0503 Mon Sep 17 00:00:00 2001 +From: Masami Hiramatsu +Date: Tue, 4 Oct 2011 19:44:38 +0900 +Subject: ftrace/kprobes: Fix not to delete probes if in use + +From: Masami Hiramatsu + +commit 02ca1521ad404cf566e0075848f80d064c0a0503 upstream. + +Fix kprobe-tracer not to delete a probe if the probe is in use. +In that case, delete operation will return -EBUSY. + +This bug can cause a kernel panic if enabled probes are deleted +during perf record. + +(Add some probes on functions) +sh-4.2# perf probe --del probe:\* +sh-4.2# exit +(kernel panic) + +This is originally reported on the fedora bugzilla: + + https://bugzilla.redhat.com/show_bug.cgi?id=742383 + +I've also checked that this problem doesn't happen on +tracepoints when module removing because perf event +locks target module. + +$ sudo ./perf record -e xfs:\* -aR sh +sh-4.2# rmmod xfs +ERROR: Module xfs is in use +sh-4.2# exit +[ perf record: Woken up 1 times to write data ] +[ perf record: Captured and wrote 0.203 MB perf.data (~8862 samples) ] + +Signed-off-by: Masami Hiramatsu +Cc: Arnaldo Carvalho de Melo +Cc: Ingo Molnar +Cc: Frederic Weisbecker +Cc: Frank Ch. Eigler +Link: http://lkml.kernel.org/r/20111004104438.14591.6553.stgit@fedora15 +Signed-off-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/trace_kprobe.c | 58 +++++++++++++++++++++++++++++++++++++------- + 1 file changed, 49 insertions(+), 9 deletions(-) + +--- a/kernel/trace/trace_kprobe.c ++++ b/kernel/trace/trace_kprobe.c +@@ -836,11 +836,17 @@ static void __unregister_trace_probe(str + } + + /* Unregister a trace_probe and probe_event: call with locking probe_lock */ +-static void unregister_trace_probe(struct trace_probe *tp) ++static int unregister_trace_probe(struct trace_probe *tp) + { ++ /* Enabled event can not be unregistered */ ++ if (trace_probe_is_enabled(tp)) ++ return -EBUSY; ++ + __unregister_trace_probe(tp); + list_del(&tp->list); + unregister_probe_event(tp); ++ ++ return 0; + } + + /* Register a trace_probe and probe_event */ +@@ -854,7 +860,9 @@ static int register_trace_probe(struct t + /* Delete old (same name) event if exist */ + old_tp = find_trace_probe(tp->call.name, tp->call.class->system); + if (old_tp) { +- unregister_trace_probe(old_tp); ++ ret = unregister_trace_probe(old_tp); ++ if (ret < 0) ++ goto end; + free_trace_probe(old_tp); + } + +@@ -892,6 +900,7 @@ static int trace_probe_module_callback(s + mutex_lock(&probe_lock); + list_for_each_entry(tp, &probe_list, list) { + if (trace_probe_within_module(tp, mod)) { ++ /* Don't need to check busy - this should have gone. */ + __unregister_trace_probe(tp); + ret = __register_trace_probe(tp); + if (ret) +@@ -1205,10 +1214,11 @@ static int create_trace_probe(int argc, + return -ENOENT; + } + /* delete an event */ +- unregister_trace_probe(tp); +- free_trace_probe(tp); ++ ret = unregister_trace_probe(tp); ++ if (ret == 0) ++ free_trace_probe(tp); + mutex_unlock(&probe_lock); +- return 0; ++ return ret; + } + + if (argc < 2) { +@@ -1317,18 +1327,29 @@ error: + return ret; + } + +-static void release_all_trace_probes(void) ++static int release_all_trace_probes(void) + { + struct trace_probe *tp; ++ int ret = 0; + + mutex_lock(&probe_lock); ++ /* Ensure no probe is in use. */ ++ list_for_each_entry(tp, &probe_list, list) ++ if (trace_probe_is_enabled(tp)) { ++ ret = -EBUSY; ++ goto end; ++ } + /* TODO: Use batch unregistration */ + while (!list_empty(&probe_list)) { + tp = list_entry(probe_list.next, struct trace_probe, list); + unregister_trace_probe(tp); + free_trace_probe(tp); + } ++ ++end: + mutex_unlock(&probe_lock); ++ ++ return ret; + } + + /* Probes listing interfaces */ +@@ -1380,9 +1401,13 @@ static const struct seq_operations probe + + static int probes_open(struct inode *inode, struct file *file) + { +- if ((file->f_mode & FMODE_WRITE) && +- (file->f_flags & O_TRUNC)) +- release_all_trace_probes(); ++ int ret; ++ ++ if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) { ++ ret = release_all_trace_probes(); ++ if (ret < 0) ++ return ret; ++ } + + return seq_open(file, &probes_seq_op); + } +@@ -2055,6 +2080,21 @@ static __init int kprobe_trace_self_test + + ret = target(1, 2, 3, 4, 5, 6); + ++ /* Disable trace points before removing it */ ++ tp = find_trace_probe("testprobe", KPROBE_EVENT_SYSTEM); ++ if (WARN_ON_ONCE(tp == NULL)) { ++ pr_warning("error on getting test probe.\n"); ++ warn++; ++ } else ++ disable_trace_probe(tp, TP_FLAG_TRACE); ++ ++ tp = find_trace_probe("testprobe2", KPROBE_EVENT_SYSTEM); ++ if (WARN_ON_ONCE(tp == NULL)) { ++ pr_warning("error on getting 2nd test probe.\n"); ++ warn++; ++ } else ++ disable_trace_probe(tp, TP_FLAG_TRACE); ++ + ret = command_trace_probe("-:testprobe"); + if (WARN_ON_ONCE(ret)) { + pr_warning("error on deleting a probe.\n"); diff --git a/queue-3.1/genirq-add-irqf_resume_early-and-resume-such-irqs-earlier.patch b/queue-3.1/genirq-add-irqf_resume_early-and-resume-such-irqs-earlier.patch new file mode 100644 index 00000000000..180b50b38b1 --- /dev/null +++ b/queue-3.1/genirq-add-irqf_resume_early-and-resume-such-irqs-earlier.patch @@ -0,0 +1,140 @@ +From 9bab0b7fbaceec47d32db51cd9e59c82fb071f5a Mon Sep 17 00:00:00 2001 +From: Ian Campbell +Date: Mon, 3 Oct 2011 15:37:00 +0100 +Subject: genirq: Add IRQF_RESUME_EARLY and resume such IRQs earlier + +From: Ian Campbell + +commit 9bab0b7fbaceec47d32db51cd9e59c82fb071f5a upstream. + +This adds a mechanism to resume selected IRQs during syscore_resume +instead of dpm_resume_noirq. + +Under Xen we need to resume IRQs associated with IPIs early enough +that the resched IPI is unmasked and we can therefore schedule +ourselves out of the stop_machine where the suspend/resume takes +place. + +This issue was introduced by 676dc3cf5bc3 "xen: Use IRQF_FORCE_RESUME". + +Signed-off-by: Ian Campbell +Cc: Rafael J. Wysocki +Cc: Jeremy Fitzhardinge +Cc: xen-devel +Cc: Konrad Rzeszutek Wilk +Link: http://lkml.kernel.org/r/1318713254.11016.52.camel@dagon.hellion.org.uk +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/xen/events.c | 2 - + include/linux/interrupt.h | 3 ++ + kernel/irq/pm.c | 48 +++++++++++++++++++++++++++++++++++++++------- + 3 files changed, 45 insertions(+), 8 deletions(-) + +--- a/drivers/xen/events.c ++++ b/drivers/xen/events.c +@@ -1021,7 +1021,7 @@ int bind_ipi_to_irqhandler(enum ipi_vect + if (irq < 0) + return irq; + +- irqflags |= IRQF_NO_SUSPEND | IRQF_FORCE_RESUME; ++ irqflags |= IRQF_NO_SUSPEND | IRQF_FORCE_RESUME | IRQF_EARLY_RESUME; + retval = request_irq(irq, handler, irqflags, devname, dev_id); + if (retval != 0) { + unbind_from_irq(irq); +--- a/include/linux/interrupt.h ++++ b/include/linux/interrupt.h +@@ -59,6 +59,8 @@ + * IRQF_NO_SUSPEND - Do not disable this IRQ during suspend + * IRQF_FORCE_RESUME - Force enable it on resume even if IRQF_NO_SUSPEND is set + * IRQF_NO_THREAD - Interrupt cannot be threaded ++ * IRQF_EARLY_RESUME - Resume IRQ early during syscore instead of at device ++ * resume time. + */ + #define IRQF_DISABLED 0x00000020 + #define IRQF_SAMPLE_RANDOM 0x00000040 +@@ -72,6 +74,7 @@ + #define IRQF_NO_SUSPEND 0x00004000 + #define IRQF_FORCE_RESUME 0x00008000 + #define IRQF_NO_THREAD 0x00010000 ++#define IRQF_EARLY_RESUME 0x00020000 + + #define IRQF_TIMER (__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD) + +--- a/kernel/irq/pm.c ++++ b/kernel/irq/pm.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + + #include "internals.h" + +@@ -39,25 +40,58 @@ void suspend_device_irqs(void) + } + EXPORT_SYMBOL_GPL(suspend_device_irqs); + +-/** +- * resume_device_irqs - enable interrupt lines disabled by suspend_device_irqs() +- * +- * Enable all interrupt lines previously disabled by suspend_device_irqs() that +- * have the IRQS_SUSPENDED flag set. +- */ +-void resume_device_irqs(void) ++static void resume_irqs(bool want_early) + { + struct irq_desc *desc; + int irq; + + for_each_irq_desc(irq, desc) { + unsigned long flags; ++ bool is_early = desc->action && ++ desc->action->flags & IRQF_EARLY_RESUME; ++ ++ if (is_early != want_early) ++ continue; + + raw_spin_lock_irqsave(&desc->lock, flags); + __enable_irq(desc, irq, true); + raw_spin_unlock_irqrestore(&desc->lock, flags); + } + } ++ ++/** ++ * irq_pm_syscore_ops - enable interrupt lines early ++ * ++ * Enable all interrupt lines with %IRQF_EARLY_RESUME set. ++ */ ++static void irq_pm_syscore_resume(void) ++{ ++ resume_irqs(true); ++} ++ ++static struct syscore_ops irq_pm_syscore_ops = { ++ .resume = irq_pm_syscore_resume, ++}; ++ ++static int __init irq_pm_init_ops(void) ++{ ++ register_syscore_ops(&irq_pm_syscore_ops); ++ return 0; ++} ++ ++device_initcall(irq_pm_init_ops); ++ ++/** ++ * resume_device_irqs - enable interrupt lines disabled by suspend_device_irqs() ++ * ++ * Enable all non-%IRQF_EARLY_RESUME interrupt lines previously ++ * disabled by suspend_device_irqs() that have the IRQS_SUSPENDED flag ++ * set as well as those with %IRQF_FORCE_RESUME. ++ */ ++void resume_device_irqs(void) ++{ ++ resume_irqs(false); ++} + EXPORT_SYMBOL_GPL(resume_device_irqs); + + /** diff --git a/queue-3.1/iwlagn-fix-priv-cfg-ht_params-null-pointer-dereference.patch b/queue-3.1/iwlagn-fix-priv-cfg-ht_params-null-pointer-dereference.patch new file mode 100644 index 00000000000..6435ab6e666 --- /dev/null +++ b/queue-3.1/iwlagn-fix-priv-cfg-ht_params-null-pointer-dereference.patch @@ -0,0 +1,44 @@ +From 107ef97a170dec95893f34614edd92eb8cb9b5d0 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Wed, 12 Oct 2011 10:16:35 +0200 +Subject: iwlagn: fix priv->cfg->ht_params NULL pointer dereference + +From: Stanislaw Gruszka + +commit 107ef97a170dec95893f34614edd92eb8cb9b5d0 upstream. + +This fix regression introduced by commit: + +commit 15b3f3b006b42a678523cad989bfd60b76bf4403 +Author: Wey-Yi Guy +Date: Fri Jun 3 07:54:13 2011 -0700 + + iwlagn: set smps mode after assoc for 1000 device + +Also remove unneeded brackets on the way. + +Address: +https://bugzilla.redhat.com/show_bug.cgi?id=744155 + +Signed-off-by: Stanislaw Gruszka +Acked-by: Wey-Yi Guy +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c ++++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +@@ -295,8 +295,8 @@ static int iwlagn_rxon_connect(struct iw + return ret; + } + +- if ((ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION) && +- priv->cfg->ht_params->smps_mode) ++ if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION && ++ priv->cfg->ht_params && priv->cfg->ht_params->smps_mode) + ieee80211_request_smps(ctx->vif, + priv->cfg->ht_params->smps_mode); + diff --git a/queue-3.1/mac80211-fix-offchannel-tx-cookie-matching.patch b/queue-3.1/mac80211-fix-offchannel-tx-cookie-matching.patch new file mode 100644 index 00000000000..f50ab0ed133 --- /dev/null +++ b/queue-3.1/mac80211-fix-offchannel-tx-cookie-matching.patch @@ -0,0 +1,71 @@ +From 28a1bcdb57d50f3038a255741ecc83e391e5282e Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Tue, 4 Oct 2011 18:27:10 +0200 +Subject: mac80211: fix offchannel TX cookie matching + +From: Johannes Berg + +commit 28a1bcdb57d50f3038a255741ecc83e391e5282e upstream. + +When I introduced in-kernel off-channel TX I +introduced a bug -- the work can't be canceled +again because the code clear the skb pointer. +Fix this by keeping track separately of whether +TX status has already been reported. + +Reported-by: Jouni Malinen +Tested-by: Jouni Malinen +Signed-off-by: Johannes Berg +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/cfg.c | 2 +- + net/mac80211/ieee80211_i.h | 1 + + net/mac80211/status.c | 2 +- + net/mac80211/work.c | 2 +- + 4 files changed, 4 insertions(+), 3 deletions(-) + +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -1821,7 +1821,7 @@ ieee80211_offchan_tx_done(struct ieee802 + * so in that case userspace will have to deal with it. + */ + +- if (wk->offchan_tx.wait && wk->offchan_tx.frame) ++ if (wk->offchan_tx.wait && !wk->offchan_tx.status) + cfg80211_mgmt_tx_status(wk->sdata->dev, + (unsigned long) wk->offchan_tx.frame, + wk->ie, wk->ie_len, false, GFP_KERNEL); +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -345,6 +345,7 @@ struct ieee80211_work { + struct { + struct sk_buff *frame; + u32 wait; ++ bool status; + } offchan_tx; + }; + +--- a/net/mac80211/status.c ++++ b/net/mac80211/status.c +@@ -336,7 +336,7 @@ void ieee80211_tx_status(struct ieee8021 + continue; + if (wk->offchan_tx.frame != skb) + continue; +- wk->offchan_tx.frame = NULL; ++ wk->offchan_tx.status = true; + break; + } + rcu_read_unlock(); +--- a/net/mac80211/work.c ++++ b/net/mac80211/work.c +@@ -579,7 +579,7 @@ ieee80211_offchannel_tx(struct ieee80211 + /* + * After this, offchan_tx.frame remains but now is no + * longer a valid pointer -- we still need it as the +- * cookie for canceling this work. ++ * cookie for canceling this work/status matching. + */ + ieee80211_tx_skb(wk->sdata, wk->offchan_tx.frame); + diff --git a/queue-3.1/md-raid5-fix-bug-that-could-result-in-reads-from-a-failed-device.patch b/queue-3.1/md-raid5-fix-bug-that-could-result-in-reads-from-a-failed-device.patch new file mode 100644 index 00000000000..a86daba593a --- /dev/null +++ b/queue-3.1/md-raid5-fix-bug-that-could-result-in-reads-from-a-failed-device.patch @@ -0,0 +1,42 @@ +From 355840e7a7e56bb2834fd3b0da64da5465f8aeaa Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Wed, 26 Oct 2011 10:31:04 +1100 +Subject: md/raid5: fix bug that could result in reads from a failed device. + +From: NeilBrown + +commit 355840e7a7e56bb2834fd3b0da64da5465f8aeaa upstream. + +This bug was introduced in 415e72d034c50520ddb7ff79e7d1792c1306f0c9 +which was in 2.6.36. + +There is a small window of time between when a device fails and when +it is removed from the array. During this time we might still read +from it, but we won't write to it - so it is possible that we could +read stale data. + +We didn't need the test of 'Faulty' before because the test on +In_sync is sufficient. Since we started allowing reads from the early +part of non-In_sync devices we need a test on Faulty too. + +This is suitable for any kernel from 2.6.36 onwards, though the patch +might need a bit of tweaking in 3.0 and earlier. + +Signed-off-by: NeilBrown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/raid5.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -3069,7 +3069,7 @@ static void analyse_stripe(struct stripe + } + } else if (test_bit(In_sync, &rdev->flags)) + set_bit(R5_Insync, &dev->flags); +- else { ++ else if (!test_bit(Faulty, &rdev->flags)) { + /* in sync if before recovery_offset */ + if (sh->sector + STRIPE_SECTORS <= rdev->recovery_offset) + set_bit(R5_Insync, &dev->flags); diff --git a/queue-3.1/net-hold-sock-reference-while-processing-tx-timestamps.patch b/queue-3.1/net-hold-sock-reference-while-processing-tx-timestamps.patch new file mode 100644 index 00000000000..926cd91e845 --- /dev/null +++ b/queue-3.1/net-hold-sock-reference-while-processing-tx-timestamps.patch @@ -0,0 +1,110 @@ +From da92b194cc36b5dc1fbd85206aeeffd80bee0c39 Mon Sep 17 00:00:00 2001 +From: Richard Cochran +Date: Fri, 21 Oct 2011 00:49:15 +0000 +Subject: net: hold sock reference while processing tx timestamps + +From: Richard Cochran + +commit da92b194cc36b5dc1fbd85206aeeffd80bee0c39 upstream. + +The pair of functions, + + * skb_clone_tx_timestamp() + * skb_complete_tx_timestamp() + +were designed to allow timestamping in PHY devices. The first +function, called during the MAC driver's hard_xmit method, identifies +PTP protocol packets, clones them, and gives them to the PHY device +driver. The PHY driver may hold onto the packet and deliver it at a +later time using the second function, which adds the packet to the +socket's error queue. + +As pointed out by Johannes, nothing prevents the socket from +disappearing while the cloned packet is sitting in the PHY driver +awaiting a timestamp. This patch fixes the issue by taking a reference +on the socket for each such packet. In addition, the comments +regarding the usage of these function are expanded to highlight the +rule that PHY drivers must use skb_complete_tx_timestamp() to release +the packet, in order to release the socket reference, too. + +These functions first appeared in v2.6.36. + +Reported-by: Johannes Berg +Signed-off-by: Richard Cochran +Signed-off-by: Eric Dumazet +Reviewed-by: Johannes Berg +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/phy.h | 2 +- + include/linux/skbuff.h | 7 ++++++- + net/core/timestamping.c | 12 ++++++++++-- + 3 files changed, 17 insertions(+), 4 deletions(-) + +--- a/include/linux/phy.h ++++ b/include/linux/phy.h +@@ -420,7 +420,7 @@ struct phy_driver { + + /* + * Requests a Tx timestamp for 'skb'. The phy driver promises +- * to deliver it to the socket's error queue as soon as a ++ * to deliver it using skb_complete_tx_timestamp() as soon as a + * timestamp becomes available. One of the PTP_CLASS_ values + * is passed in 'type'. + */ +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -2020,8 +2020,13 @@ static inline bool skb_defer_rx_timestam + /** + * skb_complete_tx_timestamp() - deliver cloned skb with tx timestamps + * ++ * PHY drivers may accept clones of transmitted packets for ++ * timestamping via their phy_driver.txtstamp method. These drivers ++ * must call this function to return the skb back to the stack, with ++ * or without a timestamp. ++ * + * @skb: clone of the the original outgoing packet +- * @hwtstamps: hardware time stamps ++ * @hwtstamps: hardware time stamps, may be NULL if not available + * + */ + void skb_complete_tx_timestamp(struct sk_buff *skb, +--- a/net/core/timestamping.c ++++ b/net/core/timestamping.c +@@ -57,9 +57,13 @@ void skb_clone_tx_timestamp(struct sk_bu + case PTP_CLASS_V2_VLAN: + phydev = skb->dev->phydev; + if (likely(phydev->drv->txtstamp)) { ++ if (!atomic_inc_not_zero(&sk->sk_refcnt)) ++ return; + clone = skb_clone(skb, GFP_ATOMIC); +- if (!clone) ++ if (!clone) { ++ sock_put(sk); + return; ++ } + clone->sk = sk; + phydev->drv->txtstamp(phydev, clone, type); + } +@@ -77,8 +81,11 @@ void skb_complete_tx_timestamp(struct sk + struct sock_exterr_skb *serr; + int err; + +- if (!hwtstamps) ++ if (!hwtstamps) { ++ sock_put(sk); ++ kfree_skb(skb); + return; ++ } + + *skb_hwtstamps(skb) = *hwtstamps; + serr = SKB_EXT_ERR(skb); +@@ -87,6 +94,7 @@ void skb_complete_tx_timestamp(struct sk + serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING; + skb->sk = NULL; + err = sock_queue_err_skb(sk, skb); ++ sock_put(sk); + if (err) + kfree_skb(skb); + } diff --git a/queue-3.1/nfs-don-t-try-to-migrate-pages-with-active-requests.patch b/queue-3.1/nfs-don-t-try-to-migrate-pages-with-active-requests.patch new file mode 100644 index 00000000000..26a0f6d82d4 --- /dev/null +++ b/queue-3.1/nfs-don-t-try-to-migrate-pages-with-active-requests.patch @@ -0,0 +1,89 @@ +From 2da956523526e440ef4f4dd174e26f5ac06fe011 Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Wed, 12 Oct 2011 10:57:42 -0400 +Subject: nfs: don't try to migrate pages with active requests + +From: Jeff Layton + +commit 2da956523526e440ef4f4dd174e26f5ac06fe011 upstream. + +nfs_find_and_lock_request will take a reference to the nfs_page and +will then put it if the req is already locked. It's possible though +that the reference will be the last one. That put then can kick off +a whole series of reference puts: + +nfs_page + nfs_open_context + dentry + inode + +If the inode ends up being deleted, then the VFS will call +truncate_inode_pages. That function will try to take the page lock, but +it was already locked when migrate_page was called. The code +deadlocks. + +Fix this by simply refusing the migration request if PagePrivate is +already set, indicating that the page is already associated with an +active read or write request. + +We've had a customer test a backported version of this patch and +the preliminary results seem good. + +Cc: Andrea Arcangeli +Reported-by: Harshula Jayasuriya +Signed-off-by: Jeff Layton +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/write.c | 36 +++++++++++------------------------- + 1 file changed, 11 insertions(+), 25 deletions(-) + +--- a/fs/nfs/write.c ++++ b/fs/nfs/write.c +@@ -1714,34 +1714,20 @@ out_error: + int nfs_migrate_page(struct address_space *mapping, struct page *newpage, + struct page *page) + { +- struct nfs_page *req; +- int ret; ++ /* ++ * If PagePrivate is set, then the page is currently associated with ++ * an in-progress read or write request. Don't try to migrate it. ++ * ++ * FIXME: we could do this in principle, but we'll need a way to ensure ++ * that we can safely release the inode reference while holding ++ * the page lock. ++ */ ++ if (PagePrivate(page)) ++ return -EBUSY; + + nfs_fscache_release_page(page, GFP_KERNEL); + +- req = nfs_find_and_lock_request(page, false); +- ret = PTR_ERR(req); +- if (IS_ERR(req)) +- goto out; +- +- ret = migrate_page(mapping, newpage, page); +- if (!req) +- goto out; +- if (ret) +- goto out_unlock; +- page_cache_get(newpage); +- spin_lock(&mapping->host->i_lock); +- req->wb_page = newpage; +- SetPagePrivate(newpage); +- set_page_private(newpage, (unsigned long)req); +- ClearPagePrivate(page); +- set_page_private(page, 0); +- spin_unlock(&mapping->host->i_lock); +- page_cache_release(page); +-out_unlock: +- nfs_clear_page_tag_locked(req); +-out: +- return ret; ++ return migrate_page(mapping, newpage, page); + } + #endif + diff --git a/queue-3.1/nfsd4-fix-open-downgrade-again.patch b/queue-3.1/nfsd4-fix-open-downgrade-again.patch new file mode 100644 index 00000000000..7fed29de41e --- /dev/null +++ b/queue-3.1/nfsd4-fix-open-downgrade-again.patch @@ -0,0 +1,67 @@ +From 3d02fa29dec920c597dd7b7db608a4bc71f088ce Mon Sep 17 00:00:00 2001 +From: "J. Bruce Fields" +Date: Mon, 19 Sep 2011 15:07:41 -0400 +Subject: nfsd4: fix open downgrade, again + +From: "J. Bruce Fields" + +commit 3d02fa29dec920c597dd7b7db608a4bc71f088ce upstream. + +Yet another open-management regression: + + - nfs4_file_downgrade() doesn't remove the BOTH access bit on + downgrade, so the server's idea of the stateid's access gets + out of sync with the client's. If we want to keep an O_RDWR + open in this case, we should do that in the file_put_access + logic rather than here. + - We forgot to convert v4 access to an open mode here. + +This logic has proven too hard to get right. In the future we may +consider: + - reexamining the lock/openowner relationship (locks probably + don't really need to take their own references here). + - adding open upgrade/downgrade support to the vfs. + - removing the atomic operations. They're redundant as long as + this is all under some other lock. + +Also, maybe some kind of additional static checking would help catch +O_/NFS4_SHARE_ACCESS confusion. + +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfsd/nfs4state.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -192,8 +192,15 @@ static void nfs4_file_put_fd(struct nfs4 + static void __nfs4_file_put_access(struct nfs4_file *fp, int oflag) + { + if (atomic_dec_and_test(&fp->fi_access[oflag])) { +- nfs4_file_put_fd(fp, O_RDWR); + nfs4_file_put_fd(fp, oflag); ++ /* ++ * It's also safe to get rid of the RDWR open *if* ++ * we no longer have need of the other kind of access ++ * or if we already have the other kind of open: ++ */ ++ if (fp->fi_fds[1-oflag] ++ || atomic_read(&fp->fi_access[1 - oflag]) == 0) ++ nfs4_file_put_fd(fp, O_RDWR); + } + } + +@@ -3530,8 +3537,9 @@ static inline void nfs4_file_downgrade(s + int i; + + for (i = 1; i < 4; i++) { +- if (test_bit(i, &stp->st_access_bmap) && !(i & to_access)) { +- nfs4_file_put_access(stp->st_file, i); ++ if (test_bit(i, &stp->st_access_bmap) ++ && ((i & to_access) != i)) { ++ nfs4_file_put_access(stp->st_file, nfs4_access_to_omode(i)); + __clear_bit(i, &stp->st_access_bmap); + } + } diff --git a/queue-3.1/nfsd4-fix-seqid_mutating_error.patch b/queue-3.1/nfsd4-fix-seqid_mutating_error.patch new file mode 100644 index 00000000000..bbf65e85946 --- /dev/null +++ b/queue-3.1/nfsd4-fix-seqid_mutating_error.patch @@ -0,0 +1,59 @@ +From 576163005de286bbd418fcb99cfd0971523a0c6d Mon Sep 17 00:00:00 2001 +From: "J. Bruce Fields" +Date: Wed, 10 Aug 2011 19:16:22 -0400 +Subject: nfsd4: fix seqid_mutating_error + +From: "J. Bruce Fields" + +commit 576163005de286bbd418fcb99cfd0971523a0c6d upstream. + +The set of errors here does *not* agree with the set of errors specified +in the rfc! + +While we're there, turn this macros into a function, for the usual +reasons, and move it to the one place where it's actually used. + +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfsd/nfs4xdr.c | 12 ++++++++++++ + fs/nfsd/state.h | 6 ------ + 2 files changed, 12 insertions(+), 6 deletions(-) + +--- a/fs/nfsd/nfs4xdr.c ++++ b/fs/nfsd/nfs4xdr.c +@@ -1623,6 +1623,18 @@ static void write_cinfo(__be32 **p, stru + \ + save = resp->p; + ++static bool seqid_mutating_err(__be32 err) ++{ ++ /* rfc 3530 section 8.1.5: */ ++ return err != nfserr_stale_clientid && ++ err != nfserr_stale_stateid && ++ err != nfserr_bad_stateid && ++ err != nfserr_bad_seqid && ++ err != nfserr_bad_xdr && ++ err != nfserr_resource && ++ err != nfserr_nofilehandle; ++} ++ + /* + * Routine for encoding the result of a "seqid-mutating" NFSv4 operation. This + * is where sequence id's are incremented, and the replay cache is filled. +--- a/fs/nfsd/state.h ++++ b/fs/nfsd/state.h +@@ -447,12 +447,6 @@ struct nfs4_stateid { + #define WR_STATE 0x00000020 + #define CLOSE_STATE 0x00000040 + +-#define seqid_mutating_err(err) \ +- (((err) != nfserr_stale_clientid) && \ +- ((err) != nfserr_bad_seqid) && \ +- ((err) != nfserr_stale_stateid) && \ +- ((err) != nfserr_bad_stateid)) +- + struct nfsd4_compound_state; + + extern __be32 nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate, diff --git a/queue-3.1/nfsd4-ignore-want-bits-in-open-downgrade.patch b/queue-3.1/nfsd4-ignore-want-bits-in-open-downgrade.patch new file mode 100644 index 00000000000..51debbf350b --- /dev/null +++ b/queue-3.1/nfsd4-ignore-want-bits-in-open-downgrade.patch @@ -0,0 +1,30 @@ +From c30e92df30d7d5fe65262fbce5d1b7de675fe34e Mon Sep 17 00:00:00 2001 +From: "J. Bruce Fields" +Date: Mon, 10 Oct 2011 17:34:31 -0400 +Subject: nfsd4: ignore WANT bits in open downgrade + +From: "J. Bruce Fields" + +commit c30e92df30d7d5fe65262fbce5d1b7de675fe34e upstream. + +We don't use WANT bits yet--and sending them can probably trigger a +BUG() further down. + +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfsd/nfs4state.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -3570,6 +3570,8 @@ nfsd4_open_downgrade(struct svc_rqst *rq + if (!access_valid(od->od_share_access, cstate->minorversion) + || !deny_valid(od->od_share_deny)) + return nfserr_inval; ++ /* We don't yet support WANT bits: */ ++ od->od_share_access &= NFS4_SHARE_ACCESS_MASK; + + nfs4_lock_state(); + if ((status = nfs4_preprocess_seqid_op(cstate, diff --git a/queue-3.1/nfsd4-permit-read-opens-of-executable-only-files.patch b/queue-3.1/nfsd4-permit-read-opens-of-executable-only-files.patch new file mode 100644 index 00000000000..e3cc53889f5 --- /dev/null +++ b/queue-3.1/nfsd4-permit-read-opens-of-executable-only-files.patch @@ -0,0 +1,72 @@ +From a043226bc140a2c1dde162246d68a67e5043e6b2 Mon Sep 17 00:00:00 2001 +From: "J. Bruce Fields" +Date: Thu, 25 Aug 2011 10:48:39 -0400 +Subject: nfsd4: permit read opens of executable-only files + +From: "J. Bruce Fields" + +commit a043226bc140a2c1dde162246d68a67e5043e6b2 upstream. + +A client that wants to execute a file must be able to read it. Read +opens over nfs are therefore implicitly allowed for executable files +even when those files are not readable. + +NFSv2/v3 get this right by using a passed-in NFSD_MAY_OWNER_OVERRIDE on +read requests, but NFSv4 has gotten this wrong ever since +dc730e173785e29b297aa605786c94adaffe2544 "nfsd4: fix owner-override on +open", when we realized that the file owner shouldn't override +permissions on non-reclaim NFSv4 opens. + +So we can't use NFSD_MAY_OWNER_OVERRIDE to tell nfsd_permission to allow +reads of executable files. + +So, do the same thing we do whenever we encounter another weird NFS +permission nit: define yet another NFSD_MAY_* flag. + +The industry's future standardization on 128-bit processors will be +motivated primarily by the need for integers with enough bits for all +the NFSD_MAY_* flags. + +Reported-by: Leonardo Borda +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfsd/nfs4proc.c | 2 ++ + fs/nfsd/vfs.c | 3 ++- + fs/nfsd/vfs.h | 1 + + 3 files changed, 5 insertions(+), 1 deletion(-) + +--- a/fs/nfsd/nfs4proc.c ++++ b/fs/nfsd/nfs4proc.c +@@ -156,6 +156,8 @@ do_open_permission(struct svc_rqst *rqst + !(open->op_share_access & NFS4_SHARE_ACCESS_WRITE)) + return nfserr_inval; + ++ accmode |= NFSD_MAY_READ_IF_EXEC; ++ + if (open->op_share_access & NFS4_SHARE_ACCESS_READ) + accmode |= NFSD_MAY_READ; + if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) +--- a/fs/nfsd/vfs.c ++++ b/fs/nfsd/vfs.c +@@ -2114,7 +2114,8 @@ nfsd_permission(struct svc_rqst *rqstp, + + /* Allow read access to binaries even when mode 111 */ + if (err == -EACCES && S_ISREG(inode->i_mode) && +- acc == (NFSD_MAY_READ | NFSD_MAY_OWNER_OVERRIDE)) ++ (acc == (NFSD_MAY_READ | NFSD_MAY_OWNER_OVERRIDE) || ++ acc == (NFSD_MAY_READ | NFSD_MAY_READ_IF_EXEC))) + err = inode_permission(inode, MAY_EXEC); + + return err? nfserrno(err) : 0; +--- a/fs/nfsd/vfs.h ++++ b/fs/nfsd/vfs.h +@@ -25,6 +25,7 @@ + #define NFSD_MAY_BYPASS_GSS_ON_ROOT 256 + #define NFSD_MAY_NOT_BREAK_LEASE 512 + #define NFSD_MAY_BYPASS_GSS 1024 ++#define NFSD_MAY_READ_IF_EXEC 2048 + + #define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE) + #define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC) diff --git a/queue-3.1/nfsd4-remove-check-for-a-32-bit-cookie-in-nfsd4_readdir.patch b/queue-3.1/nfsd4-remove-check-for-a-32-bit-cookie-in-nfsd4_readdir.patch new file mode 100644 index 00000000000..c303ab82185 --- /dev/null +++ b/queue-3.1/nfsd4-remove-check-for-a-32-bit-cookie-in-nfsd4_readdir.patch @@ -0,0 +1,34 @@ +From 832023bffb4b493f230be901f681020caf3ed1f8 Mon Sep 17 00:00:00 2001 +From: Bernd Schubert +Date: Mon, 8 Aug 2011 17:38:08 +0200 +Subject: nfsd4: Remove check for a 32-bit cookie in nfsd4_readdir() + +From: Bernd Schubert + +commit 832023bffb4b493f230be901f681020caf3ed1f8 upstream. + +Fan Yong noticed setting +FMODE_32bithash wouldn't work with nfsd v4, as +nfsd4_readdir() checks for 32 bit cookies. However, according to RFC 3530 +cookies have a 64 bit type and cookies are also defined as u64 in +'struct nfsd4_readdir'. So remove the test for >32-bit values. + +Signed-off-by: Bernd Schubert +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfsd/nfs4proc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/nfsd/nfs4proc.c ++++ b/fs/nfsd/nfs4proc.c +@@ -691,7 +691,7 @@ nfsd4_readdir(struct svc_rqst *rqstp, st + readdir->rd_bmval[1] &= nfsd_suppattrs1(cstate->minorversion); + readdir->rd_bmval[2] &= nfsd_suppattrs2(cstate->minorversion); + +- if ((cookie > ~(u32)0) || (cookie == 1) || (cookie == 2) || ++ if ((cookie == 1) || (cookie == 2) || + (cookie == 0 && memcmp(readdir->rd_verf.data, zeroverf.data, NFS4_VERIFIER_SIZE))) + return nfserr_bad_cookie; + diff --git a/queue-3.1/nfsd4-stop-using-nfserr_resource-for-transitory-errors.patch b/queue-3.1/nfsd4-stop-using-nfserr_resource-for-transitory-errors.patch new file mode 100644 index 00000000000..7f5069d77b0 --- /dev/null +++ b/queue-3.1/nfsd4-stop-using-nfserr_resource-for-transitory-errors.patch @@ -0,0 +1,104 @@ +From 3e77246393c0a433247631a1f0e9ec98d3d78a1c Mon Sep 17 00:00:00 2001 +From: "J. Bruce Fields" +Date: Wed, 10 Aug 2011 19:07:33 -0400 +Subject: nfsd4: stop using nfserr_resource for transitory errors + +From: "J. Bruce Fields" + +commit 3e77246393c0a433247631a1f0e9ec98d3d78a1c upstream. + +The server is returning nfserr_resource for both permanent errors and +for errors (like allocation failures) that might be resolved by retrying +later. Save nfserr_resource for the former and use delay/jukebox for +the latter. + +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfsd/nfs4proc.c | 2 +- + fs/nfsd/nfs4recover.c | 2 +- + fs/nfsd/nfs4state.c | 14 +++++++------- + 3 files changed, 9 insertions(+), 9 deletions(-) + +--- a/fs/nfsd/nfs4proc.c ++++ b/fs/nfsd/nfs4proc.c +@@ -930,7 +930,7 @@ _nfsd4_verify(struct svc_rqst *rqstp, st + count = 4 + (verify->ve_attrlen >> 2); + buf = kmalloc(count << 2, GFP_KERNEL); + if (!buf) +- return nfserr_resource; ++ return nfserr_jukebox; + + status = nfsd4_encode_fattr(&cstate->current_fh, + cstate->current_fh.fh_export, +--- a/fs/nfsd/nfs4recover.c ++++ b/fs/nfsd/nfs4recover.c +@@ -88,7 +88,7 @@ nfs4_make_rec_clidname(char *dname, stru + struct xdr_netobj cksum; + struct hash_desc desc; + struct scatterlist sg; +- __be32 status = nfserr_resource; ++ __be32 status = nfserr_jukebox; + + dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n", + clname->len, clname->data); +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -1946,7 +1946,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp + * of 5 bullet points, labeled as CASE0 - CASE4 below. + */ + unconf = find_unconfirmed_client_by_str(dname, strhashval); +- status = nfserr_resource; ++ status = nfserr_jukebox; + if (!conf) { + /* + * RFC 3530 14.2.33 CASE 4: +@@ -2483,7 +2483,7 @@ renew: + if (open->op_stateowner == NULL) { + sop = alloc_init_open_stateowner(strhashval, clp, open); + if (sop == NULL) +- return nfserr_resource; ++ return nfserr_jukebox; + open->op_stateowner = sop; + } + list_del_init(&sop->so_close_lru); +@@ -2619,7 +2619,7 @@ nfs4_new_open(struct svc_rqst *rqstp, st + + stp = nfs4_alloc_stateid(); + if (stp == NULL) +- return nfserr_resource; ++ return nfserr_jukebox; + + status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open); + if (status) { +@@ -2850,7 +2850,7 @@ nfsd4_process_open2(struct svc_rqst *rqs + status = nfserr_bad_stateid; + if (open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR) + goto out; +- status = nfserr_resource; ++ status = nfserr_jukebox; + fp = alloc_init_file(ino); + if (fp == NULL) + goto out; +@@ -4035,7 +4035,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struc + /* XXX: Do we need to check for duplicate stateowners on + * the same file, or should they just be allowed (and + * create new stateids)? */ +- status = nfserr_resource; ++ status = nfserr_jukebox; + lock_sop = alloc_init_lock_stateowner(strhashval, + open_sop->so_client, open_stp, lock); + if (lock_sop == NULL) +@@ -4119,9 +4119,9 @@ nfsd4_lock(struct svc_rqst *rqstp, struc + case (EDEADLK): + status = nfserr_deadlock; + break; +- default: ++ default: + dprintk("NFSD: nfsd4_lock: vfs_lock_file() failed! status %d\n",err); +- status = nfserr_resource; ++ status = nfserrno(err); + break; + } + out: diff --git a/queue-3.1/perf-probe-fix-to-show-correct-error-string.patch b/queue-3.1/perf-probe-fix-to-show-correct-error-string.patch new file mode 100644 index 00000000000..85f514001ac --- /dev/null +++ b/queue-3.1/perf-probe-fix-to-show-correct-error-string.patch @@ -0,0 +1,40 @@ +From 44a56040a0037a845d5fa218dffde464579f0cab Mon Sep 17 00:00:00 2001 +From: Masami Hiramatsu +Date: Tue, 4 Oct 2011 19:45:04 +0900 +Subject: perf probe: Fix to show correct error string + +From: Masami Hiramatsu + +commit 44a56040a0037a845d5fa218dffde464579f0cab upstream. + +Fix perf probe to show correct error string when it +fails to delete an event. The write(2) returns -1 +if failed, and errno stores real error number. + +Signed-off-by: Masami Hiramatsu +Cc: Peter Zijlstra +Cc: Arnaldo Carvalho de Melo +Cc: Paul Mackerras +Cc: Ingo Molnar +Link: http://lkml.kernel.org/r/20111004104504.14591.41266.stgit@fedora15 +Signed-off-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman + +--- + tools/perf/util/probe-event.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/tools/perf/util/probe-event.c ++++ b/tools/perf/util/probe-event.c +@@ -1956,8 +1956,10 @@ static int __del_trace_probe_event(int f + + pr_debug("Writing event: %s\n", buf); + ret = write(fd, buf, strlen(buf)); +- if (ret < 0) ++ if (ret < 0) { ++ ret = -errno; + goto error; ++ } + + printf("Remove event: %s\n", ent->s); + return 0; diff --git a/queue-3.1/rtnetlink-add-missing-manual-netlink-notification-in.patch b/queue-3.1/rtnetlink-add-missing-manual-netlink-notification-in.patch new file mode 100644 index 00000000000..8d90f251e21 --- /dev/null +++ b/queue-3.1/rtnetlink-add-missing-manual-netlink-notification-in.patch @@ -0,0 +1,40 @@ +From d2237d35748e7f448a9c2d9dc6a85ef637466e24 Mon Sep 17 00:00:00 2001 +From: "Eric W. Biederman" +Date: Fri, 21 Oct 2011 06:24:20 +0000 +Subject: rtnetlink: Add missing manual netlink notification in dev_change_net_namespaces + +From: "Eric W. Biederman" + +commit d2237d35748e7f448a9c2d9dc6a85ef637466e24 upstream. + +Renato Westphal noticed that since commit a2835763e130c343ace5320c20d33c281e7097b7 +"rtnetlink: handle rtnl_link netlink notifications manually" was merged +we no longer send a netlink message when a networking device is moved +from one network namespace to another. + +Fix this by adding the missing manual notification in dev_change_net_namespaces. + +Since all network devices that are processed by dev_change_net_namspaces are +in the initialized state the complicated tests that guard the manual +rtmsg_ifinfo calls in rollback_registered and register_netdevice are +unnecessary and we can just perform a plain notification. + +Tested-by: Renato Westphal +Signed-off-by: Eric W. Biederman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/core/dev.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -6115,6 +6115,7 @@ int dev_change_net_namespace(struct net_ + */ + call_netdevice_notifiers(NETDEV_UNREGISTER, dev); + call_netdevice_notifiers(NETDEV_UNREGISTER_BATCH, dev); ++ rtmsg_ifinfo(RTM_DELLINK, dev, ~0U); + + /* + * Flush the unicast and multicast chains diff --git a/queue-3.1/series b/queue-3.1/series index b9d9f1df3e8..fcd927e77f4 100644 --- a/queue-3.1/series +++ b/queue-3.1/series @@ -96,3 +96,25 @@ kmod-prevent-kmod_loop_msg-overflow-in-__request_module.patch revert-nfs-ensure-that-writeback_single_inode-calls-write_inode-when-syncing.patch sunrpc-nfs-make-rpc-pipe-upcall-generic.patch nfs-don-t-redirty-inode-when-ncommit-0-in.patch +ata_piix-make-dvd-drive-recognisable-on-systems-with-intel-sandybridge-chipsets-v2.patch +rtnetlink-add-missing-manual-netlink-notification-in.patch +dp83640-free-packet-queues-on-remove.patch +mac80211-fix-offchannel-tx-cookie-matching.patch +net-hold-sock-reference-while-processing-tx-timestamps.patch +wl12xx-fix-forced-passive-scans.patch +iwlagn-fix-priv-cfg-ht_params-null-pointer-dereference.patch +time-change-jiffies_to_clock_t-argument-type-to-unsigned-long.patch +apic-i386-bigsmp-fix-false-warnings-regarding-logical-apic-id-mismatches.patch +md-raid5-fix-bug-that-could-result-in-reads-from-a-failed-device.patch +perf-probe-fix-to-show-correct-error-string.patch +ftrace-kprobes-fix-not-to-delete-probes-if-in-use.patch +tracing-fix-returning-of-duplicate-data-after-eof-in-trace_pipe_raw.patch +genirq-add-irqf_resume_early-and-resume-such-irqs-earlier.patch +nfs-don-t-try-to-migrate-pages-with-active-requests.patch +nfsd4-remove-check-for-a-32-bit-cookie-in-nfsd4_readdir.patch +nfsd4-stop-using-nfserr_resource-for-transitory-errors.patch +nfsd4-fix-seqid_mutating_error.patch +nfsd4-permit-read-opens-of-executable-only-files.patch +nfsd4-fix-open-downgrade-again.patch +nfsd4-ignore-want-bits-in-open-downgrade.patch +vfs-add-device-tag-to-proc-self-mountstats.patch diff --git a/queue-3.1/time-change-jiffies_to_clock_t-argument-type-to-unsigned-long.patch b/queue-3.1/time-change-jiffies_to_clock_t-argument-type-to-unsigned-long.patch new file mode 100644 index 00000000000..45d16cece84 --- /dev/null +++ b/queue-3.1/time-change-jiffies_to_clock_t-argument-type-to-unsigned-long.patch @@ -0,0 +1,50 @@ +From cbbc719fccdb8cbd87350a05c0d33167c9b79365 Mon Sep 17 00:00:00 2001 +From: hank +Date: Tue, 20 Sep 2011 13:53:39 -0700 +Subject: time: Change jiffies_to_clock_t() argument type to unsigned long + +From: hank + +commit cbbc719fccdb8cbd87350a05c0d33167c9b79365 upstream. + +The parameter's origin type is long. On an i386 architecture, it can +easily be larger than 0x80000000, causing this function to convert it +to a sign-extended u64 type. + +Change the type to unsigned long so we get the correct result. + +Signed-off-by: hank +Cc: John Stultz +[ build fix ] +Signed-off-by: Andrew Morton +Signed-off-by: Thomas Gleixner +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/jiffies.h | 2 +- + kernel/time.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/include/linux/jiffies.h ++++ b/include/linux/jiffies.h +@@ -303,7 +303,7 @@ extern void jiffies_to_timespec(const un + extern unsigned long timeval_to_jiffies(const struct timeval *value); + extern void jiffies_to_timeval(const unsigned long jiffies, + struct timeval *value); +-extern clock_t jiffies_to_clock_t(long x); ++extern clock_t jiffies_to_clock_t(unsigned long x); + extern unsigned long clock_t_to_jiffies(unsigned long x); + extern u64 jiffies_64_to_clock_t(u64 x); + extern u64 nsec_to_clock_t(u64 x); +--- a/kernel/time.c ++++ b/kernel/time.c +@@ -575,7 +575,7 @@ EXPORT_SYMBOL(jiffies_to_timeval); + /* + * Convert jiffies/jiffies_64 to clock_t and back. + */ +-clock_t jiffies_to_clock_t(long x) ++clock_t jiffies_to_clock_t(unsigned long x) + { + #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0 + # if HZ < USER_HZ diff --git a/queue-3.1/tracing-fix-returning-of-duplicate-data-after-eof-in-trace_pipe_raw.patch b/queue-3.1/tracing-fix-returning-of-duplicate-data-after-eof-in-trace_pipe_raw.patch new file mode 100644 index 00000000000..613cbaba978 --- /dev/null +++ b/queue-3.1/tracing-fix-returning-of-duplicate-data-after-eof-in-trace_pipe_raw.patch @@ -0,0 +1,55 @@ +From 436fc280261dcfce5af38f08b89287750dc91cd2 Mon Sep 17 00:00:00 2001 +From: Steven Rostedt +Date: Fri, 14 Oct 2011 10:44:25 -0400 +Subject: tracing: Fix returning of duplicate data after EOF in trace_pipe_raw + +From: Steven Rostedt + +commit 436fc280261dcfce5af38f08b89287750dc91cd2 upstream. + +The trace_pipe_raw handler holds a cached page from the time the file +is opened to the time it is closed. The cached page is used to handle +the case of the user space buffer being smaller than what was read from +the ring buffer. The left over buffer is held in the cache so that the +next read will continue where the data left off. + +After EOF is returned (no more data in the buffer), the index of +the cached page is set to zero. If a user app reads the page again +after EOF, the check in the buffer will see that the cached page +is less than page size and will return the cached page again. This +will cause reading the trace_pipe_raw again after EOF to return +duplicate data, making the output look like the time went backwards +but instead data is just repeated. + +The fix is to not reset the index right after all data is read +from the cache, but to reset it after all data is read and more +data exists in the ring buffer. + +Reported-by: Jeremy Eder +Signed-off-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/trace.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -3808,8 +3808,6 @@ tracing_buffers_read(struct file *filp, + if (info->read < PAGE_SIZE) + goto read; + +- info->read = 0; +- + trace_access_lock(info->cpu); + ret = ring_buffer_read_page(info->tr->buffer, + &info->spare, +@@ -3819,6 +3817,8 @@ tracing_buffers_read(struct file *filp, + if (ret < 0) + return 0; + ++ info->read = 0; ++ + read: + size = PAGE_SIZE - info->read; + if (size > count) diff --git a/queue-3.1/vfs-add-device-tag-to-proc-self-mountstats.patch b/queue-3.1/vfs-add-device-tag-to-proc-self-mountstats.patch new file mode 100644 index 00000000000..1d1e6494c4a --- /dev/null +++ b/queue-3.1/vfs-add-device-tag-to-proc-self-mountstats.patch @@ -0,0 +1,33 @@ +From a877ee03ac010ded434b77f7831f43cbb1fcc60f Mon Sep 17 00:00:00 2001 +From: Bryan Schumaker +Date: Fri, 7 Oct 2011 13:41:15 -0400 +Subject: vfs: add "device" tag to /proc/self/mountstats + +From: Bryan Schumaker + +commit a877ee03ac010ded434b77f7831f43cbb1fcc60f upstream. + +nfsiostat was failing to find mounted filesystems on kernels after +2.6.38 because of changes to show_vfsstat() by commit +c7f404b40a3665d9f4e9a927cc5c1ee0479ed8f9. This patch adds back the +"device" tag before the nfs server entry so scripts can parse the +mountstats file correctly. + +Signed-off-by: Bryan Schumaker +Signed-off-by: Christoph Hellwig +Signed-off-by: Greg Kroah-Hartman + +--- + fs/namespace.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -1109,6 +1109,7 @@ static int show_vfsstat(struct seq_file + + /* device */ + if (mnt->mnt_sb->s_op->show_devname) { ++ seq_puts(m, "device "); + err = mnt->mnt_sb->s_op->show_devname(m, mnt); + } else { + if (mnt->mnt_devname) { diff --git a/queue-3.1/wl12xx-fix-forced-passive-scans.patch b/queue-3.1/wl12xx-fix-forced-passive-scans.patch new file mode 100644 index 00000000000..46b5f8fb8ab --- /dev/null +++ b/queue-3.1/wl12xx-fix-forced-passive-scans.patch @@ -0,0 +1,69 @@ +From 6cd9d21a0c1e2648c07c32c66bb25795ad3208aa Mon Sep 17 00:00:00 2001 +From: Luciano Coelho +Date: Thu, 22 Sep 2011 10:06:10 +0300 +Subject: wl12xx: fix forced passive scans + +From: Luciano Coelho + +commit 6cd9d21a0c1e2648c07c32c66bb25795ad3208aa upstream. + +We were using incorrect max and min dwell times during forced passive +scans because we were still using the active scan states to scan +(passively) the channels that were not marked as passive. + +Instead of doing passive scans in active states, we now skip active +states and scan for all channels in passive states. + +Signed-off-by: Luciano Coelho +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/wl12xx/scan.c | 19 +++++++++++++------ + 1 file changed, 13 insertions(+), 6 deletions(-) + +--- a/drivers/net/wireless/wl12xx/scan.c ++++ b/drivers/net/wireless/wl12xx/scan.c +@@ -83,14 +83,18 @@ static int wl1271_get_scan_channels(stru + for (i = 0, j = 0; + i < req->n_channels && j < WL1271_SCAN_MAX_CHANNELS; + i++) { +- + flags = req->channels[i]->flags; + + if (!test_bit(i, wl->scan.scanned_ch) && + !(flags & IEEE80211_CHAN_DISABLED) && +- ((!!(flags & IEEE80211_CHAN_PASSIVE_SCAN)) == passive) && +- (req->channels[i]->band == band)) { +- ++ (req->channels[i]->band == band) && ++ /* ++ * In passive scans, we scan all remaining ++ * channels, even if not marked as such. ++ * In active scans, we only scan channels not ++ * marked as passive. ++ */ ++ (passive || !(flags & IEEE80211_CHAN_PASSIVE_SCAN))) { + wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ", + req->channels[i]->band, + req->channels[i]->center_freq); +@@ -142,6 +146,10 @@ static int wl1271_scan_send(struct wl127 + int ret; + u16 scan_options = 0; + ++ /* skip active scans if we don't have SSIDs */ ++ if (!passive && wl->scan.req->n_ssids == 0) ++ return WL1271_NOTHING_TO_SCAN; ++ + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + trigger = kzalloc(sizeof(*trigger), GFP_KERNEL); + if (!cmd || !trigger) { +@@ -152,8 +160,7 @@ static int wl1271_scan_send(struct wl127 + /* We always use high priority scans */ + scan_options = WL1271_SCAN_OPT_PRIORITY_HIGH; + +- /* No SSIDs means that we have a forced passive scan */ +- if (passive || wl->scan.req->n_ssids == 0) ++ if (passive) + scan_options |= WL1271_SCAN_OPT_PASSIVE; + + cmd->params.scan_options = cpu_to_le16(scan_options);