3.3.1-stable review
Subsystems (101)
Greg KH
maintainerPATCH 143/175 gpio/omap: fix _set_gpio_irqenable implementation
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tarun Kanti DebBarma <[email protected]>
commit 8276536cec38bc6bde30d0aa67716f22b9b9705a upstream.
This function should be capable of both enabling and disabling interrupts based upon the *enable* parameter. Right now the function only enables the interrupt and *enable* is not used at all. So add the interrupt disable capability also using the parameter.
--- drivers/gpio/gpio-omap.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/gpio/gpio-omap.c +4 -1
@@ -508,7 +508,10 @@ static void _disable_gpio_irqbank(structstatic inline void _set_gpio_irqenable (struct gpio_bank *bank,int gpio,int enable) { -_enable_gpio_irqbank (bank,GPIO_BIT (bank, gpio)); +if (enable) +_enable_gpio_irqbank (bank,GPIO_BIT (bank, gpio)); +else +_disable_gpio_irqbank (bank,GPIO_BIT (bank, gpio)); }/*
Greg KH
maintainerPATCH 144/175 gpio/davinci: fix oops on unbanked gpio irq request
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sekhar Nori <[email protected]>
commit ab2dde9924dd1ddb791fa8b14aa52e1df681e20c upstream.
Unbanked GPIO irq setup code was overwriting chip_data leading to the following oops on request_irq()
Unable to handle kernel paging request at virtual address febfffff pgd = c22dc000 [febfffff] *pgd=00000000 Internal error: Oops: 801 [#1] PREEMPT Modules linked in: mcu(+) edmak irqk cmemk CPU: 0 Not tainted (3.0.0-rc7+ #93) PC is at irq_gc_mask_set_bit+0x68/0x7c LR is at vprintk+0x22c/0x484 pc : [<c0080c0c>] lr : [<c00457e0>] psr: 60000093
sp : c33e3ba0 ip : c33e3af0 fp : c33e3bc4
r10: c04555bc r9 : c33d4340 r8 : 60000013
r7 : 0000002d r6 : c04555bc r5 : fec67010 r4 : 00000000 r3 : c04734c8 r2 : fec00000 r1 : ffffffff r0 : 00000026
Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment user
Control: 0005317f Table: 822dc000 DAC: 00000015 Process modprobe (pid: 526, stack limit = 0xc33e2270)
Stack: (0xc33e3ba0 to 0xc33e4000)
3ba0: 00000000 c007d3d4 c33e3bcc c04555bc c04555bc c33d4340 c33e3bdc c33e3bc8 3bc0: c007f5f8 c0080bb4 00000000 c04555bc c33e3bf4 c33e3be0 c007f654 c007f5c0 3be0: 00000000 c04555bc c33e3c24 c33e3bf8 c007e6e8 c007f618 c01f2284 c0350af8 3c00: c0405214 bf016c98 00000001 00000000 c33dc008 0000002d c33e3c54 c33e3c28 3c20: c007e888 c007e408 00000001 c23ef880 c33dc000 00000000 c33dc080 c25caa00 3c40: c0487498 bf017078 c33e3c94 c33e3c58 bf016b44 c007e7d4 bf017078 c33dc008 3c60: c25caa08 c33dc008 c33e3c84 bf017484 c25caa00 c25caa00 c01f5f48 c25caa08 3c80: c0496d60 bf017484 c33e3ca4 c33e3c98 c022a698 bf01692c c33e3cd4 c33e3ca8 3ca0: c01f5d88 c022a688 00000000 bf017484 c25caa00 c25caa00 c01f5f48 c25caa08 3cc0: c0496d60 00000000 c33e3cec c33e3cd8 c01f5f8c c01f5d10 00000000 c33e3cf0 3ce0: c33e3d14 c33e3cf0 c01f5210 c01f5f58 c303cb48 c25ecf94 c25caa00 c25caa00 3d00: c25caa34 c33e3dd8 c33e3d34 c33e3d18 c01f6044 c01f51b8 c0496d3c c25caa00 3d20: c044e918 c33e3dd8 c33e3d44 c33e3d38 c01f4ff4 c01f5fcc c33e3d94 c33e3d48 3d40: c01f3d10 c01f4fd8 00000000 c044e918 00000000 00000000 c01f52c0 c034d570 3d60: c33e3d84 c33e3d70 c022bf84 c25caa00 00000000 c044e918 c33e3dd8 c25c2e00 3d80: c0496d60 bf01763c c33e3db4 c33e3d98 c022b1a0 c01f384c c25caa00 c33e3dd8 3da0: 00000000 c33e3dd8 c33e3dd4 c33e3db8 c022b27c c022b0e8 00000000 bf01763c 3dc0: c0451c80 c33e3dd8 c33e3e34 c33e3dd8 bf016f60 c022b210 5f75636d 746e6f63 3de0: 006c6f72 00000000 00000000 00000000 00000000 00000000 00000000 bf0174bc 3e00: 00000000 00989680 00000000 00000020 c0451c80 c0451c80 bf0174dc c01f5eb0 3e20: c33f0f00 bf0174dc c33e3e44 c33e3e38 c01f72f4 bf016e2c c33e3e74 c33e3e48 3e40: c01f5d88 c01f72e4 00000000 c0451c80 c0451cb4 bf0174dc c01f5eb0 c33f0f00 3e60: c0473100 00000000 c33e3e94 c33e3e78 c01f5f44 c01f5d10 00000000 c33e3e98 3e80: bf0174dc c01f5eb0 c33e3ebc c33e3e98 c01f5534 c01f5ec0 c303c038 c3061c30 3ea0: 00003cd8 00098258 bf0174dc c0462ac8 c33e3ecc c33e3ec0 c01f5bec c01f54dc 3ec0: c33e3efc c33e3ed0 c01f4d30 c01f5bdc bf0173a0 c33e2000 00003cd8 00098258 3ee0: bf0174dc c33e2000 c00301a4 bf019000 c33e3f1c c33e3f00 c01f6588 c01f4c8c 3f00: 00003cd8 00098258 00000000 c33e2000 c33e3f2c c33e3f20 c01f777c c01f6524 3f20: c33e3f3c c33e3f30 bf019014 c01f7740 c33e3f7c c33e3f40 c002f3ec bf019010 3f40: 00000000 00003cd8 00098258 bf017518 00000000 00003cd8 00098258 bf017518 3f60: 00000000 c00301a4 c33e2000 00000000 c33e3fa4 c33e3f80 c007b934 c002f3c4 3f80: c00b307c c00b2f48 00003cd8 00000000 00000003 00000080 00000000 c33e3fa8 3fa0: c0030020 c007b8b8 00003cd8 00000000 00098288 00003cd8 00098258 00098240 3fc0: 00003cd8 00000000 00000003 00000080 00098008 00098028 00098288 00000001 3fe0: be892998 be892988 00013d7c 40178740 60000010 00098288 09089041 00200845
Backtrace: [<c0080ba4>] (irq_gc_mask_set_bit+0x0/0x7c) from [<c007f5f8>] (irq_enable+0x48/0x58) r6:c33d4340 r5:c04555bc r4:c04555bc [<c007f5b0>] (irq_enable+0x0/0x58) from [<c007f654>] (irq_startup+0x4c/0x54) r5:c04555bc r4:00000000 [<c007f608>] (irq_startup+0x0/0x54) from [<c007e6e8>] (__setup_irq+0x2f0/0x3cc) r5:c04555bc r4:00000000 [<c007e3f8>] (__setup_irq+0x0/0x3cc) from [<c007e888>] (request_threaded_irq+0xc4/0x110) r8:0000002d r7:c33dc008 r6:00000000 r5:00000001 r4:bf016c98 [<c007e7c4>] (request_threaded_irq+0x0/0x110) from [<bf016b44>] (mcu_spi_probe+0x228/0x37c [mcu]) [<bf01691c>] (mcu_spi_probe+0x0/0x37c [mcu]) from [<c022a698>] (spi_drv_probe+0x20/0x24) [<c022a678>] (spi_drv_probe+0x0/0x24) from [<c01f5d88>] (driver_probe_device+0x88/0x1b0) [<c01f5d00>] (driver_probe_device+0x0/0x1b0) from [<c01f5f8c>] (__device_attach+0x44/0x48) [<c01f5f48>] (__device_attach+0x0/0x48) from [<c01f5210>] (bus_for_each_drv+0x68/0x94) r5:c33e3cf0 r4:00000000 [<c01f51a8>] (bus_for_each_drv+0x0/0x94) from [<c01f6044>] (device_attach+0x88/0xa0) r7:c33e3dd8 r6:c25caa34 r5:c25caa00 r4:c25caa00 [<c01f5fbc>] (device_attach+0x0/0xa0) from [<c01f4ff4>] (bus_probe_device+0x2c/0x4c) r7:c33e3dd8 r6:c044e918 r5:c25caa00 r4:c0496d3c [<c01f4fc8>] (bus_probe_device+0x0/0x4c) from [<c01f3d10>] (device_add+0x4d4/0x648) [<c01f383c>] (device_add+0x0/0x648) from [<c022b1a0>] (spi_add_device+0xc8/0x128) [<c022b0d8>] (spi_add_device+0x0/0x128) from [<c022b27c>] (spi_new_device+0x7c/0xb4) r7:c33e3dd8 r6:00000000 r5:c33e3dd8 r4:c25caa00 [<c022b200>] (spi_new_device+0x0/0xb4) from [<bf016f60>] (mcu_probe+0x144/0x224 [mcu]) r7:c33e3dd8 r6:c0451c80 r5:bf01763c r4:00000000 [<bf016e1c>] (mcu_probe+0x0/0x224 [mcu]) from [<c01f72f4>] (platform_drv_probe+0x20/0x24) [<c01f72d4>] (platform_drv_probe+0x0/0x24) from [<c01f5d88>] (driver_probe_device+0x88/0x1b0) [<c01f5d00>] (driver_probe_device+0x0/0x1b0) from [<c01f5f44>] (__driver_attach+0x94/0x98) [<c01f5eb0>] (__driver_attach+0x0/0x98) from [<c01f5534>] (bus_for_each_dev+0x68/0x94) r7:c01f5eb0 r6:bf0174dc r5:c33e3e98 r4:00000000 [<c01f54cc>] (bus_for_each_dev+0x0/0x94) from [<c01f5bec>] (driver_attach+0x20/0x28) r7:c0462ac8 r6:bf0174dc r5:00098258 r4:00003cd8 [<c01f5bcc>] (driver_attach+0x0/0x28) from [<c01f4d30>] (bus_add_driver+0xb4/0x258) [<c01f4c7c>] (bus_add_driver+0x0/0x258) from [<c01f6588>] (driver_register+0x74/0x158) [<c01f6514>] (driver_register+0x0/0x158) from [<c01f777c>] (platform_driver_register+0x4c/0x60) r7:c33e2000 r6:00000000 r5:00098258 r4:00003cd8 [<c01f7730>] (platform_driver_register+0x0/0x60) from [<bf019014>] (mcu_init+0x14/0x20 [mcu]) [<bf019000>] (mcu_init+0x0/0x20 [mcu]) from [<c002f3ec>] (do_one_initcall+0x38/0x170) [<c002f3b4>] (do_one_initcall+0x0/0x170) from [<c007b934>] (sys_init_module+0x8c/0x1a4) [<c007b8a8>] (sys_init_module+0x0/0x1a4) from [<c0030020>] (ret_fast_syscall+0x0/0x2c) r7:00000080 r6:00000003 r5:00000000 r4:00003cd8 Code: e1844003 e585400c e596300c e5932064 (e7814002)
Fix the issue.
--- drivers/gpio/gpio-davinci.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/gpio/gpio-davinci.c +10 -5
@@ -313,10 +313,16 @@ static int gpio_to_irq_unbanked(struct greturn -ENODEV ; } -static int gpio_irq_type_unbanked (struct irq_data *d,unsigned trigger) +static int gpio_irq_type_unbanked (struct irq_data *data,unsigned trigger) { -struct davinci_gpio_regs __iomem *g =irq2regs (d->irq); -u32 mask = (u32 )irq_data_get_irq_handler_data (d); +struct davinci_gpio_controller *d; +struct davinci_gpio_regs __iomem *g; +struct davinci_soc_info *soc_info = &davinci_soc_info; +u32 mask; + + d = (struct davinci_gpio_controller *)data->handler_data; + g = (struct davinci_gpio_regs __iomem *)d->regs; + mask =__gpio_mask (data->irq - soc_info->gpio_irq);if (trigger & ~(IRQ_TYPE_EDGE_FALLING |IRQ_TYPE_EDGE_RISING ))return -EINVAL ;
@@ -400,8 +406,7 @@ static int __init davinci_gpio_irq_setup/* set the direct IRQs up to use that irqchip */ for (gpio =0 ; gpio < soc_info->gpio_unbanked; gpio++, irq++) {irq_set_chip (irq, &gpio_irqchip_unbanked); -irq_set_handler_data (irq, (void *)__gpio_mask (gpio)); -irq_set_chip_data (irq, (__force void *)g); +irq_set_handler_data (irq, &chips[gpio /32 ]);irq_set_status_flags (irq,IRQ_TYPE_EDGE_BOTH ); }
Greg KH
maintainerPATCH 145/175 gpio/davinci: fix enabling unbanked GPIO IRQs
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sekhar Nori <[email protected]>
commit 81b279d80a63628e580c71a31d30a8c3b3047ad4 upstream.
Unbanked GPIO IRQ handling code made a copy of just the irq_chip structure for GPIO IRQ lines which caused problems after the generic IRQ chip conversion because there was no valid irq_chip_type structure with the right "regs" populated. irq_gc_mask_set_bit() was therefore accessing random addresses.
Fix it by making a copy of irq_chip_type structure instead. This will ensure sane register offsets.
--- drivers/gpio/gpio-davinci.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
drivers/gpio/gpio-davinci.c +6 -5
@@ -386,7 +386,7 @@ static int __init davinci_gpio_irq_setup* IRQ mux conflicts; gpio_irq_type_unbanked() is only for GPIOs. */ if (soc_info->gpio_unbanked) { -static struct irq_chip gpio_irqchip_unbanked; +static struct irq_chip_type gpio_unbanked;/* pass "bank 0" GPIO IRQs to AINTC */ chips[0 ].chip.to_irq = gpio_to_irq_unbanked;
@@ -394,9 +394,10 @@ static int __init davinci_gpio_irq_setup/* AINTC handles mask/unmask; GPIO handles triggering */ irq = bank_irq; - gpio_irqchip_unbanked = *irq_get_chip (irq); - gpio_irqchip_unbanked.name ="GPIO-AINTC" ; - gpio_irqchip_unbanked.irq_set_type = gpio_irq_type_unbanked; + gpio_unbanked = *container_of (irq_get_chip (irq), + struct irq_chip_type, chip); + gpio_unbanked.chip.name ="GPIO-AINTC" ; + gpio_unbanked.chip.irq_set_type = gpio_irq_type_unbanked;/* default trigger: both edges */ g =gpio2regs (0 );
@@ -405,7 +406,7 @@ static int __init davinci_gpio_irq_setup/* set the direct IRQs up to use that irqchip */ for (gpio =0 ; gpio < soc_info->gpio_unbanked; gpio++, irq++) { -irq_set_chip (irq, &gpio_irqchip_unbanked); +irq_set_chip (irq, &gpio_unbanked.chip);irq_set_handler_data (irq, &chips[gpio /32 ]);irq_set_status_flags (irq,IRQ_TYPE_EDGE_BOTH ); }
Greg KH
maintainerPATCH 146/175 mfd: Test for jack detection when deciding if wm8994 should suspend
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Brown <[email protected]>
commit d2cb87c23e8514ca49c85adc5924999927bb9494 upstream.
The jack detection on WM1811 is often required during system suspend, add it as another check when deciding if we should suspend.
--- drivers/mfd/wm8994-core.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
drivers/mfd/wm8994-core.c +14 -0
@@ -270,6 +270,20 @@ static int wm8994_suspend(struct devicebreak ; } +switch (wm8994->type) { +case WM1811 : + ret =wm8994_reg_read (wm8994,WM8994_ANTIPOP_2 ); +if (ret <0 ) { +dev_err (dev,"Failed to read jackdet: %d\n" , ret); + }else if (ret &WM1811_JACKDET_MODE_MASK ) { +dev_dbg (dev,"CODEC still active, ignoring suspend\n" ); +return 0 ; + } +break ; +default : +break ; + } +/* Disable LDO pulldowns while the device is suspended if we * don't know that something will be driving them. */ if (!wm8994->ldo_ena_always_driven)
Greg KH
maintainerPATCH 147/175 drm/radeon/kms/atom: force bpc to 8 for now
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 017d213f649c6775e4a4349e50a5631a4e4c7308 upstream.
Using the bpc (bits per color) specified by the monitor can cause problems in some cases. Until we get a better handle on how to deal with those cases, just use a bpc of 8.
--- drivers/gpu/drm/radeon/atombios_crtc.c | 8 +++++--- drivers/gpu/drm/radeon/atombios_dp.c | 3 +++ drivers/gpu/drm/radeon/atombios_encoders.c | 4 ++-- 3 files changed, 10 insertions(+), 5 deletions(-)
drivers/gpu/drm/radeon/atombios_crtc.c +5 -3
@@ -550,8 +550,8 @@ static u32 atombios_adjust_pll(struct drif (encoder->crtc == crtc) { radeon_encoder =to_radeon_encoder (encoder); connector =radeon_get_connector_for_encoder (encoder); -if (connector && connector->display_info.bpc) - bpc = connector->display_info.bpc; +/* if (connector && connector->display_info.bpc) +bpc = connector->display_info.bpc; */ encoder_mode =atombios_get_encoder_mode (encoder); is_duallink =radeon_dig_monitor_is_duallink (encoder, mode->clock); if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
@@ -922,7 +922,9 @@ static void atombios_crtc_set_pll(structstruct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;int dp_clock; - bpc = connector->display_info.bpc; + +/* if (connector->display_info.bpc) +bpc = connector->display_info.bpc; */ switch (encoder_mode) {case ATOM_ENCODER_MODE_DP_MST :
drivers/gpu/drm/radeon/atombios_dp.c +3 -0
@@ -405,10 +405,13 @@ static void dp_get_adjust_train(u8 link_/* get bpc from the EDID */ static int convert_bpc_to_bpp (int bpc) { +#if 0 if (bpc ==0 )return 24 ;else return bpc *3 ; +#endif +return 24 ; }/* get the max pix clock supported by the link rate and lane num */
drivers/gpu/drm/radeon/atombios_encoders.c +2 -2
@@ -537,7 +537,7 @@ atombios_dig_encoder_setup(struct drm_en dp_clock = dig_connector->dp_clock; dp_lane_count = dig_connector->dp_lane_count; hpd_id = radeon_connector->hpd.hpd; - bpc = connector->display_info.bpc; +/* bpc = connector->display_info.bpc; */ }/* no dig encoder assigned */
@@ -1098,7 +1098,7 @@ atombios_external_encoder_setup(struct d dp_lane_count = dig_connector->dp_lane_count; connector_object_id = (radeon_connector->connector_object_id &OBJECT_ID_MASK ) >>OBJECT_ID_SHIFT ; - bpc = connector->display_info.bpc; +/* bpc = connector->display_info.bpc; */ }memset (&args,0 ,sizeof (args));
Greg KH
maintainerPATCH 148/175 dm crypt: fix mempool deadlock
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikulas Patocka <[email protected]>
commit aeb2deae2660a1773c83d3c6e9e6575daa3855d6 upstream.
This patch fixes a possible deadlock in dm-crypt's mempool use.
Currently, dm-crypt reserves a mempool of MIN_BIO_PAGES reserved pages. It allocates first MIN_BIO_PAGES with non-failing allocation (the allocation cannot fail and waits until the mempool is refilled). Further pages are allocated with different gfp flags that allow failing.
Because allocations may be done in parallel, this code can deadlock. Example:
There are two processes, each tries to allocate MIN_BIO_PAGES and the processes run simultaneously.
It may end up in a situation where each process allocates (MIN_BIO_PAGES / 2) pages. The mempool is exhausted. Each process waits for more pages to be freed to the mempool, which never happens.
To avoid this deadlock scenario, this patch changes the code so that only the first page is allocated with non-failing gfp mask. Allocation of further pages may fail.
--- drivers/md/dm-crypt.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
drivers/md/dm-crypt.c +4 -6
@@ -176,7 +176,6 @@ struct crypt_config {#define MIN_IOS 16#define MIN_POOL_PAGES 32 -#define MIN_BIO_PAGES 8static struct kmem_cache *_crypt_io_pool;
@@ -848,12 +847,11 @@ static struct bio *crypt_alloc_buffer(st }/* -* if additional pages cannot be allocated without waiting, -* return a partially allocated bio, the caller will then try -* to allocate additional bios while submitting this partial bio +* If additional pages cannot be allocated without waiting, +* return a partially-allocated bio. The caller will then try +* to allocate more bios while submitting this partial bio. */ -if (i == (MIN_BIO_PAGES -1 )) - gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT; + gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT; len = (size >PAGE_SIZE ) ?PAGE_SIZE : size;
Greg KH
maintainerPATCH 149/175 dm crypt: add missing error handling
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikulas Patocka <[email protected]>
commit 72c6e7afc43e19f68a31dea204fc366624d6eee9 upstream.
Always set io->error to -EIO when an error is detected in dm-crypt.
There were cases where an error code would be set only if we finish processing the last sector. If there were other encryption operations in flight, the error would be ignored and bio would be returned with success as if no error happened.
This bug is present in kcryptd_crypt_write_convert, kcryptd_crypt_read_convert and kcryptd_async_done.
--- drivers/md/dm-crypt.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-)
drivers/md/dm-crypt.c +16 -12
@@ -1044,16 +1044,14 @@ static void kcryptd_queue_io(struct dm_cqueue_work (cc->io_queue, &io->work); } -static void kcryptd_crypt_write_io_submit (struct dm_crypt_io *io, -int error,int async) +static void kcryptd_crypt_write_io_submit (struct dm_crypt_io *io,int async) {struct bio *clone = io->ctx.bio_out;struct crypt_config *cc = io->target->private; -if (unlikely (error <0 )) { +if (unlikely (io->error <0 )) {crypt_free_buffer_pages (cc, clone);bio_put (clone); - io->error = -EIO ;crypt_dec_pending (io);return ; }
@@ -1104,12 +1102,16 @@ static void kcryptd_crypt_write_convert( sector +=bio_sectors (clone);crypt_inc_pending (io); + r =crypt_convert (cc, &io->ctx); +if (r <0 ) + io->error = -EIO ; + crypt_finished =atomic_dec_and_test (&io->ctx.pending);/* Encryption was already finished, submit io now */ if (crypt_finished) { -kcryptd_crypt_write_io_submit (io, r,0 ); +kcryptd_crypt_write_io_submit (io,0 );/* * If there was an error, do not try next fragments.
@@ -1160,11 +1162,8 @@ static void kcryptd_crypt_write_convert(crypt_dec_pending (io); } -static void kcryptd_crypt_read_done (struct dm_crypt_io *io,int error) +static void kcryptd_crypt_read_done (struct dm_crypt_io *io) { -if (unlikely (error <0 )) - io->error = -EIO ; -crypt_dec_pending (io); }
@@ -1179,9 +1178,11 @@ static void kcryptd_crypt_read_convert(s io->sector); r =crypt_convert (cc, &io->ctx); +if (r <0 ) + io->error = -EIO ;if (atomic_dec_and_test (&io->ctx.pending)) -kcryptd_crypt_read_done (io, r); +kcryptd_crypt_read_done (io);crypt_dec_pending (io); }
@@ -1202,15 +1203,18 @@ static void kcryptd_async_done(struct crif (!error && cc->iv_gen_ops && cc->iv_gen_ops->post) error = cc->iv_gen_ops->post (cc,iv_of_dmreq (cc, dmreq), dmreq); +if (error <0 ) + io->error = -EIO ; +mempool_free (req_of_dmreq (cc, dmreq), cc->req_pool);if (!atomic_dec_and_test (&ctx->pending))return ;if (bio_data_dir (io->base_bio) ==READ ) -kcryptd_crypt_read_done (io, error); +kcryptd_crypt_read_done (io);else -kcryptd_crypt_write_io_submit (io, error,1 ); +kcryptd_crypt_write_io_submit (io,1 ); }static void kcryptd_crypt (struct work_struct *work)
Greg KH
maintainerPATCH 150/175 dm exception store: fix init error path
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrei Warkentin <[email protected]>
commit aadbe266f2f89ccc68b52f4effc7b3a8b29521ef upstream.
Call the correct exit function on failure in dm_exception_store_init.
--- drivers/md/dm-exception-store.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/md/dm-exception-store.c +1 -1
@@ -283,7 +283,7 @@ int dm_exception_store_init(void)return 0 ; persistent_fail: -dm_persistent_snapshot_exit (); +dm_transient_snapshot_exit (); transient_fail:return r; }
Greg KH
maintainerPATCH 151/175 dm persistent data: fix btree rebalancing after remove
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joe Thornber <[email protected]>
commit b0988900bae9ecf968a8a8d086a9eec671a9517a upstream.
When we remove an entry from a node we sometimes rebalance with it's two neighbours. This wasn't being done correctly; in some cases entries have to move all the way from the right neighbour to the left neighbour, or vice versa. This patch pretty much re-writes the balancing code to fix it.
This code is barely used currently; only when you delete a thin device, and then only if you have hundreds of them in the same pool. Once we have discard support, which removes mappings, this will be used much more heavily.
--- drivers/md/persistent-data/dm-btree-remove.c | 174 +++++++++++++++------------ 1 file changed, 99 insertions(+), 75 deletions(-)
drivers/md/persistent-data/dm-btree-remove.c +99 -75
@@ -128,18 +128,9 @@ static void delete_at(struct node *n, un n->header.nr_entries =cpu_to_le32 (nr_entries -1 ); } -static unsigned del_threshold (struct node *n) -{ -return le32_to_cpu (n->header.max_entries) /3 ; -} -static unsigned merge_threshold (struct node *n) { -/* -* The extra one is because we know we're potentially going to -* delete an entry. -*/ -return 2 * (le32_to_cpu (n->header.max_entries) /3 ) +1 ; +return le32_to_cpu (n->header.max_entries) /3 ; }struct child {
@@ -188,6 +179,15 @@ static int exit_child(struct dm_btree_instatic void shift (struct node *left,struct node *right,int count) { +uint32_t nr_left =le32_to_cpu (left->header.nr_entries); +uint32_t nr_right =le32_to_cpu (right->header.nr_entries); +uint32_t max_entries =le32_to_cpu (left->header.max_entries); +uint32_t r_max_entries =le32_to_cpu (right->header.max_entries); + +BUG_ON (max_entries != r_max_entries); +BUG_ON (nr_left - count > max_entries); +BUG_ON (nr_right + count > max_entries); +if (!count)return ;
@@ -199,13 +199,8 @@ static void shift(struct node *left, strnode_shift (right, count); } - left->header.nr_entries = -cpu_to_le32 (le32_to_cpu (left->header.nr_entries) - count); -BUG_ON (le32_to_cpu (left->header.nr_entries) >le32_to_cpu (left->header.max_entries)); - - right->header.nr_entries = -cpu_to_le32 (le32_to_cpu (right->header.nr_entries) + count); -BUG_ON (le32_to_cpu (right->header.nr_entries) >le32_to_cpu (right->header.max_entries)); + left->header.nr_entries =cpu_to_le32 (nr_left - count); + right->header.nr_entries =cpu_to_le32 (nr_right + count); } static void __rebalance2(struct dm_btree_info *info, struct node *parent,
@@ -215,8 +210,9 @@ static void __rebalance2(struct dm_btreestruct node *right = r->n;uint32_t nr_left =le32_to_cpu (left->header.nr_entries);uint32_t nr_right =le32_to_cpu (right->header.nr_entries); +unsigned threshold =2 *merge_threshold (left) +1 ; -if (nr_left + nr_right <=merge_threshold (left)) { +if (nr_left + nr_right < threshold) {/* * Merge */
@@ -234,9 +230,6 @@ static void __rebalance2(struct dm_btree* Rebalance. */ unsigned target_left = (nr_left + nr_right) /2 ; -unsigned shift_ = nr_left - target_left; -BUG_ON (le32_to_cpu (left->header.max_entries) <= nr_left - shift_); -BUG_ON (le32_to_cpu (right->header.max_entries) <= nr_right + shift_);shift (left, right, nr_left - target_left); *key_ptr (parent, r->index) = right->keys[0 ]; }
@@ -272,6 +265,84 @@ static int rebalance2(struct shadow_spinreturn exit_child (info, &right); } +/* +* We dump as many entries from center as possible into left, then the rest +* in right, then rebalance2. This wastes some cpu, but I want something +* simple atm. +*/ +static void delete_center_node (struct dm_btree_info *info,struct node *parent, +struct child *l,struct child *c,struct child *r, +struct node *left,struct node *center,struct node *right, +uint32_t nr_left,uint32_t nr_center,uint32_t nr_right) +{ +uint32_t max_entries =le32_to_cpu (left->header.max_entries); +unsigned shift =min (max_entries - nr_left, nr_center); + +BUG_ON (nr_left + shift > max_entries); +node_copy (left, center, -shift); + left->header.nr_entries =cpu_to_le32 (nr_left + shift); + +if (shift != nr_center) { + shift = nr_center - shift; +BUG_ON ((nr_right + shift) > max_entries); +node_shift (right, shift); +node_copy (center, right, shift); + right->header.nr_entries =cpu_to_le32 (nr_right + shift); + } + *key_ptr (parent, r->index) = right->keys[0 ]; + +delete_at (parent, c->index); + r->index--; + +dm_tm_dec (info->tm,dm_block_location (c->block)); +__rebalance2 (info, parent, l, r); +} + +/* +* Redistributes entries among 3 sibling nodes. +*/ +static void redistribute3 (struct dm_btree_info *info,struct node *parent, +struct child *l,struct child *c,struct child *r, +struct node *left,struct node *center,struct node *right, +uint32_t nr_left,uint32_t nr_center,uint32_t nr_right) +{ +int s; +uint32_t max_entries =le32_to_cpu (left->header.max_entries); +unsigned target = (nr_left + nr_center + nr_right) /3 ; +BUG_ON (target > max_entries); + +if (nr_left < nr_right) { + s = nr_left - target; + +if (s <0 && nr_center < -s) { +/* not enough in central node */ +shift (left, center, nr_center); + s = nr_center - target; +shift (left, right, s); + nr_right += s; + }else +shift (left, center, s); + +shift (center, right, target - nr_right); + + }else { + s = target - nr_right; +if (s >0 && nr_center < s) { +/* not enough in central node */ +shift (center, right, nr_center); + s = target - nr_center; +shift (left, right, s); + nr_left -= s; + }else +shift (center, right, s); + +shift (left, center, nr_left - target); + } + + *key_ptr (parent, c->index) = center->keys[0 ]; + *key_ptr (parent, r->index) = right->keys[0 ]; +} +static void __rebalance3 (struct dm_btree_info *info,struct node *parent,struct child *l,struct child *c,struct child *r) {
@@ -282,62 +353,18 @@ static void __rebalance3(struct dm_btreeuint32_t nr_left =le32_to_cpu (left->header.nr_entries);uint32_t nr_center =le32_to_cpu (center->header.nr_entries);uint32_t nr_right =le32_to_cpu (right->header.nr_entries); -uint32_t max_entries =le32_to_cpu (left->header.max_entries); -unsigned target; +unsigned threshold =merge_threshold (left) *4 +1 ;BUG_ON (left->header.max_entries != center->header.max_entries);BUG_ON (center->header.max_entries != right->header.max_entries); -if (((nr_left + nr_center + nr_right) /2 ) <merge_threshold (center)) { -/* -* Delete center node: -* -* We dump as many entries from center as possible into -* left, then the rest in right, then rebalance2. This -* wastes some cpu, but I want something simple atm. -*/ -unsigned shift =min (max_entries - nr_left, nr_center); - -BUG_ON (nr_left + shift > max_entries); -node_copy (left, center, -shift); - left->header.nr_entries =cpu_to_le32 (nr_left + shift); - -if (shift != nr_center) { - shift = nr_center - shift; -BUG_ON ((nr_right + shift) >= max_entries); -node_shift (right, shift); -node_copy (center, right, shift); - right->header.nr_entries =cpu_to_le32 (nr_right + shift); - } - *key_ptr (parent, r->index) = right->keys[0 ]; - -delete_at (parent, c->index); - r->index--; - -dm_tm_dec (info->tm,dm_block_location (c->block)); -__rebalance2 (info, parent, l, r); - -return ; - } - -/* -* Rebalance -*/ - target = (nr_left + nr_center + nr_right) /3 ; -BUG_ON (target > max_entries); - -/* -* Adjust the left node -*/ -shift (left, center, nr_left - target); - -/* -* Adjust the right node -*/ -shift (center, right, target - nr_right); - *key_ptr (parent, c->index) = center->keys[0 ]; - *key_ptr (parent, r->index) = right->keys[0 ]; +if ((nr_left + nr_center + nr_right) < threshold) +delete_center_node (info, parent, l, c, r, left, center, right, + nr_left, nr_center, nr_right); +else +redistribute3 (info, parent, l, c, r, left, center, right, + nr_left, nr_center, nr_right); } static int rebalance3(struct shadow_spine *s, struct dm_btree_info *info,
@@ -441,9 +468,6 @@ static int rebalance_children(struct shaif (r)return r; -if (child_entries >del_threshold (n)) -return 0 ; - has_left_sibling = i >0 ; has_right_sibling = i < (le32_to_cpu (n->header.nr_entries) -1 );
Greg KH
maintainerPATCH 152/175 dm thin: fix stacked bi_next usage
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joe Thornber <[email protected]>
commit 6f94a4c45a6f744383f9f695dde019998db3df55 upstream.
Avoid using the bi_next field for the holder of a cell when deferring bios because a stacked device below might change it. Store the holder in a new field in struct cell instead.
When a cell is created, the bio that triggered creation (the holder) was added to the same bio list as subsequent bios. In some cases we pass this holder bio directly to devices underneath. If those devices use the bi_next field there will be trouble...
This also simplifies some code that had to work out which bio was the holder.
--- drivers/md/dm-thin.c | 126 +++++++++++++++++++++++++++++---------------------- 1 file changed, 74 insertions(+), 52 deletions(-)
drivers/md/dm-thin.c +74 -52
@@ -124,7 +124,7 @@ struct cell {struct hlist_node list;struct bio_prison *prison;struct cell_key key; -unsigned count; +struct bio *holder;struct bio_list bios; };
@@ -220,54 +220,59 @@ static struct cell *__search_bucket(stru* This may block if a new cell needs allocating. You must ensure that * cells will be unlocked even if the calling thread is blocked. * -* Returns the number of entries in the cell prior to the new addition -* or < 0 on failure. +* Returns 1 if the cell was already held, 0 if @inmate is the new holder. */ static int bio_detain (struct bio_prison *prison,struct cell_key *key,struct bio *inmate,struct cell **ref) { -int r; +int r =1 ;unsigned long flags;uint32_t hash =hash_key (prison, key); -struct cell *uninitialized_var (cell ), *cell2 =NULL ; +struct cell *cell, *cell2;BUG_ON (hash > prison->nr_buckets);spin_lock_irqsave (&prison->lock, flags); - cell =__search_bucket (prison->cells + hash, key); -if (!cell) { -/* -* Allocate a new cell -*/ -spin_unlock_irqrestore (&prison->lock, flags); - cell2 =mempool_alloc (prison->cell_pool,GFP_NOIO ); -spin_lock_irqsave (&prison->lock, flags); - -/* -* We've been unlocked, so we have to double check that -* nobody else has inserted this cell in the meantime. -*/ - cell =__search_bucket (prison->cells + hash, key); - -if (!cell) { - cell = cell2; - cell2 =NULL ; - - cell->prison = prison; -memcpy (&cell->key, key,sizeof (cell->key)); - cell->count =0 ; -bio_list_init (&cell->bios); -hlist_add_head (&cell->list, prison->cells + hash); - } + cell =__search_bucket (prison->cells + hash, key); +if (cell) { +bio_list_add (&cell->bios, inmate); + goto out; } - r = cell->count++; -bio_list_add (&cell->bios, inmate); +/* +* Allocate a new cell +*/ spin_unlock_irqrestore (&prison->lock, flags); + cell2 =mempool_alloc (prison->cell_pool,GFP_NOIO ); +spin_lock_irqsave (&prison->lock, flags); -if (cell2) +/* +* We've been unlocked, so we have to double check that +* nobody else has inserted this cell in the meantime. +*/ + cell =__search_bucket (prison->cells + hash, key); +if (cell) {mempool_free (cell2, prison->cell_pool); +bio_list_add (&cell->bios, inmate); + goto out; + } + +/* +* Use new cell. +*/ + cell = cell2; + + cell->prison = prison; +memcpy (&cell->key, key,sizeof (cell->key)); + cell->holder = inmate; +bio_list_init (&cell->bios); +hlist_add_head (&cell->list, prison->cells + hash); + + r =0 ; + +out: +spin_unlock_irqrestore (&prison->lock, flags); *ref = cell;
@@ -283,8 +288,8 @@ static void __cell_release(struct cell *hlist_del (&cell->list); -if (inmates) -bio_list_merge (inmates, &cell->bios); +bio_list_add (inmates, cell->holder); +bio_list_merge (inmates, &cell->bios);mempool_free (cell, prison->cell_pool); }
@@ -305,22 +310,44 @@ static void cell_release(struct cell *ce* bio may be in the cell. This function releases the cell, and also does * a sanity check. */ +static void __cell_release_singleton (struct cell *cell,struct bio *bio) +{ +hlist_del (&cell->list); +BUG_ON (cell->holder != bio); +BUG_ON (!bio_list_empty (&cell->bios)); +} +static void cell_release_singleton (struct cell *cell,struct bio *bio) { -struct bio_prison *prison = cell->prison; -struct bio_list bios; -struct bio *b;unsigned long flags; - -bio_list_init (&bios); +struct bio_prison *prison = cell->prison;spin_lock_irqsave (&prison->lock, flags); -__cell_release (cell, &bios); +__cell_release_singleton (cell, bio);spin_unlock_irqrestore (&prison->lock, flags); +} + +/* +* Sometimes we don't want the holder, just the additional bios. +*/ +static void __cell_release_no_holder (struct cell *cell,struct bio_list *inmates) +{ +struct bio_prison *prison = cell->prison; + +hlist_del (&cell->list); +bio_list_merge (inmates, &cell->bios); + +mempool_free (cell, prison->cell_pool); +} + +static void cell_release_no_holder (struct cell *cell,struct bio_list *inmates) +{ +unsigned long flags; +struct bio_prison *prison = cell->prison; - b =bio_list_pop (&bios); -BUG_ON (b != bio); -BUG_ON (!bio_list_empty (&bios)); +spin_lock_irqsave (&prison->lock, flags); +__cell_release_no_holder (cell, inmates); +spin_unlock_irqrestore (&prison->lock, flags); }static void cell_error (struct cell *cell)
@@ -800,21 +827,16 @@ static void cell_defer(struct thin_c *tc* Same as cell_defer above, except it omits one particular detainee, * a write bio that covers the block and has already been processed. */ -static void cell_defer_except (struct thin_c *tc,struct cell *cell, -struct bio *exception) +static void cell_defer_except (struct thin_c *tc,struct cell *cell) {struct bio_list bios; -struct bio *bio;struct pool *pool = tc->pool;unsigned long flags;bio_list_init (&bios); -cell_release (cell, &bios);spin_lock_irqsave (&pool->lock, flags); -while ((bio =bio_list_pop (&bios))) -if (bio != exception) -bio_list_add (&pool->deferred_bios, bio); +cell_release_no_holder (cell, &pool->deferred_bios);spin_unlock_irqrestore (&pool->lock, flags);wake_worker (pool);
@@ -854,7 +876,7 @@ static void process_prepared_mapping(str* the bios in the cell. */ if (bio) { -cell_defer_except (tc, m->cell, bio); +cell_defer_except (tc, m->cell);bio_endio (bio,0 ); }else cell_defer (tc, m->cell, m->data_block);
PATCH 1/1 dm thin: reinstate missing mempool_free in cell_release_singleton
Hi Greg,
3.3-stable pulled in upstream commit 6f94a4c45a6f744383f9f695dde019998db3df55 (dm thin: fix stacked bi_next usage)
But later in the 3.4 development window it was determined that that commit introduced a significant leak. The following upstream commit fixes it (but unfortunately didn't cc: stable).
-------------------
From: Mike Snitzer <[email protected]>
commit 03aaae7cdc71bc306888440b1f569d463e917b6d upstream.
Fix a significant memory leak inadvertently introduced during simplification of cell_release_singleton() in commit 6f94a4c45a6f744383f9f695dde019998db3df55 ("dm thin: fix stacked bi_next usage").
A cell's hlist_del() must be accompanied by a mempool_free(). Use __cell_release() to do this, like before.
--- drivers/md/dm-thin.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-)
drivers/md/dm-thin.c +6 -3
@@ -279,8 +279,10 @@ static void __cell_release(struct cell *cell, struct bio_list *inmates)hlist_del (&cell->list); -bio_list_add (inmates, cell->holder); -bio_list_merge (inmates, &cell->bios); +if (inmates) { +bio_list_add (inmates, cell->holder); +bio_list_merge (inmates, &cell->bios); + }mempool_free (cell, prison->cell_pool); }
@@ -303,9 +305,10 @@ static void cell_release(struct cell *cell, struct bio_list *bios)*/ static void __cell_release_singleton (struct cell *cell,struct bio *bio) { -hlist_del (&cell->list);BUG_ON (cell->holder != bio);BUG_ON (!bio_list_empty (&cell->bios)); + +__cell_release (cell,NULL ); }static void cell_release_singleton (struct cell *cell,struct bio *bio)
Signature · 1 line
1.7.4.4
Greg KH
maintainerRe: [PATCH] dm thin: reinstate missing mempool_free in cell_release_singleton
Quoted 8 lines · Mike Snitzer
Hi Greg,
3.3-stable pulled in upstream commit
6f94a4c45a6f744383f9f695dde019998db3df55(dm thin: fix stackedbi_nextusage)But later in the 3.4 development window it was determined that that commit introduced a significant leak. The following upstream commit fixes it (but unfortunately didn't cc: stable).
3.3 is end-of-life, so there's not much I can do with the 3.3-stable tree anymore, sorry. If there's any other tree I should apply this to that is active (i.e. 3.0 or 3.4), please let me know.
sorry,
greg k-h
Re: dm thin: reinstate missing mempool_free in cell_release_singleton
Quoted 6 lines · Greg KH
Quoted 5 lines · Mike Snitzer
Hi Greg,
3.3-stable pulled in upstream commit
6f94a4c45a6f744383f9f695dde019998db3df55(dm thin: fix stackedbi_nextusage)
Quoted 7 lines
Quoted 3 lines
But later in the 3.4 development window it was determined that that commit introduced a significant leak. The following upstream commit fixes it (but unfortunately didn't cc: stable).
3.3 is end-of-life, so there's not much I can do with the 3.3-stable tree anymore, sorry. If there's any other tree I should apply this to that is active (i.e. 3.0 or 3.4), please let me know.
OK, no other active stable tree is affected, thanks.
Re: [PATCH] dm thin: reinstate missing mempool_free in cell_release_singleton
In reply to Greg KHQuoted 7 lines · Greg KH
Quoted 6 lines · Mike Snitzer
Hi Greg,
3.3-stable pulled in upstream commit
6f94a4c45a6f744383f9f695dde019998db3df55(dm thin: fix stackedbi_nextusage)
Quoted 7 lines
Quoted 3 lines
But later in the 3.4 development window it was determined that that commit introduced a significant leak. The following upstream commit fixes it (but unfortunately didn't cc: stable).
3.3 is end-of-life, so there's not much I can do with the 3.3-stable tree anymore, sorry. If there's any other tree I should apply this to that is active (i.e. 3.0 or 3.4), please let me know.
Looks like you forgot 3.2 that is affected (since 3.2.14).
Greg KH
maintainerRe: [PATCH] dm thin: reinstate missing mempool_free in cell_release_singleton
Quoted 12 lines · Touko Korpela
Quoted 11 lines · Greg KH
Quoted 9 lines · Mike Snitzer
Hi Greg,
3.3-stable pulled in upstream commit
6f94a4c45a6f744383f9f695dde019998db3df55(dm thin: fix stackedbi_nextusage)But later in the 3.4 development window it was determined that that commit introduced a significant leak. The following upstream commit fixes it (but unfortunately didn't cc: stable).
Quoted 5 lines
Quoted 3 lines
3.3 is end-of-life, so there's not much I can do with the 3.3-stable tree anymore, sorry. If there's any other tree I should apply this to that is active (i.e. 3.0 or 3.4), please let me know.
Looks like you forgot 3.2 that is affected (since 3.2.14).
I don't maintain 3.2 :)
Re: [PATCH] dm thin: reinstate missing mempool_free in cell_release_singleton
In reply to Touko KorpelaQuoted 12 lines · Touko Korpela
Quoted 11 lines · Greg KH
Quoted 9 lines · Mike Snitzer
Hi Greg,
3.3-stable pulled in upstream commit
6f94a4c45a6f744383f9f695dde019998db3df55(dm thin: fix stackedbi_nextusage)But later in the 3.4 development window it was determined that that commit introduced a significant leak. The following upstream commit fixes it (but unfortunately didn't cc: stable).
Quoted 5 lines
Quoted 3 lines
3.3 is end-of-life, so there's not much I can do with the 3.3-stable tree anymore, sorry. If there's any other tree I should apply this to that is active (i.e. 3.0 or 3.4), please let me know.
Looks like you forgot 3.2 that is affected (since 3.2.14).
I've added this to the queue for 3.2, thanks.
Ben.
Signature · 3 lines
Ben Hutchings
Lowery's Law:
If it jams, force it. If it breaks, it needed replacing anyway.Greg KH
maintainerPATCH 153/175 backlight: fix typo in tosa_lcd.c
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masanari Iida <[email protected]>
commit 8da00edc1069f01c34510fa405dc15d96c090a3f upstream.
Fix typo in drivers/video/backlight/tosa_lcd.c
"tosa_lcd_reume" should be "tosa_lcd_resume".
--- drivers/video/backlight/tosa_lcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/video/backlight/tosa_lcd.c +1 -1
@@ -271,7 +271,7 @@ static int tosa_lcd_resume(struct spi_de }#else #define tosa_lcd_suspend NULL -#define tosa_lcd_reume NULL +#define tosa_lcd_resume NULL#endif static struct spi_driver tosa_lcd_driver = {
Greg KH
maintainerPATCH 154/175 xfs: Fix oops on IO error during xlog_recover_process_iunlinks()
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <[email protected]>
commit d97d32edcd732110758799ae60af725e5110b3dc upstream.
When an IO error happens during inode deletion run from xlog_recover_process_iunlinks() filesystem gets shutdown. Thus any subsequent attempt to read buffers fails. Code in xlog_recover_process_iunlinks() does not count with the fact that read of a buffer which was read a while ago can really fail which results in the oops on
agi = XFS_BUF_TO_AGI(agibp);
Fix the problem by cleaning up the buffer handling in xlog_recover_process_iunlinks() as suggested by Dave Chinner. We release buffer lock but keep buffer reference to AG buffer. That is enough for buffer to stay pinned in memory and we don't have to call xfs_read_agi() all the time.
--- fs/xfs/xfs_log_recover.c | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-)
fs/xfs/xfs_log_recover.c +11 -22
@@ -3161,37 +3161,26 @@ xlog_recover_process_iunlinks(*/ continue ; } +/* +* Unlock the buffer so that it can be acquired in the normal +* course of the transaction to truncate and free each inode. +* Because we are not racing with anyone else here for the AGI +* buffer, we don't even need to hold it locked to read the +* initial unlinked bucket entries out of the buffer. We keep +* buffer reference though, so that it stays pinned in memory +* while we need the buffer. +*/ agi =XFS_BUF_TO_AGI (agibp); +xfs_buf_unlock (agibp);for (bucket =0 ; bucket <XFS_AGI_UNLINKED_BUCKETS ; bucket++) { agino =be32_to_cpu (agi->agi_unlinked[bucket]);while (agino !=NULLAGINO ) { -/* -* Release the agi buffer so that it can -* be acquired in the normal course of the -* transaction to truncate and free the inode. -*/ -xfs_buf_relse (agibp); - agino =xlog_recover_process_one_iunlink (mp, agno, agino, bucket); - -/* -* Reacquire the agibuffer and continue around -* the loop. This should never fail as we know -* the buffer was good earlier on. -*/ - error =xfs_read_agi (mp,NULL , agno, &agibp); -ASSERT (error ==0 ); - agi =XFS_BUF_TO_AGI (agibp); } } - -/* -* Release the buffer for the current agi so we can -* go on to the next one. -*/ -xfs_buf_relse (agibp); +xfs_buf_rele (agibp); } mp->m_dmevmask = mp_dmevmask;
Greg KH
maintainerPATCH 155/175 slub: Do not hold slub_lock when calling sysfs_slab_add()
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Lameter <[email protected]>
commit 66c4c35c6bc5a1a452b024cf0364635b28fd94e4 upstream.
sysfs_slab_add() calls various sysfs functions that actually may end up in userspace doing all sorts of things.
Release the slub_lock after adding the kmem_cache structure to the list. At that point the address of the kmem_cache is not known so we are guaranteed exlusive access to the following modifications to the kmem_cache structure.
If the sysfs_slab_add fails then reacquire the slub_lock to remove the kmem_cache structure from the list.
--- mm/slub.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
mm/slub.c +2 -1
@@ -3929,13 +3929,14 @@ struct kmem_cache *kmem_cache_create(conif (kmem_cache_open (s, n, size, align, flags, ctor)) {list_add (&s->list, &slab_caches); +up_write (&slub_lock);if (sysfs_slab_add (s)) { +down_write (&slub_lock);list_del (&s->list);kfree (n);kfree (s); goto err; } -up_write (&slub_lock);return s; }kfree (n);
Greg KH
maintainerPATCH 156/175 NFSv4: Fix two infinite loops in the mount code
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
commit 05e9cfb408b24debb3a85fd98edbfd09dd148881 upstream.
We can currently loop forever in nfs4_lookup_root() and in nfs41_proc_secinfo_no_name(), if the first iteration returns a NFS4ERR_DELAY or something else that causes exception.retry to get set.
--- fs/nfs/nfs4proc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
fs/nfs/nfs4proc.c +4 -2
@@ -2249,11 +2249,12 @@ static int nfs4_lookup_root(struct nfs_sswitch (err) {case 0 :case -NFS4ERR_WRONGSEC : -break ; + goto out;default : err =nfs4_handle_exception (server, err, &exception); } }while (exception.retry); +out:return err; }
@@ -6068,11 +6069,12 @@ nfs41_proc_secinfo_no_name(struct nfs_secase 0 :case -NFS4ERR_WRONGSEC :case -NFS4ERR_NOTSUPP : -break ; + goto out;default : err =nfs4_handle_exception (server, err, &exception); } }while (exception.retry); +out:return err; }
Greg KH
maintainerPATCH 157/175 NFSv4.1: Fix layoutcommit error handling
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
commit e59d27e05a6435f8c04d5ad843f37fa795f2eaaa upstream.
Firstly, task->tk_status will always return negative error values, so the current tests for 'NFS4ERR_DELEG_REVOKED' etc. are all being ignored.
Secondly, clean up the code so that we only need to test task->tk_status once!
--- fs/nfs/nfs4proc.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-)
fs/nfs/nfs4proc.c +13 -12
@@ -5952,21 +5952,22 @@ nfs4_layoutcommit_done(struct rpc_task *return ;switch (task->tk_status) {/* Just ignore these failures */ -case NFS4ERR_DELEG_REVOKED :/* layout was recalled */ -case NFS4ERR_BADIOMODE :/* no IOMODE_RW layout for range */ -case NFS4ERR_BADLAYOUT :/* no layout */ -case NFS4ERR_GRACE :/* loca_recalim always false */ +case -NFS4ERR_DELEG_REVOKED :/* layout was recalled */ +case -NFS4ERR_BADIOMODE :/* no IOMODE_RW layout for range */ +case -NFS4ERR_BADLAYOUT :/* no layout */ +case -NFS4ERR_GRACE :/* loca_recalim always false */ task->tk_status =0 ; - } - -if (nfs4_async_handle_error (task, server,NULL ) == -EAGAIN ) { -rpc_restart_call_prepare (task); -return ; - } - -if (task->tk_status ==0 ) +break ; +case 0 :nfs_post_op_update_inode_force_wcc (data->args.inode, data->res.fattr); +break ; +default : +if (nfs4_async_handle_error (task, server,NULL ) == -EAGAIN ) { +rpc_restart_call_prepare (task); +return ; + } + } }static void nfs4_layoutcommit_release (void *calldata)
Greg KH
maintainerPATCH 158/175 module: Remove module size limit
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sasha Levin <[email protected]>
commit f946eeb9313ff1470758e171a60fe7438a2ded3f upstream.
Module size was limited to 64MB, this was legacy limitation due to vmalloc() which was removed a while ago.
Limiting module size to 64MB is both pointless and affects real world use cases.
--- kernel/module.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
kernel/module.c +1 -2
@@ -2380,8 +2380,7 @@ static int copy_and_check(struct load_inreturn -ENOEXEC ;/* Suck in entire file: we'll want most of it. */ -/* vmalloc barfs on "unusual" numbers. Check here */ -if (len >64 *1024 *1024 || (hdr =vmalloc (len)) ==NULL ) +if ((hdr =vmalloc (len)) ==NULL )return -ENOMEM ;if (copy_from_user (hdr, umod, len) !=0 ) {
Greg KH
maintainerPATCH 159/175 drm/i915: suspend fbdev device around suspend/hibernate
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Airlie <[email protected]>
commit 3fa016a0b5c5237e9c387fc3249592b2cb5391c6 upstream.
Looking at hibernate overwriting I though it looked like a cursor, so I tracked down this missing piece to stop the cursor blink timer. I've no idea if this is sufficient to fix the hibernate problems people are seeing, but please test it.
Both radeon and nouveau have done this for a long time.
I've run this personally all night hib/resume cycles with no fails.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=37142
--- drivers/gpu/drm/i915/i915_drv.c | 7 +++++++ drivers/gpu/drm/i915/intel_drv.h | 2 +- drivers/gpu/drm/i915/intel_fb.c | 10 ++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/i915_drv.c +7 -0
@@ -442,6 +442,10 @@ static int i915_drm_freeze(struct drm_de/* Modeset on resume, not lid events */ dev_priv->modeset_on_lid =0 ; +console_lock (); +intel_fbdev_set_suspend (dev,1 ); +console_unlock (); +return 0 ; }
@@ -514,6 +518,9 @@ static int i915_drm_thaw(struct drm_devi dev_priv->modeset_on_lid =0 ; +console_lock (); +intel_fbdev_set_suspend (dev,0 ); +console_unlock ();return error; }
drivers/gpu/drm/i915/intel_drv.h +1 -1
@@ -381,7 +381,7 @@ extern int intel_framebuffer_init(struct struct drm_i915_gem_object *obj);extern int intel_fbdev_init (struct drm_device *dev);extern void intel_fbdev_fini (struct drm_device *dev); - +extern void intel_fbdev_set_suspend (struct drm_device *dev,int state);extern void intel_prepare_page_flip (struct drm_device *dev,int plane);extern void intel_finish_page_flip (struct drm_device *dev,int pipe);extern void intel_finish_page_flip_plane (struct drm_device *dev,int plane);
drivers/gpu/drm/i915/intel_fb.c +10 -0
@@ -258,6 +258,16 @@ void intel_fbdev_fini(struct drm_devicekfree (dev_priv->fbdev); dev_priv->fbdev =NULL ; } + +void intel_fbdev_set_suspend (struct drm_device *dev,int state) +{ +drm_i915_private_t *dev_priv = dev->dev_private; +if (!dev_priv->fbdev) +return ; + +fb_set_suspend (dev_priv->fbdev->helper.fbdev, state); +} +MODULE_LICENSE ("GPL and additional rights" );void intel_fb_output_poll_changed (struct drm_device *dev)
Greg KH
maintainerPATCH 160/175 net: bpf_jit: fix BPF_S_LDX_B_MSH compilation
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit dc72d99dabb870ca5bd6d9fff674be853bb4a88d ]
Matt Evans spotted that x86 bpf_jit was incorrectly handling negative constant offsets in BPF_S_LDX_B_MSH instruction.
We need to abort JIT compilation like we do in common_load so that filter uses the interpreter code and can call __load_pointer()
Reference: http://lists.openwall.net/netdev/2011/07/19/11
Thanks to Indan Zupancic to bring back this issue.
--- arch/x86/net/bpf_jit_comp.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
arch/x86/net/bpf_jit_comp.c +5 -9
@@ -475,8 +475,10 @@ void bpf_jit_compile(struct sk_filter *fcase BPF_S_LD_W_ABS : func = sk_load_word; common_load: seen |=SEEN_DATAREF ; -if ((int )K <0 ) +if ((int )K <0 ) { +/* Abort the JIT because __load_pointer() is needed. */ goto out; + } t_offset = func - (image + addrs[i]);EMIT1_off32 (0xbe ,K );/* mov imm32,%esi */ EMIT1_off32 (0xe8 , t_offset);/* call */
@@ -489,14 +491,8 @@ common_load: seen |= SEEN_DATAREF; goto common_load;case BPF_S_LDX_B_MSH :if ((int )K <0 ) { -if (pc_ret0 >0 ) { -/* addrs[pc_ret0 - 1] is the start address */ -EMIT_JMP (addrs[pc_ret0 -1 ] - addrs[i]); -break ; - } -CLEAR_A (); -EMIT_JMP (cleanup_addr - addrs[i]); -break ; +/* Abort the JIT because __load_pointer() is needed. */ + goto out; } seen |=SEEN_DATAREF |SEEN_XREG ; t_offset = sk_load_byte_msh - (image + addrs[i]);
Greg KH
maintainerPATCH 161/175 ipv6: fix incorrent ipv6 ipsec packet fragment
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gao feng <[email protected]>
[ Upstream commit 1f85851e17b64cabd089a8a8839dddebc627948c ]
Since commit 299b0767(ipv6: Fix IPsec slowpath fragmentation problem) In func ip6_append_data,after call skb_put(skb, fraglen + dst_exthdrlen) the skb->len contains dst_exthdrlen,and we don't reduce dst_exthdrlen at last This will make fraggap>0 in next "while cycle",and cause the size of skb incorrent
Fix this by reserve headroom for dst_exthdrlen.
--- net/ipv6/ip6_output.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
net/ipv6/ip6_output.c +6 -5
@@ -1416,8 +1416,9 @@ alloc_new_skb:*/ skb->ip_summed = csummode; skb->csum =0 ; -/* reserve for fragmentation */ -skb_reserve (skb, hh_len+sizeof (struct frag_hdr )); +/* reserve for fragmentation and ipsec header */ +skb_reserve (skb, hh_len +sizeof (struct frag_hdr ) + + dst_exthdrlen);if (sk->sk_type ==SOCK_DGRAM )skb_shinfo (skb)->tx_flags = tx_flags;
@@ -1425,9 +1426,9 @@ alloc_new_skb:/* * Find where to start putting bytes */ - data =skb_put (skb, fraglen + dst_exthdrlen); -skb_set_network_header (skb, exthdrlen + dst_exthdrlen); - data += fragheaderlen + dst_exthdrlen; + data =skb_put (skb, fraglen); +skb_set_network_header (skb, exthdrlen); + data += fragheaderlen; skb->transport_header = (skb->network_header + fragheaderlen);if (fraggap) {
Greg KH
maintainerPATCH 162/175 Remove printk from rds_sendmsg
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Jones <[email protected]>
[ Upstream commit a6506e1486181975d318344143aca722b2b91621 ]
no socket layer outputs a message for this error and neither should rds.
--- net/rds/send.c | 1 - 1 file changed, 1 deletion(-)
net/rds/send.c +0 -1
@@ -935,7 +935,6 @@ int rds_sendmsg(struct kiocb *iocb, stru/* Mirror Linux UDP mirror of BSD error message compatibility */ /* XXX: Perhaps MSG_MORE someday */ if (msg->msg_flags & ~(MSG_DONTWAIT |MSG_CMSG_COMPAT )) { -printk (KERN_INFO "msg_flags 0x%08X\n" , msg->msg_flags); ret = -EOPNOTSUPP ; goto out; }
Greg KH
maintainerPATCH 163/175 Fix pppol2tp getsockname()
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin LaHaise <[email protected]>
[ Upstream commit bbdb32cb5b73597386913d052165423b9d736145 ]
While testing L2TP functionality, I came across a bug in getsockname(). The IP address returned within the pppol2tp_addr's addr memember was not being set to the IP address in use. This bug is caused by using inet_sk() on the wrong socket (the L2TP socket rather than the underlying UDP socket), and was likely introduced during the addition of L2TPv3 support.
--- net/l2tp/l2tp_ppp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/l2tp/l2tp_ppp.c +1 -1
@@ -915,7 +915,7 @@ static int pppol2tp_getname(struct socke goto end_put_sess; } - inet =inet_sk (sk); + inet =inet_sk (tunnel->sock);if (tunnel->version ==2 ) {struct sockaddr_pppol2tp sp; len =sizeof (sp);
Greg KH
maintainerPATCH 164/175 net: fix napi_reuse_skb() skb reserve
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 2a2a459eeeff48640dc557548ce576d666ab06ed ]
napi->skb is allocated in napi_get_frags() using netdev_alloc_skb_ip_align(), with a reserve of NET_SKB_PAD + NET_IP_ALIGN bytes.
However, when such skb is recycled in napi_reuse_skb(), it ends with a reserve of NET_IP_ALIGN which is suboptimal.
--- net/core/dev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/core/dev.c +2 -1
@@ -3569,7 +3569,8 @@ EXPORT_SYMBOL(napi_gro_receive);static void napi_reuse_skb (struct napi_struct *napi,struct sk_buff *skb) {__skb_pull (skb,skb_headlen (skb)); -skb_reserve (skb,NET_IP_ALIGN -skb_headroom (skb)); +/* restore the reserve we had after netdev_alloc_skb_ip_align() */ +skb_reserve (skb,NET_SKB_PAD +NET_IP_ALIGN -skb_headroom (skb)); skb->vlan_tci =0 ; skb->dev = napi->dev; skb->skb_iif =0 ;
Greg KH
maintainerPATCH 165/175 sky2: override for PCI legacy power management
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: stephen hemminger <[email protected]>
[ Upstream commit 5676cc7bfe1e388e87843f71daa229610385b41e ]
Some BIOS's don't setup power management correctly (what else is new) and don't allow use of PCI Express power control. Add a special exception module parameter to allow working around this issue. Based on slightly different patch by Knut Petersen.
--- drivers/net/ethernet/marvell/sky2.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/net/ethernet/marvell/sky2.c +11 -0
@@ -95,6 +95,10 @@ static int disable_msi = 0;module_param (disable_msi, int,0 );MODULE_PARM_DESC (disable_msi,"Disable Message Signaled Interrupt (MSI)" ); +static int legacy_pme =0 ; +module_param (legacy_pme, int,0 ); +MODULE_PARM_DESC (legacy_pme,"Legacy power management" ); +static DEFINE_PCI_DEVICE_TABLE (sky2_id_table) = { {PCI_DEVICE (PCI_VENDOR_ID_SYSKONNECT ,0x9000 ) },/* SK-9Sxx */ {PCI_DEVICE (PCI_VENDOR_ID_SYSKONNECT ,0x9E00 ) },/* SK-9Exx */
@@ -867,6 +871,13 @@ static void sky2_wol_init(struct sky2_po/* Disable PiG firmware */ sky2_write16 (hw,B0_CTST ,Y2_HW_WOL_OFF ); +/* Needed by some broken BIOSes, use PCI rather than PCI-e for WOL */ +if (legacy_pme) { +u32 reg1 =sky2_pci_read32 (hw,PCI_DEV_REG1 ); + reg1 |=PCI_Y2_PME_LEGACY ; +sky2_pci_write32 (hw,PCI_DEV_REG1 , reg1); + } +/* block receiver */ sky2_write8 (hw,SK_REG (port,RX_GMF_CTRL_T ),GMF_RST_SET );sky2_read32 (hw,B0_CTST );
Greg KH
maintainerPATCH 166/175 xfrm: Access the replay notify functions via the registered callbacks
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steffen Klassert <[email protected]>
[ Upstream commit 1265fd616782ef03b98fd19f65c2b47fcd4ea11f ]
We call the wrong replay notify function when we use ESN replay handling. This leads to the fact that we don't send notifications if we use ESN. Fix this by calling the registered callbacks instead of xfrm_replay_notify().
--- net/xfrm/xfrm_replay.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
net/xfrm/xfrm_replay.c +3 -3
@@ -167,7 +167,7 @@ static void xfrm_replay_advance(struct x }if (xfrm_aevent_is_on (xs_net (x))) -xfrm_replay_notify (x,XFRM_REPLAY_UPDATE ); + x->repl->notify (x,XFRM_REPLAY_UPDATE ); }static int xfrm_replay_overflow_bmp (struct xfrm_state *x,struct sk_buff *skb)
@@ -279,7 +279,7 @@ static void xfrm_replay_advance_bmp(stru replay_esn->bmp[nr] |= (1U << bitnr);if (xfrm_aevent_is_on (xs_net (x))) -xfrm_replay_notify (x,XFRM_REPLAY_UPDATE ); + x->repl->notify (x,XFRM_REPLAY_UPDATE ); }static void xfrm_replay_notify_bmp (struct xfrm_state *x,int event)
@@ -473,7 +473,7 @@ static void xfrm_replay_advance_esn(stru replay_esn->bmp[nr] |= (1U << bitnr);if (xfrm_aevent_is_on (xs_net (x))) -xfrm_replay_notify (x,XFRM_REPLAY_UPDATE ); + x->repl->notify (x,XFRM_REPLAY_UPDATE ); }static struct xfrm_replay xfrm_replay_legacy = {
Greg KH
maintainerPATCH 167/175 net: fix a potential rcu_read_lock() imbalance in rt6_fill_node()
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 94f826b8076e2cb92242061e92f21b5baa3eccc2 ]
Commit f2c31e32b378 (net: fix NULL dereferences in check_peer_redir() ) added a regression in rt6_fill_node(), leading to rcu_read_lock() imbalance.
Thats because NLA_PUT() can make a jump to nla_put_failure label.
Fix this by using nla_put()
Many thanks to Ben Greear for his help
--- net/ipv6/route.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
net/ipv6/route.c +6 -2
@@ -2461,8 +2461,12 @@ static int rt6_fill_node(struct net *netrcu_read_lock (); n =dst_get_neighbour_noref (&rt->dst); -if (n) -NLA_PUT (skb,RTA_GATEWAY ,16 , &n->primary_key); +if (n) { +if (nla_put (skb,RTA_GATEWAY ,16 , &n->primary_key) <0 ) { +rcu_read_unlock (); + goto nla_put_failure; + } + }rcu_read_unlock ();if (rt->dst.dev)
Greg KH
maintainerPATCH 168/175 lockd: fix arg parsing for grace_period and timeout.
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: NeilBrown <[email protected]>
commit de5b8e8e047534aac6bc9803f96e7257436aef9c upstream.
If you try to set grace_period or timeout via a module parameter to lockd, and do this on a big-endian machine where
sizeof(int) != sizeof(unsigned long)
it won't work. This number given will be effectively shifted right by the difference in those two sizes.
So cast kp->arg properly to get correct result.
--- fs/lockd/svc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/lockd/svc.c +1 -1
@@ -440,7 +440,7 @@ static int param_set_##name(const char *__typeof__ (type) num =which_strtol (val, &endp,0 ); \if (endp == val || *endp || num < (min) || num > (max)) \return -EINVAL ; \ - *((int *) kp->arg) = num; \ + *((type *) kp->arg) = num; \return 0 ; \ }
Greg KH
maintainerPATCH 169/175 x86, tsc: Skip refined tsc calibration on systems with reliable TSC
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alok Kataria <[email protected]>
commit 57779dc2b3b75bee05ef5d1ada47f615f7a13932 upstream.
While running the latest Linux as guest under VMware in highly over-committed situations, we have seen cases when the refined TSC algorithm fails to get a valid tsc_start value in tsc_refine_calibration_work from multiple attempts. As a result the kernel keeps on scheduling the tsc_irqwork task for later. Subsequently after several attempts when it gets a valid start value it goes through the refined calibration and either bails out or uses the new results. Given that the kernel originally read the TSC frequency from the platform, which is the best it can get, I don't think there is much value in refining it.
So for systems which get the TSC frequency from the platform we should skip the refined tsc algorithm.
We can use the TSC_RELIABLE cpu cap flag to detect this, right now it is set only on VMware and for Moorestown Penwell both of which have there own TSC calibration methods.
[jstultz: Reworked to simply not schedule the refining work, rather then scheduling the work and bombing out later]
--- arch/x86/kernel/tsc.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
arch/x86/kernel/tsc.c +10 -0
@@ -932,6 +932,16 @@ static int __init init_tsc_clocksource(v clocksource_tsc.rating =0 ; clocksource_tsc.flags &= ~CLOCK_SOURCE_IS_CONTINUOUS ; } + +/* +* Trust the results of the earlier calibration on systems +* exporting a reliable TSC. +*/ +if (boot_cpu_has (X86_FEATURE_TSC_RELIABLE )) { +clocksource_register_khz (&clocksource_tsc, tsc_khz); +return 0 ; + } +schedule_delayed_work (&tsc_irqwork,0 );return 0 ; }
Greg KH
maintainerPATCH 170/175 x86, tls: Off by one limit check
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
commit 8f0750f19789cf352d7e24a6cc50f2ab1b4f1372 upstream.
These are used as offsets into an array of GDT_ENTRY_TLS_ENTRIES members so GDT_ENTRY_TLS_ENTRIES is one past the end of the array.
--- arch/x86/kernel/tls.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/kernel/tls.c +2 -2
@@ -163,7 +163,7 @@ int regset_tls_get(struct task_struct *t {const struct desc_struct *tls; -if (pos >GDT_ENTRY_TLS_ENTRIES *sizeof (struct user_desc ) || +if (pos >=GDT_ENTRY_TLS_ENTRIES *sizeof (struct user_desc ) || (pos %sizeof (struct user_desc )) !=0 || (count %sizeof (struct user_desc )) !=0 )return -EINVAL ;
@@ -198,7 +198,7 @@ int regset_tls_set(struct task_struct *tstruct user_desc infobuf[GDT_ENTRY_TLS_ENTRIES ];const struct user_desc *info; -if (pos >GDT_ENTRY_TLS_ENTRIES *sizeof (struct user_desc ) || +if (pos >=GDT_ENTRY_TLS_ENTRIES *sizeof (struct user_desc ) || (pos %sizeof (struct user_desc )) !=0 || (count %sizeof (struct user_desc )) !=0 )return -EINVAL ;
Greg KH
maintainerPATCH 171/175 compat: use sys_sendfile64() implementation for sendfile syscall
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Metcalf <[email protected]>
commit 1631fcea8399da5e80a80084b3b8c5bfd99d21e7 upstream.
<asm-generic/unistd.h> was set up to use sys_sendfile() for the 32-bit compat API instead of sys_sendfile64(), but in fact the right thing to do is to use sys_sendfile64() in all cases. The 32-bit sendfile64() API in glibc uses the sendfile64 syscall, so it has to be capable of doing full 64-bit operations. But the sys_sendfile() kernel implementation has a MAX_NON_LFS test in it which explicitly limits the offset to 2^32. So, we need to use the sys_sendfile64() implementation in the kernel for this case.
--- include/asm-generic/unistd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/asm-generic/unistd.h +1 -1
@@ -218,7 +218,7 @@ __SC_COMP(__NR_pwritev, sys_pwritev, com/* fs/sendfile.c */ #define __NR3264_sendfile 71 -__SC_3264 (__NR3264_sendfile, sys_sendfile64, sys_sendfile) +__SYSCALL (__NR3264_sendfile, sys_sendfile64) /* fs/select.c */#define __NR_pselect6 72
Greg KH
maintainerPATCH 172/175 rtc: Provide flag for rtc devices that dont support UIE
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Stultz <[email protected]>
commit 4a649903f91232d02284d53724b0a45728111767 upstream.
Richard Weinberger noticed that on some RTC hardware that doesn't support UIE mode, due to coarse granular alarms (like 1minute resolution), the current virtualized RTC support doesn't properly error out when UIE is enabled.
Instead the current code queues an alarm for the next second, but it won't fire until up to a miniute later.
This patch provides a generic way to flag this sort of hardware and fixes the issue on the mpc5121 where Richard noticed the problem.
--- drivers/rtc/interface.c | 5 +++++ drivers/rtc/rtc-mpc5121.c | 2 ++ include/linux/rtc.h | 3 ++- 3 files changed, 9 insertions(+), 1 deletion(-)
drivers/rtc/interface.c +5 -0
@@ -445,6 +445,11 @@ int rtc_update_irq_enable(struct rtc_devif (rtc->uie_rtctimer.enabled == enabled) goto out; +if (rtc->uie_unsupported) { + err = -EINVAL ; + goto out; + } +if (enabled) {struct rtc_time tm;ktime_t now, onesec;
drivers/rtc/rtc-mpc5121.c +2 -0
@@ -360,6 +360,8 @@ static int __devinit mpc5121_rtc_probe(s &mpc5200_rtc_ops, THIS_MODULE); } + rtc->rtc->uie_unsupported =1 ; +if (IS_ERR (rtc->rtc)) { err =PTR_ERR (rtc->rtc); goto out_free_irq;
include/linux/rtc.h +2 -1
@@ -202,7 +202,8 @@ struct rtc_devicestruct hrtimer pie_timer;/* sub second exp, so needs hrtimer */ int pie_enabled;struct work_struct irqwork; - +/* Some hardware can't support UIE mode */ +int uie_unsupported;#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL struct work_struct uie_task;
Greg KH
maintainerPATCH 173/175 nfsd: dont allow zero length strings in cache_parse()
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
commit 6d8d17499810479eabd10731179c04b2ca22152f upstream.
There is no point in passing a zero length string here and quite a few of that cache_parse() implementations will Oops if count is zero.
--- net/sunrpc/cache.c | 2 ++ 1 file changed, 2 insertions(+)
net/sunrpc/cache.c +2 -0
@@ -828,6 +828,8 @@ static ssize_t cache_do_downcall(char *k {ssize_t ret; +if (count ==0 ) +return -EINVAL ;if (copy_from_user (kaddr, buf, count))return -EFAULT ; kaddr[count] ='\0' ;
Greg KH
maintainerPATCH 174/175 ARM: tegra: Fix device tree AUXDATA for USB/EHCI
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stephen Warren <[email protected]>
commit 8c3ec84102d171a24f050a086bfc546e9de93f9f upstream.
Commit 4a53f4e "USB: ehci-tegra: add probing through device tree" added AUXDATA for Tegra's USB/EHCI controller. However, it pointed the platform data at a location containing the address of the intended platform data, rather than the platform data itself. This change fixes that.
--- arch/arm/mach-tegra/board-dt-tegra20.c | 6 +++--- arch/arm/mach-tegra/devices.c | 7 +++---- arch/arm/mach-tegra/devices.h | 5 +++++ 3 files changed, 11 insertions(+), 7 deletions(-)
arch/arm/mach-tegra/board-dt-tegra20.c +3 -3
@@ -68,11 +68,11 @@ struct of_dev_auxdata tegra20_auxdata_loOF_DEV_AUXDATA ("nvidia,tegra20-i2s" ,TEGRA_I2S2_BASE ,"tegra-i2s.1" ,NULL ),OF_DEV_AUXDATA ("nvidia,tegra20-das" ,TEGRA_APB_MISC_DAS_BASE ,"tegra-das" ,NULL ),OF_DEV_AUXDATA ("nvidia,tegra20-ehci" ,TEGRA_USB_BASE ,"tegra-ehci.0" , - &tegra_ehci1_device.dev.platform_data), + &tegra_ehci1_pdata),OF_DEV_AUXDATA ("nvidia,tegra20-ehci" ,TEGRA_USB2_BASE ,"tegra-ehci.1" , - &tegra_ehci2_device.dev.platform_data), + &tegra_ehci2_pdata),OF_DEV_AUXDATA ("nvidia,tegra20-ehci" ,TEGRA_USB3_BASE ,"tegra-ehci.2" , - &tegra_ehci3_device.dev.platform_data), + &tegra_ehci3_pdata), {} };
arch/arm/mach-tegra/devices.c +3 -4
@@ -23,7 +23,6 @@#include <linux/fsl_devices.h> #include <linux/serial_8250.h> #include <linux/i2c-tegra.h> -#include <linux/platform_data/tegra_usb.h> #include <asm/pmu.h> #include <mach/irqs.h> #include <mach/iomap.h>
@@ -446,18 +445,18 @@ static struct tegra_ulpi_config tegra_eh .clk = "cdev2", }; -static struct tegra_ehci_platform_data tegra_ehci1_pdata = { +struct tegra_ehci_platform_data tegra_ehci1_pdata = { .operating_mode =TEGRA_USB_OTG , .power_down_on_bus_suspend =1 , }; -static struct tegra_ehci_platform_data tegra_ehci2_pdata = { +struct tegra_ehci_platform_data tegra_ehci2_pdata = { .phy_config = &tegra_ehci2_ulpi_phy_config, .operating_mode =TEGRA_USB_HOST , .power_down_on_bus_suspend =1 , }; -static struct tegra_ehci_platform_data tegra_ehci3_pdata = { +struct tegra_ehci_platform_data tegra_ehci3_pdata = { .operating_mode =TEGRA_USB_HOST , .power_down_on_bus_suspend =1 , };
arch/arm/mach-tegra/devices.h +5 -0
@@ -20,6 +20,11 @@#define __MACH_TEGRA_DEVICES_H#include <linux/platform_device.h> +#include <linux/platform_data/tegra_usb.h> + +extern struct tegra_ehci_platform_data tegra_ehci1_pdata; +extern struct tegra_ehci_platform_data tegra_ehci2_pdata; +extern struct tegra_ehci_platform_data tegra_ehci3_pdata;extern struct platform_device tegra_gpio_device;extern struct platform_device tegra_pinmux_device;
Greg KH
maintainerPATCH 175/175 serial: sh-sci: fix a race of DMA submit_tx on transfer
In reply to Greg KH3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yoshii Takashi <[email protected]>
commit 49d4bcaddca977fffdea8b0b71f6e5da96dac78e upstream.
When DMA is enabled, sh-sci transfer begins with
uart_start()
sci_start_tx()
if (cookie_tx < 0) schedule_work()
Then, starts DMA when wq scheduled, -- (A)
process_one_work()
work_fn_rx()
cookie_tx = desc->submit_tx()
And finishes when DMA transfer ends, -- (B)
sci_dma_tx_complete()
async_tx_ack()
cookie_tx = -EINVAL
(possible another schedule_work())
This A to B sequence is not reentrant, since controlling variables (for example, cookie_tx above) are not queues nor lists. So, they must be invoked as A B A B..., otherwise results in kernel crash.
To ensure the sequence, sci_start_tx() seems to test if cookie_tx < 0 (represents "not used") to call schedule_work().
But cookie_tx will not be set (to a cookie, also means "used") until in the middle of work queue scheduled function work_fn_tx().
This gap between the test and set allows the breakage of the sequence under the very frequently call of uart_start().
Another gap between async_tx_ack() and another schedule_work() results in the same issue, too.
This patch introduces a new condition "cookie_tx == 0" just to mark it is "busy" and assign it within spin-locked region to fill the gaps.
--- drivers/tty/serial/sh-sci.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/tty/serial/sh-sci.c +10 -5
@@ -1229,17 +1229,20 @@ static void sci_dma_tx_complete(void *ar port->icount.tx +=sg_dma_len (&s->sg_tx);async_tx_ack (s->desc_tx); - s->cookie_tx = -EINVAL ; s->desc_tx =NULL ;if (uart_circ_chars_pending (xmit) <WAKEUP_CHARS )uart_write_wakeup (port);if (!uart_circ_empty (xmit)) { + s->cookie_tx =0 ;schedule_work (&s->work_tx); - }else if (port->type ==PORT_SCIFA || port->type ==PORT_SCIFB ) { -u16 ctrl =sci_in (port,SCSCR ); -sci_out (port,SCSCR , ctrl & ~SCSCR_TIE ); + }else { + s->cookie_tx = -EINVAL ; +if (port->type ==PORT_SCIFA || port->type ==PORT_SCIFB ) { +u16 ctrl =sci_in (port,SCSCR ); +sci_out (port,SCSCR , ctrl & ~SCSCR_TIE ); + } }spin_unlock_irqrestore (&port->lock, flags);
@@ -1501,8 +1504,10 @@ static void sci_start_tx(struct uart_por }if (s->chan_tx && !uart_circ_empty (&s->port.state->xmit) && - s->cookie_tx <0 ) + s->cookie_tx <0 ) { + s->cookie_tx =0 ;schedule_work (&s->work_tx); + }#endif if (!s->chan_tx || port->type ==PORT_SCIFA || port->type ==PORT_SCIFB ) {