2.6.27-stable review
Subsystems (24)
cover 2.6.27-stable review
This is the start of the stable review cycle for the 2.6.27.13 release. There are 40 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, January 25, 00: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.13-rc1.gz
and the diffstat can be found below.
thanks,
greg k-h
Documentation/sound/alsa/ALSA-Configuration.txt | 3 +- Makefile | 2 +- arch/ia64/Kconfig | 1 + arch/powerpc/mm/slice.c | 11 ++- drivers/firmware/dell_rbu.c | 4 +- drivers/hwmon/abituguru3.c | 2 +- drivers/hwmon/hwmon-vid.c | 1 + drivers/misc/sgi-xp/xpc_sn2.c | 2 +- drivers/net/irda/irda-usb.c | 2 +- drivers/net/r6040.c | 17 ++- drivers/net/wireless/ath9k/hw.c | 2 +- drivers/net/wireless/p54/p54usb.c | 1 + drivers/net/wireless/rt2x00/rt73usb.c | 1 + drivers/pci/pcie/aspm.c | 125 +++++++++++++++++++---- drivers/usb/storage/libusual.c | 7 ++ drivers/usb/storage/scsiglue.c | 31 ++++++ drivers/usb/storage/transport.c | 80 +++++++++++++++ drivers/usb/storage/unusual_devs.h | 80 +++------------ drivers/usb/storage/usb.c | 6 + drivers/usb/storage/usb.h | 4 + fs/fs-writeback.c | 92 ++++++++++------- fs/sync.c | 2 +- include/linux/fs.h | 1 - include/linux/usb_usual.h | 5 +- include/linux/writeback.h | 1 - kernel/signal.c | 3 +- kernel/time/timekeeping.c | 71 ++++++------- lib/idr.c | 10 +-- mm/filemap.c | 18 +-- mm/page-writeback.c | 120 ++++++++++++++++------ net/ipv4/tcp.c | 8 +- net/ipv6/ip6_fib.c | 15 ++-- net/sched/cls_u32.c | 3 +- net/sched/sch_htb.c | 1 + net/sctp/sm_statefuns.c | 14 +++ security/keys/keyctl.c | 1 + sound/pci/hda/patch_analog.c | 49 ++++++++- sound/pci/hda/patch_realtek.c | 1 + 38 files changed, 550 insertions(+), 247 deletions(-)
PATCH 1/40 pkt_sched: sch_htb: Fix deadlock in hrtimers triggered by HTB
2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jarek Poplawski <[email protected]>
[ Upstream commit: none
This is a quick fix for -stable purposes. Upstream fixes these problems via a large set of invasive hrtimer changes. ]
Most probably there is a (still unproven) race in hrtimers (before 2.6.29 kernels), which causes a corruption of hrtimers rbtree. This patch doesn't fix it, but should let HTB avoid triggering the bug.
--- net/sched/sch_htb.c | 1 + 1 file changed, 1 insertion(+)
net/sched/sch_htb.c +1 -0
@@ -924,6 +924,7 @@ static struct sk_buff *htb_dequeue(struc } } sch->qstats.overlimits++; +qdisc_watchdog_cancel (&q->watchdog);qdisc_watchdog_schedule (&q->watchdog, next_event); fin:return skb;
PATCH 2/40 ipv6: Fix fib6_dump_table walker leak
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Herbert Xu <[email protected]>
[ Upstream commit: 7891cc818967e186be68caac32d84bfd0a3f0bd2 ]
When a fib6 table dump is prematurely ended, we won't unlink its walker from the list. This causes all sorts of grief for other users of the list later.
--- net/ipv6/ip6_fib.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
net/ipv6/ip6_fib.c +8 -7
@@ -298,6 +298,10 @@ static void fib6_dump_end(struct netlinkstruct fib6_walker_t *w = (void *)cb->args[2 ];if (w) { +if (cb->args[4 ]) { + cb->args[4 ] =0 ; +fib6_walker_unlink (w); + } cb->args[2 ] =0 ;kfree (w); }
@@ -330,15 +334,12 @@ static int fib6_dump_table(struct fib6_tread_lock_bh (&table->tb6_lock); res =fib6_walk_continue (w);read_unlock_bh (&table->tb6_lock); -if (res !=0 ) { -if (res <0 ) -fib6_walker_unlink (w); - goto end; +if (res <=0 ) { +fib6_walker_unlink (w); + cb->args[4 ] =0 ; } -fib6_walker_unlink (w); - cb->args[4 ] =0 ; } -end: +return res; }
PATCH 3/40 sctp: Avoid memory overflow while FWD-TSN chunk is received with bad stream ID
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Wei Yongjun <[email protected]>
[ Upstream commit: 9fcb95a105758b81ef0131cd18e2db5149f13e95 ]
If FWD-TSN chunk is received with bad stream ID, the sctp will not do the validity check, this may cause memory overflow when overwrite the TSN of the stream ID.
The FORWARD-TSN chunk is like this:
FORWARD-TSN chunk
Type = 192 Flags = 0 Length = 172 NewTSN = 99 Stream = 10000 StreamSequence = 0xFFFF
This patch fix this problem by discard the chunk if stream ID is not less than MIS.
--- net/sctp/sm_statefuns.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
net/sctp/sm_statefuns.c +14 -0
@@ -3635,6 +3635,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(c {struct sctp_chunk *chunk = arg;struct sctp_fwdtsn_hdr *fwdtsn_hdr; +struct sctp_fwdtsn_skip *skip;__u16 len;__u32 tsn;
@@ -3664,6 +3665,12 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(cif (sctp_tsnmap_check (&asoc->peer.tsn_map, tsn) <0 ) goto discard_noforce; +/* Silently discard the chunk if stream-id is not valid */ + sctp_walk_fwdtsn(skip, chunk) { +if (ntohs (skip->stream) >= asoc->c.sinit_max_instreams) + goto discard_noforce; + } +sctp_add_cmd_sf (commands,SCTP_CMD_REPORT_FWDTSN ,SCTP_U32 (tsn));if (len >sizeof (struct sctp_fwdtsn_hdr )) sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
@@ -3695,6 +3702,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_f {struct sctp_chunk *chunk = arg;struct sctp_fwdtsn_hdr *fwdtsn_hdr; +struct sctp_fwdtsn_skip *skip;__u16 len;__u32 tsn;
@@ -3724,6 +3732,12 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_fif (sctp_tsnmap_check (&asoc->peer.tsn_map, tsn) <0 ) goto gen_shutdown; +/* Silently discard the chunk if stream-id is not valid */ + sctp_walk_fwdtsn(skip, chunk) { +if (ntohs (skip->stream) >= asoc->c.sinit_max_instreams) + goto gen_shutdown; + } +sctp_add_cmd_sf (commands,SCTP_CMD_REPORT_FWDTSN ,SCTP_U32 (tsn));if (len >sizeof (struct sctp_fwdtsn_hdr )) sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
PATCH 4/40 pkt_sched: cls_u32: Fix locking in u32_change()
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jarek Poplawski <[email protected]>
[ Upstream commit: 6f57321422e0d359e83c978c2b03db77b967b7d5 ]
New nodes are inserted in u32_change() under rtnl_lock() with wmb(), so without tcf_tree_lock() like in other classifiers (e.g. cls_fw). This isn't enough without rmb() on the read side, but on the other hand adding such barriers doesn't give any savings, so the lock is added instead.
--- net/sched/cls_u32.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/sched/cls_u32.c +2 -1
@@ -637,8 +637,9 @@ static int u32_change(struct tcf_proto *break ; n->next = *ins; -wmb (); +tcf_tree_lock (tp); *ins = n; +tcf_tree_unlock (tp); *arg = (unsigned long )n;return 0 ;
PATCH 5/40 r6040: fix wrong logic in mdio code
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Joe Chou <[email protected]>
[ Upstream commit: 11e5e8f5d14a1229706576184d2cf4c4556ed94c ]
This patch fixes a reverse logic in the MDIO code.
--- drivers/net/r6040.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/r6040.c +2 -2
@@ -214,7 +214,7 @@ static int r6040_phy_read(void __iomem */* Wait for the read bit to be cleared */ while (limit--) { cmd =ioread16 (ioaddr +MMDIO ); -if (cmd &MDIO_READ ) +if (!(cmd &MDIO_READ ))break ; }
@@ -233,7 +233,7 @@ static void r6040_phy_write(void __iomem/* Wait for the write bit to be cleared */ while (limit--) { cmd =ioread16 (ioaddr +MMDIO ); -if (cmd &MDIO_WRITE ) +if (!(cmd &MDIO_WRITE ))break ; } }
PATCH 6/40 r6040: save and restore MIER correctly in the interrupt routine
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Joe Chou <[email protected]>
[ Upstream commit: 3e7c469f07ff14cbf9a814739e1fc99a863e0943 ]
This patch saves the MIER register contents before treating interrupts, then restores them correcty at the end of the interrupt routine.
--- drivers/net/r6040.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/net/r6040.c +7 -2
@@ -681,8 +681,10 @@ static irqreturn_t r6040_interrupt(int istruct net_device *dev = dev_id;struct r6040_private *lp =netdev_priv (dev);void __iomem *ioaddr = lp->base; -u16 status; +u16 misr, status; +/* Save MIER */ + misr =ioread16 (ioaddr +MIER );/* Mask off RDC MAC interrupt */ iowrite16 (MSK_INT , ioaddr +MIER );/* Read MISR status and clear */
@@ -702,7 +704,7 @@ static irqreturn_t r6040_interrupt(int i dev->stats.rx_fifo_errors++;/* Mask off RX interrupt */ -iowrite16 (ioread16 (ioaddr +MIER ) & ~RX_INTS , ioaddr +MIER ); + misr &= ~RX_INTS ;netif_rx_schedule (dev, &lp->napi); }
@@ -710,6 +712,9 @@ static irqreturn_t r6040_interrupt(int iif (status &TX_INTS )r6040_tx (dev); +/* Restore RDC MAC interrupt */ +iowrite16 (misr, ioaddr +MIER ); +return IRQ_HANDLED ; }
PATCH 7/40 r6040: bump release number to 0.19
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Florian Fainelli <[email protected]>
[ Upstream commit: 4707470ae7441733822efcd680b0ef3971921c4d ]
This patch bumps the release number of the driver.
--- drivers/net/r6040.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/r6040.c +2 -2
@@ -49,8 +49,8 @@#include <asm/processor.h> #define DRV_NAME "r6040" -#define DRV_VERSION "0.18" -#define DRV_RELDATE "13Jul2008" +#define DRV_VERSION "0.19" +#define DRV_RELDATE "18Dec2008"/* PHY CHIP Address */ #define PHY1_ADDR 1/* For MAC1 */
PATCH 8/40 tcp: dont mask EOF and socket errors on nonblocking splice receive
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Lennert Buytenhek <[email protected]>
[ Upstream commit: 4f7d54f59bc470f0aaa932f747a95232d7ebf8b1 ]
Currently, setting SPLICE_F_NONBLOCK on splice from a TCP socket results in masking of EOF (RDHUP) and error conditions on the socket by an -EAGAIN return. Move the NONBLOCK check in tcp_splice_read() to be after the EOF and error checks to fix this.
--- net/ipv4/tcp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
net/ipv4/tcp.c +4 -4
@@ -576,10 +576,6 @@ ssize_t tcp_splice_read(struct socket *selse if (!ret) {if (spliced)break ; -if (flags &SPLICE_F_NONBLOCK ) { - ret = -EAGAIN ; -break ; - }if (sock_flag (sk,SOCK_DONE ))break ;if (sk->sk_err) {
@@ -597,6 +593,10 @@ ssize_t tcp_splice_read(struct socket *s ret = -ENOTCONN ;break ; } +if (flags &SPLICE_F_NONBLOCK ) { + ret = -EAGAIN ; +break ; + }if (!timeo) { ret = -EAGAIN ;break ;
PATCH 9/40 usb-storage: add last-sector hacks
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Alan Stern <[email protected]>
commit 25ff1c316f6a763f1eefe7f8984b2d8c03888432 upstream.
This patch (as1189d) adds some hacks to usb-storage for dealing with the growing problems involving bad capacity values and last-sector accesses:
A new flag, US_FL_CAPACITY_OK, is created to indicate that the device is known to report its capacity correctly. An unusual_devs entry for Linux's own File-backed Storage Gadget is added with this flag set, since g_file_storage always reports the correct capacity and since the capacity need not be even (it is determined by the size of the backing file).
An entry in unusual_devs.h which has only the CAPACITY_OK flag set shouldn't prejudice libusual, since the device will work perfectly well with either usb-storage or ub. So a new macro, COMPLIANT_DEV, is added to let libusual know about these entries.
When a last-sector access fails three times in a row and neither the FIX_CAPACITY nor the CAPACITY_OK flag is set, we assume the last-sector bug is present. We replace the existing status and sense data with values that will cause the SCSI core to fail the access immediately rather than retry indefinitely. This should fix the difficulties people have been having with Nokia phones.
This version of the patch differs from the version accepted into the mainline only in that it does not trigger a WARN() when an odd-numbered last-sector access succeeds. In a stable kernel series we don't want to go around spamming users' logs and consoles for no good reason.
--- drivers/usb/storage/libusual.c | 7 +++ drivers/usb/storage/scsiglue.c | 8 +++ drivers/usb/storage/transport.c | 80 +++++++++++++++++++++++++++++++++++++ drivers/usb/storage/unusual_devs.h | 16 ++++++- drivers/usb/storage/usb.c | 6 ++ drivers/usb/storage/usb.h | 4 + include/linux/usb_usual.h | 5 +- 7 files changed, 123 insertions(+), 3 deletions(-)
drivers/usb/storage/libusual.c +7 -0
@@ -46,6 +46,12 @@ static int usu_probe_thread(void *arg); { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } +#define COMPLIANT_DEV (id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ + vendorName, productName, useProtocol, useTransport, \ + initFunction, flags) \ +{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ + .driver_info = (flags) } +#define USUAL_DEV (useProto, useTrans, useType) \ { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \ .driver_info = ((useType)<<24) }
@@ -57,6 +63,7 @@ struct usb_device_id storage_usb_ids []#undef USUAL_DEV#undef UNUSUAL_DEV +#undef COMPLIANT_DEVMODULE_DEVICE_TABLE (usb, storage_usb_ids);EXPORT_SYMBOL_GPL (storage_usb_ids);
drivers/usb/storage/scsiglue.c +8 -0
@@ -196,6 +196,14 @@ static int slave_configure(struct scsi_d* sector in a larger then 1 sector read, since the performance * impact is negible we set this flag for all USB disks */ sdev->last_sector_bug =1 ; + +/* Enable last-sector hacks for single-target devices using +* the Bulk-only transport, unless we already know the +* capacity will be decremented or is correct. */ +if (!(us->fflags & (US_FL_FIX_CAPACITY |US_FL_CAPACITY_OK | +US_FL_SCM_MULT_TARG )) && + us->protocol ==US_PR_BULK ) + us->use_last_sector_hacks =1 ; }else {/* Non-disk-type devices don't need to blacklist any pages
drivers/usb/storage/transport.c +80 -0
110 lines not on this page · raw message
drivers/usb/storage/unusual_devs.h +15 -1
@@ -27,7 +27,8 @@/* IMPORTANT NOTE: This file must be included in another file which does * the following thing for it to work: -* The macro UNUSUAL_DEV() must be defined before this file is included +* The UNUSUAL_DEV, COMPLIANT_DEV, and USUAL_DEV macros must be defined +* before this file is included. */ /* If you edit this file, please try to keep it sorted first by VendorID,
@@ -46,6 +47,12 @@* <[email protected]> */ +/* Note: If you add an entry only in order to set the CAPACITY_OK flag, +* use the COMPLIANT_DEV macro instead of UNUSUAL_DEV. This is +* because such entries mark devices which actually work correctly, +* as opposed to devices that do something strangely or wrongly. +*/ +/* patch submitted by Vivian Bregier <[email protected]> */ UNUSUAL_DEV( 0x03eb, 0x2002, 0x0100, 0x0100,
@@ -692,6 +699,13 @@ UNUSUAL_DEV( 0x0525, 0xa140, 0x0100, 0x US_SC_8070, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY ), +/* Added by Alan Stern <[email protected]> */ +COMPLIANT_DEV (0x0525 ,0xa4a5 ,0x0000 ,0x9999 , +"Linux" , +"File-backed Storage Gadget" , +US_SC_DEVICE ,US_PR_DEVICE ,NULL , +US_FL_CAPACITY_OK ), +/* Yakumo Mega Image 37 * Submitted by Stephan Fuhrmann <[email protected]> */ UNUSUAL_DEV( 0x052b, 0x1801, 0x0100, 0x0100,
drivers/usb/storage/usb.c +6 -0
@@ -126,6 +126,8 @@ MODULE_PARM_DESC(delay_use, "seconds to { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } +#define COMPLIANT_DEV UNUSUAL_DEV +#define USUAL_DEV (useProto, useTrans, useType) \ { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \ .driver_info = (USB_US_TYPE_STOR<<24) }
@@ -134,6 +136,7 @@ static struct usb_device_id storage_usb_# include "unusual_devs.h" #undef UNUSUAL_DEV +#undef COMPLIANT_DEV#undef USUAL_DEV/* Terminating entry */ { }
@@ -164,6 +167,8 @@ MODULE_DEVICE_TABLE (usb, storage_usb_id .initFunction = init_function, \ } +#define COMPLIANT_DEV UNUSUAL_DEV +#define USUAL_DEV (use_protocol, use_transport, use_type) \ { \ .useProtocol = use_protocol, \
@@ -173,6 +178,7 @@ MODULE_DEVICE_TABLE (usb, storage_usb_idstatic struct us_unusual_dev us_unusual_dev_list[] = { # include "unusual_devs.h" # undef UNUSUAL_DEV +# undef COMPLIANT_DEV # undef USUAL_DEV/* Terminating entry */
drivers/usb/storage/usb.h +4 -0
@@ -155,6 +155,10 @@ struct us_data {#ifdef CONFIG_PM pm_hook suspend_resume_hook;#endif + +/* hacks for READ CAPACITY bug handling */ +int use_last_sector_hacks; +int last_sector_retries; };/* Convert between us_data and the corresponding Scsi_Host */
include/linux/usb_usual.h +3 -2
@@ -52,8 +52,9 @@US_FLAG (MAX_SECTORS_MIN ,0x00002000 ) \ /* Sets max_sectors to arch min */ \US_FLAG (BULK_IGNORE_TAG ,0x00004000 ) \ - /* Ignore tag mismatch in bulk operations */ - + /* Ignore tag mismatch in bulk operations */ \ +US_FLAG (CAPACITY_OK ,0x00010000 ) \ + /* READ CAPACITY response is correct */#define US_FLAG (name, value) US_FL_##name = value ,enum {US_DO_ALL_FLAGS };
PATCH 10/40 usb-storage: set CAPACITY_HEURISTICS flag for bad vendors
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Alan Stern <[email protected]>
commit a81a81a25d3ecdab777abca87c5ddf484056103d upstream.
This patch (as1194c) makes usb-storage set the CAPACITY_HEURISTICS flag for all devices made by Nokia, Nikon, or Motorola. These companies seem to include the READ CAPACITY bug in all of their devices.
Since cell phones and digital cameras rely on flash storage, which always has an even number of sectors, setting CAPACITY_HEURISTICS shouldn't cause any problems. Not even if the companies wise up and start making devices without the bug.
A large number of unusual_devs entries are now unnecessary, so the patch removes them.
--- drivers/usb/storage/scsiglue.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
drivers/usb/storage/scsiglue.c +23 -0
@@ -59,6 +59,13 @@#include "transport.h" #include "protocol.h" +/* Vendor IDs for companies that seem to include the READ CAPACITY bug +* in all their devices +*/ +#define VENDOR_ID_NOKIA 0x0421 +#define VENDOR_ID_NIKON 0x04b0 +#define VENDOR_ID_MOTOROLA 0x22b8 +/*********************************************************************** * Host functions ***********************************************************************/
@@ -134,6 +141,22 @@ static int slave_configure(struct scsi_d* settings can't be overridden via the scsi devinfo mechanism. */ if (sdev->type ==TYPE_DISK ) { +/* Some vendors seem to put the READ CAPACITY bug into +* all their devices -- primarily makers of cell phones +* and digital cameras. Since these devices always use +* flash media and can be expected to have an even number +* of sectors, we will always enable the CAPACITY_HEURISTICS +* flag unless told otherwise. */ +switch (le16_to_cpu (us->pusb_dev->descriptor.idVendor)) { +case VENDOR_ID_NOKIA : +case VENDOR_ID_NIKON : +case VENDOR_ID_MOTOROLA : +if (!(us->fflags & (US_FL_FIX_CAPACITY | +US_FL_CAPACITY_OK ))) + us->fflags |=US_FL_CAPACITY_HEURISTICS ; +break ; + } +/* Disk-type devices use MODE SENSE(6) if the protocol * (SubClass) is Transparent SCSI, otherwise they use * MODE SENSE(10). */
PATCH 11/40 ALSA: hda - Add automatic model setting for Samsung Q45
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Luke Yelavich <[email protected]>
commit 3e420e78ece6f9d2accc1568e80dfd0501e13df1 upstream.
Have the Samsung Q45 (144d:c510) select ALC262_HIPPO by default
Reference: Ubuntu bug 200210
http://launchpad.net/bugs/200210
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -9882,6 +9882,7 @@ static struct snd_pci_quirk alc262_cfg_tSND_PCI_QUIRK (0x10cf ,0x142d ,"Fujitsu Lifebook E8410" ,ALC262_FUJITSU ),SND_PCI_QUIRK (0x144d ,0xc032 ,"Samsung Q1 Ultra" ,ALC262_ULTRA ),SND_PCI_QUIRK (0x144d ,0xc039 ,"Samsung Q1U EL" ,ALC262_ULTRA ), +SND_PCI_QUIRK (0x144d ,0xc510 ,"Samsung Q45" ,ALC262_HIPPO ),SND_PCI_QUIRK (0x17aa ,0x384e ,"Lenovo 3000 y410" ,ALC262_LENOVO_3000 ),SND_PCI_QUIRK (0x17ff ,0x0560 ,"Benq ED8" ,ALC262_BENQ_ED8 ), SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
PATCH 12/40 ALSA: hda - make laptop-eapd model back for AD1986A
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Takashi Iwai <[email protected]>
commit 1725b82a6e2721612a3572d0336f51f1f1c3cf54 upstream.
The changes specific for Samsung laptops seem unapplicable to other hardware models like ASUS. The mic inputs are lost on such hardware by the change 5d5d5f43f1b835c375de9bd270cce030d16e2871.
This patch adds back the old laptop-eapd model, and create a new model "samsung" for the new one specific to Samsung laptops with automatic mic selection feature.
Reference: kernel bugzilla #12070
http://bugzilla.kernel.org/show_bug.cgi?id=12070
--- Documentation/sound/alsa/ALSA-Configuration.txt | 3 - sound/pci/hda/patch_analog.c | 49 ++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 4 deletions(-)
Documentation/sound/alsa/ALSA-Configuration.txt +2 -1
@@ -960,9 +960,10 @@ Prior to version 0.9.0rc4 options had a 6stack 6-jack, separate surrounds (default) 3stack 3-stack, shared surrounds laptop 2-channel only (FSC V2060, Samsung M50) - laptop-eapd 2-channel with EAPD (Samsung R65, ASUS A6J) + laptop-eapd 2-channel with EAPD (ASUS A6J) laptop-automute 2-channel with EAPD and HP-automute (Lenovo N100) ultra 2-channel with EAPD (Samsung Ultra tablet PC) + samsung 2-channel with EAPD (Samsung R65) AD1988/AD1988B/AD1989A/AD1989B 6stack 6-jack
sound/pci/hda/patch_analog.c +46 -3
79 lines not on this page · raw message
PATCH 13/40 drivers/net/irda/irda-usb.c: fix buffer overflow
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jos-Vicente Gilabert <[email protected]>
commit 2950e952920811be465ec95c6b56f03dc66a05c0 upstream.
Taken from http://bugzilla.kernel.org/show_bug.cgi?id=12397
We're doing an sprintf of an 11-char string into an 11-char buffer. Whoops. It breaks firmware uploading.
--- drivers/net/irda/irda-usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/irda/irda-usb.c +1 -1
@@ -1075,7 +1075,7 @@ static int stir421x_patch_device(struct {unsigned int i;int ret; -char stir421x_fw_name[11 ]; +char stir421x_fw_name[12 ];const struct firmware *fw;const unsigned char *fw_version_ptr;/* pointer to version string */ unsigned long fw_version =0 ;
PATCH 14/40 IA64: Turn on CONFIG_HAVE_UNSTABLE_CLOCK
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Tony Luck <[email protected]>
commit 0773a6cf673316440999752e23f8c3d4f85e48b9 upstream.
sched_clock() on ia64 is based on ar.itc, so is never completely synchronized between cpus. On some platforms (e.g. certain models of SGI Altix) it may be running at radically different frequencies.
Based on a patch from Dimitri Sivanich which set this just for SN2 && GENERIC kernels ... it is needed for all ia64 machines.
--- arch/ia64/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/ia64/Kconfig +1 -0
@@ -15,6 +15,7 @@ config IA64 select ACPI if (!IA64_HP_SIM) select PM if (!IA64_HP_SIM) select ARCH_SUPPORTS_MSI + select HAVE_UNSTABLE_SCHED_CLOCK select HAVE_IDE select HAVE_OPROFILE select HAVE_KPROBES
PATCH 15/40 kill sig -1 must only apply to callers namespace
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Sukadev Bhattiprolu <[email protected]>
commit d25141a818383b3c3b09f065698c544a7a0ec6e7 upstream.
Currently "kill <sig> -1" kills processes in all namespaces and breaks the isolation of namespaces. Earlier attempt to fix this was discussed at:
http://lkml.org/lkml/2008/7/23/148
As suggested by Oleg Nesterov in that thread, use "task_pid_vnr() > 1" check since task_pid_vnr() returns 0 if process is outside the caller's namespace.
--- kernel/signal.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/signal.c +2 -1
@@ -1141,7 +1141,8 @@ static int kill_something_info(int sig,struct task_struct * p;for_each_process (p) { -if (p->pid >1 && !same_thread_group (p, current)) { +if (task_pid_vnr (p) >1 && + !same_thread_group (p, current)) {int err =group_send_sig_info (sig, info, p); ++count;if (err != -EPERM )
PATCH 16/40 lib/idr.c: use kmem_cache_zalloc() for the idr_layer cache
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Andrew Morton <[email protected]>
commit 5b019e99016f3a692ba45bf68fba73a402d7c01a upstream.
David points out that the idr_remove_all() function returns unused slabs to the kmem cache, but needs to zero them first or else they will be uninitialized upon next use. This causes crashes which have been observed in the firewire subsystem.
He fixed this by zeroing the object before freeing it in idr_remove_all().
But we agree that simply removing the constructor and zeroing the object at allocation time is simpler than relying upon slab constructor machinery and might even be faster.
This problem was introduced by "idr: make idr_remove rcu-safe" (commit cf481c20c476ad2c0febdace9ce23f5a4db19582), which was first released in 2.6.27.
There are no known codesites which trigger this bug in 2.6.27 or 2.6.28. The post-2.6.28 firewire changes are the only known triggerer.
There might of course be not-yet-discovered triggerers in 2.6.27 and 2.6.28, and there might be out-of-tree triggerers which are added to those kernel versions. I'll let the -stable guys decide whether they want to backport this fix.
--- lib/idr.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-)
lib/idr.c +2 -8
@@ -121,7 +121,7 @@ int idr_pre_get(struct idr *idp, gfp_t g {while (idp->id_free_cnt <IDR_FREE_MAX ) {struct idr_layer *new; - new =kmem_cache_alloc (idr_layer_cache, gfp_mask); + new =kmem_cache_zalloc (idr_layer_cache, gfp_mask);if (new ==NULL )return (0 );move_to_free_list (idp, new);
@@ -623,16 +623,10 @@ void *idr_replace(struct idr *idp, void }EXPORT_SYMBOL (idr_replace); -static void idr_cache_ctor (void *idr_layer) -{ -memset (idr_layer,0 ,sizeof (struct idr_layer )); -} -void __init idr_init_cache (void ) { idr_layer_cache =kmem_cache_create ("idr_layer_cache" , -sizeof (struct idr_layer ),0 ,SLAB_PANIC , - idr_cache_ctor); +sizeof (struct idr_layer ),0 ,SLAB_PANIC ,NULL ); }/**
PATCH 17/40 p54usb: Add USB ID for Thomson Speedtouch 121g
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Michiel <[email protected]>
commit 878e6a432f85690a2c0d88d96f177e54ff1d4a57 upstream.
Add the USB ID for Thomson Speedtouch 121g to p54usb.
--- drivers/net/wireless/p54/p54usb.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/wireless/p54/p54usb.c +1 -0
@@ -53,6 +53,7 @@ static struct usb_device_id p54u_table[] {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */ {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */ {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */ + {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */
PATCH 18/40 PCI: keep ASPM link state consistent throughout PCIe hierarchy
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Shaohua Li <[email protected]>
commit 46bbdfa44cfc0d352148a0dc33ba9f6db02ccdf0 upstream.
In a PCIe hierarchy with a switch present, if the link state of an endpoint device is changed, we must check the whole hierarchy from the endpoint device to root port, and for each link in the hierarchy, the new link state should be configured. Previously, the implementation checked the state but forgot to configure the links between root port to switch. Fixes Novell bz #448987.
--- drivers/pci/pcie/aspm.c | 127 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 107 insertions(+), 20 deletions(-)
drivers/pci/pcie/aspm.c +107 -20
@@ -33,6 +33,11 @@ struct endpoint_state {struct pcie_link_state {struct list_head sibiling;struct pci_dev *pdev; +bool downstream_has_switch; + +struct pcie_link_state *parent; +struct list_head children; +struct list_head link;/* ASPM state */ unsigned int support_state;
@@ -125,7 +130,7 @@ static void pcie_set_clock_pm(struct pci link_state->clk_pm_enabled = !!enable; } -static void pcie_check_clock_pm (struct pci_dev *pdev) +static void pcie_check_clock_pm (struct pci_dev *pdev,int blacklist) {int pos;u32 reg32;
@@ -149,10 +154,26 @@ static void pcie_check_clock_pm(struct pif (!(reg16 &PCI_EXP_LNKCTL_CLKREQ_EN )) enabled =0 ; } - link_state->clk_pm_capable = capable; link_state->clk_pm_enabled = enabled; link_state->bios_clk_state = enabled; -pcie_set_clock_pm (pdev,policy_to_clkpm_state (pdev)); +if (!blacklist) { + link_state->clk_pm_capable = capable; +pcie_set_clock_pm (pdev,policy_to_clkpm_state (pdev)); + }else { + link_state->clk_pm_capable =0 ; +pcie_set_clock_pm (pdev,0 ); + } +} + +static bool pcie_aspm_downstream_has_switch (struct pci_dev *pdev) +{ +struct pci_dev *child_dev; + +list_for_each_entry (child_dev, &pdev->subordinate->devices, bus_list) { +if (child_dev->pcie_type ==PCI_EXP_TYPE_UPSTREAM ) +return true; + } +return false; }/*
@@ -419,9 +440,9 @@ static unsigned int pcie_aspm_check_stat {struct pci_dev *child_dev; -/* If no child, disable the link */ +/* If no child, ignore the link */ if (list_empty (&pdev->subordinate->devices)) -return 0 ; +return state;list_for_each_entry (child_dev, &pdev->subordinate->devices, bus_list) {if (child_dev->pcie_type ==PCI_EXP_TYPE_PCI_BRIDGE ) {/*
@@ -462,6 +483,9 @@ static void __pcie_aspm_config_link(struint valid =1 ;struct pcie_link_state *link_state = pdev->link_state; +/* If no child, disable the link */ +if (list_empty (&pdev->subordinate->devices)) + state =0 ;/* * if the downstream component has pci bridge function, don't do ASPM * now
@@ -493,20 +517,52 @@ static void __pcie_aspm_config_link(stru link_state->enabled_state = state; } +static struct pcie_link_state *get_root_port_link (struct pcie_link_state *link) +{ +struct pcie_link_state *root_port_link = link; +while (root_port_link->parent) + root_port_link = root_port_link->parent; +return root_port_link; +} + +/* check the whole hierarchy, and configure each link in the hierarchy */ static void __pcie_aspm_configure_link_state (struct pci_dev *pdev,unsigned int state) {struct pcie_link_state *link_state = pdev->link_state; +struct pcie_link_state *root_port_link =get_root_port_link (link_state); +struct pcie_link_state *leaf; -if (link_state->support_state ==0 ) -return ; state &=PCIE_LINK_STATE_L0S |PCIE_LINK_STATE_L1 ; -/* state 0 means disabling aspm */ - state =pcie_aspm_check_state (pdev, state); +/* check all links who have specific root port link */ +list_for_each_entry (leaf, &link_list, sibiling) { +if (!list_empty (&leaf->children) || +get_root_port_link (leaf) != root_port_link) +continue ; + state =pcie_aspm_check_state (leaf->pdev, state); + } +/* check root port link too in case it hasn't children */ + state =pcie_aspm_check_state (root_port_link->pdev, state); +if (link_state->enabled_state == state)return ; -__pcie_aspm_config_link (pdev, state); + +/* +* we must change the hierarchy. See comments in +* __pcie_aspm_config_link for the order +**/ +if (state &PCIE_LINK_STATE_L1 ) { +list_for_each_entry (leaf, &link_list, sibiling) { +if (get_root_port_link (leaf) == root_port_link) +__pcie_aspm_config_link (leaf->pdev, state); + } + }else { +list_for_each_entry_reverse (leaf, &link_list, sibiling) { +if (get_root_port_link (leaf) == root_port_link) +__pcie_aspm_config_link (leaf->pdev, state); + } + } }/*
@@ -570,6 +626,7 @@ void pcie_aspm_init_link_state(struct pcunsigned int state;struct pcie_link_state *link_state;int error =0 ; +int blacklist;if (aspm_disabled || !pdev->is_pcie || pdev->link_state)return ;
@@ -580,29 +637,58 @@ void pcie_aspm_init_link_state(struct pcif (list_empty (&pdev->subordinate->devices)) goto out; -if (pcie_aspm_sanity_check (pdev)) - goto out; + blacklist = !!pcie_aspm_sanity_check (pdev);mutex_lock (&aspm_lock); link_state =kzalloc (sizeof (*link_state),GFP_KERNEL );if (!link_state) goto unlock_out; - pdev->link_state = link_state; -pcie_aspm_configure_common_clock (pdev); - -pcie_aspm_cap_init (pdev); + link_state->downstream_has_switch =pcie_aspm_downstream_has_switch (pdev); +INIT_LIST_HEAD (&link_state->children); +INIT_LIST_HEAD (&link_state->link); +if (pdev->bus->self) {/* this is a switch */ +struct pcie_link_state *parent_link_state; + + parent_link_state = pdev->bus->parent->self->link_state; +if (!parent_link_state) { +kfree (link_state); + goto unlock_out; + } +list_add (&link_state->link, &parent_link_state->children); + link_state->parent = parent_link_state; + } -/* config link state to avoid BIOS error */ - state =pcie_aspm_check_state (pdev,policy_to_aspm_state (pdev)); -__pcie_aspm_config_link (pdev, state); + pdev->link_state = link_state; -pcie_check_clock_pm (pdev); +if (!blacklist) { +pcie_aspm_configure_common_clock (pdev); +pcie_aspm_cap_init (pdev); + }else { + link_state->enabled_state =PCIE_LINK_STATE_L0S |PCIE_LINK_STATE_L1 ; + link_state->bios_aspm_state =0 ; +/* Set support state to 0, so we will disable ASPM later */ + link_state->support_state =0 ; + } link_state->pdev = pdev;list_add (&link_state->sibiling, &link_list); +if (link_state->downstream_has_switch) { +/* +* If link has switch, delay the link config. The leaf link +* initialization will config the whole hierarchy. but we must +* make sure BIOS doesn't set unsupported link state +**/ + state =pcie_aspm_check_state (pdev, link_state->bios_aspm_state); +__pcie_aspm_config_link (pdev, state); + }else +__pcie_aspm_configure_link_state (pdev, +policy_to_aspm_state (pdev)); + +pcie_check_clock_pm (pdev, blacklist); + unlock_out:if (error)free_link_state (pdev);
@@ -635,6 +721,7 @@ void pcie_aspm_exit_link_state(struct pc/* All functions are removed, so just disable ASPM for the link */ __pcie_aspm_config_one_dev (parent,0 );list_del (&link_state->sibiling); +list_del (&link_state->link);/* Clock PM is for endpoint device */ free_link_state (parent);
PATCH 19/40 rt2x00: add USB ID for the Linksys WUSB200.
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Stefan Lippers-Hollmann <[email protected]>
commit 3be36ae223271f9c2cfbe7406846c8fdcd2f50c3 upstream.
add USB ID for the Linksys WUSB200 Wireless-G Business USB Adapter to rt73usb.
--- drivers/net/wireless/rt2x00/rt73usb.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/wireless/rt2x00/rt73usb.c +1 -0
@@ -2113,6 +2113,7 @@ static struct usb_device_id rt73usb_devi/* Linksys */ { USB_DEVICE(0x13b1, 0x0020), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x13b1, 0x0023), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x13b1, 0x0028), USB_DEVICE_DATA(&rt73usb_ops) },/* MSI */ { USB_DEVICE(0x0db0, 0x6877), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0db0, 0x6874), USB_DEVICE_DATA(&rt73usb_ops) },
PATCH 20/40 security: introduce missing kfree
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Vegard Nossum <[email protected]>
commit 0d54ee1c7850a954026deec4cd4885f331da35cc upstream.
Plug this leak.
--- security/keys/keyctl.c | 1 + 1 file changed, 1 insertion(+)
security/keys/keyctl.c +1 -0
@@ -270,6 +270,7 @@ long keyctl_join_session_keyring(const c/* join the session */ ret =join_session_keyring (name); +kfree (name); error:return ret;
PATCH 21/40 sgi-xp: eliminate false detection of no heartbeat
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dean Nelson <[email protected]>
commit 158bc69effbf96f59c01cdeb20f8d4c184e59f8e upstream.
After XPC has been up and running on multiple partitions for any length of time, if XPC on one of the partitions is stopped and restarted (either by a rmmod/insmod or a system restart), it is possible for the XPCs running on the other partitions to falsely detect a lack of heartbeat from the XPC that was just restarted. This false detection will occur if the restarted XPC comes up within the five-seconds preceding one of the other XPC's heartbeat check (which occurs once every twenty seconds).
The detection of no heartbeat results in the detecting XPC deactivating from the just restarted XPC. The only remedy is to restart one of the XPCs and hope that one doesn't hit this five-second window on any of the other partitions.
--- drivers/misc/sgi-xp/xpc_sn2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/misc/sgi-xp/xpc_sn2.c +1 -1
@@ -904,7 +904,7 @@ xpc_update_partition_info_sn2(struct xpcdev_dbg (xpc_part," remote_vars_pa = 0x%016lx\n" , part_sn2->remote_vars_pa); - part->last_heartbeat = remote_vars->heartbeat; + part->last_heartbeat = remote_vars->heartbeat -1 ;dev_dbg (xpc_part," last_heartbeat = 0x%016lx\n" , part->last_heartbeat);
PATCH 22/40 clocksource: introduce clocksource_forward_now()
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Roman Zippel <[email protected]>
commit 9a055117d3d9cb562f83f8d4cd88772761f4cab0 upstream.
To keep the raw monotonic patch simple first introduce clocksource_forward_now(), which takes care of the offset since the last update_wall_time() call and adds it to the clock, so there is no need anymore to deal with it explicitly at various places, which need to make significant changes to the clock.
This is also gets rid of the timekeeping_suspend_nsecs, instead of waiting until resume, the value is accumulated during suspend. In the end there is only a single user of __get_nsec_offset() left, so I integrated it back to getnstimeofday().
--- kernel/time/timekeeping.c | 71 +++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 38 deletions(-)
kernel/time/timekeeping.c +33 -38
@@ -61,27 +61,23 @@ struct clocksource *clock;#ifdef CONFIG_GENERIC_TIME /** -* __get_nsec_offset - Returns nanoseconds since last call to periodic_hook +* clocksource_forward_now - update clock to the current time * -* private function, must hold xtime_lock lock when being -* called. Returns the number of nanoseconds since the -* last call to update_wall_time() (adjusted by NTP scaling) +* Forward the current clock to update its state since the last call to +* update_wall_time(). This is useful before significant clock changes, +* as it avoids having to deal with this time offset explicitly. */ -static inline s64 __get_nsec_offset (void ) +static void clocksource_forward_now (void ) {cycle_t cycle_now, cycle_delta; -s64 ns_offset; +s64 nsec; -/* read clocksource: */ cycle_now =clocksource_read (clock); - -/* calculate the delta since the last update_wall_time: */ cycle_delta = (cycle_now - clock->cycle_last) & clock->mask; + clock->cycle_last = cycle_now; -/* convert to nanoseconds: */ - ns_offset =cyc2ns (clock, cycle_delta); - -return ns_offset; + nsec =cyc2ns (clock, cycle_delta); +timespec_add_ns (&xtime, nsec); }/**
@@ -92,6 +88,7 @@ static inline s64 __get_nsec_offset(void*/ void getnstimeofday (struct timespec *ts) { +cycle_t cycle_now, cycle_delta;unsigned long seq;s64 nsecs;
@@ -101,7 +98,15 @@ void getnstimeofday(struct timespec *ts) seq =read_seqbegin (&xtime_lock); *ts = xtime; - nsecs =__get_nsec_offset (); + +/* read clocksource: */ + cycle_now =clocksource_read (clock); + +/* calculate the delta since the last update_wall_time: */ + cycle_delta = (cycle_now - clock->cycle_last) & clock->mask; + +/* convert to nanoseconds: */ + nsecs =cyc2ns (clock, cycle_delta); }while (read_seqretry (&xtime_lock, seq));
@@ -134,22 +139,22 @@ EXPORT_SYMBOL(do_gettimeofday);*/ int do_settimeofday (struct timespec *tv) { +struct timespec ts_delta;unsigned long flags; -time_t wtm_sec, sec = tv->tv_sec; -long wtm_nsec, nsec = tv->tv_nsec;if ((unsigned long )tv->tv_nsec >=NSEC_PER_SEC )return -EINVAL ;write_seqlock_irqsave (&xtime_lock, flags); - nsec -=__get_nsec_offset (); +clocksource_forward_now (); + + ts_delta.tv_sec = tv->tv_sec - xtime.tv_sec; + ts_delta.tv_nsec = tv->tv_nsec - xtime.tv_nsec; + wall_to_monotonic =timespec_sub (wall_to_monotonic, ts_delta); - wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); - wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); + xtime = *tv; -set_normalized_timespec (&xtime, sec, nsec); -set_normalized_timespec (&wall_to_monotonic, wtm_sec, wtm_nsec);update_xtime_cache (0 ); clock->error =0 ;
@@ -175,22 +180,17 @@ EXPORT_SYMBOL(do_settimeofday);static void change_clocksource (void ) {struct clocksource *new; -cycle_t now; -u64 nsec; new =clocksource_get_next ();if (clock == new)return ; - new->cycle_last =0 ; - now =clocksource_read (new); - nsec =__get_nsec_offset (); -timespec_add_ns (&xtime, nsec); +clocksource_forward_now (); clock = new; - clock->cycle_last = now; - + clock->cycle_last =0 ; + clock->cycle_last =clocksource_read (new); clock->error =0 ; clock->xtime_nsec =0 ;clocksource_calculate_interval (clock,NTP_INTERVAL_LENGTH );
@@ -205,8 +205,8 @@ static void change_clocksource(void) */ }#else +static inline void clocksource_forward_now (void ) { }static inline void change_clocksource (void ) { } -static inline s64 __get_nsec_offset (void ) {return 0 ; }#endif /**
@@ -268,8 +268,6 @@ void __init timekeeping_init(void)/* time in seconds when suspend began */ static unsigned long timekeeping_suspend_time; -/* xtime offset when we went into suspend */ -static s64 timekeeping_suspend_nsecs;/** * timekeeping_resume - Resumes the generic timekeeping subsystem.
@@ -295,8 +293,6 @@ static int timekeeping_resume(struct sys wall_to_monotonic.tv_sec -= sleep_length; total_sleep_time += sleep_length; } -/* Make sure that we have the correct xtime reference */ -timespec_add_ns (&xtime, timekeeping_suspend_nsecs);update_xtime_cache (0 );/* re-base the last cycle value */ clock->cycle_last =0 ;
@@ -322,8 +318,7 @@ static int timekeeping_suspend(struct sy timekeeping_suspend_time =read_persistent_clock ();write_seqlock_irqsave (&xtime_lock, flags); -/* Get the current xtime offset */ - timekeeping_suspend_nsecs =__get_nsec_offset (); +clocksource_forward_now (); timekeeping_suspended =1 ;write_sequnlock_irqrestore (&xtime_lock, flags);
@@ -464,10 +459,10 @@ void update_wall_time(void)*/ while (offset >= clock->cycle_interval) {/* accumulate one interval */ - clock->xtime_nsec += clock->xtime_interval; - clock->cycle_last += clock->cycle_interval; offset -= clock->cycle_interval; + clock->cycle_last += clock->cycle_interval; + clock->xtime_nsec += clock->xtime_interval;if (clock->xtime_nsec >= (u64 )NSEC_PER_SEC << clock->shift) { clock->xtime_nsec -= (u64 )NSEC_PER_SEC << clock->shift; xtime.tv_sec++;
PATCH 23/40 hwmon-vid: Add support for AMD family 10h CPUs
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jean Delvare <[email protected]>
commit 1b871826b3dfcdcd78140d17c00e452eec6c12a4 upstream.
The AMD family 10h CPUs use the same VID decoding table as the family 0Fh CPUs.
--- drivers/hwmon/hwmon-vid.c | 1 + 1 file changed, 1 insertion(+)
drivers/hwmon/hwmon-vid.c +1 -0
@@ -180,6 +180,7 @@ static struct vrm_model vrm_models[] = { {X86_VENDOR_AMD, 0x6, ANY, ANY, 90}, /* Athlon Duron etc */ {X86_VENDOR_AMD, 0xF, 0x3F, ANY, 24}, /* Athlon 64, Opteron */ {X86_VENDOR_AMD, 0xF, ANY, ANY, 25}, /* NPT family 0Fh */ + {X86_VENDOR_AMD, 0x10, ANY, ANY, 25}, /* NPT family 10h */ {X86_VENDOR_INTEL, 0x6, 0x9, ANY, 13}, /* Pentium M (130 nm) */ {X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85}, /* Tualatin */ {X86_VENDOR_INTEL, 0x6, 0xD, ANY, 13}, /* Pentium M (90 nm) */
PATCH 24/40 ath9k: quiet harmless ForceXPAon messages
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Luis R. Rodriguez <[email protected]>
This is a port of one line of upstream patchf1dc56003b23d2d5bb5a756de6b1633a76c9e697
The "ForceXPAon" messages on ath9k were not meant to be printed regularly, lets quiet them as this can happen quite frequently (scans) and will fill the logs with tons of these messages.
--- drivers/net/wireless/ath9k/hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/ath9k/hw.c +1 -1
@@ -729,7 +729,7 @@ ath9k_hw_eeprom_set_board_values(structAR_AN_TOP2_LOCALBIAS ,AR_AN_TOP2_LOCALBIAS_S , pModal->local_bias); -DPRINTF (ah->ah_sc,ATH_DBG_ANY ,"ForceXPAon: %d\n" , +DPRINTF (ah->ah_sc,ATH_DBG_EEPROM ,"ForceXPAon: %d\n" , pModal->force_xpaon);REG_RMW_FIELD (ah,AR_PHY_XPA_CFG ,AR_PHY_FORCE_XPA_CFG , pModal->force_xpaon);
PATCH 25/40 dell_rbu: use scnprintf() instead of less secure sprintf()
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Pavel Roskin <[email protected]>
commit 81156928f8fe31621e467490b9d441c0285998c3 upstream.
Reading 0 bytes from /sys/devices/platform/dell_rbu/image_type or /sys/devices/platform/dell_rbu/packet_size by an ordinary user causes an oops.
--- drivers/firmware/dell_rbu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/firmware/dell_rbu.c +2 -2
@@ -576,7 +576,7 @@ static ssize_t read_rbu_image_type(struc {int size =0 ;if (!pos) - size =sprintf (buffer,"%s\n" , image_type); + size =scnprintf (buffer, count,"%s\n" , image_type);return size; }
@@ -648,7 +648,7 @@ static ssize_t read_rbu_packet_size(struint size =0 ;if (!pos) {spin_lock (&rbu_data.lock); - size =sprintf (buffer,"%lu\n" , rbu_data.packetsize); + size =scnprintf (buffer, count,"%lu\n" , rbu_data.packetsize);spin_unlock (&rbu_data.lock); }return size;
PATCH 26/40 hwmon: (abituguru3) Fix CONFIG_DMI=n fallback to probe
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Alistair John Strachan <[email protected]>
commit 46a5f173fc88ffc22651162033696d8a9fbcdc5c upstream.
When CONFIG_DMI is not enabled, dmi detection should flag that no board could be detected (err=1) rather than another error condition (err<0).
This fixes the fallback to manual probing for all motherboards, even those without DMI strings, when CONFIG_DMI=n.
--- drivers/hwmon/abituguru3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwmon/abituguru3.c +1 -1
@@ -1153,7 +1153,7 @@ static int __init abituguru3_dmi_detect(static inline int abituguru3_dmi_detect (void ) { -return -ENODEV ; +return 1 ; }#endif /* CONFIG_DMI */
PATCH 27/40 powerpc: is_hugepage_only_range() must account for both 4kB and 64kB slices
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dave Kleikamp <[email protected]>
commit 9ba0fdbfaed2e74005d87fab948c5522b86ff733 upstream.
powerpc: is_hugepage_only_range() must account for both 4kB and 64kB slices
The subpage_prot syscall fails on second and subsequent calls for a given region, because is_hugepage_only_range() is mis-identifying the 4 kB slices when the process has a 64 kB page size.
--- arch/powerpc/mm/slice.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
arch/powerpc/mm/slice.c +10 -1
@@ -710,9 +710,18 @@ int is_hugepage_only_range(struct mm_str unsigned long len) {struct slice_mask mask, available; +unsigned int psize = mm->context.user_psize; mask =slice_range_to_mask (addr, len); - available =slice_mask_for_size (mm, mm->context.user_psize); + available =slice_mask_for_size (mm, psize); +#ifdef CONFIG_PPC_64K_PAGES +/* We need to account for 4k slices too */ +if (psize ==MMU_PAGE_64K ) { +struct slice_mask compat_mask; + compat_mask =slice_mask_for_size (mm,MMU_PAGE_4K ); +or_mask (available, compat_mask); + } +#endif #if 0 /* too verbose */ slice_dbg("is_hugepage_only_range(mm=%p, addr=%lx, len=%lx)\n",
PATCH 28/40 mm: write_cache_pages cyclic fix
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Nick Piggin <[email protected]>
commit 31a12666d8f0c22235297e1c1575f82061480029 upstream.
In write_cache_pages, scanned == 1 is supposed to mean that cyclic writeback has circled through zero, thus we should not circle again. However it gets set to 1 after the first successful pagevec lookup. This leads to cases where not enough data gets written.
Counterexample: file with first 10 pages dirty, writeback_index == 5, nr_to_write == 10. Then the 5 last pages will be found, and scanned will be set to 1, after writing those out, we will not cycle back to get the first 5.
Rework this logic, now we'll always cycle unless we started off from index
0. When cycling, only write out as far as 1 page before the start page from the first cycle (so we don't write parts of the file twice).
--- mm/page-writeback.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-)
mm/page-writeback.c +18 -7
@@ -872,9 +872,10 @@ int write_cache_pages(struct address_spaint done =0 ;struct pagevec pvec;int nr_pages; +pgoff_t uninitialized_var (writeback_index );pgoff_t index;pgoff_t end;/* Inclusive */ -int scanned =0 ; +int cycled;int range_whole =0 ;if (wbc->nonblocking &&bdi_write_congested (bdi)) {
@@ -884,14 +885,19 @@ int write_cache_pages(struct address_spapagevec_init (&pvec,0 );if (wbc->range_cyclic) { - index = mapping->writeback_index;/* Start from prev offset */ + writeback_index = mapping->writeback_index;/* prev offset */ + index = writeback_index; +if (index ==0 ) + cycled =1 ; +else + cycled =0 ; end =-1 ; }else { index = wbc->range_start >>PAGE_CACHE_SHIFT ; end = wbc->range_end >>PAGE_CACHE_SHIFT ;if (wbc->range_start ==0 && wbc->range_end ==LLONG_MAX ) range_whole =1 ; - scanned =1 ; + cycled =1 ;/* ignore range_cyclic tests */ } retry: while (!done && (index <= end) &&
@@ -900,7 +906,6 @@ retry: min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1))) {unsigned i; - scanned =1 ;for (i =0 ; i < nr_pages; i++) {struct page *page = pvec.pages[i];
@@ -918,7 +923,11 @@ retry:continue ; } -if (!wbc->range_cyclic && page->index > end) { +if (page->index > end) { +/* +* can't be range_cyclic (1st pass) because +* end == -1 in that case. +*/ done =1 ;unlock_page (page);continue ;
@@ -949,13 +958,15 @@ retry:pagevec_release (&pvec);cond_resched (); } -if (!scanned && !done) { +if (!cycled) {/* +* range_cyclic: * We hit the last page and there is more work to be done: wrap * back to the start of the file */ - scanned =1 ; + cycled =1 ; index =0 ; + end = writeback_index -1 ; goto retry; }if (wbc->range_cyclic || (range_whole && wbc->nr_to_write >0 ))
PATCH 29/40 mm: write_cache_pages early loop termination
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Nick Piggin <[email protected]>
commit bd19e012f6fd3b7309689165ea865cbb7bb88c1e upstream.
We'd like to break out of the loop early in many situations, however the existing code has been setting mapping->writeback_index past the final page in the pagevec lookup for cyclic writeback. This is a problem if we don't process all pages up to the final page.
Currently the code mostly keeps writeback_index reasonable and hacked around this by not breaking out of the loop or writing pages outside the range in these cases. Keep track of a real "done index" that enables us to terminate the loop in a much more flexible manner.
Needed by the subsequent patch to preserve writepage errors, and then further patches to break out of the loop early for other reasons. However there are no functional changes with this patch alone.
--- mm/page-writeback.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
mm/page-writeback.c +5 -1
@@ -875,6 +875,7 @@ int write_cache_pages(struct address_spapgoff_t uninitialized_var (writeback_index );pgoff_t index;pgoff_t end;/* Inclusive */ +pgoff_t done_index;int cycled;int range_whole =0 ;
@@ -900,6 +901,7 @@ int write_cache_pages(struct address_spa cycled =1 ;/* ignore range_cyclic tests */ } retry: + done_index = index; while (!done && (index <= end) && (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, PAGECACHE_TAG_DIRTY,
@@ -909,6 +911,8 @@ retry:for (i =0 ; i < nr_pages; i++) {struct page *page = pvec.pages[i]; + done_index = page->index +1 ; +/* * At this point we hold neither mapping->tree_lock nor * lock on the page itself: the page may be truncated or
@@ -970,7 +974,7 @@ retry: goto retry; }if (wbc->range_cyclic || (range_whole && wbc->nr_to_write >0 )) - mapping->writeback_index = index; + mapping->writeback_index = done_index;if (wbc->range_cont) wbc->range_start = index <<PAGE_CACHE_SHIFT ;
PATCH 30/40 mm: write_cache_pages writepage error fix
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Nick Piggin <[email protected]>
commit 00266770b8b3a6a77f896ca501a0613739086832 upstream.
In write_cache_pages, if ret signals a real error, but we still have some pages left in the pagevec, done would be set to 1, but the remaining pages would continue to be processed and ret will be overwritten in the process.
It could easily be overwritten with success, and thus success will be returned even if there is an error. Thus the caller is told all writes succeeded, wheras in reality some did not.
Fix this by bailing immediately if there is an error, and retaining the first error code.
This is a data integrity bug.
--- mm/page-writeback.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-)
mm/page-writeback.c +20 -5
@@ -948,11 +948,26 @@ retry: ret = (*writepage)(page, wbc, data); -if (unlikely (ret ==AOP_WRITEPAGE_ACTIVATE )) { -unlock_page (page); - ret =0 ; - } -if (ret || (--(wbc->nr_to_write) <=0 )) +if (unlikely (ret)) { +if (ret ==AOP_WRITEPAGE_ACTIVATE ) { +unlock_page (page); + ret =0 ; + }else { +/* +* done_index is set past this page, +* so media errors will not choke +* background writeout for the entire +* file. This has consequences for +* range_cyclic semantics (ie. it may +* not be suitable for data integrity +* writeout). +*/ + done =1 ; +break ; + } + } + +if (--(wbc->nr_to_write) <=0 ) done =1 ;if (wbc->nonblocking &&bdi_write_congested (bdi)) { wbc->encountered_congestion =1 ;
PATCH 31/40 mm: write_cache_pages integrity fix
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Nick Piggin <[email protected]>
commit 05fe478dd04e02fa230c305ab9b5616669821dd3 upstream.
In write_cache_pages, nr_to_write is heeded even for data-integrity syncs, so the function will return success after writing out nr_to_write pages, even if that was not sufficient to guarantee data integrity.
The callers tend to set it to values that could break data interity semantics easily in practice. For example, nr_to_write can be set to mapping->nr_pages * 2, however if a file has a single, dirty page, then fsync is called, subsequent pages might be concurrently added and dirtied, then write_cache_pages might writeout two of these newly dirty pages, while not writing out the old page that should have been written out.
Fix this by ignoring nr_to_write if it is a data integrity sync.
This is a data integrity bug.
The reason this has been done in the past is to avoid stalling sync operations behind page dirtiers.
"If a file has one dirty page at offset 1000000000000000 then someone
does an fsync() and someone else gets in first and starts madly writing pages at offset 0, we want to write that page at 1000000000000000. Somehow."
What we do today is return success after an arbitrary amount of pages are written, whether or not we have provided the data-integrity semantics that the caller has asked for. Even this doesn't actually fix all stall cases
completely: in the above situation, if the file has a huge number of pages in pagecache (but not dirty), then mapping->nrpages is going to be huge, even if pages are being dirtied.
This change does indeed make the possibility of long stalls lager, and that's not a good thing, but lying about data integrity is even worse. We have to either perform the sync, or return -ELINUXISLAME so at least the caller knows what has happened.
There are subsequent competing approaches in the works to solve the stall problems properly, without compromising data integrity.
--- mm/filemap.c | 2 +- mm/page-writeback.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-)
mm/filemap.c +1 -1
@@ -209,7 +209,7 @@ int __filemap_fdatawrite_range(struct adint ret;struct writeback_control wbc = { .sync_mode = sync_mode, - .nr_to_write = mapping->nrpages *2 , + .nr_to_write =LONG_MAX , .range_start = start, .range_end = end, };
mm/page-writeback.c +4 -2
@@ -967,8 +967,10 @@ retry: } } -if (--(wbc->nr_to_write) <=0 ) - done =1 ; +if (wbc->sync_mode ==WB_SYNC_NONE ) { +if (--wbc->nr_to_write <=0 ) + done =1 ; + }if (wbc->nonblocking &&bdi_write_congested (bdi)) { wbc->encountered_congestion =1 ; done =1 ;
PATCH 32/40 mm: write_cache_pages cleanups
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Nick Piggin <[email protected]>
commit 5a3d5c9813db56a75934eb1015367fda23a8b0b4 upstream.
Get rid of some complex expressions from flow control statements, add a comment, remove some duplicate code.
--- mm/page-writeback.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-)
mm/page-writeback.c +22 -12
@@ -902,11 +902,14 @@ int write_cache_pages(struct address_spa } retry: done_index = index; -while (!done && (index <= end) && - (nr_pages =pagevec_lookup_tag (&pvec, mapping, &index, -PAGECACHE_TAG_DIRTY , -min (end - index, (pgoff_t )PAGEVEC_SIZE -1 ) +1 ))) { -unsigned i; +while (!done && (index <= end)) { +int i; + + nr_pages =pagevec_lookup_tag (&pvec, mapping, &index, +PAGECACHE_TAG_DIRTY , +min (end - index, (pgoff_t )PAGEVEC_SIZE -1 ) +1 ); +if (nr_pages ==0 ) +break ;for (i =0 ; i < nr_pages; i++) {struct page *page = pvec.pages[i];
@@ -922,7 +925,16 @@ retry:*/ lock_page (page); +/* +* Page truncated or invalidated. We can freely skip it +* then, even for data integrity operations: the page +* has disappeared concurrently, so there could be no +* real expectation of this data interity operation +* even if there is now a new, dirty page at the same +* pagecache address. +*/ if (unlikely (page->mapping != mapping)) { +continue_unlock:unlock_page (page);continue ; }
@@ -933,18 +945,15 @@ retry:* end == -1 in that case. */ done =1 ; -unlock_page (page); -continue ; + goto continue_unlock; }if (wbc->sync_mode !=WB_SYNC_NONE )wait_on_page_writeback (page);if (PageWriteback (page) || - !clear_page_dirty_for_io (page)) { -unlock_page (page); -continue ; - } + !clear_page_dirty_for_io (page)) + goto continue_unlock; ret = (*writepage)(page, wbc, data);
@@ -968,7 +977,8 @@ retry: }if (wbc->sync_mode ==WB_SYNC_NONE ) { -if (--wbc->nr_to_write <=0 ) + wbc->nr_to_write--; +if (wbc->nr_to_write <=0 ) done =1 ; }if (wbc->nonblocking &&bdi_write_congested (bdi)) {
PATCH 33/40 mm: write_cache_pages optimise page cleaning
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Nick Piggin <[email protected]>
commit 515f4a037fb9ab736f8bad733fcd2ffd350cf265 upstream.
In write_cache_pages, if we get stuck behind another process that is cleaning pages, we will be forced to wait for them to finish, then perform our own writeout (if it was redirtied during the long wait), then wait for that.
If a page under writeout is still clean, we can skip waiting for it (if we're part of a data integrity sync, we'll be waiting for all writeout pages afterwards, so we'll still be waiting for the other guy's write that's cleaned the page).
--- mm/page-writeback.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-)
mm/page-writeback.c +13 -4
@@ -948,11 +948,20 @@ continue_unlock: goto continue_unlock; } -if (wbc->sync_mode !=WB_SYNC_NONE ) -wait_on_page_writeback (page); +if (!PageDirty (page)) { +/* someone wrote it for us */ + goto continue_unlock; + } + +if (PageWriteback (page)) { +if (wbc->sync_mode !=WB_SYNC_NONE ) +wait_on_page_writeback (page); +else + goto continue_unlock; + } -if (PageWriteback (page) || - !clear_page_dirty_for_io (page)) +BUG_ON (PageWriteback (page)); +if (!clear_page_dirty_for_io (page)) goto continue_unlock; ret = (*writepage)(page, wbc, data);
PATCH 34/40 mm: write_cache_pages terminate quickly
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Nick Piggin <[email protected]>
commit d5482cdf8a0aacb1e6468a97d5544f5829c8d8c4 upstream.
Terminate the write_cache_pages loop upon encountering the first page past end, without locking the page. Pages cannot have their index change when we have a reference on them (truncate, eg truncate_inode_pages_range performs the same check without the page lock).
--- mm/page-writeback.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-)
mm/page-writeback.c +16 -16
@@ -914,15 +914,24 @@ retry:for (i =0 ; i < nr_pages; i++) {struct page *page = pvec.pages[i]; - done_index = page->index +1 ; -/* -* At this point we hold neither mapping->tree_lock nor -* lock on the page itself: the page may be truncated or -* invalidated (changing page->mapping to NULL), or even -* swizzled back from swapper_space to tmpfs file -* mapping +* At this point, the page may be truncated or +* invalidated (changing page->mapping to NULL), or +* even swizzled back from swapper_space to tmpfs file +* mapping. However, page->index will not change +* because we have a reference on the page. */ +if (page->index > end) { +/* +* can't be range_cyclic (1st pass) because +* end == -1 in that case. +*/ + done =1 ; +break ; + } + + done_index = page->index +1 ; +lock_page (page);/*
@@ -939,15 +948,6 @@ continue_unlock:continue ; } -if (page->index > end) { -/* -* can't be range_cyclic (1st pass) because -* end == -1 in that case. -*/ - done =1 ; - goto continue_unlock; - } -if (!PageDirty (page)) {/* someone wrote it for us */ goto continue_unlock;
PATCH 35/40 mm: write_cache_pages more terminate quickly
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Andrew Morton <[email protected]>
commit 82fd1a9a8ced9607312b54859572bcc6211e8919 upstream.
Now that we have the early-termination logic in place, it makes sense to bail out early in all other cases where done is set to 1.
--- mm/page-writeback.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
mm/page-writeback.c +4 -1
@@ -987,12 +987,15 @@ continue_unlock:if (wbc->sync_mode ==WB_SYNC_NONE ) { wbc->nr_to_write--; -if (wbc->nr_to_write <=0 ) +if (wbc->nr_to_write <=0 ) { done =1 ; +break ; + } }if (wbc->nonblocking &&bdi_write_congested (bdi)) { wbc->encountered_congestion =1 ; done =1 ; +break ; } }pagevec_release (&pvec);
PATCH 36/40 mm: do_sync_mapping_range integrity fix
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Nick Piggin <[email protected]>
commit ee53a891f47444c53318b98dac947ede963db400 upstream.
Chris Mason notices do_sync_mapping_range didn't actually ask for data integrity writeout. Unfortunately, it is advertised as being usable for data integrity operations.
This is a data integrity bug.
--- fs/sync.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/sync.c +1 -1
@@ -287,7 +287,7 @@ int do_sync_mapping_range(struct addressif (flags &SYNC_FILE_RANGE_WRITE ) { ret =__filemap_fdatawrite_range (mapping, offset, endbyte, -WB_SYNC_NONE ); +WB_SYNC_ALL );if (ret <0 ) goto out; }
PATCH 37/40 mm: direct IO starvation improvement
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Nick Piggin <[email protected]>
commit 48b47c561e41525061b5bc0cfd67d6367fd11dc4 upstream.
Direct IO can invalidate and sync a lot of pagecache pages in the mapping.
A 4K direct IO will actually try to sync and/or invalidate the pagecache
of the entire file, for example (which might be many GB or TB large).
Improve this by doing range syncs. Also, memory no longer has to be unmapped to catch the dirty bits for syncing, as dirty bits would remain coherent due to dirty mmap accounting.
This fixes the immediate DM deadlocks when doing direct IO reads to block device with a mounted filesystem, if only by papering over the problem somewhat rather than addressing the fsync starvation cases.
--- mm/filemap.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-)
mm/filemap.c +5 -11
@@ -1304,7 +1304,8 @@ generic_file_aio_read(struct kiocb *iocb goto out;/* skip atime */ size =i_size_read (inode);if (pos < size) { - retval =filemap_write_and_wait (mapping); + retval =filemap_write_and_wait_range (mapping, pos, + pos +iov_length (iov, nr_segs) -1 );if (!retval) { retval = mapping->a_ops->direct_IO (READ , iocb, iov, pos, nr_segs);
@@ -2117,18 +2118,10 @@ generic_file_direct_write(struct kiocb *if (count != ocount) *nr_segs =iov_shorten ((struct iovec *)iov, *nr_segs, count); -/* -* Unmap all mmappings of the file up-front. -* -* This will cause any pte dirty bits to be propagated into the -* pageframes for the subsequent filemap_write_and_wait(). -*/ write_len =iov_length (iov, *nr_segs); end = (pos + write_len -1 ) >>PAGE_CACHE_SHIFT ; -if (mapping_mapped (mapping)) -unmap_mapping_range (mapping, pos, write_len,0 ); - written =filemap_write_and_wait (mapping); + written =filemap_write_and_wait_range (mapping, pos, pos + write_len -1 );if (written) goto out;
@@ -2519,7 +2512,8 @@ generic_file_buffered_write(struct kiocb* the file data here, to try to honour O_DIRECT expectations. */ if (unlikely (file->f_flags &O_DIRECT ) && written) - status =filemap_write_and_wait (mapping); + status =filemap_write_and_wait_range (mapping, + pos, pos + written -1 );return written ? written : status; }
PATCH 38/40 fs: remove WB_SYNC_HOLD
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Nick Piggin <[email protected]>
commit 4f5a99d64c17470a784a6c68064207d82e3e74a5 upstream.
Remove WB_SYNC_HOLD. The primary motiviation is the design of my anti-starvation code for fsync. It requires taking an inode lock over the sync operation, so we could run into lock ordering problems with multiple inodes. It is possible to take a single global lock to solve the ordering problem, but then that would prevent a future nice implementation of "sync multiple inodes" based on lock order via inode address.
Seems like a backward step to remove this, but actually it is busted
anyway: we can't use the inode lists for data integrity wait: an inode can be taken off the dirty lists but still be under writeback. In order to satisfy data integrity semantics, we should wait for it to finish writeback, but if we only search the dirty lists, we'll miss it.
It would be possible to have a "writeback" list, for sys_sync, I suppose. But why complicate things by prematurely optimise? For unmounting, we could avoid the "livelock avoidance" code, which would be easier, but again premature IMO.
Fixing the existing data integrity problem will come next.
--- fs/fs-writeback.c | 12 ++---------- include/linux/writeback.h | 1 - 2 files changed, 2 insertions(+), 11 deletions(-)
fs/fs-writeback.c +2 -10
@@ -421,9 +421,6 @@ __writeback_single_inode(struct inode *i* If we're a pdlfush thread, then implement pdflush collision avoidance * against the entire list. * -* WB_SYNC_HOLD is a hack for sys_sync(): reattach the inode to sb->s_dirty so -* that it can be located for waiting on in __writeback_single_inode(). -* * If `bdi' is non-zero then we're being asked to writeback a specific queue. * This function assumes that the blockdev superblock's inodes are backed by * a variety of queues, so all inodes are searched. For other superblocks,
@@ -499,10 +496,6 @@ void generic_sync_sb_inodes(struct super__iget (inode); pages_skipped = wbc->pages_skipped;__writeback_single_inode (inode, wbc); -if (wbc->sync_mode ==WB_SYNC_HOLD ) { - inode->dirtied_when = jiffies; -list_move (&inode->i_list, &sb->s_dirty); - }if (current_is_pdflush ())writeback_release (bdi);if (wbc->pages_skipped != pages_skipped) {
@@ -588,8 +581,7 @@ restart:/* * writeback and wait upon the filesystem's dirty inodes. The caller will -* do this in two passes - one to write, and one to wait. WB_SYNC_HOLD is -* used to park the written inodes on sb->s_dirty for the wait pass. +* do this in two passes - one to write, and one to wait. * * A finite limit is set on the number of pages which will be written. * To prevent infinite livelock of sys_sync().
@@ -600,7 +592,7 @@ restart:void sync_inodes_sb (struct super_block *sb,int wait) {struct writeback_control wbc = { - .sync_mode = wait ?WB_SYNC_ALL :WB_SYNC_HOLD , + .sync_mode = wait ?WB_SYNC_ALL :WB_SYNC_NONE , .range_start =0 , .range_end =LLONG_MAX , };
include/linux/writeback.h +0 -1
@@ -30,7 +30,6 @@ static inline int task_is_pdflush(structenum writeback_sync_modes {WB_SYNC_NONE ,/* Don't wait on anything */ WB_SYNC_ALL ,/* Wait on every mapping */ -WB_SYNC_HOLD ,/* Hold the inode on sb_dirty for sys_sync() */ };/*
PATCH 39/40 fs: sync_sb_inodes fix
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Nick Piggin <[email protected]>
commit 38f21977663126fef53f5585e7f1653d8ebe55c4 upstream.
Fix data integrity semantics required by sys_sync, by iterating over all inodes and waiting for any writeback pages after the initial writeout. Comments explain the exact problem.
--- fs/fs-writeback.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 7 deletions(-)
fs/fs-writeback.c +53 -7
@@ -440,6 +440,7 @@ void generic_sync_sb_inodes(struct super struct writeback_control *wbc) {const unsigned long start = jiffies;/* livelock avoidance */ +int sync = wbc->sync_mode ==WB_SYNC_ALL ;spin_lock (&inode_lock);if (!wbc->for_kupdate ||list_empty (&sb->s_io))
@@ -516,7 +517,49 @@ void generic_sync_sb_inodes(struct superif (!list_empty (&sb->s_more_io)) wbc->more_io =1 ; } -spin_unlock (&inode_lock); + +if (sync) { +struct inode *inode, *old_inode =NULL ; + +/* +* Data integrity sync. Must wait for all pages under writeback, +* because there may have been pages dirtied before our sync +* call, but which had writeout started before we write it out. +* In which case, the inode may not be on the dirty list, but +* we still have to wait for that writeout. +*/ +list_for_each_entry (inode, &sb->s_inodes, i_sb_list) { +struct address_space *mapping; + +if (inode->i_state & (I_FREEING |I_WILL_FREE )) +continue ; + mapping = inode->i_mapping; +if (mapping->nrpages ==0 ) +continue ; +__iget (inode); +spin_unlock (&inode_lock); +/* +* We hold a reference to 'inode' so it couldn't have +* been removed from s_inodes list while we dropped the +* inode_lock. We cannot iput the inode now as we can +* be holding the last reference and we cannot iput it +* under inode_lock. So we keep the reference and iput +* it later. +*/ +iput (old_inode); + old_inode = inode; + +filemap_fdatawait (mapping); + +cond_resched (); + +spin_lock (&inode_lock); + } +spin_unlock (&inode_lock); +iput (old_inode); + }else +spin_unlock (&inode_lock); +return ;/* Leave any unwritten inodes on s_io */ }EXPORT_SYMBOL_GPL (generic_sync_sb_inodes);
@@ -596,13 +639,16 @@ void sync_inodes_sb(struct super_block * .range_start = 0, .range_end = LLONG_MAX, }; -unsigned long nr_dirty =global_page_state (NR_FILE_DIRTY ); -unsigned long nr_unstable =global_page_state (NR_UNSTABLE_NFS ); - wbc.nr_to_write = nr_dirty + nr_unstable + - (inodes_stat.nr_inodes - inodes_stat.nr_unused) + - nr_dirty + nr_unstable; - wbc.nr_to_write += wbc.nr_to_write /2 ;/* Bit more for luck */ +if (!wait) { +unsigned long nr_dirty =global_page_state (NR_FILE_DIRTY ); +unsigned long nr_unstable =global_page_state (NR_UNSTABLE_NFS ); + + wbc.nr_to_write = nr_dirty + nr_unstable + + (inodes_stat.nr_inodes - inodes_stat.nr_unused); + }else + wbc.nr_to_write =LONG_MAX ;/* doesn't actually matter */ +sync_sb_inodes (sb, &wbc); }
PATCH 40/40 fs: sys_sync fix
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Nick Piggin <[email protected]>
commit 856bf4d717feb8c55d4e2f817b71ebb70cfbc67b upstream.
s_syncing livelock avoidance was breaking data integrity guarantee of sys_sync, by allowing sys_sync to skip writing or waiting for superblocks if there is a concurrent sys_sync happening.
This livelock avoidance is much less important now that we don't have the get_super_to_sync() call after every sb that we sync. This was replaced by __put_super_and_need_restart.
--- fs/fs-writeback.c | 20 +------------------- include/linux/fs.h | 1 - 2 files changed, 1 insertion(+), 20 deletions(-)
fs/fs-writeback.c +1 -19
@@ -652,18 +652,6 @@ void sync_inodes_sb(struct super_block *sync_sb_inodes (sb, &wbc); } -/* -* Rather lame livelock avoidance. -*/ -static void set_sb_syncing (int val) -{ -struct super_block *sb; -spin_lock (&sb_lock); -list_for_each_entry_reverse (sb, &super_blocks, s_list) - sb->s_syncing = val; -spin_unlock (&sb_lock); -} -/** * sync_inodes - writes all inodes to disk * @wait: wait for completion
@@ -690,9 +678,6 @@ static void __sync_inodes(int wait)spin_lock (&sb_lock); restart:list_for_each_entry (sb, &super_blocks, s_list) { -if (sb->s_syncing) -continue ; - sb->s_syncing =1 ; sb->s_count++;spin_unlock (&sb_lock);down_read (&sb->s_umount);
@@ -710,13 +695,10 @@ restart:void sync_inodes (int wait) { -set_sb_syncing (0 );__sync_inodes (0 ); -if (wait) { -set_sb_syncing (0 ); +if (wait)__sync_inodes (1 ); - } }/**
include/linux/fs.h +0 -1
@@ -1080,7 +1080,6 @@ struct super_block {struct rw_semaphore s_umount;struct mutex s_lock;int s_count; -int s_syncing;int s_need_sync_fs;atomic_t s_active;#ifdef CONFIG_SECURITY