2008-10-24 04:39:19

by Greg KH

[permalink] [raw]
Subject: [patch 00/27] 2.6.27.4-stable review

This is the start of the stable review cycle for the 2.6.27.4 release.
There are 27 patches in this series, all will be posted as a response to
this one. If anyone has any issues with these being applied, please let
us know. If anyone is a maintainer of the proper subsystem, and wants
to add a Signed-off-by: line to the patch, please respond with it.

These patches are sent out with a number of different people on the Cc:
line. If you wish to be a reviewer, please email [email protected] to
add your name to the list. If you want to be off the reviewer list,
also email us.

Responses should be made by Sunday, October 26 04:00:00 UTC. Anything
received after that time might be too late.

The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v2.6/stable-review/patch-2.6.27.4-rc1.gz
and the diffstat can be found below.

thanks,

the -stable release team

arch/x86/kernel/acpi/sleep.c | 3
arch/x86/kernel/amd_iommu_init.c | 2
drivers/acpi/hardware/hwsleep.c | 37 ++------
drivers/acpi/sleep/main.c | 10 ++
drivers/char/hvc_console.c | 10 +-
drivers/edac/cell_edac.c | 2
drivers/gpio/gpiolib.c | 2
drivers/md/dm-exception-store.c | 106 +++++++++++++++++--------
drivers/md/dm-kcopyd.c | 13 ++-
drivers/md/dm-snap.c | 10 --
drivers/net/wireless/ath5k/base.c | 28 ++++--
drivers/net/wireless/ath5k/base.h | 3
drivers/pci/hotplug/cpqphp_core.c | 2
drivers/scsi/device_handler/scsi_dh_rdac.c | 2
drivers/usb/atm/speedtch.c | 12 ++
drivers/usb/class/cdc-acm.c | 3
drivers/usb/class/cdc-wdm.c | 2
drivers/usb/core/driver.c | 3
drivers/usb/core/hub.c | 2
fs/cifs/readdir.c | 3
fs/ext2/dir.c | 60 ++++++++------
fs/ext3/dir.c | 10 +-
fs/ext4/dir.c | 11 +-
fs/proc/task_mmu.c | 34 +++++---
kernel/sched_stats.h | 2
mm/rmap.c | 42 +++++++--
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 2
net/ipv4/netfilter/nf_nat_snmp_basic.c | 1
net/netfilter/xt_iprange.c | 8 -
29 files changed, 278 insertions(+), 147 deletions(-)


2008-10-24 04:39:47

by Greg KH

[permalink] [raw]
Subject: [patch 01/27] gpiolib: fix oops in gpio_get_value_cansleep()

2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------

From: David Brownell <[email protected]>

commit 978ccaa8ea5d8c7bf6b676209f2fc126eae6355b upstream

We can get the following oops from gpio_get_value_cansleep() when a GPIO
controller doesn't provide a get() callback:

Unable to handle kernel paging request for instruction fetch
Faulting instruction address: 0x00000000
Oops: Kernel access of bad area, sig: 11 [#1]
[...]
NIP [00000000] 0x0
LR [c0182fb0] gpio_get_value_cansleep+0x40/0x50
Call Trace:
[c7b79e80] [c0183f28] gpio_value_show+0x5c/0x94
[c7b79ea0] [c01a584c] dev_attr_show+0x30/0x7c
[c7b79eb0] [c00d6b48] fill_read_buffer+0x68/0xe0
[c7b79ed0] [c00d6c54] sysfs_read_file+0x94/0xbc
[c7b79ef0] [c008f24c] vfs_read+0xb4/0x16c
[c7b79f10] [c008f580] sys_read+0x4c/0x90
[c7b79f40] [c0013a14] ret_from_syscall+0x0/0x38

It's OK to request the value of *any* GPIO; most GPIOs are bidirectional,
so configuring them as outputs just enables an output driver and doesn't
disable the input logic.

So the problem is that gpio_get_value_cansleep() isn't making the same
sanity check that gpio_get_value() does: making sure this GPIO isn't one
of the atypical "no input logic" cases.

Reported-by: Anton Vorontsov <[email protected]>
Signed-off-by: David Brownell <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/gpio/gpiolib.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1020,7 +1020,7 @@ int gpio_get_value_cansleep(unsigned gpi

might_sleep_if(extra_checks);
chip = gpio_to_chip(gpio);
- return chip->get(chip, gpio - chip->base);
+ return chip->get ? chip->get(chip, gpio - chip->base) : 0;
}
EXPORT_SYMBOL_GPL(gpio_get_value_cansleep);


--

2008-10-24 04:40:06

by Greg KH

[permalink] [raw]
Subject: [patch 02/27] edac cell: fix incorrect edac_mode

2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Benjamin Herrenschmidt <[email protected]>

commit 3b274f44d2ca05f719fe39947b6a5293a2dbd8fd upstream

The cell_edac driver is setting the edac_mode field of the csrow's to an
incorrect value, causing the sysfs show routine for that field to go out
of an array bound and Oopsing the kernel when used.

Signed-off-by: Benjamin Herrenschmidt <[email protected]>
Signed-off-by: Doug Thompson <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/edac/cell_edac.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/edac/cell_edac.c
+++ b/drivers/edac/cell_edac.c
@@ -142,7 +142,7 @@ static void __devinit cell_edac_init_csr
csrow->nr_pages = (r.end - r.start + 1) >> PAGE_SHIFT;
csrow->last_page = csrow->first_page + csrow->nr_pages - 1;
csrow->mtype = MEM_XDR;
- csrow->edac_mode = EDAC_FLAG_EC | EDAC_FLAG_SECDED;
+ csrow->edac_mode = EDAC_SECDED;
dev_dbg(mci->dev,
"Initialized on node %d, chanmask=0x%x,"
" first_page=0x%lx, nr_pages=0x%x\n",

--

2008-10-24 04:40:37

by Greg KH

[permalink] [raw]
Subject: [patch 03/27] x86 ACPI: fix breakage of resume on 64-bit UP systems with SMP kernel

2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Rafael J. Wysocki <[email protected]>

commit 3038edabf48f01421c621cb77a712b446d3a5d67 upstream

x86 ACPI: Fix breakage of resume on 64-bit UP systems with SMP kernel

We are now using per CPU GDT tables in head_64.S and the original
early_gdt_descr.address is invalidated after boot by
setup_per_cpu_areas(). This breaks resume from suspend to RAM on
x86_64 UP systems using SMP kernels, because this part of head_64.S
is also executed during the resume and the invalid GDT address
causes the system to crash. It doesn't break on 'true' SMP systems,
because early_gdt_descr.address is modified every time
native_cpu_up() runs. However, during resume it should point to the
GDT of the boot CPU rather than to another CPU's GDT.

For this reason, during suspend to RAM always make
early_gdt_descr.address point to the boot CPU's GDT.

This fixes http://bugzilla.kernel.org/show_bug.cgi?id=11568, which
is a regression from 2.6.26.

Signed-off-by: Rafael J. Wysocki <[email protected]>
Acked-by: Pavel Machek <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
Reported-and-tested-by: Andy Wettstein <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
arch/x86/kernel/acpi/sleep.c | 3 +++
1 file changed, 3 insertions(+)

--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -10,6 +10,7 @@
#include <linux/dmi.h>
#include <linux/cpumask.h>
#include <asm/segment.h>
+#include <asm/desc.h>

#include "realmode/wakeup.h"
#include "sleep.h"
@@ -98,6 +99,8 @@ int acpi_save_state_mem(void)
header->trampoline_segment = setup_trampoline() >> 4;
#ifdef CONFIG_SMP
stack_start.sp = temp_stack + 4096;
+ early_gdt_descr.address =
+ (unsigned long)get_cpu_gdt_table(smp_processor_id());
#endif
initial_code = (unsigned long)wakeup_long64;
saved_magic = 0x123456789abcdef0;

--

2008-10-24 04:41:37

by Greg KH

[permalink] [raw]
Subject: [patch 06/27] USB: dont rebind drivers after failed resume or reset

2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Alan Stern <[email protected]>

commit 6c6409459a18a825ce12ecb003d5686af61f7a2f upstream

This patch (as1152) may help prevent some problems associated with the
new policy of unbinding drivers that don't support suspend/resume or
pre_reset/post_reset. If for any reason the resume or reset fails, and
the device is logically disconnected, there's no point in trying to
rebind the driver. So the patch checks for success before carrying
out the unbind/rebind.

There was a report from one user that this fixed a problem he was
experiencing, but the details never became fully clear. In any case,
adding these tests can't hurt.

Signed-off-by: Alan Stern <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/usb/core/driver.c | 3 ++-
drivers/usb/core/hub.c | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)

--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1609,7 +1609,8 @@ int usb_external_resume_device(struct us
status = usb_resume_both(udev);
udev->last_busy = jiffies;
usb_pm_unlock(udev);
- do_unbind_rebind(udev, DO_REBIND);
+ if (status == 0)
+ do_unbind_rebind(udev, DO_REBIND);

/* Now that the device is awake, we can start trying to autosuspend
* it again. */
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3424,7 +3424,7 @@ int usb_reset_device(struct usb_device *
USB_INTERFACE_BOUND)
rebind = 1;
}
- if (rebind)
+ if (ret == 0 && rebind)
usb_rebind_intf(cintf);
}
}

--

2008-10-24 04:40:52

by Greg KH

[permalink] [raw]
Subject: [patch 04/27] sched: fix the wrong mask_len

2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Miao Xie <[email protected]>

commit c851c8676bd7ae456e9b3af8e6bb2c434eddcc75 upstream

If NR_CPUS isn't a multiple of 32, we get a truncated string of sched
domains by catting /proc/schedstat. This is caused by the wrong mask_len.

This patch fixes it.

Signed-off-by: Miao Xie <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
kernel/sched_stats.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/kernel/sched_stats.h
+++ b/kernel/sched_stats.h
@@ -9,7 +9,7 @@
static int show_schedstat(struct seq_file *seq, void *v)
{
int cpu;
- int mask_len = NR_CPUS/32 * 9;
+ int mask_len = (NR_CPUS/32 + 1) * 9;
char *mask_str = kmalloc(mask_len, GFP_KERNEL);

if (mask_str == NULL)

--

2008-10-24 04:42:41

by Greg KH

[permalink] [raw]
Subject: [patch 09/27] dm kcopyd: avoid queue shuffle

2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Kazuo Ito <[email protected]>

commit b673c3a8192e28f13e2050a4b82c1986be92cc15 upstream

Write throughput to LVM snapshot origin volume is an order
of magnitude slower than those to LV without snapshots or
snapshot target volumes, especially in the case of sequential
writes with O_SYNC on.

The following patch originally written by Kevin Jamieson and
Jan Blunck and slightly modified for the current RCs by myself
tries to improve the performance by modifying the behaviour
of kcopyd, so that it pushes back an I/O job to the head of
the job queue instead of the tail as process_jobs() currently
does when it has to wait for free pages. This way, write
requests aren't shuffled to cause extra seeks.

I tested the patch against 2.6.27-rc5 and got the following results.
The test is a dd command writing to snapshot origin followed by fsync
to the file just created/updated. A couple of filesystem benchmarks
gave me similar results in case of sequential writes, while random
writes didn't suffer much.

dd if=/dev/zero of=<somewhere on snapshot origin> bs=4096 count=...
[conv=notrunc when updating]

1) linux 2.6.27-rc5 without the patch, write to snapshot origin,
average throughput (MB/s)
10M 100M 1000M
create,dd 511.46 610.72 11.81
create,dd+fsync 7.10 6.77 8.13
update,dd 431.63 917.41 12.75
update,dd+fsync 7.79 7.43 8.12

compared with write throughput to LV without any snapshots,
all dd+fsync and 1000 MiB writes perform very poorly.

10M 100M 1000M
create,dd 555.03 608.98 123.29
create,dd+fsync 114.27 72.78 76.65
update,dd 152.34 1267.27 124.04
update,dd+fsync 130.56 77.81 77.84

2) linux 2.6.27-rc5 with the patch, write to snapshot origin,
average throughput (MB/s)

10M 100M 1000M
create,dd 537.06 589.44 46.21
create,dd+fsync 31.63 29.19 29.23
update,dd 487.59 897.65 37.76
update,dd+fsync 34.12 30.07 26.85

Although still not on par with plain LV performance -
cannot be avoided because it's copy on write anyway -
this simple patch successfully improves throughtput
of dd+fsync while not affecting the rest.

Signed-off-by: Jan Blunck <[email protected]>
Signed-off-by: Kazuo Ito <[email protected]>
Signed-off-by: Alasdair G Kergon <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/md/dm-kcopyd.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)

--- a/drivers/md/dm-kcopyd.c
+++ b/drivers/md/dm-kcopyd.c
@@ -268,6 +268,17 @@ static void push(struct list_head *jobs,
spin_unlock_irqrestore(&kc->job_lock, flags);
}

+
+static void push_head(struct list_head *jobs, struct kcopyd_job *job)
+{
+ unsigned long flags;
+ struct dm_kcopyd_client *kc = job->kc;
+
+ spin_lock_irqsave(&kc->job_lock, flags);
+ list_add(&job->list, jobs);
+ spin_unlock_irqrestore(&kc->job_lock, flags);
+}
+
/*
* These three functions process 1 item from the corresponding
* job list.
@@ -398,7 +409,7 @@ static int process_jobs(struct list_head
* We couldn't service this job ATM, so
* push this job back onto the list.
*/
- push(jobs, job);
+ push_head(jobs, job);
break;
}


--

2008-10-24 04:43:04

by Greg KH

[permalink] [raw]
Subject: [patch 10/27] dm snapshot: fix primary_pe race

2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Mikulas Patocka <[email protected]>

commit 7c5f78b9d7f21937e46c26db82976df4b459c95c upstream

Fix a race condition with primary_pe ref_count handling.

put_pending_exception runs under dm_snapshot->lock, it does atomic_dec_and_test
on primary_pe->ref_count, and later does atomic_read primary_pe->ref_count.

__origin_write does atomic_dec_and_test on primary_pe->ref_count without holding
dm_snapshot->lock.

This opens the following race condition:
Assume two CPUs, CPU1 is executing put_pending_exception (and holding
dm_snapshot->lock). CPU2 is executing __origin_write in parallel.
primary_pe->ref_count == 2.

CPU1:
if (primary_pe && atomic_dec_and_test(&primary_pe->ref_count))
origin_bios = bio_list_get(&primary_pe->origin_bios);
.. decrements primary_pe->ref_count to 1. Doesn't load origin_bios

CPU2:
if (first && atomic_dec_and_test(&primary_pe->ref_count)) {
flush_bios(bio_list_get(&primary_pe->origin_bios));
free_pending_exception(primary_pe);
/* If we got here, pe_queue is necessarily empty. */
return r;
}
.. decrements primary_pe->ref_count to 0, submits pending bios, frees
primary_pe.

CPU1:
if (!primary_pe || primary_pe != pe)
free_pending_exception(pe);
.. this has no effect.
if (primary_pe && !atomic_read(&primary_pe->ref_count))
free_pending_exception(primary_pe);
.. sees ref_count == 0 (written by CPU 2), does double free !!

This bug can happen only if someone is simultaneously writing to both the
origin and the snapshot.

If someone is writing only to the origin, __origin_write will submit kcopyd
request after it decrements primary_pe->ref_count (so it can't happen that the
finished copy races with primary_pe->ref_count decrementation).

If someone is writing only to the snapshot, __origin_write isn't invoked at all
and the race can't happen.

The race happens when someone writes to the snapshot --- this creates
pending_exception with primary_pe == NULL and starts copying. Then, someone
writes to the same chunk in the snapshot, and __origin_write races with
termination of already submitted request in pending_complete (that calls
put_pending_exception).

This race may be reason for bugs:
http://bugzilla.kernel.org/show_bug.cgi?id=11636
https://bugzilla.redhat.com/show_bug.cgi?id=465825

The patch fixes the code to make sure that:
1. If atomic_dec_and_test(&primary_pe->ref_count) returns false, the process
must no longer dereference primary_pe (because someone else may free it under
us).
2. If atomic_dec_and_test(&primary_pe->ref_count) returns true, the process
is responsible for freeing primary_pe.

Signed-off-by: Mikulas Patocka <[email protected]>
Signed-off-by: Alasdair G Kergon <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/md/dm-snap.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)

--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -824,8 +824,10 @@ static struct bio *put_pending_exception
* the bios for the original write to the origin.
*/
if (primary_pe &&
- atomic_dec_and_test(&primary_pe->ref_count))
+ atomic_dec_and_test(&primary_pe->ref_count)) {
origin_bios = bio_list_get(&primary_pe->origin_bios);
+ free_pending_exception(primary_pe);
+ }

/*
* Free the pe if it's not linked to an origin write or if
@@ -834,12 +836,6 @@ static struct bio *put_pending_exception
if (!primary_pe || primary_pe != pe)
free_pending_exception(pe);

- /*
- * Free the primary pe if nothing references it.
- */
- if (primary_pe && !atomic_read(&primary_pe->ref_count))
- free_pending_exception(primary_pe);
-
return origin_bios;
}


--

2008-10-24 04:41:20

by Greg KH

[permalink] [raw]
Subject: [patch 05/27] USB: cdc-wdm: make module autoload work

2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Oliver Neukum <[email protected]>

commit aa5380b904e7f896db0931320160bdea93e41f6a upstream

this fixes an omission that led to no alias being computed for the
cdc-wdm module.

Signed-off-by: Oliver Neukum <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/usb/class/cdc-wdm.c | 2 ++
1 file changed, 2 insertions(+)

--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -42,6 +42,8 @@ static struct usb_device_id wdm_ids[] =
{ }
};

+MODULE_DEVICE_TABLE (usb, wdm_ids);
+
#define WDM_MINOR_BASE 176



--

2008-10-24 04:42:21

by Greg KH

[permalink] [raw]
Subject: [patch 08/27] USB: Speedtouch: add pre_reset and post_reset routines

2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Alan Stern <[email protected]>

commit 8fc7aeab3851ed8c3ecf28901ca2c6f0400955c7 upstream

This patch (as1150) fixes a problem in the speedtch driver. When it
resets the modem during probe it will be unbound from the other
interfaces it has claimed, because it doesn't define a pre_reset and a
post_reset method.

The patch defines "do-nothing" methods. This fixes Bugzilla #11767.

Signed-off-by: Alan Stern <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/usb/atm/speedtch.c | 12 ++++++++++++
1 file changed, 12 insertions(+)

--- a/drivers/usb/atm/speedtch.c
+++ b/drivers/usb/atm/speedtch.c
@@ -722,6 +722,16 @@ static void speedtch_atm_stop(struct usb
flush_scheduled_work();
}

+static int speedtch_pre_reset(struct usb_interface *intf)
+{
+ return 0;
+}
+
+static int speedtch_post_reset(struct usb_interface *intf)
+{
+ return 0;
+}
+

/**********
** USB **
@@ -740,6 +750,8 @@ static struct usb_driver speedtch_usb_dr
.name = speedtch_driver_name,
.probe = speedtch_usb_probe,
.disconnect = usbatm_usb_disconnect,
+ .pre_reset = speedtch_pre_reset,
+ .post_reset = speedtch_post_reset,
.id_table = speedtch_usb_ids
};


--

2008-10-24 04:43:27

by Greg KH

[permalink] [raw]
Subject: [patch 11/27] dm exception store: refactor zero_area

2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Alasdair G Kergon <[email protected]>

commit 7c9e6c17325fab380fbe9c9787680ff7d4a51abd upstream

Use a separate buffer for writing zeroes to the on-disk snapshot
exception store, make the updating of ps->current_area explicit and
refactor the code in preparation for the fix in the next patch.

No functional change.

Signed-off-by: Alasdair G Kergon <[email protected]>
Signed-off-by: Mikulas Patocka <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/md/dm-exception-store.c | 103 ++++++++++++++++++++++++++--------------
1 file changed, 69 insertions(+), 34 deletions(-)

--- a/drivers/md/dm-exception-store.c
+++ b/drivers/md/dm-exception-store.c
@@ -105,6 +105,11 @@ struct pstore {
void *area;

/*
+ * An area of zeros used to clear the next area.
+ */
+ void *zero_area;
+
+ /*
* Used to keep track of which metadata area the data in
* 'chunk' refers to.
*/
@@ -149,6 +154,13 @@ static int alloc_area(struct pstore *ps)
if (!ps->area)
return r;

+ ps->zero_area = vmalloc(len);
+ if (!ps->zero_area) {
+ vfree(ps->area);
+ return r;
+ }
+ memset(ps->zero_area, 0, len);
+
return 0;
}

@@ -156,6 +168,8 @@ static void free_area(struct pstore *ps)
{
vfree(ps->area);
ps->area = NULL;
+ vfree(ps->zero_area);
+ ps->zero_area = NULL;
}

struct mdata_req {
@@ -212,13 +226,13 @@ static int chunk_io(struct pstore *ps, u
* Read or write a metadata area. Remembering to skip the first
* chunk which holds the header.
*/
-static int area_io(struct pstore *ps, uint32_t area, int rw)
+static int area_io(struct pstore *ps, int rw)
{
int r;
uint32_t chunk;

/* convert a metadata area index to a chunk index */
- chunk = 1 + ((ps->exceptions_per_area + 1) * area);
+ chunk = area_location(ps, ps->current_area);

r = chunk_io(ps, chunk, rw, 0);
if (r)
@@ -228,10 +242,27 @@ static int area_io(struct pstore *ps, ui
return 0;
}

-static int zero_area(struct pstore *ps, uint32_t area)
+static void zero_memory_area(struct pstore *ps)
{
memset(ps->area, 0, ps->snap->chunk_size << SECTOR_SHIFT);
- return area_io(ps, area, WRITE);
+}
+
+static int zero_disk_area(struct pstore *ps, chunk_t area)
+{
+ struct dm_io_region where = {
+ .bdev = ps->snap->cow->bdev,
+ .sector = ps->snap->chunk_size * area_location(ps, area),
+ .count = ps->snap->chunk_size,
+ };
+ struct dm_io_request io_req = {
+ .bi_rw = WRITE,
+ .mem.type = DM_IO_VMA,
+ .mem.ptr.vma = ps->zero_area,
+ .client = ps->io_client,
+ .notify.fn = NULL,
+ };
+
+ return dm_io(&io_req, 1, &where, NULL);
}

static int read_header(struct pstore *ps, int *new_snapshot)
@@ -404,15 +435,14 @@ static int insert_exceptions(struct psto

static int read_exceptions(struct pstore *ps)
{
- uint32_t area;
int r, full = 1;

/*
* Keeping reading chunks and inserting exceptions until
* we find a partially full area.
*/
- for (area = 0; full; area++) {
- r = area_io(ps, area, READ);
+ for (ps->current_area = 0; full; ps->current_area++) {
+ r = area_io(ps, READ);
if (r)
return r;

@@ -421,6 +451,8 @@ static int read_exceptions(struct pstore
return r;
}

+ ps->current_area--;
+
return 0;
}

@@ -479,12 +511,13 @@ static int persistent_read_metadata(stru
return r;
}

- r = zero_area(ps, 0);
+ ps->current_area = 0;
+ zero_memory_area(ps);
+ r = zero_disk_area(ps, 0);
if (r) {
- DMWARN("zero_area(0) failed");
+ DMWARN("zero_disk_area(0) failed");
return r;
}
-
} else {
/*
* Sanity checks.
@@ -542,7 +575,6 @@ static void persistent_commit(struct exc
void (*callback) (void *, int success),
void *callback_context)
{
- int r;
unsigned int i;
struct pstore *ps = get_info(store);
struct disk_exception de;
@@ -563,33 +595,36 @@ static void persistent_commit(struct exc
cb->context = callback_context;

/*
- * If there are no more exceptions in flight, or we have
- * filled this metadata area we commit the exceptions to
- * disk.
- */
- if (atomic_dec_and_test(&ps->pending_count) ||
- (ps->current_committed == ps->exceptions_per_area)) {
- r = area_io(ps, ps->current_area, WRITE);
- if (r)
- ps->valid = 0;
+ * If there are exceptions in flight and we have not yet
+ * filled this metadata area there's nothing more to do.
+ */
+ if (!atomic_dec_and_test(&ps->pending_count) &&
+ (ps->current_committed != ps->exceptions_per_area))
+ return;

- /*
- * Have we completely filled the current area ?
- */
- if (ps->current_committed == ps->exceptions_per_area) {
- ps->current_committed = 0;
- r = zero_area(ps, ps->current_area + 1);
- if (r)
- ps->valid = 0;
- }
+ /*
+ * Commit exceptions to disk.
+ */
+ if (area_io(ps, WRITE))
+ ps->valid = 0;

- for (i = 0; i < ps->callback_count; i++) {
- cb = ps->callbacks + i;
- cb->callback(cb->context, r == 0 ? 1 : 0);
- }
+ /*
+ * Advance to the next area if this one is full.
+ */
+ if (ps->current_committed == ps->exceptions_per_area) {
+ if (zero_disk_area(ps, ps->current_area + 1))
+ ps->valid = 0;
+ ps->current_committed = 0;
+ ps->current_area++;
+ zero_memory_area(ps);
+ }

- ps->callback_count = 0;
+ for (i = 0; i < ps->callback_count; i++) {
+ cb = ps->callbacks + i;
+ cb->callback(cb->context, ps->valid);
}
+
+ ps->callback_count = 0;
}

static void persistent_drop(struct exception_store *store)

--

2008-10-24 04:41:55

by Greg KH

[permalink] [raw]
Subject: [patch 07/27] USB: fix memory leak in cdc-acm

2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Oliver Neukum <[email protected]>

commit a496c64f1363ec4d67ebdc1e1f619ad6372a574c upstream

This fixes a memory leak on disconnect in cdc-acm

Thanks to 施金前 for finding it.

Signed-off-by: Oliver Neukum <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/usb/class/cdc-acm.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -849,9 +849,10 @@ static void acm_write_buffers_free(struc
{
int i;
struct acm_wb *wb;
+ struct usb_device *usb_dev = interface_to_usbdev(acm->control);

for (wb = &acm->wb[0], i = 0; i < ACM_NW; i++, wb++) {
- usb_buffer_free(acm->dev, acm->writesize, wb->buf, wb->dmah);
+ usb_buffer_free(usb_dev, acm->writesize, wb->buf, wb->dmah);
}
}


--

2008-10-24 04:43:47

by Greg KH

[permalink] [raw]
Subject: [patch 12/27] dm exception store: fix misordered writes

2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Mikulas Patocka <[email protected]>

commit 7acedc5b98a2fcff64f00c21110aae7d3ac2f7df upstream

We must zero the next chunk on disk *before* writing out the current chunk, not
after. Otherwise if the machine crashes at the wrong time, the "end of metadata"
marker may be missing.

Signed-off-by: Mikulas Patocka <[email protected]>
Signed-off-by: Alasdair G Kergon <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/md/dm-exception-store.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)

--- a/drivers/md/dm-exception-store.c
+++ b/drivers/md/dm-exception-store.c
@@ -603,17 +603,22 @@ static void persistent_commit(struct exc
return;

/*
+ * If we completely filled the current area, then wipe the next one.
+ */
+ if ((ps->current_committed == ps->exceptions_per_area) &&
+ zero_disk_area(ps, ps->current_area + 1))
+ ps->valid = 0;
+
+ /*
* Commit exceptions to disk.
*/
- if (area_io(ps, WRITE))
+ if (ps->valid && area_io(ps, WRITE))
ps->valid = 0;

/*
* Advance to the next area if this one is full.
*/
if (ps->current_committed == ps->exceptions_per_area) {
- if (zero_disk_area(ps, ps->current_area + 1))
- ps->valid = 0;
ps->current_committed = 0;
ps->current_area++;
zero_memory_area(ps);

--

2008-10-24 04:44:13

by Greg KH

[permalink] [raw]
Subject: [patch 13/27] amd_iommu: fix nasty bug that caused ILLEGAL_DEVICE_TABLE_ENTRY errors

2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Andreas Herrmann <[email protected]>

commit f609891f428e1c20e270e7c350daf8c93cc459d7 upstream

We are on 64-bit so better use u64 instead of u32 to deal with
addresses:

static void __init iommu_set_device_table(struct amd_iommu *iommu)
{
u64 entry;
...
entry = virt_to_phys(amd_iommu_dev_table);
...

(I am wondering why gcc 4.2.x did not warn about the assignment
between u32 and unsigned long.)

Cc: [email protected]
Signed-off-by: Andreas Herrmann <[email protected]>
Signed-off-by: Joerg Roedel <[email protected]>
Signed-off-by: David Woodhouse <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
arch/x86/kernel/amd_iommu_init.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/arch/x86/kernel/amd_iommu_init.c
+++ b/arch/x86/kernel/amd_iommu_init.c
@@ -210,7 +210,7 @@ static void __init iommu_set_exclusion_r
/* Programs the physical address of the device table into the IOMMU hardware */
static void __init iommu_set_device_table(struct amd_iommu *iommu)
{
- u32 entry;
+ u64 entry;

BUG_ON(iommu->mmio_base == NULL);


--

2008-10-24 04:44:35

by Greg KH

[permalink] [raw]
Subject: [patch 14/27] CIFS: fix saving of resume key before CIFSFindNext

2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Jeff Layton <[email protected]>

commit a364bc0b37f14ffd66c1f982af42990a9d77fa43 upstream

We recently fixed the cifs readdir code so that it saves the resume key
before calling CIFSFindNext. Unfortunately, this assumes that we have
just done a CIFSFindFirst (or FindNext) and have resume info to save.
This isn't necessarily the case. Fix the code to save resume info if we
had to reinitiate the search, and after a FindNext.

This fixes connectathon basic test6 against NetApp filers.

Signed-off-by: Jeff Layton <[email protected]>
Signed-off-by: Steve French <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
fs/cifs/readdir.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -762,14 +762,15 @@ static int find_cifs_entry(const int xid
rc));
return rc;
}
+ cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile);
}

while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) &&
(rc == 0) && !cifsFile->srch_inf.endOfSearch) {
cFYI(1, ("calling findnext2"));
- cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile);
rc = CIFSFindNext(xid, pTcon, cifsFile->netfid,
&cifsFile->srch_inf);
+ cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile);
if (rc)
return -ENOENT;
}

--

2008-10-24 04:44:55

by Greg KH

[permalink] [raw]
Subject: [patch 15/27] ext: Avoid printk floods in the face of directory corruption (CVE-2008-3528)

2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Eric Sandeen <[email protected]>

This is a trivial backport of the following upstream commits:

- bd39597cbd42a784105a04010100e27267481c67 (ext2)
- cdbf6dba28e8e6268c8420857696309470009fd9 (ext3)
- 9d9f177572d9e4eba0f2e18523b44f90dd51fe74 (ext4)

This addresses CVE-2008-3528

ext[234]: Avoid printk floods in the face of directory corruption

Note: some people thinks this represents a security bug, since it
might make the system go away while it is printing a large number of
console messages, especially if a serial console is involved. Hence,
it has been assigned CVE-2008-3528, but it requires that the attacker
either has physical access to your machine to insert a USB disk with a
corrupted filesystem image (at which point why not just hit the power
button), or is otherwise able to convince the system administrator to
mount an arbitrary filesystem image (at which point why not just
include a setuid shell or world-writable hard disk device file or some
such). Me, I think they're just being silly. --tytso

Signed-off-by: Eric Sandeen <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
Cc: [email protected]
Cc: Eugene Teo <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
fs/ext2/dir.c | 60 +++++++++++++++++++++++++++++++++-------------------------
fs/ext3/dir.c | 10 ++++++---
fs/ext4/dir.c | 11 +++++++---
3 files changed, 50 insertions(+), 31 deletions(-)

--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -103,7 +103,7 @@ static int ext2_commit_chunk(struct page
return err;
}

-static void ext2_check_page(struct page *page)
+static void ext2_check_page(struct page *page, int quiet)
{
struct inode *dir = page->mapping->host;
struct super_block *sb = dir->i_sb;
@@ -146,10 +146,10 @@ out:
/* Too bad, we had an error */

Ebadsize:
- ext2_error(sb, "ext2_check_page",
- "size of directory #%lu is not a multiple of chunk size",
- dir->i_ino
- );
+ if (!quiet)
+ ext2_error(sb, __func__,
+ "size of directory #%lu is not a multiple "
+ "of chunk size", dir->i_ino);
goto fail;
Eshort:
error = "rec_len is smaller than minimal";
@@ -166,32 +166,36 @@ Espan:
Einumber:
error = "inode out of bounds";
bad_entry:
- ext2_error (sb, "ext2_check_page", "bad entry in directory #%lu: %s - "
- "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
- dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
- (unsigned long) le32_to_cpu(p->inode),
- rec_len, p->name_len);
+ if (!quiet)
+ ext2_error(sb, __func__, "bad entry in directory #%lu: : %s - "
+ "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
+ dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
+ (unsigned long) le32_to_cpu(p->inode),
+ rec_len, p->name_len);
goto fail;
Eend:
- p = (ext2_dirent *)(kaddr + offs);
- ext2_error (sb, "ext2_check_page",
- "entry in directory #%lu spans the page boundary"
- "offset=%lu, inode=%lu",
- dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
- (unsigned long) le32_to_cpu(p->inode));
+ if (!quiet) {
+ p = (ext2_dirent *)(kaddr + offs);
+ ext2_error(sb, "ext2_check_page",
+ "entry in directory #%lu spans the page boundary"
+ "offset=%lu, inode=%lu",
+ dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
+ (unsigned long) le32_to_cpu(p->inode));
+ }
fail:
SetPageChecked(page);
SetPageError(page);
}

-static struct page * ext2_get_page(struct inode *dir, unsigned long n)
+static struct page * ext2_get_page(struct inode *dir, unsigned long n,
+ int quiet)
{
struct address_space *mapping = dir->i_mapping;
struct page *page = read_mapping_page(mapping, n, NULL);
if (!IS_ERR(page)) {
kmap(page);
if (!PageChecked(page))
- ext2_check_page(page);
+ ext2_check_page(page, quiet);
if (PageError(page))
goto fail;
}
@@ -292,7 +296,7 @@ ext2_readdir (struct file * filp, void *
for ( ; n < npages; n++, offset = 0) {
char *kaddr, *limit;
ext2_dirent *de;
- struct page *page = ext2_get_page(inode, n);
+ struct page *page = ext2_get_page(inode, n, 0);

if (IS_ERR(page)) {
ext2_error(sb, __func__,
@@ -361,6 +365,7 @@ struct ext2_dir_entry_2 * ext2_find_entr
struct page *page = NULL;
struct ext2_inode_info *ei = EXT2_I(dir);
ext2_dirent * de;
+ int dir_has_error = 0;

if (npages == 0)
goto out;
@@ -374,7 +379,7 @@ struct ext2_dir_entry_2 * ext2_find_entr
n = start;
do {
char *kaddr;
- page = ext2_get_page(dir, n);
+ page = ext2_get_page(dir, n, dir_has_error);
if (!IS_ERR(page)) {
kaddr = page_address(page);
de = (ext2_dirent *) kaddr;
@@ -391,7 +396,9 @@ struct ext2_dir_entry_2 * ext2_find_entr
de = ext2_next_entry(de);
}
ext2_put_page(page);
- }
+ } else
+ dir_has_error = 1;
+
if (++n >= npages)
n = 0;
/* next page is past the blocks we've got */
@@ -414,7 +421,7 @@ found:

struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p)
{
- struct page *page = ext2_get_page(dir, 0);
+ struct page *page = ext2_get_page(dir, 0, 0);
ext2_dirent *de = NULL;

if (!IS_ERR(page)) {
@@ -487,7 +494,7 @@ int ext2_add_link (struct dentry *dentry
for (n = 0; n <= npages; n++) {
char *dir_end;

- page = ext2_get_page(dir, n);
+ page = ext2_get_page(dir, n, 0);
err = PTR_ERR(page);
if (IS_ERR(page))
goto out;
@@ -655,14 +662,17 @@ int ext2_empty_dir (struct inode * inode
{
struct page *page = NULL;
unsigned long i, npages = dir_pages(inode);
+ int dir_has_error = 0;

for (i = 0; i < npages; i++) {
char *kaddr;
ext2_dirent * de;
- page = ext2_get_page(inode, i);
+ page = ext2_get_page(inode, i, dir_has_error);

- if (IS_ERR(page))
+ if (IS_ERR(page)) {
+ dir_has_error = 1;
continue;
+ }

kaddr = page_address(page);
de = (ext2_dirent *)kaddr;
--- a/fs/ext3/dir.c
+++ b/fs/ext3/dir.c
@@ -102,6 +102,7 @@ static int ext3_readdir(struct file * fi
int err;
struct inode *inode = filp->f_path.dentry->d_inode;
int ret = 0;
+ int dir_has_error = 0;

sb = inode->i_sb;

@@ -148,9 +149,12 @@ static int ext3_readdir(struct file * fi
* of recovering data when there's a bad sector
*/
if (!bh) {
- ext3_error (sb, "ext3_readdir",
- "directory #%lu contains a hole at offset %lu",
- inode->i_ino, (unsigned long)filp->f_pos);
+ if (!dir_has_error) {
+ ext3_error(sb, __func__, "directory #%lu "
+ "contains a hole at offset %lld",
+ inode->i_ino, filp->f_pos);
+ dir_has_error = 1;
+ }
/* corrupt size? Maybe no more blocks to read */
if (filp->f_pos > inode->i_blocks << 9)
break;
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -102,6 +102,7 @@ static int ext4_readdir(struct file * fi
int err;
struct inode *inode = filp->f_path.dentry->d_inode;
int ret = 0;
+ int dir_has_error = 0;

sb = inode->i_sb;

@@ -148,9 +149,13 @@ static int ext4_readdir(struct file * fi
* of recovering data when there's a bad sector
*/
if (!bh) {
- ext4_error (sb, "ext4_readdir",
- "directory #%lu contains a hole at offset %lu",
- inode->i_ino, (unsigned long)filp->f_pos);
+ if (!dir_has_error) {
+ ext4_error(sb, __func__, "directory #%lu "
+ "contains a hole at offset %Lu",
+ inode->i_ino,
+ (unsigned long long) filp->f_pos);
+ dir_has_error = 1;
+ }
/* corrupt size? Maybe no more blocks to read */
if (filp->f_pos > inode->i_blocks << 9)
break;

--

2008-10-24 04:45:28

by Greg KH

[permalink] [raw]
Subject: [patch 17/27] netfilter: snmp nat leaks memory in case of failure

2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Ilpo J?rvinen <[email protected]>

netfilter: snmp nat leaks memory in case of failure

Upstream commit 311670f3e:

Signed-off-by: Ilpo Jarvinen <[email protected]>
Signed-off-by: Patrick McHardy <[email protected]>

---
net/ipv4/netfilter/nf_nat_snmp_basic.c | 1 +
1 file changed, 1 insertion(+)

--- a/net/ipv4/netfilter/nf_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c
@@ -742,6 +742,7 @@ static unsigned char snmp_object_decode(
*obj = kmalloc(sizeof(struct snmp_object) + len,
GFP_ATOMIC);
if (*obj == NULL) {
+ kfree(p);
kfree(id);
if (net_ratelimit())
printk("OOM in bsalg (%d)\n", __LINE__);

--

2008-10-24 04:45:49

by Greg KH

[permalink] [raw]
Subject: [patch 16/27] netfilter: xt_iprange: fix range inversion match


2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Alexey Dobriyan <[email protected]>

netfilter: xt_iprange: fix range inversion match

Upstream commit 6def1eb48:

Inverted IPv4 v1 and IPv6 v0 matches don't match anything since 2.6.25-rc1!

Signed-off-by: Alexey Dobriyan <[email protected]>
Acked-by: Jan Engelhardt <[email protected]>
Signed-off-by: Patrick McHardy <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
net/netfilter/xt_iprange.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

--- a/net/netfilter/xt_iprange.c
+++ b/net/netfilter/xt_iprange.c
@@ -67,7 +67,7 @@ iprange_mt4(const struct sk_buff *skb, c
if (info->flags & IPRANGE_SRC) {
m = ntohl(iph->saddr) < ntohl(info->src_min.ip);
m |= ntohl(iph->saddr) > ntohl(info->src_max.ip);
- m ^= info->flags & IPRANGE_SRC_INV;
+ m ^= !!(info->flags & IPRANGE_SRC_INV);
if (m) {
pr_debug("src IP " NIPQUAD_FMT " NOT in range %s"
NIPQUAD_FMT "-" NIPQUAD_FMT "\n",
@@ -81,7 +81,7 @@ iprange_mt4(const struct sk_buff *skb, c
if (info->flags & IPRANGE_DST) {
m = ntohl(iph->daddr) < ntohl(info->dst_min.ip);
m |= ntohl(iph->daddr) > ntohl(info->dst_max.ip);
- m ^= info->flags & IPRANGE_DST_INV;
+ m ^= !!(info->flags & IPRANGE_DST_INV);
if (m) {
pr_debug("dst IP " NIPQUAD_FMT " NOT in range %s"
NIPQUAD_FMT "-" NIPQUAD_FMT "\n",
@@ -123,14 +123,14 @@ iprange_mt6(const struct sk_buff *skb, c
if (info->flags & IPRANGE_SRC) {
m = iprange_ipv6_sub(&iph->saddr, &info->src_min.in6) < 0;
m |= iprange_ipv6_sub(&iph->saddr, &info->src_max.in6) > 0;
- m ^= info->flags & IPRANGE_SRC_INV;
+ m ^= !!(info->flags & IPRANGE_SRC_INV);
if (m)
return false;
}
if (info->flags & IPRANGE_DST) {
m = iprange_ipv6_sub(&iph->daddr, &info->dst_min.in6) < 0;
m |= iprange_ipv6_sub(&iph->daddr, &info->dst_max.in6) > 0;
- m ^= info->flags & IPRANGE_DST_INV;
+ m ^= !!(info->flags & IPRANGE_DST_INV);
if (m)
return false;
}

--

2008-10-24 04:46:13

by Greg KH

[permalink] [raw]
Subject: [patch 18/27] netfilter: restore lost ifdef guarding defrag exception

2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Patrick McHardy <[email protected]>

netfilter: restore lost #ifdef guarding defrag exception

Upstream commit 38f7ac3eb:

Nir Tzachar <[email protected]> reported a warning when sending
fragments over loopback with NAT:

[ 6658.338121] WARNING: at net/ipv4/netfilter/nf_nat_standalone.c:89 nf_nat_fn+0x33/0x155()

The reason is that defragmentation is skipped for already tracked connections.
This is wrong in combination with NAT and ip_conntrack actually had some ifdefs
to avoid this behaviour when NAT is compiled in.

The entire "optimization" may seem a bit silly, for now simply restoring the
lost #ifdef is the easiest solution until we can come up with something better.

Signed-off-by: Patrick McHardy <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 2 ++
1 file changed, 2 insertions(+)

--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -150,10 +150,12 @@ static unsigned int ipv4_conntrack_defra
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
+#if !defined(CONFIG_NF_NAT) && !defined(CONFIG_NF_NAT_MODULE)
/* Previously seen (loopback)? Ignore. Do this before
fragment check. */
if (skb->nfct)
return NF_ACCEPT;
+#endif

/* Gather fragments. */
if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {

--

2008-10-24 04:46:33

by Greg KH

[permalink] [raw]
Subject: [patch 19/27] anon_vma_prepare: properly lock even newly allocated entries

2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Linus Torvalds <[email protected]>

commit d9d332e0874f46b91d8ac4604b68ee42b8a7a2c6 upstream

The anon_vma code is very subtle, and we end up doing optimistic lookups
of anon_vmas under RCU in page_lock_anon_vma() with no locking. Other
CPU's can also see the newly allocated entry immediately after we've
exposed it by setting "vma->anon_vma" to the new value.

We protect against the anon_vma being destroyed by having the SLAB
marked as SLAB_DESTROY_BY_RCU, so the RCU lookup can depend on the
allocation not being destroyed - but it might still be free'd and
re-allocated here to a new vma.

As a result, we should not do the anon_vma list ops on a newly allocated
vma without proper locking.

Acked-by: Nick Piggin <[email protected]>
Acked-by: Hugh Dickins <[email protected]>
Acked-by: Peter Zijlstra <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
mm/rmap.c | 42 ++++++++++++++++++++++++++++++++----------
1 file changed, 32 insertions(+), 10 deletions(-)

--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -55,7 +55,33 @@

struct kmem_cache *anon_vma_cachep;

-/* This must be called under the mmap_sem. */
+/**
+ * anon_vma_prepare - attach an anon_vma to a memory region
+ * @vma: the memory region in question
+ *
+ * This makes sure the memory mapping described by 'vma' has
+ * an 'anon_vma' attached to it, so that we can associate the
+ * anonymous pages mapped into it with that anon_vma.
+ *
+ * The common case will be that we already have one, but if
+ * if not we either need to find an adjacent mapping that we
+ * can re-use the anon_vma from (very common when the only
+ * reason for splitting a vma has been mprotect()), or we
+ * allocate a new one.
+ *
+ * Anon-vma allocations are very subtle, because we may have
+ * optimistically looked up an anon_vma in page_lock_anon_vma()
+ * and that may actually touch the spinlock even in the newly
+ * allocated vma (it depends on RCU to make sure that the
+ * anon_vma isn't actually destroyed).
+ *
+ * As a result, we need to do proper anon_vma locking even
+ * for the new allocation. At the same time, we do not want
+ * to do any locking for the common case of already having
+ * an anon_vma.
+ *
+ * This must be called with the mmap_sem held for reading.
+ */
int anon_vma_prepare(struct vm_area_struct *vma)
{
struct anon_vma *anon_vma = vma->anon_vma;
@@ -63,20 +89,17 @@ int anon_vma_prepare(struct vm_area_stru
might_sleep();
if (unlikely(!anon_vma)) {
struct mm_struct *mm = vma->vm_mm;
- struct anon_vma *allocated, *locked;
+ struct anon_vma *allocated;

anon_vma = find_mergeable_anon_vma(vma);
- if (anon_vma) {
- allocated = NULL;
- locked = anon_vma;
- spin_lock(&locked->lock);
- } else {
+ allocated = NULL;
+ if (!anon_vma) {
anon_vma = anon_vma_alloc();
if (unlikely(!anon_vma))
return -ENOMEM;
allocated = anon_vma;
- locked = NULL;
}
+ spin_lock(&anon_vma->lock);

/* page_table_lock to protect against threads */
spin_lock(&mm->page_table_lock);
@@ -87,8 +110,7 @@ int anon_vma_prepare(struct vm_area_stru
}
spin_unlock(&mm->page_table_lock);

- if (locked)
- spin_unlock(&locked->lock);
+ spin_unlock(&anon_vma->lock);
if (unlikely(allocated))
anon_vma_free(allocated);
}

--

2008-10-24 04:46:53

by Greg KH

[permalink] [raw]
Subject: [patch 24/27] proc: fix vma display mismatch between /proc/pid/{maps,smaps}

2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Joe Korty <[email protected]>

[ backport of 7c88db0cb589df980acfb2f73c3595a0653004ec to 2.7.27.3 by Joe
Korty <[email protected] ]

proc: fix vma display mismatch between /proc/pid/{maps,smaps}

Commit 4752c369789250eafcd7813e11c8fb689235b0d2 aka
"maps4: simplify interdependence of maps and smaps" broke /proc/pid/smaps,
causing it to display some vmas twice and other vmas not at all. For example:

grep .- /proc/1/smaps >/tmp/smaps; diff /proc/1/maps /tmp/smaps

1 25d24
2 < 7fd7e23aa000-7fd7e23ac000 rw-p 7fd7e23aa000 00:00 0
3 28a28
4 > ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]

The bug has something to do with setting m->version before all the
seq_printf's have been performed. show_map was doing this correctly,
but show_smap was doing this in the middle of its seq_printf sequence.
This patch arranges things so that the setting of m->version in show_smap
is also done at the end of its seq_printf sequence.

Testing: in addition to the above grep test, for each process I summed
up the 'Rss' fields of /proc/pid/smaps and compared that to the 'VmRSS'
field of /proc/pid/status. All matched except for Xorg (which has a
/dev/mem mapping which Rss accounts for but VmRSS does not). This result
gives us some confidence that neither /proc/pid/maps nor /proc/pid/smaps
are any longer skipping or double-counting vmas.

Signed-off-by: Joe Korty <[email protected]>
Cc: Matt Mackall <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Alexey Dobriyan <[email protected]>

---
fs/proc/task_mmu.c | 34 ++++++++++++++++++++++------------
1 file changed, 22 insertions(+), 12 deletions(-)

--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -198,11 +198,8 @@ static int do_maps_open(struct inode *in
return ret;
}

-static int show_map(struct seq_file *m, void *v)
+static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
{
- struct proc_maps_private *priv = m->private;
- struct task_struct *task = priv->task;
- struct vm_area_struct *vma = v;
struct mm_struct *mm = vma->vm_mm;
struct file *file = vma->vm_file;
int flags = vma->vm_flags;
@@ -210,9 +207,6 @@ static int show_map(struct seq_file *m,
dev_t dev = 0;
int len;

- if (maps_protect && !ptrace_may_access(task, PTRACE_MODE_READ))
- return -EACCES;
-
if (file) {
struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
dev = inode->i_sb->s_dev;
@@ -257,6 +251,18 @@ static int show_map(struct seq_file *m,
}
}
seq_putc(m, '\n');
+}
+
+static int show_map(struct seq_file *m, void *v)
+{
+ struct vm_area_struct *vma = v;
+ struct proc_maps_private *priv = m->private;
+ struct task_struct *task = priv->task;
+
+ if (maps_protect && !ptrace_may_access(task, PTRACE_MODE_READ))
+ return -EACCES;
+
+ show_map_vma(m, vma);

if (m->count < m->size) /* vma is copied successfully */
m->version = (vma != get_gate_vma(task))? vma->vm_start: 0;
@@ -367,23 +373,25 @@ static int smaps_pte_range(pmd_t *pmd, u

static int show_smap(struct seq_file *m, void *v)
{
+ struct proc_maps_private *priv = m->private;
+ struct task_struct *task = priv->task;
struct vm_area_struct *vma = v;
struct mem_size_stats mss;
- int ret;
struct mm_walk smaps_walk = {
.pmd_entry = smaps_pte_range,
.mm = vma->vm_mm,
.private = &mss,
};

+ if (maps_protect && !ptrace_may_access(task, PTRACE_MODE_READ))
+ return -EACCES;
+
memset(&mss, 0, sizeof mss);
mss.vma = vma;
if (vma->vm_mm && !is_vm_hugetlb_page(vma))
walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);

- ret = show_map(m, v);
- if (ret)
- return ret;
+ show_map_vma(m, vma);

seq_printf(m,
"Size: %8lu kB\n"
@@ -405,7 +413,9 @@ static int show_smap(struct seq_file *m,
mss.referenced >> 10,
mss.swap >> 10);

- return ret;
+ if (m->count < m->size) /* vma is copied successfully */
+ m->version = (vma != get_gate_vma(task)) ? vma->vm_start : 0;
+ return 0;
}

static const struct seq_operations proc_pid_smaps_op = {

--

2008-10-24 04:47:18

by Greg KH

[permalink] [raw]
Subject: [patch 23/27] ACPI suspend: Always use the 32-bit waking vector

2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Rafael J. Wysocki <[email protected]>

commit a6629105dd03d370fcb31e97bddf223fa4bb651e upstream.

According to the ACPI specification 2.0c and later, the 64-bit waking vector
should be cleared and the 32-bit waking vector should be used, unless we want
the wake-up code to be called by the BIOS in Protected Mode. Moreover, some
systems (for example HP dv5-1004nr) are known to fail to resume if the 64-bit
waking vector is used. Therefore, modify the code to clear the 64-bit waking
vector, for FACS version 1 or greater, and set the 32-bit one before suspend.

http://bugzilla.kernel.org/show_bug.cgi?id=11368

Signed-off-by: Rafael J. Wysocki <[email protected]>
Signed-off-by: Len Brown <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/acpi/hardware/hwsleep.c | 37 +++++++++++--------------------------
1 file changed, 11 insertions(+), 26 deletions(-)

--- a/drivers/acpi/hardware/hwsleep.c
+++ b/drivers/acpi/hardware/hwsleep.c
@@ -78,19 +78,17 @@ acpi_set_firmware_waking_vector(acpi_phy
return_ACPI_STATUS(status);
}

- /* Set the vector */
+ /*
+ * According to the ACPI specification 2.0c and later, the 64-bit
+ * waking vector should be cleared and the 32-bit waking vector should
+ * be used, unless we want the wake-up code to be called by the BIOS in
+ * Protected Mode. Some systems (for example HP dv5-1004nr) are known
+ * to fail to resume if the 64-bit vector is used.
+ */
+ if (facs->version >= 1)
+ facs->xfirmware_waking_vector = 0;

- if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) {
- /*
- * ACPI 1.0 FACS or short table or optional X_ field is zero
- */
- facs->firmware_waking_vector = (u32) physical_address;
- } else {
- /*
- * ACPI 2.0 FACS with valid X_ field
- */
- facs->xfirmware_waking_vector = physical_address;
- }
+ facs->firmware_waking_vector = (u32)physical_address;

return_ACPI_STATUS(AE_OK);
}
@@ -134,20 +132,7 @@ acpi_get_firmware_waking_vector(acpi_phy
}

/* Get the vector */
-
- if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) {
- /*
- * ACPI 1.0 FACS or short table or optional X_ field is zero
- */
- *physical_address =
- (acpi_physical_address) facs->firmware_waking_vector;
- } else {
- /*
- * ACPI 2.0 FACS with valid X_ field
- */
- *physical_address =
- (acpi_physical_address) facs->xfirmware_waking_vector;
- }
+ *physical_address = (acpi_physical_address)facs->firmware_waking_vector;

return_ACPI_STATUS(AE_OK);
}

--

2008-10-24 04:47:36

by Greg KH

[permalink] [raw]
Subject: [patch 22/27] ACPI suspend: Blacklist HP xw4600 Workstation for old code ordering

2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Rafael J. Wysocki <[email protected]>

commit 4fb507b6b764195bb7821cf2baa988f6eb677d30 upstream

HP xw4600 Workstation is known to require the "old" (ie. compatible
with ACPI 1.0) suspend code ordering, so blacklist it for this
purpose.

Signed-off-by: Rafael J. Wysocki <[email protected]>
Tested-by: John Brown <[email protected]>
Signed-off-by: Len Brown <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/acpi/sleep/main.c | 8 ++++++++
1 file changed, 8 insertions(+)

--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -298,6 +298,14 @@ static struct dmi_system_id __initdata a
DMI_MATCH(DMI_BOARD_NAME, "KN9 Series(NF-CK804)"),
},
},
+ {
+ .callback = init_old_suspend_ordering,
+ .ident = "HP xw4600 Workstation",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP xw4600 Workstation"),
+ },
+ },
{},
};
#endif /* CONFIG_SUSPEND */

--

2008-10-24 04:47:54

by Greg KH

[permalink] [raw]
Subject: [patch 25/27] SCSI: scsi_dh: add Dell product information into rdac device handler

2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------
From: [email protected] <[email protected]>

commit 650849d71ca05d55a1553fe42fb21af9dce5612b upstream.

Add Dell Powervault storage arrays into device list of rdac device
handler.

Signed-off-by: Yanqing Liu <[email protected]>
Signed-off-by: James Bottomley <[email protected]>
Cc: shyam iyer <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/scsi/device_handler/scsi_dh_rdac.c | 2 ++
1 file changed, 2 insertions(+)

--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -590,6 +590,8 @@ static const struct scsi_dh_devlist rdac
{"STK", "OPENstorage D280"},
{"SUN", "CSM200_R"},
{"SUN", "LCSM100_F"},
+ {"DELL", "MD3000"},
+ {"DELL", "MD3000i"},
{NULL, NULL},
};


--

2008-10-24 04:48:21

by Greg KH

[permalink] [raw]
Subject: [patch 26/27] PCI hotplug: cpqphp: fix kernel NULL pointer dereference

2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Kenji Kaneshige <[email protected]>

commit d2174c3c07adad88dd9ba37a731e0b00b746822a upstream

The following patch fixes the regression in 2.6.27 that causes kernel
NULL pointer dereference at cpqphp driver probe time. This patch should
be backported to the .27 stable series.

Seems to have been introduced by
f46753c5e354b857b20ab8e0fe7b2579831dc369.

The root cause of this problem seems that cpqphp driver calls
pci_hp_register() wrongly. In current implementation, cpqphp driver
passes 'ctrl->pci_dev->subordinate' as a second parameter for
pci_hp_register(). But because hotplug slots and it's hotplug controller
(exists as a pci funcion) are on the same bus, it should be
'ctrl->pci_dev->bus' instead.

Tested-by: Ingo Molnar <[email protected]>
Signed-off-by: Kenji Kaneshige <[email protected]>
Signed-off-by: Jesse Barnes <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/pci/hotplug/cpqphp_core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/pci/hotplug/cpqphp_core.c
+++ b/drivers/pci/hotplug/cpqphp_core.c
@@ -435,7 +435,7 @@ static int ctrl_slot_setup(struct contro
slot->number, ctrl->slot_device_offset,
slot_number);
result = pci_hp_register(hotplug_slot,
- ctrl->pci_dev->subordinate,
+ ctrl->pci_dev->bus,
slot->device);
if (result) {
err("pci_hp_register failed with error %d\n", result);

--

2008-10-24 04:48:54

by Greg KH

[permalink] [raw]
Subject: [patch 21/27] ACPI Suspend: Enable ACPI during resume if SCI_EN is not set

2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Rafael J. Wysocki <[email protected]>

commit d0c71fe7ebc180f1b7bc7da1d39a07fc19eec768 upstream.

On some machines, like for example MSI Wind U100, the BIOS doesn't
enable ACPI before returning control to the OS, which sometimes
causes resume to fail. This is against the ACPI specification,
which clearly states that "When the platform is waking from an S1, S2
or S3 state, OSPM assumes the hardware is already in the ACPI mode
and will not issue an ACPI_ENABLE", but it won't hurt to check the
SCI_EN bit and enable ACPI during resume from S3 if this bit is not
set.

Fortunately, we already have acpi_enable() for that, so use it in the
resume code path, before executing _BFS, in analogy with the
resume-from-hibernation code path.

NOTE: We aren't supposed to set SCI_EN directly, because it's owned
by the hardware.

Signed-off-by: Rafael J. Wysocki <[email protected]>
Acked-by: Pavel Machek <[email protected]>
Signed-off-by: Len Brown <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/acpi/sleep/main.c | 2 ++
1 file changed, 2 insertions(+)

--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -200,6 +200,8 @@ static int acpi_suspend_enter(suspend_st
break;
}

+ /* If ACPI is not enabled by the BIOS, we need to enable it here. */
+ acpi_enable();
/* Reprogram control registers and execute _BFS */
acpi_leave_sleep_state_prep(acpi_state);


--

2008-10-24 04:48:38

by Greg KH

[permalink] [raw]
Subject: [patch 27/27] ath5k: fix suspend-related oops on rmmod

2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Bob Copeland <[email protected]>

commit 8bdd5b9c6bd53add260756b6673a0545fbdbba21 upstream

Based on a patch by Elias Oltmanns, we call ath5k_init in resume even
if we didn't previously open the device. Besides starting up the
device unnecessarily, this also causes an oops on rmmod because
mac80211 will not invoke ath5k_stop and softirqs are left running after
the module has been unloaded. Add a new state bit, ATH_STAT_STARTED,
to indicate that we have been started up.

Reported-by: Toralf F?rster <[email protected]>
Signed-off-by: Elias Oltmanns <[email protected]>
Signed-off-by: Bob Copeland <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/net/wireless/ath5k/base.c | 28 ++++++++++++++++++++--------
drivers/net/wireless/ath5k/base.h | 3 ++-
2 files changed, 22 insertions(+), 9 deletions(-)

--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -294,9 +294,9 @@ static inline u64 ath5k_extend_tsf(struc
}

/* Interrupt handling */
-static int ath5k_init(struct ath5k_softc *sc);
+static int ath5k_init(struct ath5k_softc *sc, bool is_resume);
static int ath5k_stop_locked(struct ath5k_softc *sc);
-static int ath5k_stop_hw(struct ath5k_softc *sc);
+static int ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend);
static irqreturn_t ath5k_intr(int irq, void *dev_id);
static void ath5k_tasklet_reset(unsigned long data);

@@ -584,7 +584,7 @@ ath5k_pci_suspend(struct pci_dev *pdev,

ath5k_led_off(sc);

- ath5k_stop_hw(sc);
+ ath5k_stop_hw(sc, true);

free_irq(pdev->irq, sc);
pci_save_state(pdev);
@@ -621,7 +621,7 @@ ath5k_pci_resume(struct pci_dev *pdev)
goto err_no_irq;
}

- err = ath5k_init(sc);
+ err = ath5k_init(sc, true);
if (err)
goto err_irq;
ath5k_led_enable(sc);
@@ -2197,12 +2197,17 @@ ath5k_beacon_config(struct ath5k_softc *
\********************/

static int
-ath5k_init(struct ath5k_softc *sc)
+ath5k_init(struct ath5k_softc *sc, bool is_resume)
{
int ret;

mutex_lock(&sc->lock);

+ if (is_resume && !test_bit(ATH_STAT_STARTED, sc->status))
+ goto out_ok;
+
+ __clear_bit(ATH_STAT_STARTED, sc->status);
+
ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode);

/*
@@ -2250,12 +2255,16 @@ ath5k_init(struct ath5k_softc *sc)
AR5K_INT_MIB;

ath5k_hw_set_intr(sc->ah, sc->imask);
+
+ __set_bit(ATH_STAT_STARTED, sc->status);
+
/* Set ack to be sent at low bit-rates */
ath5k_hw_set_ack_bitrate_high(sc->ah, false);

mod_timer(&sc->calib_tim, round_jiffies(jiffies +
msecs_to_jiffies(ath5k_calinterval * 1000)));

+out_ok:
ret = 0;
done:
mmiowb();
@@ -2310,7 +2319,7 @@ ath5k_stop_locked(struct ath5k_softc *sc
* stop is preempted).
*/
static int
-ath5k_stop_hw(struct ath5k_softc *sc)
+ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend)
{
int ret;

@@ -2341,6 +2350,9 @@ ath5k_stop_hw(struct ath5k_softc *sc)
}
}
ath5k_txbuf_free(sc, sc->bbuf);
+ if (!is_suspend)
+ __clear_bit(ATH_STAT_STARTED, sc->status);
+
mmiowb();
mutex_unlock(&sc->lock);

@@ -2719,12 +2731,12 @@ err:

static int ath5k_start(struct ieee80211_hw *hw)
{
- return ath5k_init(hw->priv);
+ return ath5k_init(hw->priv, false);
}

static void ath5k_stop(struct ieee80211_hw *hw)
{
- ath5k_stop_hw(hw->priv);
+ ath5k_stop_hw(hw->priv, false);
}

static int ath5k_add_interface(struct ieee80211_hw *hw,
--- a/drivers/net/wireless/ath5k/base.h
+++ b/drivers/net/wireless/ath5k/base.h
@@ -132,11 +132,12 @@ struct ath5k_softc {
size_t desc_len; /* size of TX/RX descriptors */
u16 cachelsz; /* cache line size */

- DECLARE_BITMAP(status, 4);
+ DECLARE_BITMAP(status, 5);
#define ATH_STAT_INVALID 0 /* disable hardware accesses */
#define ATH_STAT_MRRETRY 1 /* multi-rate retry support */
#define ATH_STAT_PROMISC 2
#define ATH_STAT_LEDSOFT 3 /* enable LED gpio status */
+#define ATH_STAT_STARTED 4 /* opened & irqs enabled */

unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */
unsigned int curmode; /* current phy mode */

--

2008-10-24 04:49:25

by Greg KH

[permalink] [raw]
Subject: [patch 20/27] hvc_console: Fix free_irq in spinlocked section

2.6.27-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Christian Borntraeger <[email protected]>

commit eef2622a9fcfa964073333ea72c7c9cd20ad45e6 upstream

hvc_console: Fix free_irq in spinlocked section

commit 611e097d7707741a336a0677d9d69bec40f29f3d
Author: Christian Borntraeger <[email protected]>
hvc_console: rework setup to replace irq functions with callbacks
introduced a spinlock recursion problem. The notifier_del is
called with a lock held, and in turns calls free_irq which then
complains when manipulating procfs. This fixes it by moving the
call to the notifier to outside of the locked section.

Signed-off-by: Christian Borntraeger<[email protected]>
Signed-off-by: Benjamin Herrenschmidt <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/char/hvc_console.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)

--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -367,13 +367,13 @@ static void hvc_close(struct tty_struct
spin_lock_irqsave(&hp->lock, flags);

if (--hp->count == 0) {
- if (hp->ops->notifier_del)
- hp->ops->notifier_del(hp, hp->data);
-
/* We are done with the tty pointer now. */
hp->tty = NULL;
spin_unlock_irqrestore(&hp->lock, flags);

+ if (hp->ops->notifier_del)
+ hp->ops->notifier_del(hp, hp->data);
+
/*
* Chain calls chars_in_buffer() and returns immediately if
* there is no buffered data otherwise sleeps on a wait queue
@@ -416,11 +416,11 @@ static void hvc_hangup(struct tty_struct
hp->n_outbuf = 0;
hp->tty = NULL;

+ spin_unlock_irqrestore(&hp->lock, flags);
+
if (hp->ops->notifier_del)
hp->ops->notifier_del(hp, hp->data);

- spin_unlock_irqrestore(&hp->lock, flags);
-
while(temp_open_count) {
--temp_open_count;
kref_put(&hp->kref, destroy_hvc_struct);

--

2008-10-24 05:39:10

by Greg KH

[permalink] [raw]
Subject: Re: [patch 11/27] dm exception store: refactor zero_area

On Thu, Oct 23, 2008 at 09:34:23PM -0700, Greg KH wrote:
> 2.6.27-stable review patch. If anyone has any objections, please let us
> know.
>
> ------------------
> From: Alasdair G Kergon <[email protected]>
>
> commit 7c9e6c17325fab380fbe9c9787680ff7d4a51abd upstream
>
> Use a separate buffer for writing zeroes to the on-disk snapshot
> exception store, make the updating of ps->current_area explicit and
> refactor the code in preparation for the fix in the next patch.
>
> No functional change.
>
> Signed-off-by: Alasdair G Kergon <[email protected]>
> Signed-off-by: Mikulas Patocka <[email protected]>
> Signed-off-by: Greg Kroah-Hartman <[email protected]>
>
> ---
> drivers/md/dm-exception-store.c | 103 ++++++++++++++++++++++++++--------------
> 1 file changed, 69 insertions(+), 34 deletions(-)

Oops, this patch causes a build error:

drivers/md/dm-exception-store.c:235: error: implicit declaration of function 'area_location'
drivers/md/dm-exception-store.c:241: error: 'area' undeclared (first use in this function)
drivers/md/dm-exception-store.c:241: error: (Each undeclared identifier is reported only once
drivers/md/dm-exception-store.c:241: error: for each function it appears in.)

I'll drop this one, and the follow-on dm-exception-store.c patch as
well, as that was the only reason this patch was added.

If you want to redo these two patches, and get them into the
2.6.27-stable tree, please do so and send them to [email protected].

thanks,

greg k-h

2008-10-24 05:43:47

by Greg KH

[permalink] [raw]
Subject: Re: [patch 00/27] 2.6.27.4-stable review

On Thu, Oct 23, 2008 at 09:33:03PM -0700, Greg KH wrote:
> The whole patch series can be found in one patch at:
> kernel.org/pub/linux/kernel/v2.6/stable-review/patch-2.6.27.4-rc1.gz
> and the diffstat can be found below.

There was a build error in this release, so I've now put up a -rc2
version at:
kernel.org/pub/linux/kernel/v2.6/stable-review/patch-2.6.27.4-rc2.gz

and the diffstat is below.

thanks,

greg k-h

Makefile | 2
arch/x86/kernel/acpi/sleep.c | 3 +
arch/x86/kernel/amd_iommu_init.c | 2
drivers/acpi/hardware/hwsleep.c | 37 ++++-----------
drivers/acpi/sleep/main.c | 10 ++++
drivers/char/hvc_console.c | 10 ++--
drivers/edac/cell_edac.c | 2
drivers/gpio/gpiolib.c | 2
drivers/md/dm-kcopyd.c | 13 +++++
drivers/md/dm-snap.c | 10 +---
drivers/net/wireless/ath5k/base.c | 28 ++++++++---
drivers/net/wireless/ath5k/base.h | 3 -
drivers/pci/hotplug/cpqphp_core.c | 2
drivers/scsi/device_handler/scsi_dh_rdac.c | 2
drivers/usb/atm/speedtch.c | 12 +++++
drivers/usb/class/cdc-acm.c | 3 -
drivers/usb/class/cdc-wdm.c | 2
drivers/usb/core/driver.c | 3 -
drivers/usb/core/hub.c | 2
fs/cifs/readdir.c | 3 -
fs/ext2/dir.c | 60 ++++++++++++++-----------
fs/ext3/dir.c | 10 ++--
fs/ext4/dir.c | 11 +++-
fs/proc/task_mmu.c | 34 +++++++++-----
kernel/sched_stats.h | 2
mm/rmap.c | 42 +++++++++++++----
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 2
net/ipv4/netfilter/nf_nat_snmp_basic.c | 1
net/netfilter/xt_iprange.c | 8 +--
29 files changed, 206 insertions(+), 115 deletions(-)

2008-10-24 20:36:57

by Elias Oltmanns

[permalink] [raw]
Subject: Re: [patch 27/27] ath5k: fix suspend-related oops on rmmod

Greg KH <[email protected]> wrote:
> 2.6.27-stable review patch. If anyone has any objections, please let us
> know.
>
> ------------------
> From: Bob Copeland <[email protected]>
>
> commit 8bdd5b9c6bd53add260756b6673a0545fbdbba21 upstream
>
> Based on a patch by Elias Oltmanns, we call ath5k_init in resume even
> if we didn't previously open the device. Besides starting up the
> device unnecessarily, this also causes an oops on rmmod because
> mac80211 will not invoke ath5k_stop and softirqs are left running after
> the module has been unloaded. Add a new state bit, ATH_STAT_STARTED,
> to indicate that we have been started up.
>
> Reported-by: Toralf F?rster <[email protected]>
> Signed-off-by: Elias Oltmanns <[email protected]>
> Signed-off-by: Bob Copeland <[email protected]>
> Signed-off-by: John W. Linville <[email protected]>
> Signed-off-by: Greg Kroah-Hartman <[email protected]>

I've done some more testing and I'm ashamed to say that this patch is
incomplete and does indeed introduce a regression itself. Having only
just sent the fix to John, I'm afraid this patch has to be deferred for
the next stable release since the required fix is not likely to hit
Linus' tree in time. Anyway, I'm adding my patch and the changelog entry
by way of explanation.

Regards,

Elias

From: Elias Oltmanns <[email protected]>
Subject: [PATCH] ath5k: Reset key cache on interface up, thus fixing resume

After a s2ram / resume cycle, resetting the key cache does not work
unless it is deferred until after the hardware has been reinitialised by
a call to ath5k_hw_reset(). This fixes a regression introduced in commit
8bdd5b9c6bd53add260756b6673a0545fbdbba21 (ath5k: fix suspend-related
oops on rmmod).

Signed-off-by: Elias Oltmanns <[email protected]>
---

base.c | 29 ++++++++++-------------------
1 file changed, 10 insertions(+), 19 deletions(-)

diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index 0f1d6bd..8acf0ce 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -688,16 +688,6 @@ ath5k_pci_resume(struct pci_dev *pdev)
goto err_irq;
ath5k_led_enable(sc);

- /*
- * Reset the key cache since some parts do not
- * reset the contents on initial power up or resume.
- *
- * FIXME: This may need to be revisited when mac80211 becomes
- * aware of suspend/resume.
- */
- for (i = 0; i < AR5K_KEYTABLE_SIZE; i++)
- ath5k_hw_reset_key(ah, i);
-
return 0;
err_irq:
free_irq(pdev->irq, sc);
@@ -737,13 +727,6 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
__set_bit(ATH_STAT_MRRETRY, sc->status);

/*
- * Reset the key cache since some parts do not
- * reset the contents on initial power up.
- */
- for (i = 0; i < AR5K_KEYTABLE_SIZE; i++)
- ath5k_hw_reset_key(ah, i);
-
- /*
* Collect the channel list. The 802.11 layer
* is resposible for filtering this list based
* on settings like the phy mode and regulatory
@@ -2202,7 +2185,8 @@ ath5k_beacon_config(struct ath5k_softc *sc)
static int
ath5k_init(struct ath5k_softc *sc, bool is_resume)
{
- int ret;
+ struct ath5k_hw *ah = sc->ah;
+ int ret, i;

mutex_lock(&sc->lock);

@@ -2235,10 +2219,17 @@ ath5k_init(struct ath5k_softc *sc, bool is_resume)
if (ret)
goto done;

+ /*
+ * Reset the key cache since some parts do not reset the
+ * contents on initial power up or resume from suspend.
+ */
+ for (i = 0; i < AR5K_KEYTABLE_SIZE; i++)
+ ath5k_hw_reset_key(ah, i);
+
__set_bit(ATH_STAT_STARTED, sc->status);

/* Set ack to be sent at low bit-rates */
- ath5k_hw_set_ack_bitrate_high(sc->ah, false);
+ ath5k_hw_set_ack_bitrate_high(ah, false);

mod_timer(&sc->calib_tim, round_jiffies(jiffies +
msecs_to_jiffies(ath5k_calinterval * 1000)));

2008-10-24 21:10:56

by Bob Copeland

[permalink] [raw]
Subject: Re: [patch 27/27] ath5k: fix suspend-related oops on rmmod

On Fri, 24 Oct 2008 22:36:24 +0200, Elias Oltmanns wrote
> I've done some more testing and I'm ashamed to say that this patch is
> incomplete and does indeed introduce a regression itself. Having only
> just sent the fix to John, I'm afraid this patch has to be deferred for
> the next stable release since the required fix is not likely to hit
> Linus' tree in time.

Yeah, let's drop the patch from stable since it resets the key cache
even in the not-opened resume case.

Note, ath5k_set_key is a no-op right now so we can just elide that
whole section of code.

--
Bob Copeland %% http://www.bobcopeland.com

2008-10-24 21:34:08

by Greg KH

[permalink] [raw]
Subject: Re: [patch 27/27] ath5k: fix suspend-related oops on rmmod

On Fri, Oct 24, 2008 at 10:36:24PM +0200, Elias Oltmanns wrote:
> Greg KH <[email protected]> wrote:
> > 2.6.27-stable review patch. If anyone has any objections, please let us
> > know.
> >
> > ------------------
> > From: Bob Copeland <[email protected]>
> >
> > commit 8bdd5b9c6bd53add260756b6673a0545fbdbba21 upstream
> >
> > Based on a patch by Elias Oltmanns, we call ath5k_init in resume even
> > if we didn't previously open the device. Besides starting up the
> > device unnecessarily, this also causes an oops on rmmod because
> > mac80211 will not invoke ath5k_stop and softirqs are left running after
> > the module has been unloaded. Add a new state bit, ATH_STAT_STARTED,
> > to indicate that we have been started up.
> >
> > Reported-by: Toralf F?rster <[email protected]>
> > Signed-off-by: Elias Oltmanns <[email protected]>
> > Signed-off-by: Bob Copeland <[email protected]>
> > Signed-off-by: John W. Linville <[email protected]>
> > Signed-off-by: Greg Kroah-Hartman <[email protected]>
>
> I've done some more testing and I'm ashamed to say that this patch is
> incomplete and does indeed introduce a regression itself. Having only
> just sent the fix to John, I'm afraid this patch has to be deferred for
> the next stable release since the required fix is not likely to hit
> Linus' tree in time. Anyway, I'm adding my patch and the changelog entry
> by way of explanation.

Ok, I've dropped this from the 2.6.27-stable queue now, thanks for
letting me know.

greg k-h

2008-10-24 21:44:27

by Greg KH

[permalink] [raw]
Subject: Re: [stable] [patch 00/27] 2.6.27.4-stable review

On Thu, Oct 23, 2008 at 10:41:11PM -0700, Greg KH wrote:
> On Thu, Oct 23, 2008 at 09:33:03PM -0700, Greg KH wrote:
> > The whole patch series can be found in one patch at:
> > kernel.org/pub/linux/kernel/v2.6/stable-review/patch-2.6.27.4-rc1.gz
> > and the diffstat can be found below.
>
> There was a build error in this release, so I've now put up a -rc2
> version at:
> kernel.org/pub/linux/kernel/v2.6/stable-review/patch-2.6.27.4-rc2.gz

And there was an error in this release as well, the ath5k patch was
dropped as it was found to cause regressions itself.

Also a pvrusb2 patch was added to let the device work again with the
2.6.27 kernel, which is always a nice thing to have. I'll follow up
this message with that patch.

I've now put up a -rc3 version at:
kernel.org/pub/linux/kernel/v2.6/stable-review/patch-2.6.27.4-rc3.gz

and the diffstat is below.

thanks,

greg k-h

Makefile | 2
arch/x86/kernel/acpi/sleep.c | 3 +
arch/x86/kernel/amd_iommu_init.c | 2
drivers/acpi/hardware/hwsleep.c | 37 ++++-----------
drivers/acpi/sleep/main.c | 10 ++++
drivers/char/hvc_console.c | 10 ++--
drivers/edac/cell_edac.c | 2
drivers/gpio/gpiolib.c | 2
drivers/md/dm-kcopyd.c | 13 +++++
drivers/md/dm-snap.c | 10 +---
drivers/media/video/pvrusb2/pvrusb2-hdw.c | 6 --
drivers/pci/hotplug/cpqphp_core.c | 2
drivers/scsi/device_handler/scsi_dh_rdac.c | 2
drivers/usb/atm/speedtch.c | 12 +++++
drivers/usb/class/cdc-acm.c | 3 -
drivers/usb/class/cdc-wdm.c | 2
drivers/usb/core/driver.c | 3 -
drivers/usb/core/hub.c | 2
fs/cifs/readdir.c | 3 -
fs/ext2/dir.c | 60 ++++++++++++++-----------
fs/ext3/dir.c | 10 ++--
fs/ext4/dir.c | 11 +++-
fs/proc/task_mmu.c | 34 +++++++++-----
kernel/sched_stats.h | 2
mm/rmap.c | 42 +++++++++++++----
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 2
net/ipv4/netfilter/nf_nat_snmp_basic.c | 1
net/netfilter/xt_iprange.c | 8 +--
28 files changed, 184 insertions(+), 112 deletions(-)

2008-10-24 21:44:42

by Greg KH

[permalink] [raw]
Subject: [patch 28/27] V4L/DVB (9300): pvrusb2: Fix deadlock problem

2.6.27-stable patch

---------------------

From: Mike Isely <[email protected]>

commit c82732a42896364296599b0f73f01c5e3fd781ae upstream

Fix deadlock problem in 2.6.27 caused by new USB core behavior in
response to a USB device reset request. With older kernels, the USB
device reset was "in line"; the reset simply took place and the driver
retained its association with the hardware. However now this reset
triggers a disconnect, and worse still the disconnect callback happens
in the context of the caller who asked for the device reset. This
results in an attempt by the pvrusb2 driver to recursively take a
mutex it already has, which deadlocks the driver's worker thread.
(Even if the disconnect callback were to happen on a different thread
we'd still have problems however - because while the driver should
survive and correctly disconnect / reconnect, it will then trigger
another device reset during the repeated initialization, which will
then cause another disconect, etc, forever.) The fix here is simply
to not attempt the device reset (it was of marginal value anyway).

Signed-off-by: Mike Isely <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/media/video/pvrusb2/pvrusb2-hdw.c | 6 ------
1 file changed, 6 deletions(-)

--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -60,7 +60,6 @@ static struct pvr2_hdw *unit_pointers[PV
static DEFINE_MUTEX(pvr2_unit_mtx);

static int ctlchg;
-static int initusbreset = 1;
static int procreload;
static int tuner[PVR_NUM] = { [0 ... PVR_NUM-1] = -1 };
static int tolerance[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 };
@@ -71,8 +70,6 @@ module_param(ctlchg, int, S_IRUGO|S_IWUS
MODULE_PARM_DESC(ctlchg, "0=optimize ctl change 1=always accept new ctl value");
module_param(init_pause_msec, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(init_pause_msec, "hardware initialization settling delay");
-module_param(initusbreset, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(initusbreset, "Do USB reset device on probe");
module_param(procreload, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(procreload,
"Attempt init failure recovery with firmware reload");
@@ -1698,9 +1695,6 @@ static void pvr2_hdw_setup_low(struct pv
}
hdw->fw1_state = FW1_STATE_OK;

- if (initusbreset) {
- pvr2_hdw_device_reset(hdw);
- }
if (!pvr2_hdw_dev_ok(hdw)) return;

for (idx = 0; idx < hdw->hdw_desc->client_modules.cnt; idx++) {

2008-10-25 01:40:28

by Mikulas Patocka

[permalink] [raw]
Subject: Re: [patch 11/27] dm exception store: refactor zero_area



On Thu, 23 Oct 2008, Greg KH wrote:

> On Thu, Oct 23, 2008 at 09:34:23PM -0700, Greg KH wrote:
> > 2.6.27-stable review patch. If anyone has any objections, please let us
> > know.
> >
> > ------------------
> > From: Alasdair G Kergon <[email protected]>
> >
> > commit 7c9e6c17325fab380fbe9c9787680ff7d4a51abd upstream
> >
> > Use a separate buffer for writing zeroes to the on-disk snapshot
> > exception store, make the updating of ps->current_area explicit and
> > refactor the code in preparation for the fix in the next patch.
> >
> > No functional change.
> >
> > Signed-off-by: Alasdair G Kergon <[email protected]>
> > Signed-off-by: Mikulas Patocka <[email protected]>
> > Signed-off-by: Greg Kroah-Hartman <[email protected]>
> >
> > ---
> > drivers/md/dm-exception-store.c | 103 ++++++++++++++++++++++++++--------------
> > 1 file changed, 69 insertions(+), 34 deletions(-)
>
> Oops, this patch causes a build error:
>
> drivers/md/dm-exception-store.c:235: error: implicit declaration of function 'area_location'
> drivers/md/dm-exception-store.c:241: error: 'area' undeclared (first use in this function)
> drivers/md/dm-exception-store.c:241: error: (Each undeclared identifier is reported only once
> drivers/md/dm-exception-store.c:241: error: for each function it appears in.)
>
> I'll drop this one, and the follow-on dm-exception-store.c patch as
> well, as that was the only reason this patch was added.
>
> If you want to redo these two patches, and get them into the
> 2.6.27-stable tree, please do so and send them to [email protected].
>
> thanks,
>
> greg k-h

You should apply this one patch before:
ftp://ftp.kernel.org/pub/linux/kernel/people/agk/patches/2.6/editing/dm-exception-store-introduce-area_location-function.patch

Mikulas

2008-10-25 20:48:57

by Greg KH

[permalink] [raw]
Subject: Re: [patch 11/27] dm exception store: refactor zero_area

On Fri, Oct 24, 2008 at 09:40:04PM -0400, Mikulas Patocka wrote:
>
>
> On Thu, 23 Oct 2008, Greg KH wrote:
>
> > On Thu, Oct 23, 2008 at 09:34:23PM -0700, Greg KH wrote:
> > > 2.6.27-stable review patch. If anyone has any objections, please let us
> > > know.
> > >
> > > ------------------
> > > From: Alasdair G Kergon <[email protected]>
> > >
> > > commit 7c9e6c17325fab380fbe9c9787680ff7d4a51abd upstream
> > >
> > > Use a separate buffer for writing zeroes to the on-disk snapshot
> > > exception store, make the updating of ps->current_area explicit and
> > > refactor the code in preparation for the fix in the next patch.
> > >
> > > No functional change.
> > >
> > > Signed-off-by: Alasdair G Kergon <[email protected]>
> > > Signed-off-by: Mikulas Patocka <[email protected]>
> > > Signed-off-by: Greg Kroah-Hartman <[email protected]>
> > >
> > > ---
> > > drivers/md/dm-exception-store.c | 103 ++++++++++++++++++++++++++--------------
> > > 1 file changed, 69 insertions(+), 34 deletions(-)
> >
> > Oops, this patch causes a build error:
> >
> > drivers/md/dm-exception-store.c:235: error: implicit declaration of function 'area_location'
> > drivers/md/dm-exception-store.c:241: error: 'area' undeclared (first use in this function)
> > drivers/md/dm-exception-store.c:241: error: (Each undeclared identifier is reported only once
> > drivers/md/dm-exception-store.c:241: error: for each function it appears in.)
> >
> > I'll drop this one, and the follow-on dm-exception-store.c patch as
> > well, as that was the only reason this patch was added.
> >
> > If you want to redo these two patches, and get them into the
> > 2.6.27-stable tree, please do so and send them to [email protected].
> >
> > thanks,
> >
> > greg k-h
>
> You should apply this one patch before:
> ftp://ftp.kernel.org/pub/linux/kernel/people/agk/patches/2.6/editing/dm-exception-store-introduce-area_location-function.patch

Hm, so we need 2 "cleanup" patches to get one tiny fix in a third patch?
Is it worth it? If so, care to resend these three to [email protected]
or possibly, just backport what you really need in the third one, with
the needed first 2 patches merged into it in one patch to get it all in
a simpler way?

thanks,

greg k-h