From: Greg Kroah-Hartman Date: Fri, 21 Sep 2012 18:38:04 +0000 (-0700) Subject: 3.5-stable patches X-Git-Tag: v3.0.44~76 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c588bf09a68eaa24b840bfe66844eaee1f8214bc;p=thirdparty%2Fkernel%2Fstable-queue.git 3.5-stable patches added patches: asoc-samsung-dma-don-t-indicate-support-for-pause-resume.patch can-mcp251x-avoid-repeated-frame-bug.patch drivers-rtc-rtc-twl.c-ensure-all-interrupts-are-disabled-during-probe.patch gma500-fix-regression-on-oaktrail-devices.patch hwmon-ina2xx-fix-word-size-register-read-and-write-operations.patch hwmon-twl4030-madc-hwmon-initialize-uninitialized-structure-elements.patch md-don-t-truncate-size-at-4tb-for-raid0-and-linear.patch md-make-sure-metadata-is-updated-when-spares-are-activated-or-removed.patch md-raid10-fix-problem-with-on-stack-allocation-of-r10bio-structure.patch md-raid5-fix-calculate-of-degraded-when-a-replacement-becomes-active.patch memory-hotplug-fix-section-info-double-registration-bug.patch misdn-fix-wrong-usage-of-flush_work_sync-while-holding-locks.patch mm-ia64-fix-a-memory-block-size-bug.patch mm-page_alloc-fix-the-page-address-of-higher-page-s-buddy-calculation.patch nbd-clear-waiting_queue-on-shutdown.patch sched-add-missing-call-to-calc_load_exit_idle.patch --- diff --git a/queue-3.5/asoc-samsung-dma-don-t-indicate-support-for-pause-resume.patch b/queue-3.5/asoc-samsung-dma-don-t-indicate-support-for-pause-resume.patch new file mode 100644 index 00000000000..c94878c78b7 --- /dev/null +++ b/queue-3.5/asoc-samsung-dma-don-t-indicate-support-for-pause-resume.patch @@ -0,0 +1,64 @@ +From 57b2d68863f281737d8596cb3d76d89d9cc54fd8 Mon Sep 17 00:00:00 2001 +From: Dylan Reid +Date: Sat, 1 Sep 2012 01:38:19 -0700 +Subject: ASoC: samsung dma - Don't indicate support for pause/resume. + +From: Dylan Reid + +commit 57b2d68863f281737d8596cb3d76d89d9cc54fd8 upstream. + +The pause and resume operations indicate that the stream can be +un-paused/resumed from the exact location they were paused/suspended. +This is not true for this driver, the pause and suspend triggers share +the same code path with stop, they flush all pending DMA transfers. +This drops all pending samples. The pause_release/resume triggers are +the same as start, except that prepare won't be called beforehand, +nothing will be enqueued to the DMA engine and nothing will happen (no +audio). Removing the pause flag will let apps know that it isn't +supported. Removing the resume flag will cause user space to call +prepare and start instead of resume, so audio will continue playing when +the system wakes up. + +Before removing the pause and resume flags, I tested this on an exynos +5250, using 'aplay -i'. Pause/un-pause leads to silence followed by a +write error. Suspend/resume testing led to the same result. Removing +the two flags fixes suspend/resume (since snd_pcm_prepare is called +again). And leads to a proper reporting of pause not supported. + +Signed-off-by: Dylan Reid +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/samsung/dma.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +--- a/sound/soc/samsung/dma.c ++++ b/sound/soc/samsung/dma.c +@@ -34,9 +34,7 @@ static const struct snd_pcm_hardware dma + .info = SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP | +- SNDRV_PCM_INFO_MMAP_VALID | +- SNDRV_PCM_INFO_PAUSE | +- SNDRV_PCM_INFO_RESUME, ++ SNDRV_PCM_INFO_MMAP_VALID, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_U16_LE | + SNDRV_PCM_FMTBIT_U8 | +@@ -246,15 +244,11 @@ static int dma_trigger(struct snd_pcm_su + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: +- case SNDRV_PCM_TRIGGER_RESUME: +- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + prtd->state |= ST_RUNNING; + prtd->params->ops->trigger(prtd->params->ch); + break; + + case SNDRV_PCM_TRIGGER_STOP: +- case SNDRV_PCM_TRIGGER_SUSPEND: +- case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + prtd->state &= ~ST_RUNNING; + prtd->params->ops->stop(prtd->params->ch); + break; diff --git a/queue-3.5/can-mcp251x-avoid-repeated-frame-bug.patch b/queue-3.5/can-mcp251x-avoid-repeated-frame-bug.patch new file mode 100644 index 00000000000..f885b69d616 --- /dev/null +++ b/queue-3.5/can-mcp251x-avoid-repeated-frame-bug.patch @@ -0,0 +1,58 @@ +From cab32f39dcc5b35db96497dc0a026b5dea76e4e7 Mon Sep 17 00:00:00 2001 +From: Benoît Locher +Date: Mon, 27 Aug 2012 15:02:45 +0200 +Subject: can: mcp251x: avoid repeated frame bug + +From: Benoît Locher + +commit cab32f39dcc5b35db96497dc0a026b5dea76e4e7 upstream. + +The MCP2515 has a silicon bug causing repeated frame transmission, see section +5 of MCP2515 Rev. B Silicon Errata Revision G (March 2007). + +Basically, setting TXBnCTRL.TXREQ in either SPI mode (00 or 11) will eventually +cause the bug. The workaround proposed by Microchip is to use mode 00 and send +a RTS command on the SPI bus to initiate the transmission. + +Signed-off-by: Benoît Locher +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/mcp251x.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +--- a/drivers/net/can/mcp251x.c ++++ b/drivers/net/can/mcp251x.c +@@ -83,6 +83,11 @@ + #define INSTRUCTION_LOAD_TXB(n) (0x40 + 2 * (n)) + #define INSTRUCTION_READ_RXB(n) (((n) == 0) ? 0x90 : 0x94) + #define INSTRUCTION_RESET 0xC0 ++#define RTS_TXB0 0x01 ++#define RTS_TXB1 0x02 ++#define RTS_TXB2 0x04 ++#define INSTRUCTION_RTS(n) (0x80 | ((n) & 0x07)) ++ + + /* MPC251x registers */ + #define CANSTAT 0x0e +@@ -397,6 +402,7 @@ static void mcp251x_hw_tx_frame(struct s + static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame, + int tx_buf_idx) + { ++ struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); + u32 sid, eid, exide, rtr; + u8 buf[SPI_TRANSFER_BUF_LEN]; + +@@ -418,7 +424,10 @@ static void mcp251x_hw_tx(struct spi_dev + buf[TXBDLC_OFF] = (rtr << DLC_RTR_SHIFT) | frame->can_dlc; + memcpy(buf + TXBDAT_OFF, frame->data, frame->can_dlc); + mcp251x_hw_tx_frame(spi, buf, frame->can_dlc, tx_buf_idx); +- mcp251x_write_reg(spi, TXBCTRL(tx_buf_idx), TXBCTRL_TXREQ); ++ ++ /* use INSTRUCTION_RTS, to avoid "repeated frame problem" */ ++ priv->spi_tx_buf[0] = INSTRUCTION_RTS(1 << tx_buf_idx); ++ mcp251x_spi_trans(priv->spi, 1); + } + + static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf, diff --git a/queue-3.5/drivers-rtc-rtc-twl.c-ensure-all-interrupts-are-disabled-during-probe.patch b/queue-3.5/drivers-rtc-rtc-twl.c-ensure-all-interrupts-are-disabled-during-probe.patch new file mode 100644 index 00000000000..76c94dcd888 --- /dev/null +++ b/queue-3.5/drivers-rtc-rtc-twl.c-ensure-all-interrupts-are-disabled-during-probe.patch @@ -0,0 +1,54 @@ +From 8dcebaa9a0ae8a0487f4342f3d56d2cb1c980860 Mon Sep 17 00:00:00 2001 +From: Kevin Hilman +Date: Mon, 17 Sep 2012 14:09:17 -0700 +Subject: drivers/rtc/rtc-twl.c: ensure all interrupts are disabled during probe + +From: Kevin Hilman + +commit 8dcebaa9a0ae8a0487f4342f3d56d2cb1c980860 upstream. + +On some platforms, bootloaders are known to do some interesting RTC +programming. Without going into the obscurities as to why this may be +the case, suffice it to say the the driver should not make any +assumptions about the state of the RTC when the driver loads. In +particular, the driver probe should be sure that all interrupts are +disabled until otherwise programmed. + +This was discovered when finding bursty I2C traffic every second on +Overo platforms. This I2C overhead was keeping the SoC from hitting +deep power states. The cause was found to be the RTC firing every +second on the I2C-connected TWL PMIC. + +Special thanks to Felipe Balbi for suggesting to look for a rogue driver +as the source of the I2C traffic rather than the I2C driver itself. + +Special thanks to Steve Sakoman for helping track down the source of the +continuous RTC interrups on the Overo boards. + +Signed-off-by: Kevin Hilman +Cc: Felipe Balbi +Tested-by: Steve Sakoman +Cc: Alessandro Zummo +Tested-by: Shubhrajyoti Datta +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/rtc/rtc-twl.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/rtc/rtc-twl.c ++++ b/drivers/rtc/rtc-twl.c +@@ -495,6 +495,11 @@ static int __devinit twl_rtc_probe(struc + if (ret < 0) + goto out1; + ++ /* ensure interrupts are disabled, bootloaders can be strange */ ++ ret = twl_rtc_write_u8(0, REG_RTC_INTERRUPTS_REG); ++ if (ret < 0) ++ dev_warn(&pdev->dev, "unable to disable interrupt\n"); ++ + /* init cached IRQ enable bits */ + ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG); + if (ret < 0) diff --git a/queue-3.5/gma500-fix-regression-on-oaktrail-devices.patch b/queue-3.5/gma500-fix-regression-on-oaktrail-devices.patch new file mode 100644 index 00000000000..9f808278a3f --- /dev/null +++ b/queue-3.5/gma500-fix-regression-on-oaktrail-devices.patch @@ -0,0 +1,40 @@ +From 26df641eac05abe1a3276eea441359b4d1120816 Mon Sep 17 00:00:00 2001 +From: Alan Cox +Date: Wed, 12 Sep 2012 10:05:04 +0000 +Subject: gma500: Fix regression on Oaktrail devices + +From: Alan Cox + +commit 26df641eac05abe1a3276eea441359b4d1120816 upstream. + +The register map patches didn't set one value for the GMA600 which +means the Fujitsu Q550 dies on boot with the GMA500 driver enabled. + +Add the map entry so we don't read from the device MMIO + 0 by mistake. + +Signed-off-by: Alan Cox +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/gma500/oaktrail_device.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/gpu/drm/gma500/oaktrail_device.c ++++ b/drivers/gpu/drm/gma500/oaktrail_device.c +@@ -476,6 +476,7 @@ static const struct psb_offset oaktrail_ + .pos = DSPAPOS, + .surf = DSPASURF, + .addr = MRST_DSPABASE, ++ .base = MRST_DSPABASE, + .status = PIPEASTAT, + .linoff = DSPALINOFF, + .tileoff = DSPATILEOFF, +@@ -499,6 +500,7 @@ static const struct psb_offset oaktrail_ + .pos = DSPBPOS, + .surf = DSPBSURF, + .addr = DSPBBASE, ++ .base = DSPBBASE, + .status = PIPEBSTAT, + .linoff = DSPBLINOFF, + .tileoff = DSPBTILEOFF, diff --git a/queue-3.5/hwmon-ina2xx-fix-word-size-register-read-and-write-operations.patch b/queue-3.5/hwmon-ina2xx-fix-word-size-register-read-and-write-operations.patch new file mode 100644 index 00000000000..cd8adc574d4 --- /dev/null +++ b/queue-3.5/hwmon-ina2xx-fix-word-size-register-read-and-write-operations.patch @@ -0,0 +1,90 @@ +From 080b98e9ab30734bda2f1b8b33cd55a4c4ef406a Mon Sep 17 00:00:00 2001 +From: Guenter Roeck +Date: Tue, 11 Sep 2012 08:22:14 -0700 +Subject: hwmon: (ina2xx) Fix word size register read and write operations + +From: Guenter Roeck + +commit 080b98e9ab30734bda2f1b8b33cd55a4c4ef406a upstream. + +The driver uses be16_to_cpu and cpu_to_be16 to convert data in SMBus word +operations from chip to host byte order. However, the data passed from and to +the SMBus word API functions is in host byte order, not in chip byte order. +Conversion should therefore use swab16 instead of be16 to change the byte order. + +Replace driver internal word conversion functions with SMBus API functions to +solve the problem. + +Signed-off-by: Guenter Roeck +Acked-by: Jean Delvare +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hwmon/ina2xx.c | 30 +++++++++--------------------- + 1 file changed, 9 insertions(+), 21 deletions(-) + +--- a/drivers/hwmon/ina2xx.c ++++ b/drivers/hwmon/ina2xx.c +@@ -69,22 +69,6 @@ struct ina2xx_data { + u16 regs[INA2XX_MAX_REGISTERS]; + }; + +-int ina2xx_read_word(struct i2c_client *client, int reg) +-{ +- int val = i2c_smbus_read_word_data(client, reg); +- if (unlikely(val < 0)) { +- dev_dbg(&client->dev, +- "Failed to read register: %d\n", reg); +- return val; +- } +- return be16_to_cpu(val); +-} +- +-void ina2xx_write_word(struct i2c_client *client, int reg, int data) +-{ +- i2c_smbus_write_word_data(client, reg, cpu_to_be16(data)); +-} +- + static struct ina2xx_data *ina2xx_update_device(struct device *dev) + { + struct i2c_client *client = to_i2c_client(dev); +@@ -102,7 +86,7 @@ static struct ina2xx_data *ina2xx_update + + /* Read all registers */ + for (i = 0; i < data->registers; i++) { +- int rv = ina2xx_read_word(client, i); ++ int rv = i2c_smbus_read_word_swapped(client, i); + if (rv < 0) { + ret = ERR_PTR(rv); + goto abort; +@@ -279,22 +263,26 @@ static int ina2xx_probe(struct i2c_clien + switch (data->kind) { + case ina219: + /* device configuration */ +- ina2xx_write_word(client, INA2XX_CONFIG, INA219_CONFIG_DEFAULT); ++ i2c_smbus_write_word_swapped(client, INA2XX_CONFIG, ++ INA219_CONFIG_DEFAULT); + + /* set current LSB to 1mA, shunt is in uOhms */ + /* (equation 13 in datasheet) */ +- ina2xx_write_word(client, INA2XX_CALIBRATION, 40960000 / shunt); ++ i2c_smbus_write_word_swapped(client, INA2XX_CALIBRATION, ++ 40960000 / shunt); + dev_info(&client->dev, + "power monitor INA219 (Rshunt = %li uOhm)\n", shunt); + data->registers = INA219_REGISTERS; + break; + case ina226: + /* device configuration */ +- ina2xx_write_word(client, INA2XX_CONFIG, INA226_CONFIG_DEFAULT); ++ i2c_smbus_write_word_swapped(client, INA2XX_CONFIG, ++ INA226_CONFIG_DEFAULT); + + /* set current LSB to 1mA, shunt is in uOhms */ + /* (equation 1 in datasheet)*/ +- ina2xx_write_word(client, INA2XX_CALIBRATION, 5120000 / shunt); ++ i2c_smbus_write_word_swapped(client, INA2XX_CALIBRATION, ++ 5120000 / shunt); + dev_info(&client->dev, + "power monitor INA226 (Rshunt = %li uOhm)\n", shunt); + data->registers = INA226_REGISTERS; diff --git a/queue-3.5/hwmon-twl4030-madc-hwmon-initialize-uninitialized-structure-elements.patch b/queue-3.5/hwmon-twl4030-madc-hwmon-initialize-uninitialized-structure-elements.patch new file mode 100644 index 00000000000..b6a5f7e1c6f --- /dev/null +++ b/queue-3.5/hwmon-twl4030-madc-hwmon-initialize-uninitialized-structure-elements.patch @@ -0,0 +1,44 @@ +From 73d7c119255615a26070f9d6cdb722a166a29015 Mon Sep 17 00:00:00 2001 +From: Guenter Roeck +Date: Tue, 19 Jun 2012 08:00:00 -0700 +Subject: hwmon: (twl4030-madc-hwmon) Initialize uninitialized structure elements + +From: Guenter Roeck + +commit 73d7c119255615a26070f9d6cdb722a166a29015 upstream. + +twl4030_madc_conversion uses do_avg and type structure elements of +twl4030_madc_request. Initialize structure to avoid random operation. + +Fix for: Coverity CID 200794 Uninitialized scalar variable. + +Cc: Keerthy +Signed-off-by: Guenter Roeck +Acked-by: Jean Delvare +Acked-by: Keerthy +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hwmon/twl4030-madc-hwmon.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/drivers/hwmon/twl4030-madc-hwmon.c ++++ b/drivers/hwmon/twl4030-madc-hwmon.c +@@ -44,12 +44,13 @@ static ssize_t madc_read(struct device * + struct device_attribute *devattr, char *buf) + { + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); +- struct twl4030_madc_request req; ++ struct twl4030_madc_request req = { ++ .channels = 1 << attr->index, ++ .method = TWL4030_MADC_SW2, ++ .type = TWL4030_MADC_WAIT, ++ }; + long val; + +- req.channels = (1 << attr->index); +- req.method = TWL4030_MADC_SW2; +- req.func_cb = NULL; + val = twl4030_madc_conversion(&req); + if (val < 0) + return val; diff --git a/queue-3.5/md-don-t-truncate-size-at-4tb-for-raid0-and-linear.patch b/queue-3.5/md-don-t-truncate-size-at-4tb-for-raid0-and-linear.patch new file mode 100644 index 00000000000..d4ac026da03 --- /dev/null +++ b/queue-3.5/md-don-t-truncate-size-at-4tb-for-raid0-and-linear.patch @@ -0,0 +1,58 @@ +From 667a5313ecd7308d79629c0738b0db588b0b0a4e Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Thu, 16 Aug 2012 16:46:12 +1000 +Subject: md: Don't truncate size at 4TB for RAID0 and Linear + +From: NeilBrown + +commit 667a5313ecd7308d79629c0738b0db588b0b0a4e upstream. + +commit 27a7b260f71439c40546b43588448faac01adb93 + md: Fix handling for devices from 2TB to 4TB in 0.90 metadata. + +changed 0.90 metadata handling to truncated size to 4TB as that is +all that 0.90 can record. +However for RAID0 and Linear, 0.90 doesn't need to record the size, so +this truncation is not needed and causes working arrays to become too small. + +So avoid the truncation for RAID0 and Linear + +This bug was introduced in 3.1 and is suitable for any stable kernels +from then onwards. +As the offending commit was tagged for 'stable', any stable kernel +that it was applied to should also get this patch. That includes +at least 2.6.32, 2.6.33 and 3.0. (Thanks to Ben Hutchings for +providing that list). + +Signed-off-by: Neil Brown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/md.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -1157,8 +1157,11 @@ static int super_90_load(struct md_rdev + ret = 0; + } + rdev->sectors = rdev->sb_start; +- /* Limit to 4TB as metadata cannot record more than that */ +- if (rdev->sectors >= (2ULL << 32)) ++ /* Limit to 4TB as metadata cannot record more than that. ++ * (not needed for Linear and RAID0 as metadata doesn't ++ * record this size) ++ */ ++ if (rdev->sectors >= (2ULL << 32) && sb->level >= 1) + rdev->sectors = (2ULL << 32) - 2; + + if (rdev->sectors < ((sector_t)sb->size) * 2 && sb->level >= 1) +@@ -1449,7 +1452,7 @@ super_90_rdev_size_change(struct md_rdev + /* Limit to 4TB as metadata cannot record more than that. + * 4TB == 2^32 KB, or 2*2^32 sectors. + */ +- if (num_sectors >= (2ULL << 32)) ++ if (num_sectors >= (2ULL << 32) && rdev->mddev->level >= 1) + num_sectors = (2ULL << 32) - 2; + md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, + rdev->sb_page); diff --git a/queue-3.5/md-make-sure-metadata-is-updated-when-spares-are-activated-or-removed.patch b/queue-3.5/md-make-sure-metadata-is-updated-when-spares-are-activated-or-removed.patch new file mode 100644 index 00000000000..16b4c3d7bcc --- /dev/null +++ b/queue-3.5/md-make-sure-metadata-is-updated-when-spares-are-activated-or-removed.patch @@ -0,0 +1,60 @@ +From 6dafab6b1383e912cd252fa809570b484eb6e0dc Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Wed, 19 Sep 2012 12:54:22 +1000 +Subject: md: make sure metadata is updated when spares are activated or removed. + +From: NeilBrown + +commit 6dafab6b1383e912cd252fa809570b484eb6e0dc upstream. + +It isn't always necessary to update the metadata when spares are +removed as the presence-or-not of a spare isn't really important to +the integrity of an array. +Also activating a spare doesn't always require updating the metadata +as the update on 'recovery-completed' is usually sufficient. + +However the introduction of 'replacement' devices have made these +transitions sometimes more important. For example the 'Replacement' +flag isn't cleared until the original device is removed, so we need +to ensure a metadata update after that 'spare' is removed. + +So set MD_CHANGE_DEVS whenever a spare is activated or removed, to +complement the current situation where it is set when a spare is added +or a device is failed (or a number of other less common situations). + +This is suitable for -stable as out-of-data metadata could lead +to data corruption. +This is only relevant for 3.3 and later 9when 'replacement' as +introduced. + +Signed-off-by: NeilBrown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/md.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -7672,6 +7672,8 @@ static int remove_and_add_spares(struct + } + } + } ++ if (removed) ++ set_bit(MD_CHANGE_DEVS, &mddev->flags); + return spares; + } + +@@ -7685,9 +7687,11 @@ static void reap_sync_thread(struct mdde + !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { + /* success...*/ + /* activate any spares */ +- if (mddev->pers->spare_active(mddev)) ++ if (mddev->pers->spare_active(mddev)) { + sysfs_notify(&mddev->kobj, NULL, + "degraded"); ++ set_bit(MD_CHANGE_DEVS, &mddev->flags); ++ } + } + if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) && + mddev->pers->finish_reshape) diff --git a/queue-3.5/md-raid10-fix-problem-with-on-stack-allocation-of-r10bio-structure.patch b/queue-3.5/md-raid10-fix-problem-with-on-stack-allocation-of-r10bio-structure.patch new file mode 100644 index 00000000000..f12d8e5ded8 --- /dev/null +++ b/queue-3.5/md-raid10-fix-problem-with-on-stack-allocation-of-r10bio-structure.patch @@ -0,0 +1,132 @@ +From e0ee778528bbaad28a5c69d2e219269a3a096607 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Sat, 18 Aug 2012 09:51:42 +1000 +Subject: md/raid10: fix problem with on-stack allocation of r10bio structure. + +From: NeilBrown + +commit e0ee778528bbaad28a5c69d2e219269a3a096607 upstream. + +A 'struct r10bio' has an array of per-copy information at the end. +This array is declared with size [0] and r10bio_pool_alloc allocates +enough extra space to store the per-copy information depending on the +number of copies needed. + +So declaring a 'struct r10bio on the stack isn't going to work. It +won't allocate enough space, and memory corruption will ensue. + +So in the two places where this is done, declare a sufficiently large +structure and use that instead. + +The two call-sites of this bug were introduced in 3.4 and 3.5 +so this is suitable for both those kernels. The patch will have to +be modified for 3.4 as it only has one bug. + +Reported-by: Ivan Vasilyev +Tested-by: Ivan Vasilyev +Signed-off-by: NeilBrown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/raid10.c | 30 +++++++++++++++++++----------- + drivers/md/raid10.h | 2 +- + 2 files changed, 20 insertions(+), 12 deletions(-) + +--- a/drivers/md/raid10.c ++++ b/drivers/md/raid10.c +@@ -645,7 +645,11 @@ static int raid10_mergeable_bvec(struct + max = biovec->bv_len; + + if (mddev->merge_check_needed) { +- struct r10bio r10_bio; ++ struct { ++ struct r10bio r10_bio; ++ struct r10dev devs[conf->copies]; ++ } on_stack; ++ struct r10bio *r10_bio = &on_stack.r10_bio; + int s; + if (conf->reshape_progress != MaxSector) { + /* Cannot give any guidance during reshape */ +@@ -653,18 +657,18 @@ static int raid10_mergeable_bvec(struct + return biovec->bv_len; + return 0; + } +- r10_bio.sector = sector; +- raid10_find_phys(conf, &r10_bio); ++ r10_bio->sector = sector; ++ raid10_find_phys(conf, r10_bio); + rcu_read_lock(); + for (s = 0; s < conf->copies; s++) { +- int disk = r10_bio.devs[s].devnum; ++ int disk = r10_bio->devs[s].devnum; + struct md_rdev *rdev = rcu_dereference( + conf->mirrors[disk].rdev); + if (rdev && !test_bit(Faulty, &rdev->flags)) { + struct request_queue *q = + bdev_get_queue(rdev->bdev); + if (q->merge_bvec_fn) { +- bvm->bi_sector = r10_bio.devs[s].addr ++ bvm->bi_sector = r10_bio->devs[s].addr + + rdev->data_offset; + bvm->bi_bdev = rdev->bdev; + max = min(max, q->merge_bvec_fn( +@@ -676,7 +680,7 @@ static int raid10_mergeable_bvec(struct + struct request_queue *q = + bdev_get_queue(rdev->bdev); + if (q->merge_bvec_fn) { +- bvm->bi_sector = r10_bio.devs[s].addr ++ bvm->bi_sector = r10_bio->devs[s].addr + + rdev->data_offset; + bvm->bi_bdev = rdev->bdev; + max = min(max, q->merge_bvec_fn( +@@ -4389,14 +4393,18 @@ static int handle_reshape_read_error(str + { + /* Use sync reads to get the blocks from somewhere else */ + int sectors = r10_bio->sectors; +- struct r10bio r10b; + struct r10conf *conf = mddev->private; ++ struct { ++ struct r10bio r10_bio; ++ struct r10dev devs[conf->copies]; ++ } on_stack; ++ struct r10bio *r10b = &on_stack.r10_bio; + int slot = 0; + int idx = 0; + struct bio_vec *bvec = r10_bio->master_bio->bi_io_vec; + +- r10b.sector = r10_bio->sector; +- __raid10_find_phys(&conf->prev, &r10b); ++ r10b->sector = r10_bio->sector; ++ __raid10_find_phys(&conf->prev, r10b); + + while (sectors) { + int s = sectors; +@@ -4407,7 +4415,7 @@ static int handle_reshape_read_error(str + s = PAGE_SIZE >> 9; + + while (!success) { +- int d = r10b.devs[slot].devnum; ++ int d = r10b->devs[slot].devnum; + struct md_rdev *rdev = conf->mirrors[d].rdev; + sector_t addr; + if (rdev == NULL || +@@ -4415,7 +4423,7 @@ static int handle_reshape_read_error(str + !test_bit(In_sync, &rdev->flags)) + goto failed; + +- addr = r10b.devs[slot].addr + idx * PAGE_SIZE; ++ addr = r10b->devs[slot].addr + idx * PAGE_SIZE; + success = sync_page_io(rdev, + addr, + s << 9, +--- a/drivers/md/raid10.h ++++ b/drivers/md/raid10.h +@@ -110,7 +110,7 @@ struct r10bio { + * We choose the number when they are allocated. + * We sometimes need an extra bio to write to the replacement. + */ +- struct { ++ struct r10dev { + struct bio *bio; + union { + struct bio *repl_bio; /* used for resync and diff --git a/queue-3.5/md-raid5-fix-calculate-of-degraded-when-a-replacement-becomes-active.patch b/queue-3.5/md-raid5-fix-calculate-of-degraded-when-a-replacement-becomes-active.patch new file mode 100644 index 00000000000..3d6da6fa00a --- /dev/null +++ b/queue-3.5/md-raid5-fix-calculate-of-degraded-when-a-replacement-becomes-active.patch @@ -0,0 +1,51 @@ +From e5c86471f933608db5d43679f84cb4346c32033e Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Wed, 19 Sep 2012 12:52:30 +1000 +Subject: md/raid5: fix calculate of 'degraded' when a replacement becomes active. + +From: NeilBrown + +commit e5c86471f933608db5d43679f84cb4346c32033e upstream. + +When a replacement device becomes active, we mark the device that it +replaces as 'faulty' so that it can subsequently get removed. +However 'calc_degraded' only pays attention to the primary device, not +the replacement, so the array appears to become degraded, which is +wrong. + +So teach 'calc_degraded' to consider any replacement if a primary +device is faulty. + +This is suitable for -stable as an incorrect 'degraded' value can +confuse md and could lead to data corruption. +This is only relevant for 3.3 and later. + +Reported-by: Robin Hill +Reported-by: John Drescher +Signed-off-by: NeilBrown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/raid5.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -380,6 +380,8 @@ static int calc_degraded(struct r5conf * + degraded = 0; + for (i = 0; i < conf->previous_raid_disks; i++) { + struct md_rdev *rdev = rcu_dereference(conf->disks[i].rdev); ++ if (rdev && test_bit(Faulty, &rdev->flags)) ++ rdev = rcu_dereference(conf->disks[i].replacement); + if (!rdev || test_bit(Faulty, &rdev->flags)) + degraded++; + else if (test_bit(In_sync, &rdev->flags)) +@@ -404,6 +406,8 @@ static int calc_degraded(struct r5conf * + degraded2 = 0; + for (i = 0; i < conf->raid_disks; i++) { + struct md_rdev *rdev = rcu_dereference(conf->disks[i].rdev); ++ if (rdev && test_bit(Faulty, &rdev->flags)) ++ rdev = rcu_dereference(conf->disks[i].replacement); + if (!rdev || test_bit(Faulty, &rdev->flags)) + degraded2++; + else if (test_bit(In_sync, &rdev->flags)) diff --git a/queue-3.5/memory-hotplug-fix-section-info-double-registration-bug.patch b/queue-3.5/memory-hotplug-fix-section-info-double-registration-bug.patch new file mode 100644 index 00000000000..516790cb430 --- /dev/null +++ b/queue-3.5/memory-hotplug-fix-section-info-double-registration-bug.patch @@ -0,0 +1,77 @@ +From f14851af0ebb32745c6c5a2e400aa0549f9d20df Mon Sep 17 00:00:00 2001 +From: qiuxishi +Date: Mon, 17 Sep 2012 14:09:24 -0700 +Subject: memory hotplug: fix section info double registration bug + +From: qiuxishi + +commit f14851af0ebb32745c6c5a2e400aa0549f9d20df upstream. + +There may be a bug when registering section info. For example, on my +Itanium platform, the pfn range of node0 includes the other nodes, so +other nodes' section info will be double registered, and memmap's page +count will equal to 3. + + node0: start_pfn=0x100, spanned_pfn=0x20fb00, present_pfn=0x7f8a3, => 0x000100-0x20fc00 + node1: start_pfn=0x80000, spanned_pfn=0x80000, present_pfn=0x80000, => 0x080000-0x100000 + node2: start_pfn=0x100000, spanned_pfn=0x80000, present_pfn=0x80000, => 0x100000-0x180000 + node3: start_pfn=0x180000, spanned_pfn=0x80000, present_pfn=0x80000, => 0x180000-0x200000 + + free_all_bootmem_node() + register_page_bootmem_info_node() + register_page_bootmem_info_section() + +When hot remove memory, we can't free the memmap's page because +page_count() is 2 after put_page_bootmem(). + + sparse_remove_one_section() + free_section_usemap() + free_map_bootmem() + put_page_bootmem() + +[akpm@linux-foundation.org: add code comment] +Signed-off-by: Xishi Qiu +Signed-off-by: Jiang Liu +Acked-by: Mel Gorman +Cc: "Luck, Tony" +Cc: Yasuaki Ishimatsu +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/memory_hotplug.c | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +--- a/mm/memory_hotplug.c ++++ b/mm/memory_hotplug.c +@@ -126,9 +126,6 @@ static void register_page_bootmem_info_s + struct mem_section *ms; + struct page *page, *memmap; + +- if (!pfn_valid(start_pfn)) +- return; +- + section_nr = pfn_to_section_nr(start_pfn); + ms = __nr_to_section(section_nr); + +@@ -187,9 +184,16 @@ void register_page_bootmem_info_node(str + end_pfn = pfn + pgdat->node_spanned_pages; + + /* register_section info */ +- for (; pfn < end_pfn; pfn += PAGES_PER_SECTION) +- register_page_bootmem_info_section(pfn); +- ++ for (; pfn < end_pfn; pfn += PAGES_PER_SECTION) { ++ /* ++ * Some platforms can assign the same pfn to multiple nodes - on ++ * node0 as well as nodeN. To avoid registering a pfn against ++ * multiple nodes we check that this pfn does not already ++ * reside in some other node. ++ */ ++ if (pfn_valid(pfn) && (pfn_to_nid(pfn) == node)) ++ register_page_bootmem_info_section(pfn); ++ } + } + #endif /* !CONFIG_SPARSEMEM_VMEMMAP */ + diff --git a/queue-3.5/misdn-fix-wrong-usage-of-flush_work_sync-while-holding-locks.patch b/queue-3.5/misdn-fix-wrong-usage-of-flush_work_sync-while-holding-locks.patch new file mode 100644 index 00000000000..209e5ef852a --- /dev/null +++ b/queue-3.5/misdn-fix-wrong-usage-of-flush_work_sync-while-holding-locks.patch @@ -0,0 +1,128 @@ +From 4b921eda53366b319602351ff4d7256fafa4bd1b Mon Sep 17 00:00:00 2001 +From: Karsten Keil +Date: Thu, 13 Sep 2012 04:36:20 +0000 +Subject: mISDN: Fix wrong usage of flush_work_sync while holding locks + +From: Karsten Keil + +commit 4b921eda53366b319602351ff4d7256fafa4bd1b upstream. + +It is a bad idea to hold a spinlock and call flush_work_sync. +Move the workqueue cleanup outside the spinlock and use cancel_work_sync, +on closing the channel this seems to be the more correct function. +Remove the never used and constant return value of mISDN_freebchannel. + +Signed-off-by: Karsten Keil +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/isdn/hardware/mISDN/avmfritz.c | 3 ++- + drivers/isdn/hardware/mISDN/mISDNipac.c | 3 ++- + drivers/isdn/hardware/mISDN/mISDNisar.c | 3 ++- + drivers/isdn/hardware/mISDN/netjet.c | 3 ++- + drivers/isdn/hardware/mISDN/w6692.c | 3 ++- + drivers/isdn/mISDN/hwchannel.c | 9 ++++----- + include/linux/mISDNhw.h | 2 +- + 7 files changed, 15 insertions(+), 11 deletions(-) + +--- a/drivers/isdn/hardware/mISDN/avmfritz.c ++++ b/drivers/isdn/hardware/mISDN/avmfritz.c +@@ -857,8 +857,9 @@ avm_bctrl(struct mISDNchannel *ch, u32 c + switch (cmd) { + case CLOSE_CHANNEL: + test_and_clear_bit(FLG_OPEN, &bch->Flags); ++ cancel_work_sync(&bch->workq); + spin_lock_irqsave(&fc->lock, flags); +- mISDN_freebchannel(bch); ++ mISDN_clear_bchannel(bch); + modehdlc(bch, ISDN_P_NONE); + spin_unlock_irqrestore(&fc->lock, flags); + ch->protocol = ISDN_P_NONE; +--- a/drivers/isdn/hardware/mISDN/mISDNipac.c ++++ b/drivers/isdn/hardware/mISDN/mISDNipac.c +@@ -1406,8 +1406,9 @@ hscx_bctrl(struct mISDNchannel *ch, u32 + switch (cmd) { + case CLOSE_CHANNEL: + test_and_clear_bit(FLG_OPEN, &bch->Flags); ++ cancel_work_sync(&bch->workq); + spin_lock_irqsave(hx->ip->hwlock, flags); +- mISDN_freebchannel(bch); ++ mISDN_clear_bchannel(bch); + hscx_mode(hx, ISDN_P_NONE); + spin_unlock_irqrestore(hx->ip->hwlock, flags); + ch->protocol = ISDN_P_NONE; +--- a/drivers/isdn/hardware/mISDN/mISDNisar.c ++++ b/drivers/isdn/hardware/mISDN/mISDNisar.c +@@ -1588,8 +1588,9 @@ isar_bctrl(struct mISDNchannel *ch, u32 + switch (cmd) { + case CLOSE_CHANNEL: + test_and_clear_bit(FLG_OPEN, &bch->Flags); ++ cancel_work_sync(&bch->workq); + spin_lock_irqsave(ich->is->hwlock, flags); +- mISDN_freebchannel(bch); ++ mISDN_clear_bchannel(bch); + modeisar(ich, ISDN_P_NONE); + spin_unlock_irqrestore(ich->is->hwlock, flags); + ch->protocol = ISDN_P_NONE; +--- a/drivers/isdn/hardware/mISDN/netjet.c ++++ b/drivers/isdn/hardware/mISDN/netjet.c +@@ -812,8 +812,9 @@ nj_bctrl(struct mISDNchannel *ch, u32 cm + switch (cmd) { + case CLOSE_CHANNEL: + test_and_clear_bit(FLG_OPEN, &bch->Flags); ++ cancel_work_sync(&bch->workq); + spin_lock_irqsave(&card->lock, flags); +- mISDN_freebchannel(bch); ++ mISDN_clear_bchannel(bch); + mode_tiger(bc, ISDN_P_NONE); + spin_unlock_irqrestore(&card->lock, flags); + ch->protocol = ISDN_P_NONE; +--- a/drivers/isdn/hardware/mISDN/w6692.c ++++ b/drivers/isdn/hardware/mISDN/w6692.c +@@ -1054,8 +1054,9 @@ w6692_bctrl(struct mISDNchannel *ch, u32 + switch (cmd) { + case CLOSE_CHANNEL: + test_and_clear_bit(FLG_OPEN, &bch->Flags); ++ cancel_work_sync(&bch->workq); + spin_lock_irqsave(&card->lock, flags); +- mISDN_freebchannel(bch); ++ mISDN_clear_bchannel(bch); + w6692_mode(bc, ISDN_P_NONE); + spin_unlock_irqrestore(&card->lock, flags); + ch->protocol = ISDN_P_NONE; +--- a/drivers/isdn/mISDN/hwchannel.c ++++ b/drivers/isdn/mISDN/hwchannel.c +@@ -148,17 +148,16 @@ mISDN_clear_bchannel(struct bchannel *ch + ch->next_minlen = ch->init_minlen; + ch->maxlen = ch->init_maxlen; + ch->next_maxlen = ch->init_maxlen; ++ skb_queue_purge(&ch->rqueue); ++ ch->rcount = 0; + } + EXPORT_SYMBOL(mISDN_clear_bchannel); + +-int ++void + mISDN_freebchannel(struct bchannel *ch) + { ++ cancel_work_sync(&ch->workq); + mISDN_clear_bchannel(ch); +- skb_queue_purge(&ch->rqueue); +- ch->rcount = 0; +- flush_work_sync(&ch->workq); +- return 0; + } + EXPORT_SYMBOL(mISDN_freebchannel); + +--- a/include/linux/mISDNhw.h ++++ b/include/linux/mISDNhw.h +@@ -183,7 +183,7 @@ extern int mISDN_initbchannel(struct bch + unsigned short); + extern int mISDN_freedchannel(struct dchannel *); + extern void mISDN_clear_bchannel(struct bchannel *); +-extern int mISDN_freebchannel(struct bchannel *); ++extern void mISDN_freebchannel(struct bchannel *); + extern int mISDN_ctrl_bchannel(struct bchannel *, struct mISDN_ctrl_req *); + extern void queue_ch_frame(struct mISDNchannel *, u_int, + int, struct sk_buff *); diff --git a/queue-3.5/mm-ia64-fix-a-memory-block-size-bug.patch b/queue-3.5/mm-ia64-fix-a-memory-block-size-bug.patch new file mode 100644 index 00000000000..f562cf02eb1 --- /dev/null +++ b/queue-3.5/mm-ia64-fix-a-memory-block-size-bug.patch @@ -0,0 +1,63 @@ +From 05cf96398e1b6502f9e191291b715c7463c9d5dd Mon Sep 17 00:00:00 2001 +From: Jianguo Wu +Date: Mon, 17 Sep 2012 14:08:56 -0700 +Subject: mm/ia64: fix a memory block size bug + +From: Jianguo Wu + +commit 05cf96398e1b6502f9e191291b715c7463c9d5dd upstream. + +I found following definition in include/linux/memory.h, in my IA64 +platform, SECTION_SIZE_BITS is equal to 32, and MIN_MEMORY_BLOCK_SIZE +will be 0. + + #define MIN_MEMORY_BLOCK_SIZE (1 << SECTION_SIZE_BITS) + +Because MIN_MEMORY_BLOCK_SIZE is int type and length of 32bits, +so MIN_MEMORY_BLOCK_SIZE(1 << 32) will will equal to 0. +Actually when SECTION_SIZE_BITS >= 31, MIN_MEMORY_BLOCK_SIZE will be wrong. +This will cause wrong system memory infomation in sysfs. +I think it should be: + + #define MIN_MEMORY_BLOCK_SIZE (1UL << SECTION_SIZE_BITS) + +And "echo offline > memory0/state" will cause following call trace: + + kernel BUG at mm/memory_hotplug.c:885! + sh[6455]: bugcheck! 0 [1] + Pid: 6455, CPU 0, comm: sh + psr : 0000101008526030 ifs : 8000000000000fa4 ip : [] Not tainted (3.6.0-rc1) + ip is at offline_pages+0x210/0xee0 + Call Trace: + show_stack+0x80/0xa0 + show_regs+0x640/0x920 + die+0x190/0x2c0 + die_if_kernel+0x50/0x80 + ia64_bad_break+0x3d0/0x6e0 + ia64_native_leave_kernel+0x0/0x270 + offline_pages+0x210/0xee0 + alloc_pages_current+0x180/0x2a0 + +Signed-off-by: Jianguo Wu +Signed-off-by: Jiang Liu +Cc: "Luck, Tony" +Reviewed-by: Michal Hocko +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/memory.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/linux/memory.h ++++ b/include/linux/memory.h +@@ -19,7 +19,7 @@ + #include + #include + +-#define MIN_MEMORY_BLOCK_SIZE (1 << SECTION_SIZE_BITS) ++#define MIN_MEMORY_BLOCK_SIZE (1UL << SECTION_SIZE_BITS) + + struct memory_block { + unsigned long start_section_nr; diff --git a/queue-3.5/mm-page_alloc-fix-the-page-address-of-higher-page-s-buddy-calculation.patch b/queue-3.5/mm-page_alloc-fix-the-page-address-of-higher-page-s-buddy-calculation.patch new file mode 100644 index 00000000000..72a1c7ad87d --- /dev/null +++ b/queue-3.5/mm-page_alloc-fix-the-page-address-of-higher-page-s-buddy-calculation.patch @@ -0,0 +1,46 @@ +From 0ba8f2d59304dfe69b59c034de723ad80f7ab9ac Mon Sep 17 00:00:00 2001 +From: Li Haifeng +Date: Mon, 17 Sep 2012 14:09:21 -0700 +Subject: mm/page_alloc: fix the page address of higher page's buddy calculation + +From: Li Haifeng + +commit 0ba8f2d59304dfe69b59c034de723ad80f7ab9ac upstream. + +The heuristic method for buddy has been introduced since commit +43506fad21ca ("mm/page_alloc.c: simplify calculation of combined index +of adjacent buddy lists"). But the page address of higher page's buddy +was wrongly calculated, which will lead page_is_buddy to fail for ever. +IOW, the heuristic method would be disabled with the wrong page address +of higher page's buddy. + +Calculating the page address of higher page's buddy should be based +higher_page with the offset between index of higher page and index of +higher page's buddy. + +Signed-off-by: Haifeng Li +Signed-off-by: Gavin Shan +Reviewed-by: Michal Hocko +Cc: KyongHo Cho +Cc: Mel Gorman +Cc: Minchan Kim +Cc: Johannes Weiner +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/page_alloc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -580,7 +580,7 @@ static inline void __free_one_page(struc + combined_idx = buddy_idx & page_idx; + higher_page = page + (combined_idx - page_idx); + buddy_idx = __find_buddy_index(combined_idx, order + 1); +- higher_buddy = page + (buddy_idx - combined_idx); ++ higher_buddy = higher_page + (buddy_idx - combined_idx); + if (page_is_buddy(higher_page, higher_buddy, order + 1)) { + list_add_tail(&page->lru, + &zone->free_area[order].free_list[migratetype]); diff --git a/queue-3.5/nbd-clear-waiting_queue-on-shutdown.patch b/queue-3.5/nbd-clear-waiting_queue-on-shutdown.patch new file mode 100644 index 00000000000..40ac0070658 --- /dev/null +++ b/queue-3.5/nbd-clear-waiting_queue-on-shutdown.patch @@ -0,0 +1,56 @@ +From fded4e090c60100d709318896c79816d68d5b47d Mon Sep 17 00:00:00 2001 +From: Paul Clements +Date: Mon, 17 Sep 2012 14:09:02 -0700 +Subject: nbd: clear waiting_queue on shutdown + +From: Paul Clements + +commit fded4e090c60100d709318896c79816d68d5b47d upstream. + +Fix a serious but uncommon bug in nbd which occurs when there is heavy +I/O going to the nbd device while, at the same time, a failure (server, +network) or manual disconnect of the nbd connection occurs. + +There is a small window between the time that the nbd_thread is stopped +and the socket is shutdown where requests can continue to be queued to +nbd's internal waiting_queue. When this happens, those requests are +never completed or freed. + +The fix is to clear the waiting_queue on shutdown of the nbd device, in +the same way that the nbd request queue (queue_head) is already being +cleared. + +Signed-off-by: Paul Clements +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/block/nbd.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -445,6 +445,14 @@ static void nbd_clear_que(struct nbd_dev + req->errors++; + nbd_end_request(req); + } ++ ++ while (!list_empty(&nbd->waiting_queue)) { ++ req = list_entry(nbd->waiting_queue.next, struct request, ++ queuelist); ++ list_del_init(&req->queuelist); ++ req->errors++; ++ nbd_end_request(req); ++ } + } + + +@@ -594,6 +602,7 @@ static int __nbd_ioctl(struct block_devi + nbd->file = NULL; + nbd_clear_que(nbd); + BUG_ON(!list_empty(&nbd->queue_head)); ++ BUG_ON(!list_empty(&nbd->waiting_queue)); + if (file) + fput(file); + return 0; diff --git a/queue-3.5/sched-add-missing-call-to-calc_load_exit_idle.patch b/queue-3.5/sched-add-missing-call-to-calc_load_exit_idle.patch new file mode 100644 index 00000000000..94eb0b6f414 --- /dev/null +++ b/queue-3.5/sched-add-missing-call-to-calc_load_exit_idle.patch @@ -0,0 +1,42 @@ +From 749c8814f08f12baa4a9c2812a7c6ede7d69507d Mon Sep 17 00:00:00 2001 +From: Charles Wang +Date: Mon, 20 Aug 2012 16:02:33 +0800 +Subject: sched: Add missing call to calc_load_exit_idle() + +From: Charles Wang + +commit 749c8814f08f12baa4a9c2812a7c6ede7d69507d upstream. + +Azat Khuzhin reported high loadavg in Linux v3.6 + +After checking the upstream scheduler code, I found Peter's commit: + + 5167e8d5417b sched/nohz: Rewrite and fix load-avg computation -- again + +not fully applied, missing the call to calc_load_exit_idle(). + +After that idle exit in sampling window will always be calculated +to non-idle, and the load will be higher than normal. + +This patch adds the missing call to calc_load_exit_idle(). + +Signed-off-by: Charles Wang +Signed-off-by: Peter Zijlstra +Link: http://lkml.kernel.org/r/1345449754-27130-1-git-send-email-muming.wq@gmail.com +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/time/tick-sched.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/kernel/time/tick-sched.c ++++ b/kernel/time/tick-sched.c +@@ -145,6 +145,7 @@ static void tick_nohz_update_jiffies(kti + tick_do_update_jiffies64(now); + local_irq_restore(flags); + ++ calc_load_exit_idle(); + touch_softlockup_watchdog(); + } + diff --git a/queue-3.5/series b/queue-3.5/series index 44a5a6c106e..08fcd313f90 100644 --- a/queue-3.5/series +++ b/queue-3.5/series @@ -87,3 +87,19 @@ dyndbg-fix-for-soh-in-logging-messages.patch redefine-atomic_init-and-atomic64_init-to-drop-the-casts.patch digsig-add-hash-size-comparision-on-signature-verification.patch sunrpc-fix-a-udp-transport-regression.patch +md-don-t-truncate-size-at-4tb-for-raid0-and-linear.patch +md-raid10-fix-problem-with-on-stack-allocation-of-r10bio-structure.patch +md-make-sure-metadata-is-updated-when-spares-are-activated-or-removed.patch +md-raid5-fix-calculate-of-degraded-when-a-replacement-becomes-active.patch +nbd-clear-waiting_queue-on-shutdown.patch +asoc-samsung-dma-don-t-indicate-support-for-pause-resume.patch +mm-page_alloc-fix-the-page-address-of-higher-page-s-buddy-calculation.patch +drivers-rtc-rtc-twl.c-ensure-all-interrupts-are-disabled-during-probe.patch +hwmon-twl4030-madc-hwmon-initialize-uninitialized-structure-elements.patch +hwmon-ina2xx-fix-word-size-register-read-and-write-operations.patch +sched-add-missing-call-to-calc_load_exit_idle.patch +gma500-fix-regression-on-oaktrail-devices.patch +misdn-fix-wrong-usage-of-flush_work_sync-while-holding-locks.patch +can-mcp251x-avoid-repeated-frame-bug.patch +mm-ia64-fix-a-memory-block-size-bug.patch +memory-hotplug-fix-section-info-double-registration-bug.patch