From 7d311cdab663f4f7ab3a4c0d5d484234406f8268 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Thu, 21 Feb 2013 16:42:48 -0800 Subject: bdi: allow block devices to say that they require stable page writes This patchset ("stable page writes, part 2") makes some key modifications to the original 'stable page writes' patchset. First, it provides creators (devices and filesystems) of a backing_dev_info a flag that declares whether or not it is necessary to ensure that page contents cannot change during writeout. It is no longer assumed that this is true of all devices (which was never true anyway). Second, the flag is used to relaxed the wait_on_page_writeback calls so that wait only occurs if the device needs it. Third, it fixes up the remaining disk-backed filesystems to use this improved conditional-wait logic to provide stable page writes on those filesystems. It is hoped that (for people not using checksumming devices, anyway) this patchset will give back unnecessary performance decreases since the original stable page write patchset went into 3.0. Sorry about not fixing it sooner. Complaints were registered by several people about the long write latencies introduced by the original stable page write patchset. Generally speaking, the kernel ought to allocate as little extra memory as possible to facilitate writeout, but for people who simply cannot wait, a second page stability strategy is (re)introduced: snapshotting page contents. The waiting behavior is still the default strategy; to enable page snapshotting, a superblock flag (MS_SNAP_STABLE) must be set. This flag is used to bandaid^Henable stable page writeback on ext3[1], and is not used anywhere else. Given that there are already a few storage devices and network FSes that have rolled their own page stability wait/page snapshot code, it would be nice to move towards consolidating all of these. It seems possible that iscsi and raid5 may wish to use the new stable page write support to enable zero-copy writeout. Thank you to Jan Kara for helping fix a couple more filesystems. Per Andrew Morton's request, here are the result of using dbench to measure latencies on ext2: 3.8.0-rc3: Operation Count AvgLat MaxLat ---------------------------------------- WriteX 109347 0.028 59.817 ReadX 347180 0.004 3.391 Flush 15514 29.828 287.283 Throughput 57.429 MB/sec 4 clients 4 procs max_latency=287.290 ms 3.8.0-rc3 + patches: WriteX 105556 0.029 4.273 ReadX 335004 0.005 4.112 Flush 14982 30.540 298.634 Throughput 55.4496 MB/sec 4 clients 4 procs max_latency=298.650 ms As you can see, for ext2 the maximum write latency decreases from ~60ms on a laptop hard disk to ~4ms. I'm not sure why the flush latencies increase, though I suspect that being able to dirty pages faster gives the flusher more work to do. On ext4, the average write latency decreases as well as all the maximum latencies: 3.8.0-rc3: WriteX 85624 0.152 33.078 ReadX 272090 0.010 61.210 Flush 12129 36.219 168.260 Throughput 44.8618 MB/sec 4 clients 4 procs max_latency=168.276 ms 3.8.0-rc3 + patches: WriteX 86082 0.141 30.928 ReadX 273358 0.010 36.124 Flush 12214 34.800 165.689 Throughput 44.9941 MB/sec 4 clients 4 procs max_latency=165.722 ms XFS seems to exhibit similar latency improvements as ext2: 3.8.0-rc3: WriteX 125739 0.028 104.343 ReadX 399070 0.005 4.115 Flush 17851 25.004 131.390 Throughput 66.0024 MB/sec 4 clients 4 procs max_latency=131.406 ms 3.8.0-rc3 + patches: WriteX 123529 0.028 6.299 ReadX 392434 0.005 4.287 Flush 17549 25.120 188.687 Throughput 64.9113 MB/sec 4 clients 4 procs max_latency=188.704 ms ...and btrfs, just to round things out, also shows some latency decreases: 3.8.0-rc3: WriteX 67122 0.083 82.355 ReadX 212719 0.005 2.828 Flush 9547 47.561 147.418 Throughput 35.3391 MB/sec 4 clients 4 procs max_latency=147.433 ms 3.8.0-rc3 + patches: WriteX 64898 0.101 71.631 ReadX 206673 0.005 7.123 Flush 9190 47.963 219.034 Throughput 34.0795 MB/sec 4 clients 4 procs max_latency=219.044 ms Before this patchset, all filesystems would block, regardless of whether or not it was necessary. ext3 would wait, but still generate occasional checksum errors. The network filesystems were left to do their own thing, so they'd wait too. After this patchset, all the disk filesystems except ext3 and btrfs will wait only if the hardware requires it. ext3 (if necessary) snapshots pages instead of blocking, and btrfs provides its own bdi so the mm will never wait. Network filesystems haven't been touched, so either they provide their own wait code, or they don't block at all. The blocking behavior is back to what it was before 3.0 if you don't have a disk requiring stable page writes. This patchset has been tested on 3.8.0-rc3 on x64 with ext3, ext4, and xfs. I've spot-checked 3.8.0-rc4 and seem to be getting the same results as -rc3. [1] The alternative fixes to ext3 include fixing the locking order and page bit handling like we did for ext4 (but then why not just use ext4?), or setting PG_writeback so early that ext3 becomes extremely slow. I tried that, but the number of write()s I could initiate dropped by nearly an order of magnitude. That was a bit much even for the author of the stable page series! :) This patch: Creates a per-backing-device flag that tracks whether or not pages must be held immutable during writeout. Eventually it will be used to waive wait_for_page_writeback() if nothing requires stable pages. Signed-off-by: Darrick J. Wong Reviewed-by: Jan Kara Cc: Adrian Hunter Cc: Andy Lutomirski Cc: Artem Bityutskiy Cc: Joel Becker Cc: Mark Fasheh Cc: Steven Whitehouse Cc: Jens Axboe Cc: Eric Van Hensbergen Cc: Ron Minnich Cc: Latchesar Ionkov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/ABI/testing/sysfs-class-bdi | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-class-bdi b/Documentation/ABI/testing/sysfs-class-bdi index 5f500977b42f..d773d5697cf5 100644 --- a/Documentation/ABI/testing/sysfs-class-bdi +++ b/Documentation/ABI/testing/sysfs-class-bdi @@ -48,3 +48,8 @@ max_ratio (read-write) most of the write-back cache. For example in case of an NFS mount that is prone to get stuck, or a FUSE mount which cannot be trusted to play fair. + +stable_pages_required (read-only) + + If set, the backing device requires that all pages comprising a write + request must not be changed until writeout is complete. -- cgit v1.2.3-58-ga151 From 242260fb858e99674289484bc2bfe3b41f9c4cbb Mon Sep 17 00:00:00 2001 From: Christian Kujau Date: Thu, 21 Feb 2013 16:43:05 -0800 Subject: sun.com documentation fixes After I came across a help text for SUNGEM mentioning a broken sun.com URL, I felt like fixing those up, as they are now pointing to oracle.com URLs. Signed-off-by: Christian Kujau Acked-by: David S. Miller Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/devicetree/booting-without-of.txt | 2 +- drivers/net/ethernet/sun/Kconfig | 4 ++-- include/uapi/linux/elf.h | 12 ++++++------ net/ipv6/Kconfig | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/booting-without-of.txt b/Documentation/devicetree/booting-without-of.txt index d4d66757354e..b2fb2f5e1922 100644 --- a/Documentation/devicetree/booting-without-of.txt +++ b/Documentation/devicetree/booting-without-of.txt @@ -1228,7 +1228,7 @@ hierarchy and routing of interrupts in the hardware. The interrupt tree model is fully described in the document "Open Firmware Recommended Practice: Interrupt Mapping Version 0.9". The document is available at: -. + 1) interrupts property ---------------------- diff --git a/drivers/net/ethernet/sun/Kconfig b/drivers/net/ethernet/sun/Kconfig index 57bfd8599679..208c39dedc2e 100644 --- a/drivers/net/ethernet/sun/Kconfig +++ b/drivers/net/ethernet/sun/Kconfig @@ -61,7 +61,7 @@ config SUNGEM select SUNGEM_PHY ---help--- Support for the Sun GEM chip, aka Sun GigabitEthernet/P 2.0. See also - . + . config CASSINI tristate "Sun Cassini support" @@ -69,7 +69,7 @@ config CASSINI select CRC32 ---help--- Support for the Sun Cassini chip, aka Sun GigaSwift Ethernet. See also - + . config SUNVNET tristate "Sun Virtual Network support" diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h index 126a8175e3e2..900b9484445b 100644 --- a/include/uapi/linux/elf.h +++ b/include/uapi/linux/elf.h @@ -49,14 +49,14 @@ typedef __s64 Elf64_Sxword; * * Specifications are available in: * - * - Sun microsystems: Linker and Libraries. - * Part No: 817-1984-17, September 2008. - * URL: http://docs.sun.com/app/docs/doc/817-1984 + * - Oracle: Linker and Libraries. + * Part No: 817–1984–19, August 2011. + * http://docs.oracle.com/cd/E18752_01/pdf/817-1984.pdf * * - System V ABI AMD64 Architecture Processor Supplement - * Draft Version 0.99., - * May 11, 2009. - * URL: http://www.x86-64.org/ + * Draft Version 0.99.4, + * January 13, 2010. + * http://www.cs.washington.edu/education/courses/cse351/12wi/supp-docs/abi.pdf */ #define PN_XNUM 0xffff diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig index 4f7fe7270e37..a2246afc0007 100644 --- a/net/ipv6/Kconfig +++ b/net/ipv6/Kconfig @@ -11,7 +11,7 @@ menuconfig IPV6 You will still be able to do traditional IPv4 networking as well. For general information about IPv6, see - . + . For Linux IPv6 development information, see . For specific information about IPv6 under Linux, read the HOWTO at . -- cgit v1.2.3-58-ga151 From 7d7992108d02aa92ad4c77e5d9ce14088c942e75 Mon Sep 17 00:00:00 2001 From: Stepan Moskovchenko Date: Thu, 21 Feb 2013 16:43:09 -0800 Subject: lib/vsprintf.c: add %pa format specifier for phys_addr_t types Add the %pa format specifier for printing a phys_addr_t type and its derivative types (such as resource_size_t), since the physical address size on some platforms can vary based on build options, regardless of the native integer type. Signed-off-by: Stepan Moskovchenko Cc: Rob Landley Cc: George Spelvin Cc: Andy Shevchenko Cc: Stephen Boyd Cc: Andrei Emeltchenko Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/printk-formats.txt | 14 +++++++++++--- lib/vsprintf.c | 7 +++++++ 2 files changed, 18 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/printk-formats.txt b/Documentation/printk-formats.txt index 8ffb274367c7..e8a6aa473bab 100644 --- a/Documentation/printk-formats.txt +++ b/Documentation/printk-formats.txt @@ -53,6 +53,14 @@ Struct Resources: For printing struct resources. The 'R' and 'r' specifiers result in a printed resource with ('R') or without ('r') a decoded flags member. +Physical addresses: + + %pa 0x01234567 or 0x0123456789abcdef + + For printing a phys_addr_t type (and its derivatives, such as + resource_size_t) which can vary based on build options, regardless of + the width of the CPU data path. Passed by reference. + Raw buffer as a hex string: %*ph 00 01 02 ... 3f %*phC 00:01:02: ... :3f @@ -150,9 +158,9 @@ s64 SHOULD be printed with %lld/%llx, (long long): printk("%lld", (long long)s64_var); If is dependent on a config option for its size (e.g., sector_t, -blkcnt_t, phys_addr_t, resource_size_t) or is architecture-dependent -for its size (e.g., tcflag_t), use a format specifier of its largest -possible type and explicitly cast to it. Example: +blkcnt_t) or is architecture-dependent for its size (e.g., tcflag_t), use a +format specifier of its largest possible type and explicitly cast to it. +Example: printk("test: sector number/total blocks: %llu/%llu\n", (unsigned long long)sector, (unsigned long long)blockcount); diff --git a/lib/vsprintf.c b/lib/vsprintf.c index fab33a9c5318..0d62fd700f68 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1030,6 +1030,7 @@ int kptr_restrict __read_mostly; * N no separator * The maximum supported length is 64 bytes of the input. Consider * to use print_hex_dump() for the larger input. + * - 'a' For a phys_addr_t type and its derivative types (passed by reference) * * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 * function pointers are really function descriptors, which contain a @@ -1120,6 +1121,12 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, return netdev_feature_string(buf, end, ptr, spec); } break; + case 'a': + spec.flags |= SPECIAL | SMALL | ZEROPAD; + spec.field_width = sizeof(phys_addr_t) * 2 + 2; + spec.base = 16; + return number(buf, end, + (unsigned long long) *((phys_addr_t *)ptr), spec); } spec.flags |= SMALL; if (spec.field_width == -1) { -- cgit v1.2.3-58-ga151 From 26e8ccc223ebfd2047a96074f142544dc7062cfe Mon Sep 17 00:00:00 2001 From: "Kim, Milo" Date: Thu, 21 Feb 2013 16:44:06 -0800 Subject: backlight: lp855x_bl: support new LP8557 device LP8557 is one of LP855x family device, but it has different register map and initialization process. To support this device, device specific configuration is done through the lp855x_device_config structure. Few register definitions are fixed for better readability. BRIGHTNESS_CTRL -> LP855X_BRIGHTNESS_CTRL DEVICE_CTRL -> LP855X_DEVICE_CTRL EEPROM_START -> LP855X_EEPROM_START EEPROM_END -> LP855X_EEPROM_END EPROM_START -> LP8556_EPROM_START EPROM_END -> LP8556_EPROM_END And LP8557 register definitions are added. New register function, lp855x_update_bit() is added. Signed-off-by: Milo(Woogyom) Kim Acked-by: Jingoo Han Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/backlight/lp855x-driver.txt | 4 +- drivers/video/backlight/Kconfig | 2 +- drivers/video/backlight/lp855x_bl.c | 87 +++++++++++++++++++++++++------ include/linux/platform_data/lp855x.h | 19 +++++++ 4 files changed, 94 insertions(+), 18 deletions(-) (limited to 'Documentation') diff --git a/Documentation/backlight/lp855x-driver.txt b/Documentation/backlight/lp855x-driver.txt index 1529394cfe8b..18b06ca038ea 100644 --- a/Documentation/backlight/lp855x-driver.txt +++ b/Documentation/backlight/lp855x-driver.txt @@ -4,7 +4,7 @@ Kernel driver lp855x Backlight driver for LP855x ICs Supported chips: - Texas Instruments LP8550, LP8551, LP8552, LP8553 and LP8556 + Texas Instruments LP8550, LP8551, LP8552, LP8553, LP8556 and LP8557 Author: Milo(Woogyom) Kim @@ -24,7 +24,7 @@ Value : pwm based or register based 2) chip_id The lp855x chip id. -Value : lp8550/lp8551/lp8552/lp8553/lp8556 +Value : lp8550/lp8551/lp8552/lp8553/lp8556/lp8557 Platform data for lp855x ------------------------ diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index a942a2488480..be27b551473f 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -381,7 +381,7 @@ config BACKLIGHT_LP855X tristate "Backlight driver for TI LP855X" depends on BACKLIGHT_CLASS_DEVICE && I2C help - This supports TI LP8550, LP8551, LP8552, LP8553 and LP8556 + This supports TI LP8550, LP8551, LP8552, LP8553, LP8556 and LP8557 backlight driver. config BACKLIGHT_OT200 diff --git a/drivers/video/backlight/lp855x_bl.c b/drivers/video/backlight/lp855x_bl.c index 050cfbb53667..edd2041b1527 100644 --- a/drivers/video/backlight/lp855x_bl.c +++ b/drivers/video/backlight/lp855x_bl.c @@ -17,13 +17,23 @@ #include #include -/* Registers */ -#define BRIGHTNESS_CTRL 0x00 -#define DEVICE_CTRL 0x01 -#define EEPROM_START 0xA0 -#define EEPROM_END 0xA7 -#define EPROM_START 0xA0 -#define EPROM_END 0xAF +/* LP8550/1/2/3/6 Registers */ +#define LP855X_BRIGHTNESS_CTRL 0x00 +#define LP855X_DEVICE_CTRL 0x01 +#define LP855X_EEPROM_START 0xA0 +#define LP855X_EEPROM_END 0xA7 +#define LP8556_EPROM_START 0xA0 +#define LP8556_EPROM_END 0xAF + +/* LP8557 Registers */ +#define LP8557_BL_CMD 0x00 +#define LP8557_BL_MASK 0x01 +#define LP8557_BL_ON 0x01 +#define LP8557_BL_OFF 0x00 +#define LP8557_BRIGHTNESS_CTRL 0x04 +#define LP8557_CONFIG 0x10 +#define LP8557_EPROM_START 0x10 +#define LP8557_EPROM_END 0x1E #define BUF_SIZE 20 #define DEFAULT_BL_NAME "lcd-backlight" @@ -75,6 +85,24 @@ static int lp855x_write_byte(struct lp855x *lp, u8 reg, u8 data) return i2c_smbus_write_byte_data(lp->client, reg, data); } +static int lp855x_update_bit(struct lp855x *lp, u8 reg, u8 mask, u8 data) +{ + int ret; + u8 tmp; + + ret = i2c_smbus_read_byte_data(lp->client, reg); + if (ret < 0) { + dev_err(lp->dev, "failed to read 0x%.2x\n", reg); + return ret; + } + + tmp = (u8)ret; + tmp &= ~mask; + tmp |= data & mask; + + return lp855x_write_byte(lp, reg, tmp); +} + static bool lp855x_is_valid_rom_area(struct lp855x *lp, u8 addr) { u8 start, end; @@ -84,12 +112,16 @@ static bool lp855x_is_valid_rom_area(struct lp855x *lp, u8 addr) case LP8551: case LP8552: case LP8553: - start = EEPROM_START; - end = EEPROM_END; + start = LP855X_EEPROM_START; + end = LP855X_EEPROM_END; break; case LP8556: - start = EPROM_START; - end = EPROM_END; + start = LP8556_EPROM_START; + end = LP8556_EPROM_END; + break; + case LP8557: + start = LP8557_EPROM_START; + end = LP8557_EPROM_END; break; default: return false; @@ -98,9 +130,30 @@ static bool lp855x_is_valid_rom_area(struct lp855x *lp, u8 addr) return (addr >= start && addr <= end); } +static int lp8557_bl_off(struct lp855x *lp) +{ + /* BL_ON = 0 before updating EPROM settings */ + return lp855x_update_bit(lp, LP8557_BL_CMD, LP8557_BL_MASK, + LP8557_BL_OFF); +} + +static int lp8557_bl_on(struct lp855x *lp) +{ + /* BL_ON = 1 after updating EPROM settings */ + return lp855x_update_bit(lp, LP8557_BL_CMD, LP8557_BL_MASK, + LP8557_BL_ON); +} + static struct lp855x_device_config lp855x_dev_cfg = { - .reg_brightness = BRIGHTNESS_CTRL, - .reg_devicectrl = DEVICE_CTRL, + .reg_brightness = LP855X_BRIGHTNESS_CTRL, + .reg_devicectrl = LP855X_DEVICE_CTRL, +}; + +static struct lp855x_device_config lp8557_dev_cfg = { + .reg_brightness = LP8557_BRIGHTNESS_CTRL, + .reg_devicectrl = LP8557_CONFIG, + .pre_init_device = lp8557_bl_off, + .post_init_device = lp8557_bl_on, }; /* @@ -123,6 +176,9 @@ static int lp855x_configure(struct lp855x *lp) case LP8550 ... LP8556: lp->cfg = &lp855x_dev_cfg; break; + case LP8557: + lp->cfg = &lp8557_dev_cfg; + break; default: return -EINVAL; } @@ -210,7 +266,7 @@ static int lp855x_bl_update_status(struct backlight_device *bl) } else if (mode == REGISTER_BASED) { u8 val = bl->props.brightness; - lp855x_write_byte(lp, BRIGHTNESS_CTRL, val); + lp855x_write_byte(lp, lp->cfg->reg_brightness, val); } return 0; @@ -224,7 +280,7 @@ static int lp855x_bl_get_brightness(struct backlight_device *bl) if (mode == REGISTER_BASED) { u8 val = 0; - lp855x_read_byte(lp, BRIGHTNESS_CTRL, &val); + lp855x_read_byte(lp, lp->cfg->reg_brightness, &val); bl->props.brightness = val; } @@ -376,6 +432,7 @@ static const struct i2c_device_id lp855x_ids[] = { {"lp8552", LP8552}, {"lp8553", LP8553}, {"lp8556", LP8556}, + {"lp8557", LP8557}, { } }; MODULE_DEVICE_TABLE(i2c, lp855x_ids); diff --git a/include/linux/platform_data/lp855x.h b/include/linux/platform_data/lp855x.h index e81f62d24ee2..20ee8b221dbd 100644 --- a/include/linux/platform_data/lp855x.h +++ b/include/linux/platform_data/lp855x.h @@ -49,12 +49,24 @@ #define LP8556_FAST_CONFIG BIT(7) /* use it if EPROMs should be maintained when exiting the low power mode */ +/* CONFIG register - LP8557 */ +#define LP8557_PWM_STANDBY BIT(7) +#define LP8557_PWM_FILTER BIT(6) +#define LP8557_RELOAD_EPROM BIT(3) /* use it if EPROMs should be reset + when the backlight turns on */ +#define LP8557_OFF_OPENLEDS BIT(2) +#define LP8557_PWM_CONFIG LP8557_PWM_ONLY +#define LP8557_I2C_CONFIG LP8557_I2C_ONLY +#define LP8557_COMB1_CONFIG LP8557_COMBINED1 +#define LP8557_COMB2_CONFIG LP8557_COMBINED2 + enum lp855x_chip_id { LP8550, LP8551, LP8552, LP8553, LP8556, + LP8557, }; enum lp855x_brightness_ctrl_mode { @@ -89,6 +101,13 @@ enum lp8556_brightness_source { LP8556_COMBINED2, /* pwm + i2c after the shaper block */ }; +enum lp8557_brightness_source { + LP8557_PWM_ONLY, + LP8557_I2C_ONLY, + LP8557_COMBINED1, /* pwm + i2c after the shaper block */ + LP8557_COMBINED2, /* pwm + i2c before the shaper block */ +}; + struct lp855x_rom_data { u8 addr; u8 val; -- cgit v1.2.3-58-ga151