From 0b1f6ec7a5fb3faff1a62afee132dac316eec63d Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 9 Feb 2015 08:05:22 +0000 Subject: [PATCH 01/95] ASoC: rsnd: set device data before snd_soc_register_platform/component Set device data before snd_soc_register_platform/component. Otherwise, it will use NULL pointer if user calls unbind -> bind or rmmod -> insmod Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 75308bbc2ce896..fc227d3bc021b2 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -1268,6 +1268,8 @@ static int rsnd_probe(struct platform_device *pdev) goto exit_snd_probe; } + dev_set_drvdata(dev, priv); + /* * asoc register */ @@ -1284,8 +1286,6 @@ static int rsnd_probe(struct platform_device *pdev) goto exit_snd_soc; } - dev_set_drvdata(dev, priv); - pm_runtime_enable(dev); dev_info(dev, "probed\n"); From 541b03ad6cfe0e415273f096fd8c47d2879c6c15 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Tue, 10 Feb 2015 21:31:43 -0800 Subject: [PATCH 02/95] ASoC: fsl_ssi: Fix the incorrect limitation of the bit clock rate According to i.MX Reference Manual, the bit-clock frequency generated by SSI must be never greater than 1/5 of the peripheral clock frequency. This peripheral clock, however, is not baudclk but the IPG clock (i.e. ssi_private->clk in the fsl_ssi driver). So this patch just simply fixes the incorrect limitation applied to the bit clock (baudclk) rate. Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 059496ed9ad76c..d7365c5d7ec0b4 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -603,10 +603,6 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, factor = (div2 + 1) * (7 * psr + 1) * 2; for (i = 0; i < 255; i++) { - /* The bclk rate must be smaller than 1/5 sysclk rate */ - if (factor * (i + 1) < 5) - continue; - tmprate = freq * factor * (i + 2); if (baudclk_is_used) @@ -614,6 +610,13 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, else clkrate = clk_round_rate(ssi_private->baudclk, tmprate); + /* + * Hardware limitation: The bclk rate must be + * never greater than 1/5 IPG clock rate + */ + if (clkrate * 5 > clk_get_rate(ssi_private->clk)) + continue; + clkrate /= factor; afreq = clkrate / (i + 1); From ffa047577127336861d91f3934133f8e8906d1b4 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 11 Feb 2015 13:13:18 -0800 Subject: [PATCH 03/95] ASoC: Fix MAX98357A codec driver dependencies The max98357a driver depends on GPIOLIB. This may cause the following build failure. sound/soc/codecs/max98357a.c: In function 'max98357a_daiops_trigger': sound/soc/codecs/max98357a.c:30:3: error: implicit declaration of function 'gpiod_set_value' sound/soc/codecs/max98357a.c: In function 'max98357a_codec_probe': sound/soc/codecs/max98357a.c:55:2: error: implicit declaration of function 'devm_gpiod_get' sound/soc/codecs/max98357a.c:61:2: error: implicit declaration of function 'gpiod_direction_output' Seen with mips:allmodconfig as well as various randconfig builds. Fixes: af5adf129369 ("ASoC: max98357a: Add MAX98357A codec driver") Cc: Kenneth Westfield Signed-off-by: Guenter Roeck Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 064e6c18e10923..ea9f0e31f9d40d 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -69,7 +69,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_MAX98088 if I2C select SND_SOC_MAX98090 if I2C select SND_SOC_MAX98095 if I2C - select SND_SOC_MAX98357A + select SND_SOC_MAX98357A if GPIOLIB select SND_SOC_MAX9850 if I2C select SND_SOC_MAX9768 if I2C select SND_SOC_MAX9877 if I2C From 5c8be987d4d9c0262e6229e342fa0da8a5aeee47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20Stehl=C3=A9?= Date: Wed, 11 Feb 2015 23:08:59 +0100 Subject: [PATCH 04/95] ASoC: max98357a: Fix missing include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes the following compilation errors: sound/soc/codecs/max98357a.c: In function ‘max98357a_daiops_trigger’: sound/soc/codecs/max98357a.c:30:3: error: implicit declaration of function ‘gpiod_set_value’ [-Werror=implicit-function-declaration] sound/soc/codecs/max98357a.c: In function ‘max98357a_codec_probe’: sound/soc/codecs/max98357a.c:55:2: error: implicit declaration of function ‘devm_gpiod_get’ [-Werror=implicit-function-declaration] sound/soc/codecs/max98357a.c:61:2: error: implicit declaration of function ‘gpiod_direction_output’ [-Werror=implicit-function-declaration] cc1: some warnings being treated as errors Signed-off-by: Vincent Stehlé Cc: Kenneth Westfield Cc: Mark Brown Signed-off-by: Mark Brown --- sound/soc/codecs/max98357a.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/max98357a.c b/sound/soc/codecs/max98357a.c index 1806333ea29e5a..f493fb6fd4ea76 100644 --- a/sound/soc/codecs/max98357a.c +++ b/sound/soc/codecs/max98357a.c @@ -14,6 +14,7 @@ #include #include +#include #include #define DRV_NAME "max98357a" From fb5ab7296a2bea17c38fae48af2808a07049ac90 Mon Sep 17 00:00:00 2001 From: Kiran Padwal Date: Thu, 12 Feb 2015 14:38:02 +0530 Subject: [PATCH 05/95] ASoC: omap-hdmi-audio: Add missing error check for devm_kzalloc This patch add a missing check on the return value of devm_kzalloc, which would cause a NULL pointer dereference in a OOM situation. Signed-off-by: Kiran Padwal Acked-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-hdmi-audio.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/omap/omap-hdmi-audio.c b/sound/soc/omap/omap-hdmi-audio.c index 3f9ac7dbdc8014..069ad451d05d9c 100644 --- a/sound/soc/omap/omap-hdmi-audio.c +++ b/sound/soc/omap/omap-hdmi-audio.c @@ -352,6 +352,9 @@ static int omap_hdmi_audio_probe(struct platform_device *pdev) return ret; card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); + if (!card) + return -ENOMEM; + card->name = devm_kasprintf(dev, GFP_KERNEL, "HDMI %s", dev_name(ad->dssdev)); card->owner = THIS_MODULE; From 7bd345c9e87d879d696c6843fe200b60c2051c84 Mon Sep 17 00:00:00 2001 From: Mengdong Lin Date: Fri, 13 Feb 2015 19:21:25 +0800 Subject: [PATCH 06/95] ASoC: Intel: set initial runtime PM status to active for ACPI-enumerated ADSP The ADSP on Braswell/Baytrail is an ACPI device. This patch sets its initial runtime PM status to active. Otherwise, its initial status is suspended and runtime_suspend ops will not be called after probe and thus cannot further trigger ACPI _PS3 (D3) method to put the device into low power D3cold state. Signed-off-by: Mengdong Lin Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/soc/intel/sst/sst.c b/sound/soc/intel/sst/sst.c index 8a8d56a146e75a..d6ea80076ea21c 100644 --- a/sound/soc/intel/sst/sst.c +++ b/sound/soc/intel/sst/sst.c @@ -379,6 +379,10 @@ void sst_configure_runtime_pm(struct intel_sst_drv *ctx) * initially active. So change the state to active before * enabling the pm */ + + if (!acpi_disabled) + pm_runtime_set_active(ctx->dev); + pm_runtime_enable(ctx->dev); if (acpi_disabled) From ce204e9a4bd82e9e6e7479bca8057e45aaac5c42 Mon Sep 17 00:00:00 2001 From: Ivan Khoronzhuk Date: Wed, 18 Feb 2015 15:51:41 +0200 Subject: [PATCH 07/95] firmware: dmi_scan: Fix dmi scan to handle "End of Table" structure The dmi-sysfs should create "End of Table" entry, that is type 127. But after adding initial SMBIOS v3 support fc43026278b2 ("dmi: add support for SMBIOS 3.0 64-bit entry point") the 127-0 entry is not handled any more, as result it's not created in dmi sysfs for instance. This is important because the size of whole DMI table must correspond to sum of all DMI entry sizes. So move the end-of-table check after it's handled by dmi_table. Reviewed-by: Ard Biesheuvel Signed-off-by: Ivan Khoronzhuk Cc: # v3.19 Signed-off-by: Matt Fleming --- drivers/firmware/dmi_scan.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index c5f7b4e9eb6c6e..a44b87c7b45c5a 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -92,12 +92,6 @@ static void dmi_table(u8 *buf, int len, int num, while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) { const struct dmi_header *dm = (const struct dmi_header *)data; - /* - * 7.45 End-of-Table (Type 127) [SMBIOS reference spec v3.0.0] - */ - if (dm->type == DMI_ENTRY_END_OF_TABLE) - break; - /* * We want to know the total length (formatted area and * strings) before decoding to make sure we won't run off the @@ -108,6 +102,13 @@ static void dmi_table(u8 *buf, int len, int num, data++; if (data - buf < len - 1) decode(dm, private_data); + + /* + * 7.45 End-of-Table (Type 127) [SMBIOS reference spec v3.0.0] + */ + if (dm->type == DMI_ENTRY_END_OF_TABLE) + break; + data += 2; i++; } From e7a961c9578ce227d3c62c4cce9463b763a1e0c0 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Tue, 17 Feb 2015 13:59:27 +0800 Subject: [PATCH 08/95] ASoC: rt5670: Fix the speaker mono output issue We need to set left/right control for the speaker amp to get stereo output on speaker. Signed-off-by: Bard Liao Signed-off-by: Mark Brown --- sound/soc/codecs/rt5670.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index 8a0833de1665bc..d33f33ce865a2a 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c @@ -2591,6 +2591,12 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, regmap_write(rt5670->regmap, RT5670_RESET, 0); + regmap_read(rt5670->regmap, RT5670_VENDOR_ID, &val); + if (val >= 4) + regmap_write(rt5670->regmap, RT5670_GPIO_CTRL3, 0x0980); + else + regmap_write(rt5670->regmap, RT5670_GPIO_CTRL3, 0x0d00); + ret = regmap_register_patch(rt5670->regmap, init_list, ARRAY_SIZE(init_list)); if (ret != 0) From 014c4d637604c9af2f7f2ff4fd91b725a0c58a5c Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 18 Feb 2015 21:35:08 +0100 Subject: [PATCH 09/95] ASoC: Samsung: add missing I2C/SPI dependencies A few sound drivers for the samsung platforms are missing dependencies on I2C or SPI, which can lead to build errors like codecs/rt5631.c:1737:1: warning: data definition has no type or storage class 31_i2c_driver); codecs/rt5631.c:1737:1: error: type defaults to 'int' in declaration of 'module_i2c_driver' [-Werror=implicit-int] codecs/rt5631.c:1737:1: warning: parameter names (without types) in function declaration codecs/rt5631.c:1726:26: warning: 'rt5631_i2c_driver' defined but not used [-Wunused-variable] I have gone through all the ones that did not already have an I2C dependency and added the ones that I found missing, namely arndale, odroid-x2, littlemill, bells and speyside and this patch adds all the dependencies. Signed-off-by: Arnd Bergmann Signed-off-by: Mark Brown --- sound/soc/samsung/Kconfig | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index fc67f97f19f633..e0c4a4ec42809a 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -185,7 +185,7 @@ config SND_SOC_SMDK_WM8994_PCM config SND_SOC_SPEYSIDE tristate "Audio support for Wolfson Speyside" - depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 + depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 && I2C && SPI_MASTER select SND_SAMSUNG_I2S select SND_SOC_WM8996 select SND_SOC_WM9081 @@ -200,7 +200,7 @@ config SND_SOC_TOBERMORY config SND_SOC_BELLS tristate "Audio support for Wolfson Bells" - depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 && MFD_ARIZONA + depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 && MFD_ARIZONA && I2C && SPI_MASTER select SND_SAMSUNG_I2S select SND_SOC_WM5102 select SND_SOC_WM5110 @@ -217,7 +217,7 @@ config SND_SOC_LOWLAND config SND_SOC_LITTLEMILL tristate "Audio support for Wolfson Littlemill" - depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 + depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 && I2C select SND_SAMSUNG_I2S select MFD_WM8994 select SND_SOC_WM8994 @@ -234,7 +234,7 @@ config SND_SOC_SNOW config SND_SOC_ODROIDX2 tristate "Audio support for Odroid-X2 and Odroid-U3" - depends on SND_SOC_SAMSUNG + depends on SND_SOC_SAMSUNG && I2C select SND_SOC_MAX98090 select SND_SAMSUNG_I2S help @@ -242,6 +242,6 @@ config SND_SOC_ODROIDX2 config SND_SOC_ARNDALE_RT5631_ALC5631 tristate "Audio support for RT5631(ALC5631) on Arndale Board" - depends on SND_SOC_SAMSUNG + depends on SND_SOC_SAMSUNG && I2C select SND_SAMSUNG_I2S select SND_SOC_RT5631 From 52554fbd2f88a432a16e9e88e14c4b02ccb7cdb6 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 18 Feb 2015 21:43:13 +0100 Subject: [PATCH 10/95] ASoC: cirrus: tlv320aic23 needs I2C The tlv320aic23 codec is selected by the ep93xx snapper platform, which are missing a dependency on I2C, and that can result in this build error, as found during randconfig builds: .../codecs/tlv320aic23-i2c.c: In function 'tlv320aic23_i2c_probe': .../codecs/tlv320aic23-i2c.c:27:2: error: implicit declaration of function 'i2c_check_functionality' [-Werror=implicit-function-declaration] if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) ^ This adds the missing dependency. Signed-off-by: Arnd Bergmann Signed-off-by: Mark Brown --- sound/soc/cirrus/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/cirrus/Kconfig b/sound/soc/cirrus/Kconfig index 7b7fbcd49e5e42..c7cd60f009e93e 100644 --- a/sound/soc/cirrus/Kconfig +++ b/sound/soc/cirrus/Kconfig @@ -16,7 +16,7 @@ config SND_EP93XX_SOC_AC97 config SND_EP93XX_SOC_SNAPPERCL15 tristate "SoC Audio support for Bluewater Systems Snapper CL15 module" - depends on SND_EP93XX_SOC && MACH_SNAPPER_CL15 + depends on SND_EP93XX_SOC && MACH_SNAPPER_CL15 && I2C select SND_EP93XX_SOC_I2S select SND_SOC_TLV320AIC23_I2C help From 08d0a55c33393e6dc838e37b7a8657c28a6de10d Mon Sep 17 00:00:00 2001 From: Kenneth Westfield Date: Tue, 17 Feb 2015 00:53:11 -0800 Subject: [PATCH 11/95] ASoC: max98357a: Add missing header files Add missing header files to avoid implicit declarations and indirect inclusions. Signed-off-by: Kenneth Westfield Signed-off-by: Mark Brown --- sound/soc/codecs/max98357a.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/max98357a.c b/sound/soc/codecs/max98357a.c index f493fb6fd4ea76..e9e6efbc21dd52 100644 --- a/sound/soc/codecs/max98357a.c +++ b/sound/soc/codecs/max98357a.c @@ -12,10 +12,19 @@ * max98357a.c -- MAX98357A ALSA SoC Codec driver */ -#include +#include +#include #include #include +#include +#include +#include +#include +#include +#include #include +#include +#include #define DRV_NAME "max98357a" From b3ec1c35385a16ddd98fdf104dcf4623a66e042a Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Thu, 12 Feb 2015 09:59:55 +0530 Subject: [PATCH 12/95] ASoC: Intel: update MMX ID to 3 The updated firmware expects the MMX ID to be used as 3, so update the driver as well Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst-atom-controls.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/sst-atom-controls.h b/sound/soc/intel/sst-atom-controls.h index dfebfdd5eb2aaa..daecc58f28afaf 100644 --- a/sound/soc/intel/sst-atom-controls.h +++ b/sound/soc/intel/sst-atom-controls.h @@ -150,7 +150,7 @@ enum sst_cmd_type { enum sst_task { SST_TASK_SBA = 1, - SST_TASK_MMX, + SST_TASK_MMX = 3, }; enum sst_type { From a825ac7678a43f7a22ff19842baebcf4aa14e950 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Thu, 12 Feb 2015 09:59:59 +0530 Subject: [PATCH 13/95] ASoC: Intel: save and restore the CSR register The IPC driver saved only IMR register, we need to save the CSR as well, so add it Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/soc/intel/sst/sst.c b/sound/soc/intel/sst/sst.c index d6ea80076ea21c..97234ec4e416b2 100644 --- a/sound/soc/intel/sst/sst.c +++ b/sound/soc/intel/sst/sst.c @@ -350,7 +350,9 @@ static inline void sst_save_shim64(struct intel_sst_drv *ctx, spin_lock_irqsave(&ctx->ipc_spin_lock, irq_flags); - shim_regs->imrx = sst_shim_read64(shim, SST_IMRX), + shim_regs->imrx = sst_shim_read64(shim, SST_IMRX); + shim_regs->csr = sst_shim_read64(shim, SST_CSR); + spin_unlock_irqrestore(&ctx->ipc_spin_lock, irq_flags); } @@ -367,6 +369,7 @@ static inline void sst_restore_shim64(struct intel_sst_drv *ctx, */ spin_lock_irqsave(&ctx->ipc_spin_lock, irq_flags); sst_shim_write64(shim, SST_IMRX, shim_regs->imrx), + sst_shim_write64(shim, SST_CSR, shim_regs->csr), spin_unlock_irqrestore(&ctx->ipc_spin_lock, irq_flags); } From de251d773bb214fa5e7666a0da1225528e07da5e Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Thu, 12 Feb 2015 10:00:00 +0530 Subject: [PATCH 14/95] ASoC: Intel: reset the DSP while suspending The manual recommends that we reset the DSP when we suspend so add that in runtime suspend handler Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst/sst.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/intel/sst/sst.c b/sound/soc/intel/sst/sst.c index 97234ec4e416b2..11c578651c1c8c 100644 --- a/sound/soc/intel/sst/sst.c +++ b/sound/soc/intel/sst/sst.c @@ -416,6 +416,7 @@ static int intel_sst_runtime_suspend(struct device *dev) synchronize_irq(ctx->irq_num); flush_workqueue(ctx->post_msg_wq); + ctx->ops->reset(ctx); /* save the shim registers because PMC doesn't save state */ sst_save_shim64(ctx, ctx->shim, ctx->shim_regs64); From 9b1dcbc8cf4679ecf090b343ac31bda6e55ddabe Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 12 Feb 2015 10:14:51 -0500 Subject: [PATCH 15/95] xprtrdma: Store RDMA credits in unsigned variables Dan Carpenter's static checker pointed out: net/sunrpc/xprtrdma/rpc_rdma.c:879 rpcrdma_reply_handler() warn: can 'credits' be negative? "credits" is defined as an int. The credits value comes from the server as a 32-bit unsigned integer. A malicious or broken server can plant a large unsigned integer in that field which would result in an underflow in the following logic, potentially triggering a deadlock of the mount point by blocking the client from issuing more RPC requests. net/sunrpc/xprtrdma/rpc_rdma.c: 876 credits = be32_to_cpu(headerp->rm_credit); 877 if (credits == 0) 878 credits = 1; /* don't deadlock */ 879 else if (credits > r_xprt->rx_buf.rb_max_requests) 880 credits = r_xprt->rx_buf.rb_max_requests; 881 882 cwnd = xprt->cwnd; 883 xprt->cwnd = credits << RPC_CWNDSHIFT; 884 if (xprt->cwnd > cwnd) 885 xprt_release_rqst_cong(rqst->rq_task); Reported-by: Dan Carpenter Fixes: eba8ff660b2d ("xprtrdma: Move credit update to RPC . . .") Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- net/sunrpc/xprtrdma/rpc_rdma.c | 3 ++- net/sunrpc/xprtrdma/xprt_rdma.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c index 7e9acd9361c55b..91ffde82fa0c49 100644 --- a/net/sunrpc/xprtrdma/rpc_rdma.c +++ b/net/sunrpc/xprtrdma/rpc_rdma.c @@ -738,8 +738,9 @@ rpcrdma_reply_handler(struct rpcrdma_rep *rep) struct rpc_xprt *xprt = rep->rr_xprt; struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt); __be32 *iptr; - int credits, rdmalen, status; + int rdmalen, status; unsigned long cwnd; + u32 credits; /* Check status. If bad, signal disconnect and return rep to pool */ if (rep->rr_len == ~0U) { diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h index d1b70397c60f0d..0a16fb6f088590 100644 --- a/net/sunrpc/xprtrdma/xprt_rdma.h +++ b/net/sunrpc/xprtrdma/xprt_rdma.h @@ -285,7 +285,7 @@ rpcr_to_rdmar(struct rpc_rqst *rqst) */ struct rpcrdma_buffer { spinlock_t rb_lock; /* protects indexes */ - int rb_max_requests;/* client max requests */ + u32 rb_max_requests;/* client max requests */ struct list_head rb_mws; /* optional memory windows/fmrs/frmrs */ struct list_head rb_all; int rb_send_index; From 850529249d7cce02e9bfae9476d09c8c51410d28 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Mon, 16 Feb 2015 13:06:45 +0800 Subject: [PATCH 16/95] ASoC: rt5670: Set RT5670_IRQ_CTRL1 non volatile RT5670_IRQ_CTRL1(0xbd) is a non volatile register. And we need to restore its value after suspend/resume. Signed-off-by: Bard Liao Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/codecs/rt5670.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index d33f33ce865a2a..b651bc06cfdf59 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c @@ -223,7 +223,6 @@ static bool rt5670_volatile_register(struct device *dev, unsigned int reg) case RT5670_ADC_EQ_CTRL1: case RT5670_EQ_CTRL1: case RT5670_ALC_CTRL_1: - case RT5670_IRQ_CTRL1: case RT5670_IRQ_CTRL2: case RT5670_INT_IRQ_ST: case RT5670_IL_CMD: From 148388f375394ac1afed543cb653c94be5faa810 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Niederpr=C3=BCm?= Date: Sat, 21 Feb 2015 17:22:38 +0100 Subject: [PATCH 17/95] ASoC: sta32x: fix register range in regmap. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The STA32X_AUTO3 is a writable register that currently does not appear in the regmap ranges(neither read nor write). By adding this register to the register ranges there is no gap anymore and the existing register ranges can be joined. This fixes a regression introduced in commit a1be4cead9b9504aa6fc93b624975601cec8c188 where the driver was moved to direct regmap usage and the STA32X_AUTO3 register was missed. That made it impossible to choose the preset EQ mode set through the STA32X_AUTO3 register. Fixes: a1be4cead9 (ASoC: sta32x: Convert to direct regmap API usage) Signed-off-by: Thomas Niederprüm Signed-off-by: Mark Brown --- sound/soc/codecs/sta32x.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c index 3a1343fa109b48..007a0e3bc2735c 100644 --- a/sound/soc/codecs/sta32x.c +++ b/sound/soc/codecs/sta32x.c @@ -106,13 +106,11 @@ static const struct reg_default sta32x_regs[] = { }; static const struct regmap_range sta32x_write_regs_range[] = { - regmap_reg_range(STA32X_CONFA, STA32X_AUTO2), - regmap_reg_range(STA32X_C1CFG, STA32X_FDRC2), + regmap_reg_range(STA32X_CONFA, STA32X_FDRC2), }; static const struct regmap_range sta32x_read_regs_range[] = { - regmap_reg_range(STA32X_CONFA, STA32X_AUTO2), - regmap_reg_range(STA32X_C1CFG, STA32X_FDRC2), + regmap_reg_range(STA32X_CONFA, STA32X_FDRC2), }; static const struct regmap_range sta32x_volatile_regs_range[] = { From 7ed620bb343f434f8a85f830020c04988df2a140 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 19 Feb 2015 20:18:03 -0800 Subject: [PATCH 18/95] efi/libstub: Fix boundary checking in efi_high_alloc() While adding support loading kernel and initrd above 4G to grub2 in legacy mode, I was referring to efi_high_alloc(). That will allocate buffer for kernel and then initrd, and initrd will use kernel buffer start as limit. During testing found two buffers will be overlapped when initrd size is very big like 400M. It turns out efi_high_alloc() boundary checking is not right. end - size will be the new start, and should not compare new start with max, we need to make sure end is smaller than max. [ Basically, with the current efi_high_alloc() code it's possible to allocate memory above 'max', because efi_high_alloc() doesn't check that the tail of the allocation is below 'max'. If you have an EFI memory map with a single entry that looks like so, [0xc0000000-0xc0004000] And want to allocate 0x3000 bytes below 0xc0003000 the current code will allocate [0xc0001000-0xc0004000], not [0xc0000000-0xc0003000] like you would expect. - Matt ] Signed-off-by: Yinghai Lu Reviewed-by: Ard Biesheuvel Reviewed-by: Mark Rutland Tested-by: Mark Rutland Cc: Signed-off-by: Matt Fleming --- drivers/firmware/efi/libstub/efi-stub-helper.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c index 9bd9fbb5bea821..c927bccd92bd16 100644 --- a/drivers/firmware/efi/libstub/efi-stub-helper.c +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c @@ -170,12 +170,12 @@ efi_status_t efi_high_alloc(efi_system_table_t *sys_table_arg, start = desc->phys_addr; end = start + desc->num_pages * (1UL << EFI_PAGE_SHIFT); - if ((start + size) > end || (start + size) > max) - continue; - - if (end - size > max) + if (end > max) end = max; + if ((start + size) > end) + continue; + if (round_down(end - size, align) < start) continue; From 6d9ff473317245e3e5cd9922b4520411c2296388 Mon Sep 17 00:00:00 2001 From: Ivan Khoronzhuk Date: Wed, 18 Feb 2015 13:33:19 +0200 Subject: [PATCH 19/95] firmware: dmi_scan: Fix dmi_len type According to SMBIOSv3 specification the length of DMI table can be up to 32bits wide. So use appropriate type to avoid overflow. It's obvious that dmi_num theoretically can be more than u16 also, so it's can be changed to u32 or at least it's better to use int instead of u16, but on that moment I cannot imagine dmi structure count more than 65535 and it can require changing type of vars that work with it. So I didn't correct it. Acked-by: Ard Biesheuvel Signed-off-by: Ivan Khoronzhuk Cc: Signed-off-by: Matt Fleming --- drivers/firmware/dmi_scan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index a44b87c7b45c5a..69fac068669fde 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -78,7 +78,7 @@ static const char * __init dmi_string(const struct dmi_header *dm, u8 s) * We have to be cautious here. We have seen BIOSes with DMI pointers * pointing to completely the wrong place for example */ -static void dmi_table(u8 *buf, int len, int num, +static void dmi_table(u8 *buf, u32 len, int num, void (*decode)(const struct dmi_header *, void *), void *private_data) { @@ -115,7 +115,7 @@ static void dmi_table(u8 *buf, int len, int num, } static phys_addr_t dmi_base; -static u16 dmi_len; +static u32 dmi_len; static u16 dmi_num; static int __init dmi_walk_early(void (*decode)(const struct dmi_header *, From 2a559a8bdeae853b6a8abb477c88875e1d4de591 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 23 Feb 2015 11:34:10 +0000 Subject: [PATCH 20/95] eCryptfs: ensure copy to crypt_stat->cipher does not overrun The patch 237fead61998: "[PATCH] ecryptfs: fs/Makefile and fs/Kconfig" from Oct 4, 2006, leads to the following static checker warning: fs/ecryptfs/crypto.c:846 ecryptfs_new_file_context() error: off-by-one overflow 'crypt_stat->cipher' size 32. rl = '0-32' There is a mismatch between the size of ecryptfs_crypt_stat.cipher and ecryptfs_mount_crypt_stat.global_default_cipher_name causing the copy of the cipher name to cause a off-by-one string copy error. This fix ensures the space reserved for this string is the same size including the trailing zero at the end throughout ecryptfs. This fix avoids increasing the size of ecryptfs_crypt_stat.cipher and also ecryptfs_parse_tag_70_packet_silly_stack.cipher_string and instead reduces the of ECRYPTFS_MAX_CIPHER_NAME_SIZE to 31 and includes the + 1 for the end of string terminator. NOTE: An overflow is not possible in practice since the value copied into global_default_cipher_name is validated by ecryptfs_code_for_cipher_string() at mount time. None of the allowed cipher strings are long enough to cause the potential buffer overflow fixed by this patch. Signed-off-by: Colin Ian King Reported-by: Dan Carpenter [tyhicks: Added the NOTE about the overflow not being triggerable] Signed-off-by: Tyler Hicks --- fs/ecryptfs/ecryptfs_kernel.h | 4 ++-- fs/ecryptfs/keystore.c | 2 +- fs/ecryptfs/main.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 90d1882b306fac..5ba029e627cc22 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h @@ -124,7 +124,7 @@ ecryptfs_get_key_payload_data(struct key *key) } #define ECRYPTFS_MAX_KEYSET_SIZE 1024 -#define ECRYPTFS_MAX_CIPHER_NAME_SIZE 32 +#define ECRYPTFS_MAX_CIPHER_NAME_SIZE 31 #define ECRYPTFS_MAX_NUM_ENC_KEYS 64 #define ECRYPTFS_MAX_IV_BYTES 16 /* 128 bits */ #define ECRYPTFS_SALT_BYTES 2 @@ -237,7 +237,7 @@ struct ecryptfs_crypt_stat { struct crypto_ablkcipher *tfm; struct crypto_hash *hash_tfm; /* Crypto context for generating * the initialization vectors */ - unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE]; + unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE + 1]; unsigned char key[ECRYPTFS_MAX_KEY_BYTES]; unsigned char root_iv[ECRYPTFS_MAX_IV_BYTES]; struct list_head keysig_list; diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index 917bd5c9776aab..6bd67e2011f083 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c @@ -891,7 +891,7 @@ struct ecryptfs_parse_tag_70_packet_silly_stack { struct blkcipher_desc desc; char fnek_sig_hex[ECRYPTFS_SIG_SIZE_HEX + 1]; char iv[ECRYPTFS_MAX_IV_BYTES]; - char cipher_string[ECRYPTFS_MAX_CIPHER_NAME_SIZE]; + char cipher_string[ECRYPTFS_MAX_CIPHER_NAME_SIZE + 1]; }; /** diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 1895d60f4122c2..c095d32642599f 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c @@ -407,7 +407,7 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options, if (!cipher_name_set) { int cipher_name_len = strlen(ECRYPTFS_DEFAULT_CIPHER); - BUG_ON(cipher_name_len >= ECRYPTFS_MAX_CIPHER_NAME_SIZE); + BUG_ON(cipher_name_len > ECRYPTFS_MAX_CIPHER_NAME_SIZE); strcpy(mount_crypt_stat->global_default_cipher_name, ECRYPTFS_DEFAULT_CIPHER); } From 737eb0301f296d55c22350c6968ff1ef51bacb5f Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Fri, 20 Feb 2015 14:53:46 +0000 Subject: [PATCH 21/95] genirq / PM: better describe IRQF_NO_SUSPEND semantics The IRQF_NO_SUSPEND flag is intended to be used for interrupts required to be enabled during the suspend-resume cycle. This mostly consists of IPIs and timer interrupts, potentially including chained irqchip interrupts if these are necessary to handle timers or IPIs. If an interrupt does not fall into one of the aforementioned categories, requesting it with IRQF_NO_SUSPEND is likely incorrect. Using IRQF_NO_SUSPEND does not guarantee that the interrupt can wake the system from a suspended state. For an interrupt to be able to trigger a wakeup, it may be necessary to program various components of the system. In these cases it is necessary to use {enable,disabled}_irq_wake. Unfortunately, several drivers assume that IRQF_NO_SUSPEND ensures that an IRQ can wake up the system, and the documentation can be read ambiguously w.r.t. this property. This patch updates the documentation regarding IRQF_NO_SUSPEND to make this caveat explicit, hopefully making future misuse rarer. Cleanup of existing misuse will occur as part of later patch series. Signed-off-by: Mark Rutland Acked-by: Peter Zijlstra (Intel) Signed-off-by: Rafael J. Wysocki --- Documentation/power/suspend-and-interrupts.txt | 6 ++++-- include/linux/interrupt.h | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Documentation/power/suspend-and-interrupts.txt b/Documentation/power/suspend-and-interrupts.txt index 2f9c5a5fcb25ff..50493c9284b417 100644 --- a/Documentation/power/suspend-and-interrupts.txt +++ b/Documentation/power/suspend-and-interrupts.txt @@ -40,8 +40,10 @@ but also to IPIs and to some other special-purpose interrupts. The IRQF_NO_SUSPEND flag is used to indicate that to the IRQ subsystem when requesting a special-purpose interrupt. It causes suspend_device_irqs() to -leave the corresponding IRQ enabled so as to allow the interrupt to work all -the time as expected. +leave the corresponding IRQ enabled so as to allow the interrupt to work as +expected during the suspend-resume cycle, but does not guarantee that the +interrupt will wake the system from a suspended state -- for such cases it is +necessary to use enable_irq_wake(). Note that the IRQF_NO_SUSPEND flag affects the entire IRQ and not just one user of it. Thus, if the IRQ is shared, all of the interrupt handlers installed diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index d9b05b5bf8c795..606771c7cac2bf 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -52,7 +52,9 @@ * IRQF_ONESHOT - Interrupt is not reenabled after the hardirq handler finished. * Used by threaded interrupts which need to keep the * irq line disabled until the threaded handler has been run. - * IRQF_NO_SUSPEND - Do not disable this IRQ during suspend + * IRQF_NO_SUSPEND - Do not disable this IRQ during suspend. Does not guarantee + * that this interrupt will wake the system from a suspended + * state. See Documentation/power/suspend-and-interrupts.txt * IRQF_FORCE_RESUME - Force enable it on resume even if IRQF_NO_SUSPEND is set * IRQF_NO_THREAD - Interrupt cannot be threaded * IRQF_EARLY_RESUME - Resume IRQ early during syscore instead of at device From 70068776c49b37fe0c8f9115cec068d07375c6fb Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Wed, 25 Feb 2015 17:36:13 +0800 Subject: [PATCH 22/95] ASoC: rt5677: Correct the routing paths of that after IF1/2 DACx Mux The patch corrects the routing paths of that after IF1/2 DACx Mux Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5677.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index 5d0bb8748dd1df..fb9c20eace3fbe 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -3284,8 +3284,8 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { { "IB45 Bypass Mux", "Bypass", "IB45 Mux" }, { "IB45 Bypass Mux", "Pass SRC", "IB45 Mux" }, - { "IB6 Mux", "IF1 DAC 6", "IF1 DAC6" }, - { "IB6 Mux", "IF2 DAC 6", "IF2 DAC6" }, + { "IB6 Mux", "IF1 DAC 6", "IF1 DAC6 Mux" }, + { "IB6 Mux", "IF2 DAC 6", "IF2 DAC6 Mux" }, { "IB6 Mux", "SLB DAC 6", "SLB DAC6" }, { "IB6 Mux", "STO4 ADC MIX L", "Stereo4 ADC MIXL" }, { "IB6 Mux", "IF4 DAC L", "IF4 DAC L" }, @@ -3293,8 +3293,8 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { { "IB6 Mux", "STO2 ADC MIX L", "Stereo2 ADC MIXL" }, { "IB6 Mux", "STO3 ADC MIX L", "Stereo3 ADC MIXL" }, - { "IB7 Mux", "IF1 DAC 7", "IF1 DAC7" }, - { "IB7 Mux", "IF2 DAC 7", "IF2 DAC7" }, + { "IB7 Mux", "IF1 DAC 7", "IF1 DAC7 Mux" }, + { "IB7 Mux", "IF2 DAC 7", "IF2 DAC7 Mux" }, { "IB7 Mux", "SLB DAC 7", "SLB DAC7" }, { "IB7 Mux", "STO4 ADC MIX R", "Stereo4 ADC MIXR" }, { "IB7 Mux", "IF4 DAC R", "IF4 DAC R" }, @@ -3635,15 +3635,15 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { { "DAC1 FS", NULL, "DAC1 MIXL" }, { "DAC1 FS", NULL, "DAC1 MIXR" }, - { "DAC2 L Mux", "IF1 DAC 2", "IF1 DAC2" }, - { "DAC2 L Mux", "IF2 DAC 2", "IF2 DAC2" }, + { "DAC2 L Mux", "IF1 DAC 2", "IF1 DAC2 Mux" }, + { "DAC2 L Mux", "IF2 DAC 2", "IF2 DAC2 Mux" }, { "DAC2 L Mux", "IF3 DAC L", "IF3 DAC L" }, { "DAC2 L Mux", "IF4 DAC L", "IF4 DAC L" }, { "DAC2 L Mux", "SLB DAC 2", "SLB DAC2" }, { "DAC2 L Mux", "OB 2", "OutBound2" }, - { "DAC2 R Mux", "IF1 DAC 3", "IF1 DAC3" }, - { "DAC2 R Mux", "IF2 DAC 3", "IF2 DAC3" }, + { "DAC2 R Mux", "IF1 DAC 3", "IF1 DAC3 Mux" }, + { "DAC2 R Mux", "IF2 DAC 3", "IF2 DAC3 Mux" }, { "DAC2 R Mux", "IF3 DAC R", "IF3 DAC R" }, { "DAC2 R Mux", "IF4 DAC R", "IF4 DAC R" }, { "DAC2 R Mux", "SLB DAC 3", "SLB DAC3" }, @@ -3651,29 +3651,29 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { { "DAC2 R Mux", "Haptic Generator", "Haptic Generator" }, { "DAC2 R Mux", "VAD ADC", "VAD ADC Mux" }, - { "DAC3 L Mux", "IF1 DAC 4", "IF1 DAC4" }, - { "DAC3 L Mux", "IF2 DAC 4", "IF2 DAC4" }, + { "DAC3 L Mux", "IF1 DAC 4", "IF1 DAC4 Mux" }, + { "DAC3 L Mux", "IF2 DAC 4", "IF2 DAC4 Mux" }, { "DAC3 L Mux", "IF3 DAC L", "IF3 DAC L" }, { "DAC3 L Mux", "IF4 DAC L", "IF4 DAC L" }, { "DAC3 L Mux", "SLB DAC 4", "SLB DAC4" }, { "DAC3 L Mux", "OB 4", "OutBound4" }, - { "DAC3 R Mux", "IF1 DAC 5", "IF1 DAC4" }, - { "DAC3 R Mux", "IF2 DAC 5", "IF2 DAC4" }, + { "DAC3 R Mux", "IF1 DAC 5", "IF1 DAC5 Mux" }, + { "DAC3 R Mux", "IF2 DAC 5", "IF2 DAC5 Mux" }, { "DAC3 R Mux", "IF3 DAC R", "IF3 DAC R" }, { "DAC3 R Mux", "IF4 DAC R", "IF4 DAC R" }, { "DAC3 R Mux", "SLB DAC 5", "SLB DAC5" }, { "DAC3 R Mux", "OB 5", "OutBound5" }, - { "DAC4 L Mux", "IF1 DAC 6", "IF1 DAC6" }, - { "DAC4 L Mux", "IF2 DAC 6", "IF2 DAC6" }, + { "DAC4 L Mux", "IF1 DAC 6", "IF1 DAC6 Mux" }, + { "DAC4 L Mux", "IF2 DAC 6", "IF2 DAC6 Mux" }, { "DAC4 L Mux", "IF3 DAC L", "IF3 DAC L" }, { "DAC4 L Mux", "IF4 DAC L", "IF4 DAC L" }, { "DAC4 L Mux", "SLB DAC 6", "SLB DAC6" }, { "DAC4 L Mux", "OB 6", "OutBound6" }, - { "DAC4 R Mux", "IF1 DAC 7", "IF1 DAC7" }, - { "DAC4 R Mux", "IF2 DAC 7", "IF2 DAC7" }, + { "DAC4 R Mux", "IF1 DAC 7", "IF1 DAC7 Mux" }, + { "DAC4 R Mux", "IF2 DAC 7", "IF2 DAC7 Mux" }, { "DAC4 R Mux", "IF3 DAC R", "IF3 DAC R" }, { "DAC4 R Mux", "IF4 DAC R", "IF4 DAC R" }, { "DAC4 R Mux", "SLB DAC 7", "SLB DAC7" }, From 8af4baa7087a0ae74c6ee29d4d979a60e14b119e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Niederpr=C3=BCm?= Date: Sat, 21 Feb 2015 18:11:29 +0100 Subject: [PATCH 23/95] ASoC: OMAP: mcbsp: Fix CLKX and CLKR pinmux when used as inputs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes faulty behaviour in a setup where the input clock for the SRG is fed through the CLKR/CLKX pin but the McBSP is configured to be master (SND_SOC_DAIFMT_CBS_CFS). In that case of course CLKR/CLKX must not be configured as output pin. Otherwise the input clock is messed up horribly. This patch makes it possible to use the CLKR/CLKX pin rather than CLKS to inject a reference clock in setups where McBSP is master and not both rx and tx are used. However for this to work it has to be ensured that set_dai_sysclk() is called after set_dai_fmt(). This was tested on a beagleboard-xm using McBSP1 to drive a i2s DAC through the tx lines (CLKX,FSX,DX). Using this patch the CLKR pin is used to inject an external reference clock. Signed-off-by: Thomas Niederprüm Acked-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-mcbsp.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index c7eb9dd67f608c..fd99d89de6a854 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -530,8 +530,19 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, case OMAP_MCBSP_SYSCLK_CLKX_EXT: regs->srgr2 |= CLKSM; + regs->pcr0 |= SCLKME; + /* + * If McBSP is master but yet the CLKX/CLKR pin drives the SRG, + * disable output on those pins. This enables to inject the + * reference clock through CLKX/CLKR. For this to work + * set_dai_sysclk() _needs_ to be called after set_dai_fmt(). + */ + regs->pcr0 &= ~CLKXM; + break; case OMAP_MCBSP_SYSCLK_CLKR_EXT: regs->pcr0 |= SCLKME; + /* Disable ouput on CLKR pin in master mode */ + regs->pcr0 &= ~CLKRM; break; default: err = -ENODEV; From f2b14c0bc510c6a8f67a4f36049deefe5d99a537 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Fri, 27 Feb 2015 09:39:32 +0900 Subject: [PATCH 24/95] ALSA: oxfw: fix a condition and return code in start_stream() The amdtp_stream_wait_callback() doesn't return minus value and the return code is not for error code. This commit fixes with a propper condition and an error code. Fixes: f3699e2c7745 ('ALSA: oxfw: Change the way to start stream') Reported-by: Dan Carpenter Signed-off-by: Takashi Sakamoto Cc: # 3.19+ Signed-off-by: Takashi Iwai --- sound/firewire/oxfw/oxfw-stream.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/firewire/oxfw/oxfw-stream.c b/sound/firewire/oxfw/oxfw-stream.c index 29ccb3637164f8..e6757cd8572422 100644 --- a/sound/firewire/oxfw/oxfw-stream.c +++ b/sound/firewire/oxfw/oxfw-stream.c @@ -171,9 +171,10 @@ static int start_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream, } /* Wait first packet */ - err = amdtp_stream_wait_callback(stream, CALLBACK_TIMEOUT); - if (err < 0) + if (!amdtp_stream_wait_callback(stream, CALLBACK_TIMEOUT)) { stop_stream(oxfw, stream); + err = -ETIMEDOUT; + } end: return err; } From be36e185bd26388355d3ea1847278b96ab350792 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 27 Feb 2015 17:04:17 -0500 Subject: [PATCH 25/95] NFSv4: nfs4_open_recover_helper() must set share access The share access mode is now specified as an argument in the nfs4_opendata, and so nfs4_open_recover_helper() needs to call nfs4_map_atomic_open_share() in order to set it. Fixes: 6ae373394c42 ("NFSv4.1: Ask for no delegation on OPEN if using O_DIRECT") Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 88180ac5ea0eeb..4e41340e957d36 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1552,6 +1552,9 @@ static int nfs4_open_recover_helper(struct nfs4_opendata *opendata, fmode_t fmod opendata->o_arg.open_flags = 0; opendata->o_arg.fmode = fmode; + opendata->o_arg.share_access = nfs4_map_atomic_open_share( + NFS_SB(opendata->dentry->d_sb), + fmode, 0); memset(&opendata->o_res, 0, sizeof(opendata->o_res)); memset(&opendata->c_res, 0, sizeof(opendata->c_res)); nfs4_init_opendata_res(opendata); From f1651a24280997c75836b4380bcbf60fd2aa34fd Mon Sep 17 00:00:00 2001 From: Joachim Nilsson Date: Wed, 25 Feb 2015 16:15:02 +0100 Subject: [PATCH 26/95] PCI: versatile: Update for list_for_each_entry() API change In Linux 4.0-rc1 ARM Versatile PCI build fails to build due to what appears to be an API update. This patch is a very simple correction, merely posted as a heads-up to the maintainers. Hopefully a better fix can be forwarded to Linus. [ arnd: the patch actually looks correct, so let's take this version ] Signed-off-by: Joachim Nilsson Signed-off-by: Arnd Bergmann Acked-by: Linus Walleij Acked-by: Bjorn Helgaas Signed-off-by: Rafael J. Wysocki --- drivers/pci/host/pci-versatile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/host/pci-versatile.c b/drivers/pci/host/pci-versatile.c index 1ec694a52379ea..464bf492ee2ae3 100644 --- a/drivers/pci/host/pci-versatile.c +++ b/drivers/pci/host/pci-versatile.c @@ -80,7 +80,7 @@ static int versatile_pci_parse_request_of_pci_ranges(struct device *dev, if (err) return err; - resource_list_for_each_entry(win, res, list) { + resource_list_for_each_entry(win, res) { struct resource *parent, *res = win->res; switch (resource_type(res)) { From 01e04f466e12e883907937eb04a9010533363f55 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 27 Feb 2015 00:39:21 +0100 Subject: [PATCH 27/95] idle / sleep: Avoid excessive disabling and enabling interrupts Disabling interrupts at the end of cpuidle_enter_freeze() is not useful, because its caller, cpuidle_idle_call(), re-enables them right away after invoking it. To avoid that unnecessary back and forth dance with interrupts, make cpuidle_enter_freeze() enable interrupts after calling enter_freeze_proper() and drop the local_irq_disable() at its end, so that all of the code paths in it end up with interrupts enabled. Then, cpuidle_idle_call() will not need to re-enable interrupts after calling cpuidle_enter_freeze() any more, because the latter will return with interrupts enabled, in analogy with cpuidle_enter(). Reported-by: Lorenzo Pieralisi Signed-off-by: Rafael J. Wysocki Acked-by: Peter Zijlstra (Intel) --- drivers/cpuidle/cpuidle.c | 6 +++--- kernel/sched/idle.c | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 4d534582514e01..b573f584b15a4a 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -117,6 +117,8 @@ static void enter_freeze_proper(struct cpuidle_driver *drv, * If there are states with the ->enter_freeze callback, find the deepest of * them and enter it with frozen tick. Otherwise, find the deepest state * available and enter it normally. + * + * Returns with enabled interrupts. */ void cpuidle_enter_freeze(void) { @@ -132,6 +134,7 @@ void cpuidle_enter_freeze(void) index = cpuidle_find_deepest_state(drv, dev, true); if (index >= 0) { enter_freeze_proper(drv, dev, index); + local_irq_enable(); return; } @@ -144,9 +147,6 @@ void cpuidle_enter_freeze(void) cpuidle_enter(drv, dev, index); else arch_cpu_idle(); - - /* Interrupts are enabled again here. */ - local_irq_disable(); } /** diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c index 94b2d7b88a2728..f59198bda1bf34 100644 --- a/kernel/sched/idle.c +++ b/kernel/sched/idle.c @@ -116,7 +116,6 @@ static void cpuidle_idle_call(void) */ if (idle_should_freeze()) { cpuidle_enter_freeze(); - local_irq_enable(); goto exit_idle; } From 31a3409065d1d5bf0f12ad76b8c7f471134bf596 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 27 Feb 2015 00:39:56 +0100 Subject: [PATCH 28/95] cpuidle / sleep: Do sanity checks in cpuidle_enter_freeze() too Modify cpuidle_enter_freeze() to do the sanity checks done by cpuidle_select() to avoid crashing the suspend-to-idle code path in case something is missing. Fixes: 381063133246 (PM / sleep: Re-implement suspend-to-idle handling) Original-by: Lorenzo Pieralisi Signed-off-by: Rafael J. Wysocki Acked-by: Peter Zijlstra (Intel) --- drivers/cpuidle/cpuidle.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index b573f584b15a4a..8b3e132b6a0139 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -44,6 +44,12 @@ void disable_cpuidle(void) off = 1; } +static bool cpuidle_not_available(struct cpuidle_driver *drv, + struct cpuidle_device *dev) +{ + return off || !initialized || !drv || !dev || !dev->enabled; +} + /** * cpuidle_play_dead - cpu off-lining * @@ -126,6 +132,9 @@ void cpuidle_enter_freeze(void) struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); int index; + if (cpuidle_not_available(drv, dev)) + goto fallback; + /* * Find the deepest state with ->enter_freeze present, which guarantees * that interrupts won't be enabled when it exits and allows the tick to @@ -143,10 +152,13 @@ void cpuidle_enter_freeze(void) * at all and try to enter it normally. */ index = cpuidle_find_deepest_state(drv, dev, false); - if (index >= 0) + if (index >= 0) { cpuidle_enter(drv, dev, index); - else - arch_cpu_idle(); + return; + } + + fallback: + arch_cpu_idle(); } /** @@ -205,12 +217,9 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, */ int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) { - if (off || !initialized) + if (cpuidle_not_available(drv, dev)) return -ENODEV; - if (!drv || !dev || !dev->enabled) - return -EBUSY; - return cpuidle_curr_governor->select(drv, dev); } From 8cdebf71098c07168ef6335e2f1f35d85dbe3049 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Sun, 1 Mar 2015 18:12:16 +0900 Subject: [PATCH 29/95] ALSA: dice: fix wrong offsets for Dice interface For received packet stream, the offset of 'RX_SEQ_START' locates after the offset of 'RX_NUMBER_MIDI', although current macro and proc output includes wrong offsets. Fortunately, this bug doesn't affect streaming functionality because these macro is not used. This commit fixes these wrong macro and outputs. Signed-off-by: Takashi Sakamoto Signed-off-by: Takashi Iwai --- sound/firewire/dice/dice-interface.h | 18 +++++++++--------- sound/firewire/dice/dice-proc.c | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/sound/firewire/dice/dice-interface.h b/sound/firewire/dice/dice-interface.h index 27b044f84c816f..de7602bd69b569 100644 --- a/sound/firewire/dice/dice-interface.h +++ b/sound/firewire/dice/dice-interface.h @@ -298,24 +298,24 @@ */ #define RX_ISOCHRONOUS 0x008 -/* - * Index of first quadlet to be interpreted; read/write. If > 0, that many - * quadlets at the beginning of each data block will be ignored, and all the - * audio and MIDI quadlets will follow. - */ -#define RX_SEQ_START 0x00c - /* * The number of audio channels; read-only. There will be one quadlet per * channel. */ -#define RX_NUMBER_AUDIO 0x010 +#define RX_NUMBER_AUDIO 0x00c /* * The number of MIDI ports, 0-8; read-only. If > 0, there will be one * additional quadlet in each data block, following the audio quadlets. */ -#define RX_NUMBER_MIDI 0x014 +#define RX_NUMBER_MIDI 0x010 + +/* + * Index of first quadlet to be interpreted; read/write. If > 0, that many + * quadlets at the beginning of each data block will be ignored, and all the + * audio and MIDI quadlets will follow. + */ +#define RX_SEQ_START 0x014 /* * Names of all audio channels; read-only. Quadlets are byte-swapped. Names diff --git a/sound/firewire/dice/dice-proc.c b/sound/firewire/dice/dice-proc.c index f5c1d1bced59fe..ecfe20fd4de578 100644 --- a/sound/firewire/dice/dice-proc.c +++ b/sound/firewire/dice/dice-proc.c @@ -99,9 +99,9 @@ static void dice_proc_read(struct snd_info_entry *entry, } tx; struct { u32 iso; - u32 seq_start; u32 number_audio; u32 number_midi; + u32 seq_start; char names[RX_NAMES_SIZE]; u32 ac3_caps; u32 ac3_enable; @@ -204,10 +204,10 @@ static void dice_proc_read(struct snd_info_entry *entry, break; snd_iprintf(buffer, "rx %u:\n", stream); snd_iprintf(buffer, " iso channel: %d\n", (int)buf.rx.iso); - snd_iprintf(buffer, " sequence start: %u\n", buf.rx.seq_start); snd_iprintf(buffer, " audio channels: %u\n", buf.rx.number_audio); snd_iprintf(buffer, " midi ports: %u\n", buf.rx.number_midi); + snd_iprintf(buffer, " sequence start: %u\n", buf.rx.seq_start); if (quadlets >= 68) { dice_proc_fixup_string(buf.rx.names, RX_NAMES_SIZE); snd_iprintf(buffer, " names: %s\n", buf.rx.names); From aa5accea404b2b92d39c1924cfeb90f6082f6389 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 27 Feb 2015 22:54:19 -0500 Subject: [PATCH 30/95] NFS: Ensure that buffered writes wait for O_DIRECT writes to complete The O_DIRECT code will grab the inode->i_mutex and flush out buffered writes, before scheduling a read or a write. However there is no equivalent in the buffered write code to wait for O_DIRECT to complete. Fixes a reported issue in xfstests generic/133, when first performing an O_DIRECT write followed by a buffered write. Signed-off-by: Trond Myklebust Tested-by: Chuck Lever --- fs/nfs/file.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 94712fc781fa58..c045c7169fa0f7 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -372,6 +372,10 @@ static int nfs_write_begin(struct file *file, struct address_space *mapping, nfs_wait_bit_killable, TASK_KILLABLE); if (ret) return ret; + /* + * Wait for O_DIRECT to complete + */ + nfs_inode_dio_wait(mapping->host); page = grab_cache_page_write_begin(mapping, index, flags); if (!page) From 140e049c64ce848392adbf4678983ecc76888dde Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 26 Feb 2015 17:42:42 -0500 Subject: [PATCH 31/95] NFS: Add a helper to set attribute barriers Signed-off-by: Trond Myklebust Tested-by: Chuck Lever --- fs/nfs/inode.c | 16 ++++++++++++++++ include/linux/nfs_fs.h | 1 + 2 files changed, 17 insertions(+) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 83107be3dd0109..b0cbc1ba82dab8 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1260,6 +1260,22 @@ void nfs_fattr_init(struct nfs_fattr *fattr) } EXPORT_SYMBOL_GPL(nfs_fattr_init); +/** + * nfs_fattr_set_barrier + * @fattr: attributes + * + * Used to set a barrier after an attribute was updated. This + * barrier ensures that older attributes from RPC calls that may + * have raced with our update cannot clobber these new values. + * Note that you are still responsible for ensuring that other + * operations which change the attribute on the server do not + * collide. + */ +void nfs_fattr_set_barrier(struct nfs_fattr *fattr) +{ + fattr->gencount = nfs_inc_attr_generation_counter(); +} + struct nfs_fattr *nfs_alloc_fattr(void) { struct nfs_fattr *fattr; diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 2f77e0c651c898..3a4ffb5856cd6a 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -369,6 +369,7 @@ extern struct nfs_lock_context *nfs_get_lock_context(struct nfs_open_context *ct extern void nfs_put_lock_context(struct nfs_lock_context *l_ctx); extern u64 nfs_compat_user_ino64(u64 fileid); extern void nfs_fattr_init(struct nfs_fattr *fattr); +extern void nfs_fattr_set_barrier(struct nfs_fattr *fattr); extern unsigned long nfs_inc_attr_generation_counter(void); extern struct nfs_fattr *nfs_alloc_fattr(void); From f044636d972246d451e06226cc1675d5da389762 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 26 Feb 2015 16:09:04 -0500 Subject: [PATCH 32/95] NFS: Add attribute update barriers to nfs_setattr_update_inode() Ensure that other operations which raced with our setattr RPC call cannot revert the file attribute changes that were made on the server. To do so, we artificially bump the attribute generation counter on the inode so that all calls to nfs_fattr_init() that precede ours will be dropped. The motivation for the patch came from Chuck Lever's reports of readaheads racing with truncate operations and causing the file size to be reverted. Reported-by: Chuck Lever Signed-off-by: Trond Myklebust Tested-by: Chuck Lever --- fs/nfs/inode.c | 17 ++++++++++++----- fs/nfs/nfs3proc.c | 2 +- fs/nfs/nfs4proc.c | 6 +++--- fs/nfs/proc.c | 2 +- include/linux/nfs_fs.h | 2 +- 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index b0cbc1ba82dab8..3a2d127de499fc 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -556,6 +556,7 @@ EXPORT_SYMBOL_GPL(nfs_setattr); * This is a copy of the common vmtruncate, but with the locking * corrected to take into account the fact that NFS requires * inode->i_size to be updated under the inode->i_lock. + * Note: must be called with inode->i_lock held! */ static int nfs_vmtruncate(struct inode * inode, loff_t offset) { @@ -565,14 +566,14 @@ static int nfs_vmtruncate(struct inode * inode, loff_t offset) if (err) goto out; - spin_lock(&inode->i_lock); i_size_write(inode, offset); /* Optimisation */ if (offset == 0) NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_DATA; - spin_unlock(&inode->i_lock); + spin_unlock(&inode->i_lock); truncate_pagecache(inode, offset); + spin_lock(&inode->i_lock); out: return err; } @@ -585,10 +586,15 @@ static int nfs_vmtruncate(struct inode * inode, loff_t offset) * Note: we do this in the *proc.c in order to ensure that * it works for things like exclusive creates too. */ -void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr) +void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr, + struct nfs_fattr *fattr) { + /* Barrier: bump the attribute generation count. */ + nfs_fattr_set_barrier(fattr); + + spin_lock(&inode->i_lock); + NFS_I(inode)->attr_gencount = fattr->gencount; if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0) { - spin_lock(&inode->i_lock); if ((attr->ia_valid & ATTR_MODE) != 0) { int mode = attr->ia_mode & S_IALLUGO; mode |= inode->i_mode & ~S_IALLUGO; @@ -600,12 +606,13 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr) inode->i_gid = attr->ia_gid; nfs_set_cache_invalid(inode, NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL); - spin_unlock(&inode->i_lock); } if ((attr->ia_valid & ATTR_SIZE) != 0) { nfs_inc_stats(inode, NFSIOS_SETATTRTRUNC); nfs_vmtruncate(inode, attr->ia_size); } + nfs_update_inode(inode, fattr); + spin_unlock(&inode->i_lock); } EXPORT_SYMBOL_GPL(nfs_setattr_update_inode); diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 78e557c3ab87d0..11109a137c0c80 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -138,7 +138,7 @@ nfs3_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr, nfs_fattr_init(fattr); status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); if (status == 0) - nfs_setattr_update_inode(inode, sattr); + nfs_setattr_update_inode(inode, sattr, fattr); dprintk("NFS reply setattr: %d\n", status); return status; } diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 4e41340e957d36..c499e02a58ca63 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2416,8 +2416,8 @@ static int _nfs4_do_open(struct inode *dir, opendata->o_res.f_attr, sattr, state, label, olabel); if (status == 0) { - nfs_setattr_update_inode(state->inode, sattr); - nfs_post_op_update_inode(state->inode, opendata->o_res.f_attr); + nfs_setattr_update_inode(state->inode, sattr, + opendata->o_res.f_attr); nfs_setsecurity(state->inode, opendata->o_res.f_attr, olabel); } } @@ -3291,7 +3291,7 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr, status = nfs4_do_setattr(inode, cred, fattr, sattr, state, NULL, label); if (status == 0) { - nfs_setattr_update_inode(inode, sattr); + nfs_setattr_update_inode(inode, sattr, fattr); nfs_setsecurity(inode, fattr, label); } nfs4_label_free(label); diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index b09cc23d6f433b..6202bc0f11bb2b 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c @@ -139,7 +139,7 @@ nfs_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr, nfs_fattr_init(fattr); status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); if (status == 0) - nfs_setattr_update_inode(inode, sattr); + nfs_setattr_update_inode(inode, sattr, fattr); dprintk("NFS reply setattr: %d\n", status); return status; } diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 3a4ffb5856cd6a..f26e64e0aff846 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -356,7 +356,7 @@ extern int nfs_revalidate_inode_rcu(struct nfs_server *server, struct inode *ino extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *); extern int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping); extern int nfs_setattr(struct dentry *, struct iattr *); -extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr); +extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr, struct nfs_fattr *); extern void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr, struct nfs4_label *label); extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx); From f5062003465c20cfe584d9129a463322ad5cf4ea Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 26 Feb 2015 19:34:32 -0500 Subject: [PATCH 33/95] NFS: Set an attribute barrier on all updates Ensure that we update the attribute barrier even if there were no invalidations, provided that this value is newer than the old one. Signed-off-by: Trond Myklebust Tested-by: Chuck Lever --- fs/nfs/inode.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 3a2d127de499fc..299bf7171a4daf 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1738,6 +1738,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE); nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); nfsi->attrtimeo_timestamp = now; + /* Set barrier to be more recent than all outstanding updates */ nfsi->attr_gencount = nfs_inc_attr_generation_counter(); } else { if (!time_in_range_open(now, nfsi->attrtimeo_timestamp, nfsi->attrtimeo_timestamp + nfsi->attrtimeo)) { @@ -1745,6 +1746,9 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) nfsi->attrtimeo = NFS_MAXATTRTIMEO(inode); nfsi->attrtimeo_timestamp = now; } + /* Set the barrier to be more recent than this fattr */ + if ((long)fattr->gencount - (long)nfsi->attr_gencount > 0) + nfsi->attr_gencount = fattr->gencount; } invalid &= ~NFS_INO_INVALID_ATTR; /* Don't invalidate the data if we were to blame */ From a08a8cd375db9769588257e7782f6b6b68561b88 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 26 Feb 2015 17:36:09 -0500 Subject: [PATCH 34/95] NFS: Add attribute update barriers to NFS writebacks Ensure that other operations that race with our write RPC calls cannot revert the file size updates that were made on the server. Signed-off-by: Trond Myklebust Tested-by: Chuck Lever --- fs/nfs/inode.c | 25 ++++++++++++++++++++++--- fs/nfs/internal.h | 1 + fs/nfs/nfs3proc.c | 2 +- fs/nfs/nfs4proc.c | 2 +- fs/nfs/proc.c | 4 +--- fs/nfs/write.c | 30 ++++++++++++++++++++++++++++++ include/linux/nfs_fs.h | 1 + 7 files changed, 57 insertions(+), 8 deletions(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 299bf7171a4daf..ff9a6795da46c0 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1491,7 +1491,7 @@ int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr) EXPORT_SYMBOL_GPL(nfs_post_op_update_inode); /** - * nfs_post_op_update_inode_force_wcc - try to update the inode attribute cache + * nfs_post_op_update_inode_force_wcc_locked - update the inode attribute cache * @inode - pointer to inode * @fattr - updated attributes * @@ -1501,11 +1501,10 @@ EXPORT_SYMBOL_GPL(nfs_post_op_update_inode); * * This function is mainly designed to be used by the ->write_done() functions. */ -int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr) +int nfs_post_op_update_inode_force_wcc_locked(struct inode *inode, struct nfs_fattr *fattr) { int status; - spin_lock(&inode->i_lock); /* Don't do a WCC update if these attributes are already stale */ if ((fattr->valid & NFS_ATTR_FATTR) == 0 || !nfs_inode_attrs_need_update(inode, fattr)) { @@ -1537,6 +1536,26 @@ int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fa } out_noforce: status = nfs_post_op_update_inode_locked(inode, fattr); + return status; +} + +/** + * nfs_post_op_update_inode_force_wcc - try to update the inode attribute cache + * @inode - pointer to inode + * @fattr - updated attributes + * + * After an operation that has changed the inode metadata, mark the + * attribute cache as being invalid, then try to update it. Fake up + * weak cache consistency data, if none exist. + * + * This function is mainly designed to be used by the ->write_done() functions. + */ +int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr) +{ + int status; + + spin_lock(&inode->i_lock); + status = nfs_post_op_update_inode_force_wcc_locked(inode, fattr); spin_unlock(&inode->i_lock); return status; } diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index b802fb3a2d99ff..9e6475bc5ba22b 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -459,6 +459,7 @@ void nfs_mark_request_commit(struct nfs_page *req, struct nfs_commit_info *cinfo, u32 ds_commit_idx); int nfs_write_need_commit(struct nfs_pgio_header *); +void nfs_writeback_update_inode(struct nfs_pgio_header *hdr); int nfs_generic_commit_list(struct inode *inode, struct list_head *head, int how, struct nfs_commit_info *cinfo); void nfs_retry_commit(struct list_head *page_list, diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 11109a137c0c80..1f11d2533ee410 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -834,7 +834,7 @@ static int nfs3_write_done(struct rpc_task *task, struct nfs_pgio_header *hdr) if (nfs3_async_handle_jukebox(task, inode)) return -EAGAIN; if (task->tk_status >= 0) - nfs_post_op_update_inode_force_wcc(inode, hdr->res.fattr); + nfs_writeback_update_inode(hdr); return 0; } diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index c499e02a58ca63..b022e64b76a52f 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -4237,7 +4237,7 @@ static int nfs4_write_done_cb(struct rpc_task *task, } if (task->tk_status >= 0) { renew_lease(NFS_SERVER(inode), hdr->timestamp); - nfs_post_op_update_inode_force_wcc(inode, &hdr->fattr); + nfs_writeback_update_inode(hdr); } return 0; } diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index 6202bc0f11bb2b..c63189acd0523c 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c @@ -609,10 +609,8 @@ static int nfs_proc_pgio_rpc_prepare(struct rpc_task *task, static int nfs_write_done(struct rpc_task *task, struct nfs_pgio_header *hdr) { - struct inode *inode = hdr->inode; - if (task->tk_status >= 0) - nfs_post_op_update_inode_force_wcc(inode, hdr->res.fattr); + nfs_writeback_update_inode(hdr); return 0; } diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 595d81e354d189..849ed784d6ac1f 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -1377,6 +1377,36 @@ static int nfs_should_remove_suid(const struct inode *inode) return 0; } +static void nfs_writeback_check_extend(struct nfs_pgio_header *hdr, + struct nfs_fattr *fattr) +{ + struct nfs_pgio_args *argp = &hdr->args; + struct nfs_pgio_res *resp = &hdr->res; + + if (!(fattr->valid & NFS_ATTR_FATTR_SIZE)) + return; + if (argp->offset + resp->count != fattr->size) + return; + if (nfs_size_to_loff_t(fattr->size) < i_size_read(hdr->inode)) + return; + /* Set attribute barrier */ + nfs_fattr_set_barrier(fattr); +} + +void nfs_writeback_update_inode(struct nfs_pgio_header *hdr) +{ + struct nfs_fattr *fattr = hdr->res.fattr; + struct inode *inode = hdr->inode; + + if (fattr == NULL) + return; + spin_lock(&inode->i_lock); + nfs_writeback_check_extend(hdr, fattr); + nfs_post_op_update_inode_force_wcc_locked(inode, fattr); + spin_unlock(&inode->i_lock); +} +EXPORT_SYMBOL_GPL(nfs_writeback_update_inode); + /* * This function is called when the WRITE call is complete. */ diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index f26e64e0aff846..59b1516b9fd491 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -343,6 +343,7 @@ extern struct inode *nfs_fhget(struct super_block *, struct nfs_fh *, extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *); extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr); extern int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr); +extern int nfs_post_op_update_inode_force_wcc_locked(struct inode *inode, struct nfs_fattr *fattr); extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *); extern void nfs_access_add_cache(struct inode *, struct nfs_access_entry *); extern void nfs_access_set_mask(struct nfs_access_entry *, u32); From 8f8ba1d739b7047e2e1d91735716af2799ff2b1e Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 26 Feb 2015 17:54:58 -0500 Subject: [PATCH 35/95] NFSv4: Add attribute update barriers to delegreturn and pNFS layoutcommit Ensure that other operations that race with delegreturn and layoutcommit cannot revert the attribute updates that were made on the server. Signed-off-by: Trond Myklebust Tested-by: Chuck Lever --- fs/nfs/inode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index ff9a6795da46c0..cd094d6521993f 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1555,6 +1555,7 @@ int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fa int status; spin_lock(&inode->i_lock); + nfs_fattr_set_barrier(fattr); status = nfs_post_op_update_inode_force_wcc_locked(inode, fattr); spin_unlock(&inode->i_lock); return status; From 00fb4c9f8421c9aac3947d36ffe8e049b95f7ab1 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 26 Feb 2015 17:57:14 -0500 Subject: [PATCH 36/95] NFS: Remove size hack in nfs_inode_attrs_need_update() Prior to this patch, we used to always OK attribute updates that extended the file size on the assumption that we might be performing writeback. Now that we have attribute barriers to protect the writeback related updates, we should remove this hack, as it can cause truncate() operations to apparently be reverted if/when a readahead or getattr RPC call races with our on-the-wire SETATTR. Signed-off-by: Trond Myklebust Tested-by: Chuck Lever --- fs/nfs/inode.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index cd094d6521993f..fef65d1e024e4c 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1238,13 +1238,6 @@ static int nfs_ctime_need_update(const struct inode *inode, const struct nfs_fat return timespec_compare(&fattr->ctime, &inode->i_ctime) > 0; } -static int nfs_size_need_update(const struct inode *inode, const struct nfs_fattr *fattr) -{ - if (!(fattr->valid & NFS_ATTR_FATTR_SIZE)) - return 0; - return nfs_size_to_loff_t(fattr->size) > i_size_read(inode); -} - static atomic_long_t nfs_attr_generation_counter; static unsigned long nfs_read_attr_generation_counter(void) @@ -1393,7 +1386,6 @@ static int nfs_inode_attrs_need_update(const struct inode *inode, const struct n return ((long)fattr->gencount - (long)nfsi->attr_gencount) > 0 || nfs_ctime_need_update(inode, fattr) || - nfs_size_need_update(inode, fattr) || ((long)nfsi->attr_gencount - (long)nfs_read_attr_generation_counter() > 0); } From 92d64e47b67b5e7fe1b5358402ab222a32ec3479 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 26 Feb 2015 19:48:26 -0500 Subject: [PATCH 37/95] NFS: Fix nfs_post_op_update_inode() to set an attribute barrier nfs_post_op_update_inode() is called after a self-induced attribute update. Ensure that it also sets the barrier. Signed-off-by: Trond Myklebust Tested-by: Chuck Lever --- fs/nfs/inode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index fef65d1e024e4c..c66c1df467f4a5 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1475,6 +1475,7 @@ int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr) int status; spin_lock(&inode->i_lock); + nfs_fattr_set_barrier(fattr); status = nfs_post_op_update_inode_locked(inode, fattr); spin_unlock(&inode->i_lock); From 3235b40303b6f609c446275d0e7f6f9f4fe94156 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 26 Feb 2015 19:52:06 -0500 Subject: [PATCH 38/95] NFSv4: Set a barrier in the update_changeattr() helper Ensure that we don't regress the changes that were made to the directory. Signed-off-by: Trond Myklebust Tested-by: Chuck Lever --- fs/nfs/inode.c | 1 + fs/nfs/nfs4proc.c | 1 + 2 files changed, 2 insertions(+) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index c66c1df467f4a5..5026c44a98e1c1 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1249,6 +1249,7 @@ unsigned long nfs_inc_attr_generation_counter(void) { return atomic_long_inc_return(&nfs_attr_generation_counter); } +EXPORT_SYMBOL_GPL(nfs_inc_attr_generation_counter); void nfs_fattr_init(struct nfs_fattr *fattr) { diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index b022e64b76a52f..a211daf58c328e 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -901,6 +901,7 @@ static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo) if (!cinfo->atomic || cinfo->before != dir->i_version) nfs_force_lookup_revalidate(dir); dir->i_version = cinfo->after; + nfsi->attr_gencount = nfs_inc_attr_generation_counter(); nfs_fscache_invalidate(dir); spin_unlock(&dir->i_lock); } From 6c441c254eea2354d686be7f5544bcd79fb6a61f Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sun, 22 Feb 2015 16:35:36 -0500 Subject: [PATCH 39/95] NFS: Don't invalidate a submounted dentry in nfs_prime_dcache() If we're traversing a directory which contains a submounted filesystem, or one that has a referral, the NFS server that is processing the READDIR request will often return information for the underlying (mounted-on) directory. It may, or may not, also return filehandle information. If this happens, and the lookup in nfs_prime_dcache() returns the dentry for the submounted directory, the filehandle comparison will fail, and we call d_invalidate(). Post-commit 8ed936b5671bf ("vfs: Lazily remove mounts on unlinked files and directories."), this means the entire subtree is unmounted. The following minimal patch addresses this problem by punting on the invalidation if there is a submount. Kudos to Neil Brown for having tracked down this issue (see link). Reported-by: Nix Link: http://lkml.kernel.org/r/87iofju9ht.fsf@spindle.srvr.nix Cc: stable@vger.kernel.org # 3.18+ Signed-off-by: Trond Myklebust --- fs/nfs/dir.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 9b0c55cb2a2eaa..4ad7fff9ccaf7d 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -469,6 +469,8 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry) struct inode *inode; int status; + if (!(entry->fattr->valid & NFS_ATTR_FATTR_FSID)) + return; if (filename.name[0] == '.') { if (filename.len == 1) return; @@ -479,6 +481,10 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry) dentry = d_lookup(parent, &filename); if (dentry != NULL) { + /* Is there a mountpoint here? If so, just exit */ + if (!nfs_fsid_equal(&NFS_SB(dentry->d_sb)->fsid, + &entry->fattr->fsid)) + goto out; if (nfs_same_file(dentry, entry)) { nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); status = nfs_refresh_inode(dentry->d_inode, entry->fattr); From 1ae04b252351188cfa66af1b8b0628512a72dd7b Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 23 Feb 2015 16:15:00 -0500 Subject: [PATCH 40/95] NFSv3: Use the readdir fileid as the mounted-on-fileid When we call readdirplus, set the fileid normally returned by readdir as the mounted-on-fileid, since that is commonly the case if there is a mountpoint. To ensure that we get it right, we only set the flag if the readdir fileid differs from the one returned in the readdirplus attributes. This again means that we can avoid the issues described in commit 2ef47eb1aee17 ("NFS: Fix use of nfs_attr_use_mounted_on_fileid()"), which only fixed NFSv4. Signed-off-by: Trond Myklebust --- fs/nfs/nfs3xdr.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index 2a932fdc57cb37..53852a4bd88be6 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -1987,6 +1987,11 @@ int nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, if (entry->fattr->valid & NFS_ATTR_FATTR_V3) entry->d_type = nfs_umode_to_dtype(entry->fattr->mode); + if (entry->fattr->fileid != entry->ino) { + entry->fattr->mounted_on_fileid = entry->ino; + entry->fattr->valid |= NFS_ATTR_FATTR_MOUNTED_ON_FILEID; + } + /* In fact, a post_op_fh3: */ p = xdr_inline_decode(xdr, 4); if (unlikely(p == NULL)) From fa9233699cc1dc236f4cf42245d13e40966938c5 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 23 Feb 2015 18:51:32 -0500 Subject: [PATCH 41/95] NFS: Don't require a filehandle to refresh the inode in nfs_prime_dcache() If the server does not return a valid set of attributes that we can use to either create a file or refresh the inode, then there is no value in calling nfs_prime_dcache(). However if we're just refreshing the inode using the attributes that the server returned, then it shouldn't matter whether or not we have a filehandle, as long as we check the fsid+fileid combination. Signed-off-by: Trond Myklebust --- fs/nfs/dir.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 4ad7fff9ccaf7d..c19e16f0b2d049 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -408,14 +408,22 @@ static int xdr_decode(nfs_readdir_descriptor_t *desc, return 0; } +/* Match file and dirent using either filehandle or fileid + * Note: caller is responsible for checking the fsid + */ static int nfs_same_file(struct dentry *dentry, struct nfs_entry *entry) { + struct nfs_inode *nfsi; + if (dentry->d_inode == NULL) goto different; - if (nfs_compare_fh(entry->fh, NFS_FH(dentry->d_inode)) != 0) - goto different; - return 1; + + nfsi = NFS_I(dentry->d_inode); + if (entry->fattr->fileid == nfsi->fileid) + return 1; + if (nfs_compare_fh(entry->fh, &nfsi->fh) == 0) + return 1; different: return 0; } @@ -469,6 +477,8 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry) struct inode *inode; int status; + if (!(entry->fattr->valid & NFS_ATTR_FATTR_FILEID)) + return; if (!(entry->fattr->valid & NFS_ATTR_FATTR_FSID)) return; if (filename.name[0] == '.') { From 7c0af9ffb7bb4e5355470fa60b3eb711ddf226fa Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 26 Feb 2015 12:54:46 -0500 Subject: [PATCH 42/95] NFSv4: Don't call put_rpccred() under the rcu_read_lock() put_rpccred() can sleep. Fixes: 8f649c3762547 ("NFSv4: Fix the locking in nfs_inode_reclaim_delegation()") Cc: stable@vger.kernel.org # 2.6.35+ Signed-off-by: Trond Myklebust --- fs/nfs/delegation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index a1f0685b42ff7d..2e37d8315d9207 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -181,8 +181,8 @@ void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, clear_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags); spin_unlock(&delegation->lock); - put_rpccred(oldcred); rcu_read_unlock(); + put_rpccred(oldcred); trace_nfs4_reclaim_delegation(inode, res->delegation_type); } else { /* We appear to have raced with a delegation return. */ From 42b696e808bbea3a4ebf8029e1965d2314612402 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 24 Feb 2015 13:56:54 +0900 Subject: [PATCH 43/95] thermal: exynos: Fix wrong control of power down detection mode for Exynos7 This patch fixes the wrong control of PD_DET_EN (power down detection mode) for Exynos7 because exynos7_tmu_control() always enables the power down detection mode regardless 'on' parameter. Cc: Zhang Rui Cc: Eduardo Valentin Signed-off-by: Chanwoo Choi Tested-by: Abhilash Kesavan Signed-off-by: Lukasz Majewski --- drivers/thermal/samsung/exynos_tmu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 1fc54ab911d206..1d30b097565154 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -682,6 +682,7 @@ static void exynos7_tmu_control(struct platform_device *pdev, bool on) if (on) { con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT); + con |= (1 << EXYNOS7_PD_DET_EN_SHIFT); interrupt_en = (of_thermal_is_trip_valid(tz, 7) << EXYNOS7_TMU_INTEN_RISE7_SHIFT) | @@ -704,9 +705,9 @@ static void exynos7_tmu_control(struct platform_device *pdev, bool on) interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT; } else { con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT); + con &= ~(1 << EXYNOS7_PD_DET_EN_SHIFT); interrupt_en = 0; /* Disable all interrupts */ } - con |= 1 << EXYNOS7_PD_DET_EN_SHIFT; writel(interrupt_en, data->base + EXYNOS7_TMU_REG_INTEN); writel(con, data->base + EXYNOS_TMU_REG_CONTROL); From 0fc83929d03c2e16cbcf6cf944bd5df8d829847f Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Thu, 5 Feb 2015 16:45:06 +0100 Subject: [PATCH 44/95] cpufreq: exynos: Use simple approach to asses if cpu cooling can be used Commit: e725d26c4857e5e41975b5e74e64ce6ab09a7121 provided possibility to use device tree to asses if cpu can be used as cooling device. Since the code was somewhat awkward, simpler approach has been proposed. Test HW: Exynos 4412 - Odroid U3. Suggested-by: Viresh Kumar Signed-off-by: Lukasz Majewski Acked-by: Viresh Kumar --- drivers/cpufreq/exynos-cpufreq.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c index 5e98c6b1f284b6..82d2fbb20f7eb7 100644 --- a/drivers/cpufreq/exynos-cpufreq.c +++ b/drivers/cpufreq/exynos-cpufreq.c @@ -159,7 +159,7 @@ static struct cpufreq_driver exynos_driver = { static int exynos_cpufreq_probe(struct platform_device *pdev) { - struct device_node *cpus, *np; + struct device_node *cpu0; int ret = -EINVAL; exynos_info = kzalloc(sizeof(*exynos_info), GFP_KERNEL); @@ -206,28 +206,19 @@ static int exynos_cpufreq_probe(struct platform_device *pdev) if (ret) goto err_cpufreq_reg; - cpus = of_find_node_by_path("/cpus"); - if (!cpus) { - pr_err("failed to find cpus node\n"); + cpu0 = of_get_cpu_node(0, NULL); + if (!cpu0) { + pr_err("failed to find cpu0 node\n"); return 0; } - np = of_get_next_child(cpus, NULL); - if (!np) { - pr_err("failed to find cpus child node\n"); - of_node_put(cpus); - return 0; - } - - if (of_find_property(np, "#cooling-cells", NULL)) { - cdev = of_cpufreq_cooling_register(np, + if (of_find_property(cpu0, "#cooling-cells", NULL)) { + cdev = of_cpufreq_cooling_register(cpu0, cpu_present_mask); if (IS_ERR(cdev)) pr_err("running cpufreq without cooling device: %ld\n", PTR_ERR(cdev)); } - of_node_put(np); - of_node_put(cpus); return 0; From 93c537affd5d2a7b2fcea4a1d608b011841d3c04 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Tue, 24 Feb 2015 16:31:28 +0100 Subject: [PATCH 45/95] MAINTAINERS: Add entry for SAMSUNG THERMAL DRIVER This patch adds entry for SAMSUNG THERMAL DRIVER in the MAINTAINERS file. It has been agreed, that pull request are going to be sent to Eduardo Valentin. Signed-off-by: Lukasz Majewski Acked-by: Eduardo Valentin --- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index ddc5a8cf9a8ac0..be837a0d228018 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8481,6 +8481,14 @@ S: Supported L: netdev@vger.kernel.org F: drivers/net/ethernet/samsung/sxgbe/ +SAMSUNG THERMAL DRIVER +M: Lukasz Majewski +L: linux-pm@vger.kernel.org +L: linux-samsung-soc@vger.kernel.org +S: Supported +T: https://github.com/lmajewski/linux-samsung-thermal.git +F: drivers/thermal/samsung/ + SAMSUNG USB2 PHY DRIVER M: Kamil Debski L: linux-kernel@vger.kernel.org From d7a6fe015b2abe33565538a3faf757e095e094e7 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 6 Jan 2015 12:14:32 +0100 Subject: [PATCH 46/95] ASoC: sam9g20_wm8731: drop machine_is_xxx Atmel based boards can now only be used with device tree. Drop non DT initialization. Signed-off-by: Alexandre Belloni Signed-off-by: Mark Brown --- sound/soc/atmel/sam9g20_wm8731.c | 68 +++++++++++++++----------------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c index f5ad214663f98b..8de836165cf2ed 100644 --- a/sound/soc/atmel/sam9g20_wm8731.c +++ b/sound/soc/atmel/sam9g20_wm8731.c @@ -46,8 +46,6 @@ #include #include -#include - #include "../codecs/wm8731.h" #include "atmel-pcm.h" #include "atmel_ssc_dai.h" @@ -171,9 +169,7 @@ static int at91sam9g20ek_audio_probe(struct platform_device *pdev) int ret; if (!np) { - if (!(machine_is_at91sam9g20ek() || - machine_is_at91sam9g20ek_2mmc())) - return -ENODEV; + return -ENODEV; } ret = atmel_ssc_set_audio(0); @@ -210,39 +206,37 @@ static int at91sam9g20ek_audio_probe(struct platform_device *pdev) card->dev = &pdev->dev; /* Parse device node info */ - if (np) { - ret = snd_soc_of_parse_card_name(card, "atmel,model"); - if (ret) - goto err; - - ret = snd_soc_of_parse_audio_routing(card, - "atmel,audio-routing"); - if (ret) - goto err; - - /* Parse codec info */ - at91sam9g20ek_dai.codec_name = NULL; - codec_np = of_parse_phandle(np, "atmel,audio-codec", 0); - if (!codec_np) { - dev_err(&pdev->dev, "codec info missing\n"); - return -EINVAL; - } - at91sam9g20ek_dai.codec_of_node = codec_np; - - /* Parse dai and platform info */ - at91sam9g20ek_dai.cpu_dai_name = NULL; - at91sam9g20ek_dai.platform_name = NULL; - cpu_np = of_parse_phandle(np, "atmel,ssc-controller", 0); - if (!cpu_np) { - dev_err(&pdev->dev, "dai and pcm info missing\n"); - return -EINVAL; - } - at91sam9g20ek_dai.cpu_of_node = cpu_np; - at91sam9g20ek_dai.platform_of_node = cpu_np; - - of_node_put(codec_np); - of_node_put(cpu_np); + ret = snd_soc_of_parse_card_name(card, "atmel,model"); + if (ret) + goto err; + + ret = snd_soc_of_parse_audio_routing(card, + "atmel,audio-routing"); + if (ret) + goto err; + + /* Parse codec info */ + at91sam9g20ek_dai.codec_name = NULL; + codec_np = of_parse_phandle(np, "atmel,audio-codec", 0); + if (!codec_np) { + dev_err(&pdev->dev, "codec info missing\n"); + return -EINVAL; + } + at91sam9g20ek_dai.codec_of_node = codec_np; + + /* Parse dai and platform info */ + at91sam9g20ek_dai.cpu_dai_name = NULL; + at91sam9g20ek_dai.platform_name = NULL; + cpu_np = of_parse_phandle(np, "atmel,ssc-controller", 0); + if (!cpu_np) { + dev_err(&pdev->dev, "dai and pcm info missing\n"); + return -EINVAL; } + at91sam9g20ek_dai.cpu_of_node = cpu_np; + at91sam9g20ek_dai.platform_of_node = cpu_np; + + of_node_put(codec_np); + of_node_put(cpu_np); ret = snd_soc_register_card(card); if (ret) { From dfcacc154fb38fdb2c243c3dbbdc1f26a64cedc8 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 2 Mar 2015 22:25:37 +0100 Subject: [PATCH 47/95] cpuidle: Clean up fallback handling in cpuidle_idle_call() Move the fallback code path in cpuidle_idle_call() to the end of the function to avoid jumping to a label in an if () branch. Signed-off-by: Rafael J. Wysocki --- kernel/sched/idle.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c index f59198bda1bf34..84b93b68482a8c 100644 --- a/kernel/sched/idle.c +++ b/kernel/sched/idle.c @@ -124,20 +124,8 @@ static void cpuidle_idle_call(void) * Fall back to the default arch idle method on errors. */ next_state = cpuidle_select(drv, dev); - if (next_state < 0) { -use_default: - /* - * We can't use the cpuidle framework, let's use the default - * idle routine. - */ - if (current_clr_polling_and_test()) - local_irq_enable(); - else - arch_cpu_idle(); - - goto exit_idle; - } - + if (next_state < 0) + goto use_default; /* * The idle task must be scheduled, it is pointless to @@ -195,6 +183,19 @@ static void cpuidle_idle_call(void) rcu_idle_exit(); start_critical_timings(); + return; + +use_default: + /* + * We can't use the cpuidle framework, let's use the default + * idle routine. + */ + if (current_clr_polling_and_test()) + local_irq_enable(); + else + arch_cpu_idle(); + + goto exit_idle; } /* From 4d884fceaa2c838abb598778813e93f6d9fea723 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Mon, 9 Feb 2015 17:17:43 +0000 Subject: [PATCH 48/95] Btrfs: fix fsync race leading to ordered extent memory leaks We can have multiple fsync operations against the same file during the same transaction and they can collect the same ordered extents while they don't complete (still accessible from the inode's ordered tree). If this happens, those ordered extents will never get their reference counts decremented to 0, leading to memory leaks and inode leaks (an iput for an ordered extent's inode is scheduled only when the ordered extent's refcount drops to 0). The following sequence diagram explains this race: CPU 1 CPU 2 btrfs_sync_file() btrfs_sync_file() mutex_lock(inode->i_mutex) btrfs_log_inode() btrfs_get_logged_extents() --> collects ordered extent X --> increments ordered extent X's refcount btrfs_submit_logged_extents() mutex_unlock(inode->i_mutex) mutex_lock(inode->i_mutex) btrfs_sync_log() btrfs_wait_logged_extents() --> list_del_init(&ordered->log_list) btrfs_log_inode() btrfs_get_logged_extents() --> Adds ordered extent X to logged_list because at this point: list_empty(&ordered->log_list) && test_bit(BTRFS_ORDERED_LOGGED, &ordered->flags) == 0 --> Increments ordered extent X's refcount --> check if ordered extent's io is finished or not, start it if necessary and wait for it to finish --> sets bit BTRFS_ORDERED_LOGGED on ordered extent X's flags and adds it to trans->ordered btrfs_sync_log() finishes btrfs_submit_logged_extents() btrfs_log_inode() finishes mutex_unlock(inode->i_mutex) btrfs_sync_file() finishes btrfs_sync_log() btrfs_wait_logged_extents() --> Sees ordered extent X has the bit BTRFS_ORDERED_LOGGED set in its flags --> X's refcount is untouched btrfs_sync_log() finishes btrfs_sync_file() finishes btrfs_commit_transaction() --> called by transaction kthread for e.g. btrfs_wait_pending_ordered() --> waits for ordered extent X to complete --> decrements ordered extent X's refcount by 1 only, corresponding to the increment done by the fsync task ran by CPU 1 In the scenario of the above diagram, after the transaction commit, the ordered extent will remain with a refcount of 1 forever, leaking the ordered extent structure and preventing the i_count of its inode from ever decreasing to 0, since the delayed iput is scheduled only when the ordered extent's refcount drops to 0, preventing the inode from ever being evicted by the VFS. Fix this by using the flag BTRFS_ORDERED_LOGGED differently. Use it to mean that an ordered extent is already being processed by an fsync call, which will attach it to the current transaction, preventing it from being collected by subsequent fsync operations against the same inode. This race was introduced with the following change (added in 3.19 and backported to stable 3.18 and 3.17): Btrfs: make sure logged extents complete in the current transaction V3 commit 50d9aa99bd35c77200e0e3dd7a72274f8304701f I ran into this issue while running xfstests/generic/113 in a loop, which failed about 1 out of 10 runs with the following warning in dmesg: [ 2612.440038] WARNING: CPU: 4 PID: 22057 at fs/btrfs/disk-io.c:3558 free_fs_root+0x36/0x133 [btrfs]() [ 2612.442810] Modules linked in: btrfs crc32c_generic xor raid6_pq nfsd auth_rpcgss oid_registry nfs_acl nfs lockd grace fscache sunrpc loop processor parport_pc parport psmouse therma l_sys i2c_piix4 serio_raw pcspkr evdev microcode button i2c_core ext4 crc16 jbd2 mbcache sd_mod sg sr_mod cdrom virtio_scsi ata_generic virtio_pci ata_piix virtio_ring libata virtio flo ppy e1000 scsi_mod [last unloaded: btrfs] [ 2612.452711] CPU: 4 PID: 22057 Comm: umount Tainted: G W 3.19.0-rc5-btrfs-next-4+ #1 [ 2612.454921] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.7.5-0-ge51488c-20140602_164612-nilsson.home.kraxel.org 04/01/2014 [ 2612.457709] 0000000000000009 ffff8801342c3c78 ffffffff8142425e ffff88023ec8f2d8 [ 2612.459829] 0000000000000000 ffff8801342c3cb8 ffffffff81045308 ffff880046460000 [ 2612.461564] ffffffffa036da56 ffff88003d07b000 ffff880046460000 ffff880046460068 [ 2612.463163] Call Trace: [ 2612.463719] [] dump_stack+0x4c/0x65 [ 2612.464789] [] warn_slowpath_common+0xa1/0xbb [ 2612.466026] [] ? free_fs_root+0x36/0x133 [btrfs] [ 2612.467247] [] warn_slowpath_null+0x1a/0x1c [ 2612.468416] [] free_fs_root+0x36/0x133 [btrfs] [ 2612.469625] [] btrfs_drop_and_free_fs_root+0x93/0x9b [btrfs] [ 2612.471251] [] btrfs_free_fs_roots+0xa4/0xd6 [btrfs] [ 2612.472536] [] ? wait_for_completion+0x24/0x26 [ 2612.473742] [] close_ctree+0x1f3/0x33c [btrfs] [ 2612.475477] [] ? destroy_workqueue+0x148/0x1ba [ 2612.476695] [] btrfs_put_super+0x19/0x1b [btrfs] [ 2612.477911] [] generic_shutdown_super+0x73/0xef [ 2612.479106] [] kill_anon_super+0x13/0x1e [ 2612.480226] [] btrfs_kill_super+0x17/0x23 [btrfs] [ 2612.481471] [] deactivate_locked_super+0x3b/0x50 [ 2612.482686] [] deactivate_super+0x3f/0x43 [ 2612.483791] [] cleanup_mnt+0x59/0x78 [ 2612.484842] [] __cleanup_mnt+0x12/0x14 [ 2612.485900] [] task_work_run+0x8f/0xbc [ 2612.486960] [] do_notify_resume+0x5a/0x6b [ 2612.488083] [] ? trace_hardirqs_on_thunk+0x3a/0x3f [ 2612.489333] [] int_signal+0x12/0x17 [ 2612.490353] ---[ end trace 54a960a6bdcb8d93 ]--- [ 2612.557253] VFS: Busy inodes after unmount of sdb. Self-destruct in 5 seconds. Have a nice day... Kmemleak confirmed the ordered extent leak (and btrfs inode specific structures such as delayed nodes): $ cat /sys/kernel/debug/kmemleak unreferenced object 0xffff880154290db0 (size 576): comm "btrfsck", pid 21980, jiffies 4295542503 (age 1273.412s) hex dump (first 32 bytes): 01 40 00 00 01 00 00 00 b0 1d f1 4e 01 88 ff ff .@.........N.... 00 00 00 00 00 00 00 00 c8 0d 29 54 01 88 ff ff ..........)T.... backtrace: [] kmemleak_update_trace+0x4c/0x6a [] radix_tree_node_alloc+0x6d/0x83 [] __radix_tree_create+0x109/0x190 [] radix_tree_insert+0x30/0xac [] btrfs_get_or_create_delayed_node+0x130/0x187 [btrfs] [] btrfs_delayed_delete_inode_ref+0x32/0xac [btrfs] [] __btrfs_unlink_inode+0xee/0x288 [btrfs] [] btrfs_unlink_inode+0x1e/0x40 [btrfs] [] btrfs_unlink+0x60/0x9b [btrfs] [] vfs_unlink+0x9c/0xed [] do_unlinkat+0x12c/0x1fa [] SyS_unlinkat+0x29/0x2b [] system_call_fastpath+0x12/0x17 [] 0xffffffffffffffff unreferenced object 0xffff88014ef11db0 (size 576): comm "rm", pid 22009, jiffies 4295542593 (age 1273.052s) hex dump (first 32 bytes): 02 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 c8 1d f1 4e 01 88 ff ff ...........N.... backtrace: [] kmemleak_update_trace+0x4c/0x6a [] radix_tree_node_alloc+0x6d/0x83 [] __radix_tree_create+0x109/0x190 [] radix_tree_insert+0x30/0xac [] btrfs_get_or_create_delayed_node+0x130/0x187 [btrfs] [] btrfs_delayed_delete_inode_ref+0x32/0xac [btrfs] [] __btrfs_unlink_inode+0xee/0x288 [btrfs] [] btrfs_unlink_inode+0x1e/0x40 [btrfs] [] btrfs_unlink+0x60/0x9b [btrfs] [] vfs_unlink+0x9c/0xed [] do_unlinkat+0x12c/0x1fa [] SyS_unlinkat+0x29/0x2b [] system_call_fastpath+0x12/0x17 [] 0xffffffffffffffff unreferenced object 0xffff8800336feda8 (size 584): comm "aio-stress", pid 22031, jiffies 4295543006 (age 1271.400s) hex dump (first 32 bytes): 00 40 3e 00 00 00 00 00 00 00 8f 42 00 00 00 00 .@>........B.... 00 00 01 00 00 00 00 00 00 00 01 00 00 00 00 00 ................ backtrace: [] create_object+0x172/0x29a [] kmemleak_alloc+0x25/0x41 [] kmemleak_alloc_recursive.constprop.52+0x16/0x18 [] kmem_cache_alloc+0xf7/0x198 [] __btrfs_add_ordered_extent+0x43/0x309 [btrfs] [] btrfs_add_ordered_extent_dio+0x12/0x14 [btrfs] [] btrfs_get_blocks_direct+0x3ef/0x571 [btrfs] [] do_blockdev_direct_IO+0x62a/0xb47 [] __blockdev_direct_IO+0x34/0x36 [] btrfs_direct_IO+0x16a/0x1e8 [btrfs] [] generic_file_direct_write+0xb8/0x12d [] btrfs_file_write_iter+0x24b/0x42f [btrfs] [] aio_run_iocb+0x2b7/0x32e [] do_io_submit+0x26e/0x2ff [] SyS_io_submit+0x10/0x12 [] system_call_fastpath+0x12/0x17 CC: # 3.19, 3.18 and 3.17 Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/ordered-data.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 534544e08f7694..157cc54fc63486 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -452,9 +452,7 @@ void btrfs_get_logged_extents(struct inode *inode, continue; if (entry_end(ordered) <= start) break; - if (!list_empty(&ordered->log_list)) - continue; - if (test_bit(BTRFS_ORDERED_LOGGED, &ordered->flags)) + if (test_and_set_bit(BTRFS_ORDERED_LOGGED, &ordered->flags)) continue; list_add(&ordered->log_list, logged_list); atomic_inc(&ordered->refs); @@ -511,8 +509,7 @@ void btrfs_wait_logged_extents(struct btrfs_trans_handle *trans, wait_event(ordered->wait, test_bit(BTRFS_ORDERED_IO_DONE, &ordered->flags)); - if (!test_and_set_bit(BTRFS_ORDERED_LOGGED, &ordered->flags)) - list_add_tail(&ordered->trans_list, &trans->ordered); + list_add_tail(&ordered->trans_list, &trans->ordered); spin_lock_irq(&log->log_extents_lock[index]); } spin_unlock_irq(&log->log_extents_lock[index]); From 0c0ef4bc842ba6b593bb94f9fb8b653fe18c5ed8 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Thu, 12 Feb 2015 09:43:51 -0500 Subject: [PATCH 49/95] Btrfs: abort the transaction if we fail to update the free space cache inode Our gluster boxes were hitting a problem where they'd run out of space when updating the block group cache and therefore wouldn't be able to update the free space inode. This is a problem because this is how we invalidate the cache and protect ourselves from errors further down the stack, so if this fails we have to abort the transaction so we make sure we don't end up with stale free space cache. Thanks, Signed-off-by: Josef Bacik Signed-off-by: Chris Mason --- fs/btrfs/extent-tree.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 28ce5c8004d456..92146a5afdc1a5 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -3208,6 +3208,8 @@ static int cache_save_setup(struct btrfs_block_group_cache *block_group, return 0; } + if (trans->aborted) + return 0; again: inode = lookup_free_space_inode(root, block_group, path); if (IS_ERR(inode) && PTR_ERR(inode) != -ENOENT) { @@ -3243,6 +3245,20 @@ static int cache_save_setup(struct btrfs_block_group_cache *block_group, */ BTRFS_I(inode)->generation = 0; ret = btrfs_update_inode(trans, root, inode); + if (ret) { + /* + * So theoretically we could recover from this, simply set the + * super cache generation to 0 so we know to invalidate the + * cache, but then we'd have to keep track of the block groups + * that fail this way so we know we _have_ to reset this cache + * before the next commit or risk reading stale cache. So to + * limit our exposure to horrible edge cases lets just abort the + * transaction, this only happens in really bad situations + * anyway. + */ + btrfs_abort_transaction(trans, root, ret); + goto out_put; + } WARN_ON(ret); if (i_size_read(inode) > 0) { From e8c1c76e804b18120e6977fc092769c043876212 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Sun, 15 Feb 2015 22:38:54 +0000 Subject: [PATCH 50/95] Btrfs: add missing inode update when punching hole When punching a file hole if we endup only zeroing parts of a page, because the start offset isn't a multiple of the sector size or the start offset and length fall within the same page, we were not updating the inode item. This prevented an fsync from doing anything, if no other file changes happened in the current transaction, because the fields in btrfs_inode used to check if the inode needs to be fsync'ed weren't updated. This issue is easy to reproduce and the following excerpt from the xfstest case I made shows how to trigger it: _scratch_mkfs >> $seqres.full 2>&1 _init_flakey _mount_flakey # Create our test file. $XFS_IO_PROG -f -c "pwrite -S 0x22 -b 16K 0 16K" \ $SCRATCH_MNT/foo | _filter_xfs_io # Fsync the file, this makes btrfs update some btrfs inode specific fields # that are used to track if the inode needs to be written/updated to the fsync # log or not. After this fsync, the new values for those fields indicate that # a subsequent fsync does not need to touch the fsync log. $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/foo # Force a commit of the current transaction. After this point, any operation # that modifies the data or metadata of our file, should update those fields in # the btrfs inode with values that make the next fsync operation write to the # fsync log. sync # Punch a hole in our file. This small range affects only 1 page. # This made the btrfs hole punching implementation write only some zeroes in # one page, but it did not update the btrfs inode fields used to determine if # the next fsync needs to write to the fsync log. $XFS_IO_PROG -c "fpunch 8000 4K" $SCRATCH_MNT/foo # Another variation of the previously mentioned case. $XFS_IO_PROG -c "fpunch 15000 100" $SCRATCH_MNT/foo # Now fsync the file. This was a no-operation because the previous hole punch # operation didn't update the inode's fields mentioned before, so they remained # with the values they had after the first fsync - that is, they indicate that # it is not needed to write to fsync log. $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/foo echo "File content before:" od -t x1 $SCRATCH_MNT/foo # Simulate a crash/power loss. _load_flakey_table $FLAKEY_DROP_WRITES _unmount_flakey # Enable writes and mount the fs. This makes the fsync log replay code run. _load_flakey_table $FLAKEY_ALLOW_WRITES _mount_flakey # Because the last fsync didn't do anything, here the file content matched what # it was after the first fsync, before the holes were punched, and not what it # was after the holes were punched. echo "File content after:" od -t x1 $SCRATCH_MNT/foo This issue has been around since 2012, when the punch hole implementation was added, commit 2aaa66558172 ("Btrfs: add hole punching"). A test case for xfstests follows soon. Signed-off-by: Filipe Manana Reviewed-by: Liu Bo Signed-off-by: Chris Mason --- fs/btrfs/file.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index e4090259569bcc..b476e5645034cb 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -2276,6 +2276,8 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len) bool same_page; bool no_holes = btrfs_fs_incompat(root->fs_info, NO_HOLES); u64 ino_size; + bool truncated_page = false; + bool updated_inode = false; ret = btrfs_wait_ordered_range(inode, offset, len); if (ret) @@ -2307,13 +2309,18 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len) * entire page. */ if (same_page && len < PAGE_CACHE_SIZE) { - if (offset < ino_size) + if (offset < ino_size) { + truncated_page = true; ret = btrfs_truncate_page(inode, offset, len, 0); + } else { + ret = 0; + } goto out_only_mutex; } /* zero back part of the first page */ if (offset < ino_size) { + truncated_page = true; ret = btrfs_truncate_page(inode, offset, 0, 0); if (ret) { mutex_unlock(&inode->i_mutex); @@ -2349,6 +2356,7 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len) if (!ret) { /* zero the front end of the last page */ if (tail_start + tail_len < ino_size) { + truncated_page = true; ret = btrfs_truncate_page(inode, tail_start + tail_len, 0, 1); if (ret) @@ -2358,8 +2366,8 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len) } if (lockend < lockstart) { - mutex_unlock(&inode->i_mutex); - return 0; + ret = 0; + goto out_only_mutex; } while (1) { @@ -2507,6 +2515,7 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len) trans->block_rsv = &root->fs_info->trans_block_rsv; ret = btrfs_update_inode(trans, root, inode); + updated_inode = true; btrfs_end_transaction(trans, root); btrfs_btree_balance_dirty(root); out_free: @@ -2516,6 +2525,22 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len) unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart, lockend, &cached_state, GFP_NOFS); out_only_mutex: + if (!updated_inode && truncated_page && !ret && !err) { + /* + * If we only end up zeroing part of a page, we still need to + * update the inode item, so that all the time fields are + * updated as well as the necessary btrfs inode in memory fields + * for detecting, at fsync time, if the inode isn't yet in the + * log tree or it's there but not up to date. + */ + trans = btrfs_start_transaction(root, 1); + if (IS_ERR(trans)) { + err = PTR_ERR(trans); + } else { + err = btrfs_update_inode(trans, root, inode); + ret = btrfs_end_transaction(trans, root); + } + } mutex_unlock(&inode->i_mutex); if (ret && !err) err = ret; From 5dfe2be7ead15863fd7b3fcc8bd69e470fae2bec Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Mon, 23 Feb 2015 19:48:52 +0000 Subject: [PATCH 51/95] Btrfs: fix off-by-one logic error in btrfs_realloc_node The end_slot variable actually matches the number of pointers in the node and not the last slot (which is 'nritems - 1'). Therefore in order to check that the current slot in the for loop doesn't match the last one, the correct logic is to check if 'i' is less than 'end_slot - 1' and not 'end_slot - 2'. Fix this and set end_slot to be 'nritems - 1', as it's less confusing since the variable name implies it's inclusive rather then exclusive. Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/ctree.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 993642199326a7..6d67f32e648df7 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -1645,14 +1645,14 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, parent_nritems = btrfs_header_nritems(parent); blocksize = root->nodesize; - end_slot = parent_nritems; + end_slot = parent_nritems - 1; - if (parent_nritems == 1) + if (parent_nritems <= 1) return 0; btrfs_set_lock_blocking(parent); - for (i = start_slot; i < end_slot; i++) { + for (i = start_slot; i <= end_slot; i++) { int close = 1; btrfs_node_key(parent, &disk_key, i); @@ -1669,7 +1669,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, other = btrfs_node_blockptr(parent, i - 1); close = close_blocks(blocknr, other, blocksize); } - if (!close && i < end_slot - 2) { + if (!close && i < end_slot) { other = btrfs_node_blockptr(parent, i + 1); close = close_blocks(blocknr, other, blocksize); } From 5cdf83edb8e41cad1ec8eab2d402b4f9d9eb7ee0 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Mon, 23 Feb 2015 19:50:49 +0000 Subject: [PATCH 52/95] Btrfs: do not ignore errors from btrfs_lookup_xattr in do_setxattr The return value from btrfs_lookup_xattr() can be a pointer encoding an error, therefore deal with it. This fixes commit 5f5bc6b1e2d5 ("Btrfs: make xattr replace operations atomic"). Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/xattr.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c index 47b19465f0dc64..883b93623bc568 100644 --- a/fs/btrfs/xattr.c +++ b/fs/btrfs/xattr.c @@ -111,6 +111,8 @@ static int do_setxattr(struct btrfs_trans_handle *trans, name, name_len, -1); if (!di && (flags & XATTR_REPLACE)) ret = -ENODATA; + else if (IS_ERR(di)) + ret = PTR_ERR(di); else if (di) ret = btrfs_delete_one_dir_name(trans, root, path, di); goto out; @@ -127,10 +129,12 @@ static int do_setxattr(struct btrfs_trans_handle *trans, ASSERT(mutex_is_locked(&inode->i_mutex)); di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(inode), name, name_len, 0); - if (!di) { + if (!di) ret = -ENODATA; + else if (IS_ERR(di)) + ret = PTR_ERR(di); + if (ret) goto out; - } btrfs_release_path(path); di = NULL; } From 1932b7be973b554ffe20a5bba6ffaed6fa995cdc Mon Sep 17 00:00:00 2001 From: David Sterba Date: Tue, 24 Feb 2015 18:57:18 +0100 Subject: [PATCH 53/95] btrfs: fix lost return value due to variable shadowing A block-local variable stores error code but btrfs_get_blocks_direct may not return it in the end as there's a ret defined in the function scope. CC: # 3.6+ Fixes: d187663ef24c ("Btrfs: lock extents as we map them in DIO") Signed-off-by: David Sterba Signed-off-by: Chris Mason --- fs/btrfs/inode.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 8564d8ce03de68..91a87f53be3c1d 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -7288,7 +7288,6 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock, ((BTRFS_I(inode)->flags & BTRFS_INODE_NODATACOW) && em->block_start != EXTENT_MAP_HOLE)) { int type; - int ret; u64 block_start, orig_start, orig_block_len, ram_bytes; if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) From 84471e2429ed82fdbac0c56d5b2a18d450f99f6a Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Sat, 28 Feb 2015 22:29:22 +0000 Subject: [PATCH 54/95] Btrfs: incremental send, don't rename a directory too soon There's one more case where we can't issue a rename operation for a directory as soon as we process it. We used to delay directory renames only if they have some ancestor directory with a higher inode number that got renamed too, but there's another case where we need to delay the rename too - when a directory A is renamed to the old name of a directory B but that directory B has its rename delayed because it has now (in the send root) an ancestor with a higher inode number that was renamed. If we don't delay the directory rename in this case, the receiving end of the send stream will attempt to rename A to the old name of B before B got renamed to its new name, which results in a "directory not empty" error. So fix this by delaying directory renames for this case too. Steps to reproduce: $ mkfs.btrfs -f /dev/sdb $ mount /dev/sdb /mnt $ mkdir /mnt/a $ mkdir /mnt/b $ mkdir /mnt/c $ touch /mnt/a/file $ btrfs subvolume snapshot -r /mnt /mnt/snap1 $ mv /mnt/c /mnt/x $ mv /mnt/a /mnt/x/y $ mv /mnt/b /mnt/a $ btrfs subvolume snapshot -r /mnt /mnt/snap2 $ btrfs send /mnt/snap1 -f /tmp/1.send $ btrfs send -p /mnt/snap1 /mnt/snap2 -f /tmp/2.send $ mkfs.btrfs -f /dev/sdc $ mount /dev/sdc /mnt2 $ btrfs receive /mnt2 -f /tmp/1.send $ btrfs receive /mnt2 -f /tmp/2.send ERROR: rename b -> a failed. Directory not empty A test case for xfstests follows soon. Reported-by: Ames Cornish Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/send.c | 171 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 156 insertions(+), 15 deletions(-) diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index fe5857223515d1..d6033f540cc75c 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c @@ -230,6 +230,7 @@ struct pending_dir_move { u64 parent_ino; u64 ino; u64 gen; + bool is_orphan; struct list_head update_refs; }; @@ -2984,7 +2985,8 @@ static int add_pending_dir_move(struct send_ctx *sctx, u64 ino_gen, u64 parent_ino, struct list_head *new_refs, - struct list_head *deleted_refs) + struct list_head *deleted_refs, + const bool is_orphan) { struct rb_node **p = &sctx->pending_dir_moves.rb_node; struct rb_node *parent = NULL; @@ -2999,6 +3001,7 @@ static int add_pending_dir_move(struct send_ctx *sctx, pm->parent_ino = parent_ino; pm->ino = ino; pm->gen = ino_gen; + pm->is_orphan = is_orphan; INIT_LIST_HEAD(&pm->list); INIT_LIST_HEAD(&pm->update_refs); RB_CLEAR_NODE(&pm->node); @@ -3131,16 +3134,20 @@ static int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm) rmdir_ino = dm->rmdir_ino; free_waiting_dir_move(sctx, dm); - ret = get_first_ref(sctx->parent_root, pm->ino, - &parent_ino, &parent_gen, name); - if (ret < 0) - goto out; - - ret = get_cur_path(sctx, parent_ino, parent_gen, - from_path); - if (ret < 0) - goto out; - ret = fs_path_add_path(from_path, name); + if (pm->is_orphan) { + ret = gen_unique_name(sctx, pm->ino, + pm->gen, from_path); + } else { + ret = get_first_ref(sctx->parent_root, pm->ino, + &parent_ino, &parent_gen, name); + if (ret < 0) + goto out; + ret = get_cur_path(sctx, parent_ino, parent_gen, + from_path); + if (ret < 0) + goto out; + ret = fs_path_add_path(from_path, name); + } if (ret < 0) goto out; @@ -3150,7 +3157,8 @@ static int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm) LIST_HEAD(deleted_refs); ASSERT(ancestor > BTRFS_FIRST_FREE_OBJECTID); ret = add_pending_dir_move(sctx, pm->ino, pm->gen, ancestor, - &pm->update_refs, &deleted_refs); + &pm->update_refs, &deleted_refs, + pm->is_orphan); if (ret < 0) goto out; if (rmdir_ino) { @@ -3283,6 +3291,127 @@ static int apply_children_dir_moves(struct send_ctx *sctx) return ret; } +/* + * We might need to delay a directory rename even when no ancestor directory + * (in the send root) with a higher inode number than ours (sctx->cur_ino) was + * renamed. This happens when we rename a directory to the old name (the name + * in the parent root) of some other unrelated directory that got its rename + * delayed due to some ancestor with higher number that got renamed. + * + * Example: + * + * Parent snapshot: + * . (ino 256) + * |---- a/ (ino 257) + * | |---- file (ino 260) + * | + * |---- b/ (ino 258) + * |---- c/ (ino 259) + * + * Send snapshot: + * . (ino 256) + * |---- a/ (ino 258) + * |---- x/ (ino 259) + * |---- y/ (ino 257) + * |----- file (ino 260) + * + * Here we can not rename 258 from 'b' to 'a' without the rename of inode 257 + * from 'a' to 'x/y' happening first, which in turn depends on the rename of + * inode 259 from 'c' to 'x'. So the order of rename commands the send stream + * must issue is: + * + * 1 - rename 259 from 'c' to 'x' + * 2 - rename 257 from 'a' to 'x/y' + * 3 - rename 258 from 'b' to 'a' + * + * Returns 1 if the rename of sctx->cur_ino needs to be delayed, 0 if it can + * be done right away and < 0 on error. + */ +static int wait_for_dest_dir_move(struct send_ctx *sctx, + struct recorded_ref *parent_ref, + const bool is_orphan) +{ + struct btrfs_path *path; + struct btrfs_key key; + struct btrfs_key di_key; + struct btrfs_dir_item *di; + u64 left_gen; + u64 right_gen; + int ret = 0; + + if (RB_EMPTY_ROOT(&sctx->waiting_dir_moves)) + return 0; + + path = alloc_path_for_send(); + if (!path) + return -ENOMEM; + + key.objectid = parent_ref->dir; + key.type = BTRFS_DIR_ITEM_KEY; + key.offset = btrfs_name_hash(parent_ref->name, parent_ref->name_len); + + ret = btrfs_search_slot(NULL, sctx->parent_root, &key, path, 0, 0); + if (ret < 0) { + goto out; + } else if (ret > 0) { + ret = 0; + goto out; + } + + di = btrfs_match_dir_item_name(sctx->parent_root, path, + parent_ref->name, parent_ref->name_len); + if (!di) { + ret = 0; + goto out; + } + /* + * di_key.objectid has the number of the inode that has a dentry in the + * parent directory with the same name that sctx->cur_ino is being + * renamed to. We need to check if that inode is in the send root as + * well and if it is currently marked as an inode with a pending rename, + * if it is, we need to delay the rename of sctx->cur_ino as well, so + * that it happens after that other inode is renamed. + */ + btrfs_dir_item_key_to_cpu(path->nodes[0], di, &di_key); + if (di_key.type != BTRFS_INODE_ITEM_KEY) { + ret = 0; + goto out; + } + + ret = get_inode_info(sctx->parent_root, di_key.objectid, NULL, + &left_gen, NULL, NULL, NULL, NULL); + if (ret < 0) + goto out; + ret = get_inode_info(sctx->send_root, di_key.objectid, NULL, + &right_gen, NULL, NULL, NULL, NULL); + if (ret < 0) { + if (ret == -ENOENT) + ret = 0; + goto out; + } + + /* Different inode, no need to delay the rename of sctx->cur_ino */ + if (right_gen != left_gen) { + ret = 0; + goto out; + } + + if (is_waiting_for_move(sctx, di_key.objectid)) { + ret = add_pending_dir_move(sctx, + sctx->cur_ino, + sctx->cur_inode_gen, + di_key.objectid, + &sctx->new_refs, + &sctx->deleted_refs, + is_orphan); + if (!ret) + ret = 1; + } +out: + btrfs_free_path(path); + return ret; +} + static int wait_for_parent_move(struct send_ctx *sctx, struct recorded_ref *parent_ref) { @@ -3349,7 +3478,8 @@ static int wait_for_parent_move(struct send_ctx *sctx, sctx->cur_inode_gen, ino, &sctx->new_refs, - &sctx->deleted_refs); + &sctx->deleted_refs, + false); if (!ret) ret = 1; } @@ -3372,6 +3502,7 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move) int did_overwrite = 0; int is_orphan = 0; u64 last_dir_ino_rm = 0; + bool can_rename = true; verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino); @@ -3490,12 +3621,22 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino); } } + if (S_ISDIR(sctx->cur_inode_mode) && sctx->parent_root) { + ret = wait_for_dest_dir_move(sctx, cur, is_orphan); + if (ret < 0) + goto out; + if (ret == 1) { + can_rename = false; + *pending_move = 1; + } + } + /* * link/move the ref to the new place. If we have an orphan * inode, move it and update valid_path. If not, link or move * it depending on the inode mode. */ - if (is_orphan) { + if (is_orphan && can_rename) { ret = send_rename(sctx, valid_path, cur->full_path); if (ret < 0) goto out; @@ -3503,7 +3644,7 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino); ret = fs_path_copy(valid_path, cur->full_path); if (ret < 0) goto out; - } else { + } else if (can_rename) { if (S_ISDIR(sctx->cur_inode_mode)) { /* * Dirs can't be linked, so move it. For moved From 369d6b7f00977eb9090212d4a47ac71f3ec5c217 Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Mon, 2 Mar 2015 16:46:09 -0500 Subject: [PATCH 55/95] NFS: Fix stateid used for NFS v4 closes After 566fcec60 the client uses the "current stateid" from the nfs4_state structure to close a file. This could potentially contain a delegation stateid, which is disallowed by the protocol and causes servers to return NFS4ERR_BAD_STATEID. This patch restores the (correct) behavior of sending the open stateid to close a file. Reported-by: Olga Kornievskaia Fixes: 566fcec60 (NFSv4: Fix an atomicity problem in CLOSE) Signed-off-by: Anna Schumaker Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index a211daf58c328e..732526e04cd59b 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2655,7 +2655,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data) case -NFS4ERR_BAD_STATEID: case -NFS4ERR_EXPIRED: if (!nfs4_stateid_match(&calldata->arg.stateid, - &state->stateid)) { + &state->open_stateid)) { rpc_restart_call_prepare(task); goto out_release; } @@ -2691,7 +2691,7 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data) is_rdwr = test_bit(NFS_O_RDWR_STATE, &state->flags); is_rdonly = test_bit(NFS_O_RDONLY_STATE, &state->flags); is_wronly = test_bit(NFS_O_WRONLY_STATE, &state->flags); - nfs4_stateid_copy(&calldata->arg.stateid, &state->stateid); + nfs4_stateid_copy(&calldata->arg.stateid, &state->open_stateid); /* Calculate the change in open mode */ calldata->arg.fmode = 0; if (state->n_rdwr == 0) { From b04b22f4ca691280f0ab3f77954f5a21500881e7 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 26 Feb 2015 13:59:38 -0500 Subject: [PATCH 56/95] NFSv4: Ensure that we don't reap a delegation that is being returned Signed-off-by: Trond Myklebust --- fs/nfs/delegation.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 2e37d8315d9207..d9caf73eef48d0 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -815,12 +815,14 @@ void nfs_delegation_reap_unclaimed(struct nfs_client *clp) inode = nfs_delegation_grab_inode(delegation); if (inode == NULL) continue; - delegation = nfs_detach_delegation(NFS_I(inode), - delegation, server); + delegation = nfs_start_delegation_return_locked(NFS_I(inode)); rcu_read_unlock(); - - if (delegation != NULL) - nfs_free_delegation(delegation); + if (delegation != NULL) { + delegation = nfs_detach_delegation(NFS_I(inode), + delegation, server); + if (delegation != NULL) + nfs_free_delegation(delegation); + } iput(inode); goto restart; } From ade04647dd56881e285983af3db702d56ee97e86 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 27 Feb 2015 14:25:50 -0500 Subject: [PATCH 57/95] NFSv4: Ensure we honour NFS_DELEGATION_RETURNING in nfs_inode_set_delegation() Ensure that nfs_inode_set_delegation() doesn't inadvertently detach a delegation that is already in the process of being returned. Signed-off-by: Trond Myklebust --- fs/nfs/delegation.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index d9caf73eef48d0..5ca502b5f87783 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -370,7 +370,10 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct delegation = NULL; goto out; } - freeme = nfs_detach_delegation_locked(nfsi, + if (test_and_set_bit(NFS_DELEGATION_RETURNING, + &old_delegation->flags)) + goto out; + freeme = nfs_detach_delegation_locked(nfsi, old_delegation, clp); if (freeme == NULL) goto out; From 9f0f8e12c48e4bb89192a0de876c77dc1fbfaa75 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 26 Feb 2015 09:57:34 -0500 Subject: [PATCH 58/95] NFSv4: Pin the superblock while we're returning the delegation This patch ensures that the superblock doesn't go ahead and disappear underneath us while the state manager thread is returning delegations. Signed-off-by: Trond Myklebust --- fs/nfs/delegation.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 5ca502b5f87783..be313e791e6752 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -474,14 +474,20 @@ int nfs_client_return_marked_delegations(struct nfs_client *clp) super_list) { if (!nfs_delegation_need_return(delegation)) continue; - inode = nfs_delegation_grab_inode(delegation); - if (inode == NULL) + if (!nfs_sb_active(server->super)) continue; + inode = nfs_delegation_grab_inode(delegation); + if (inode == NULL) { + rcu_read_unlock(); + nfs_sb_deactive(server->super); + goto restart; + } delegation = nfs_start_delegation_return_locked(NFS_I(inode)); rcu_read_unlock(); err = nfs_end_delegation_return(inode, delegation, 0); iput(inode); + nfs_sb_deactive(server->super); if (!err) goto restart; set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state); @@ -815,9 +821,14 @@ void nfs_delegation_reap_unclaimed(struct nfs_client *clp) if (test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags) == 0) continue; - inode = nfs_delegation_grab_inode(delegation); - if (inode == NULL) + if (!nfs_sb_active(server->super)) continue; + inode = nfs_delegation_grab_inode(delegation); + if (inode == NULL) { + rcu_read_unlock(); + nfs_sb_deactive(server->super); + goto restart; + } delegation = nfs_start_delegation_return_locked(NFS_I(inode)); rcu_read_unlock(); if (delegation != NULL) { @@ -827,6 +838,7 @@ void nfs_delegation_reap_unclaimed(struct nfs_client *clp) nfs_free_delegation(delegation); } iput(inode); + nfs_sb_deactive(server->super); goto restart; } } From ec3ca4e57e00d52ff724b0ae49f4489667a9c311 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 26 Feb 2015 14:05:05 -0500 Subject: [PATCH 59/95] NFSv4: Ensure we skip delegations that are already being returned In nfs_client_return_marked_delegations() and nfs_delegation_reap_unclaimed() we want to optimise the loop traversal by skipping delegations that are already in the process of being returned. Signed-off-by: Trond Myklebust --- fs/nfs/delegation.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index be313e791e6752..a6ad6886588034 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -436,6 +436,8 @@ static bool nfs_delegation_need_return(struct nfs_delegation *delegation) { bool ret = false; + if (test_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) + goto out; if (test_and_clear_bit(NFS_DELEGATION_RETURN, &delegation->flags)) ret = true; if (test_and_clear_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags) && !ret) { @@ -447,6 +449,7 @@ static bool nfs_delegation_need_return(struct nfs_delegation *delegation) ret = true; spin_unlock(&delegation->lock); } +out: return ret; } @@ -818,6 +821,9 @@ void nfs_delegation_reap_unclaimed(struct nfs_client *clp) list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) { list_for_each_entry_rcu(delegation, &server->delegations, super_list) { + if (test_bit(NFS_DELEGATION_RETURNING, + &delegation->flags)) + continue; if (test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags) == 0) continue; From c064a0de1bfb07c34a3798822c7e1636eea866e8 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sat, 28 Feb 2015 22:24:48 +0100 Subject: [PATCH 60/95] livepatch: fix RCU usage in klp_find_external_symbol() While one must hold RCU-sched (aka. preempt_disable) for find_symbol() one must equally hold it over the use of the object returned. The moment you release the RCU-sched read lock, the object can be dead and gone. [jkosina@suse.cz: change subject line to be aligned with other patches] Cc: Seth Jennings Cc: Josh Poimboeuf Cc: Masami Hiramatsu Cc: Miroslav Benes Cc: Petr Mladek Cc: Jiri Kosina Cc: "Paul E. McKenney" Cc: Rusty Russell Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Masami Hiramatsu Acked-by: Paul E. McKenney Acked-by: Josh Poimboeuf Signed-off-by: Jiri Kosina --- kernel/livepatch/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index 782172f073c5ed..01ca08804f5115 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -248,11 +248,12 @@ static int klp_find_external_symbol(struct module *pmod, const char *name, /* first, check if it's an exported symbol */ preempt_disable(); sym = find_symbol(name, NULL, NULL, true, true); - preempt_enable(); if (sym) { *addr = sym->value; + preempt_enable(); return 0; } + preempt_enable(); /* otherwise check if it's in another .o within the patch module */ return klp_find_object_symbol(pmod->name, name, addr); From 6d65261a09adaa374c05de807f73a144d783669e Mon Sep 17 00:00:00 2001 From: Tyler Hicks Date: Tue, 24 Feb 2015 19:28:10 -0600 Subject: [PATCH 61/95] eCryptfs: don't pass fs-specific ioctl commands through eCryptfs can't be aware of what to expect when after passing an arbitrary ioctl command through to the lower filesystem. The ioctl command may trigger an action in the lower filesystem that is incompatible with eCryptfs. One specific example is when one attempts to use the Btrfs clone ioctl command when the source file is in the Btrfs filesystem that eCryptfs is mounted on top of and the destination fd is from a new file created in the eCryptfs mount. The ioctl syscall incorrectly returns success because the command is passed down to Btrfs which thinks that it was able to do the clone operation. However, the result is an empty eCryptfs file. This patch allows the trim, {g,s}etflags, and {g,s}etversion ioctl commands through and then copies up the inode metadata from the lower inode to the eCryptfs inode to catch any changes made to the lower inode's metadata. Those five ioctl commands are mostly common across all filesystems but the whitelist may need to be further pruned in the future. https://bugzilla.kernel.org/show_bug.cgi?id=93691 https://launchpad.net/bugs/1305335 Signed-off-by: Tyler Hicks Cc: Rocko Cc: Colin Ian King Cc: stable@vger.kernel.org # v2.6.36+: c43f7b8 eCryptfs: Handle ioctl calls with unlocked and compat functions --- fs/ecryptfs/file.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index b07731e68c0b4d..fd39bad6f1bdf8 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c @@ -303,9 +303,22 @@ ecryptfs_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) struct file *lower_file = ecryptfs_file_to_lower(file); long rc = -ENOTTY; - if (lower_file->f_op->unlocked_ioctl) + if (!lower_file->f_op->unlocked_ioctl) + return rc; + + switch (cmd) { + case FITRIM: + case FS_IOC_GETFLAGS: + case FS_IOC_SETFLAGS: + case FS_IOC_GETVERSION: + case FS_IOC_SETVERSION: rc = lower_file->f_op->unlocked_ioctl(lower_file, cmd, arg); - return rc; + fsstack_copy_attr_all(file_inode(file), file_inode(lower_file)); + + return rc; + default: + return rc; + } } #ifdef CONFIG_COMPAT @@ -315,9 +328,22 @@ ecryptfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) struct file *lower_file = ecryptfs_file_to_lower(file); long rc = -ENOIOCTLCMD; - if (lower_file->f_op->compat_ioctl) + if (!lower_file->f_op->compat_ioctl) + return rc; + + switch (cmd) { + case FITRIM: + case FS_IOC32_GETFLAGS: + case FS_IOC32_SETFLAGS: + case FS_IOC32_GETVERSION: + case FS_IOC32_SETVERSION: rc = lower_file->f_op->compat_ioctl(lower_file, cmd, arg); - return rc; + fsstack_copy_attr_all(file_inode(file), file_inode(lower_file)); + + return rc; + default: + return rc; + } } #endif From 31f3032c1a5504259f6fa8e0c7f8d2d3e2f5db48 Mon Sep 17 00:00:00 2001 From: Vishal Thanki Date: Tue, 3 Mar 2015 18:59:00 +0530 Subject: [PATCH 62/95] ASoC: simple-card: Add a NULL pointer check in asoc_simple_card_dai_link_of Make sure devm_kzalloc() succeeds. Signed-off-by: Vishal Thanki Signed-off-by: Mark Brown --- sound/soc/generic/simple-card.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index f7c6734bd5daee..fb550b5869d21f 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -372,6 +372,11 @@ static int asoc_simple_card_dai_link_of(struct device_node *node, strlen(dai_link->cpu_dai_name) + strlen(dai_link->codec_dai_name) + 2, GFP_KERNEL); + if (!name) { + ret = -ENOMEM; + goto dai_link_of_err; + } + sprintf(name, "%s-%s", dai_link->cpu_dai_name, dai_link->codec_dai_name); dai_link->name = dai_link->stream_name = name; From 874f946376de57c8d6230b30ad71f742883fee3a Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 2 Mar 2015 23:32:08 -0500 Subject: [PATCH 63/95] NFS: Fix a regression in the read() syscall When invalidating the page cache for a regular file, we want to first sync all dirty data to disk and then call invalidate_inode_pages2(). The latter relies on nfs_launder_page() and nfs_release_page() to deal respectively with dirty pages, and unstable written pages. When commit 9590544694bec ("NFS: avoid deadlocks with loop-back mounted NFS filesystems.") changed the behaviour of nfs_release_page(), then it made it possible for invalidate_inode_pages2() to fail with an EBUSY. Unfortunately, that error is then propagated back to read(). Let's therefore work around the problem for now by protecting the call to sync the data and invalidate_inode_pages2() so that they are atomic w.r.t. the addition of new writes. Later on, we can revisit whether or not we still need nfs_launder_page() and nfs_release_page(). Signed-off-by: Trond Myklebust --- fs/nfs/file.c | 4 ++-- fs/nfs/inode.c | 37 ++++++++++++++++++++++++++++++++++--- include/linux/nfs_fs.h | 1 + 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/fs/nfs/file.c b/fs/nfs/file.c index c045c7169fa0f7..41963ffca597f9 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -178,7 +178,7 @@ nfs_file_read(struct kiocb *iocb, struct iov_iter *to) iocb->ki_filp, iov_iter_count(to), (unsigned long) iocb->ki_pos); - result = nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping); + result = nfs_revalidate_mapping_protected(inode, iocb->ki_filp->f_mapping); if (!result) { result = generic_file_read_iter(iocb, to); if (result > 0) @@ -199,7 +199,7 @@ nfs_file_splice_read(struct file *filp, loff_t *ppos, dprintk("NFS: splice_read(%pD2, %lu@%Lu)\n", filp, (unsigned long) count, (unsigned long long) *ppos); - res = nfs_revalidate_mapping(inode, filp->f_mapping); + res = nfs_revalidate_mapping_protected(inode, filp->f_mapping); if (!res) { res = generic_file_splice_read(filp, ppos, pipe, count, flags); if (res > 0) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 5026c44a98e1c1..8edb7d049565a8 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1067,11 +1067,14 @@ static bool nfs_mapping_need_revalidate_inode(struct inode *inode) } /** - * nfs_revalidate_mapping - Revalidate the pagecache + * __nfs_revalidate_mapping - Revalidate the pagecache * @inode - pointer to host inode * @mapping - pointer to mapping + * @may_lock - take inode->i_mutex? */ -int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping) +static int __nfs_revalidate_mapping(struct inode *inode, + struct address_space *mapping, + bool may_lock) { struct nfs_inode *nfsi = NFS_I(inode); unsigned long *bitlock = &nfsi->flags; @@ -1120,7 +1123,12 @@ int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping) nfsi->cache_validity &= ~NFS_INO_INVALID_DATA; spin_unlock(&inode->i_lock); trace_nfs_invalidate_mapping_enter(inode); - ret = nfs_invalidate_mapping(inode, mapping); + if (may_lock) { + mutex_lock(&inode->i_mutex); + ret = nfs_invalidate_mapping(inode, mapping); + mutex_unlock(&inode->i_mutex); + } else + ret = nfs_invalidate_mapping(inode, mapping); trace_nfs_invalidate_mapping_exit(inode, ret); clear_bit_unlock(NFS_INO_INVALIDATING, bitlock); @@ -1130,6 +1138,29 @@ int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping) return ret; } +/** + * nfs_revalidate_mapping - Revalidate the pagecache + * @inode - pointer to host inode + * @mapping - pointer to mapping + */ +int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping) +{ + return __nfs_revalidate_mapping(inode, mapping, false); +} + +/** + * nfs_revalidate_mapping_protected - Revalidate the pagecache + * @inode - pointer to host inode + * @mapping - pointer to mapping + * + * Differs from nfs_revalidate_mapping() in that it grabs the inode->i_mutex + * while invalidating the mapping. + */ +int nfs_revalidate_mapping_protected(struct inode *inode, struct address_space *mapping) +{ + return __nfs_revalidate_mapping(inode, mapping, true); +} + static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr) { struct nfs_inode *nfsi = NFS_I(inode); diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 59b1516b9fd491..b01ccf371fdcaf 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -356,6 +356,7 @@ extern int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode); extern int nfs_revalidate_inode_rcu(struct nfs_server *server, struct inode *inode); extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *); extern int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping); +extern int nfs_revalidate_mapping_protected(struct inode *inode, struct address_space *mapping); extern int nfs_setattr(struct dentry *, struct iattr *); extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr, struct nfs_fattr *); extern void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr, From ef070dcb3989f553f5d84edf555eebc7e204099d Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 3 Mar 2015 00:06:35 -0500 Subject: [PATCH 64/95] NFS: Don't write enable new pages while an invalidation is proceeding nfs_vm_page_mkwrite() should wait until the page cache invalidation is finished. This is the second patch in a 2 patch series to deprecate the NFS client's reliance on nfs_release_page() in the context of nfs_invalidate_mapping(). Signed-off-by: Trond Myklebust --- fs/nfs/file.c | 3 +++ fs/nfs/inode.c | 1 + 2 files changed, 4 insertions(+) diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 41963ffca597f9..e679d24c39d3a5 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -623,6 +623,9 @@ static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) /* make sure the cache has finished storing the page */ nfs_fscache_wait_on_page_write(NFS_I(inode), page); + wait_on_bit_action(&NFS_I(inode)->flags, NFS_INO_INVALIDATING, + nfs_wait_bit_killable, TASK_KILLABLE); + lock_page(page); mapping = page_file_mapping(page); if (mapping != inode->i_mapping) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 8edb7d049565a8..d42dff6d5e983f 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1035,6 +1035,7 @@ static int nfs_invalidate_mapping(struct inode *inode, struct address_space *map if (mapping->nrpages != 0) { if (S_ISREG(inode->i_mode)) { + unmap_mapping_range(mapping, 0, 0, 0); ret = nfs_sync_mapping(mapping); if (ret < 0) return ret; From 48d66b9749e39e0d4cc37d635df3f18906af38a6 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 3 Mar 2015 20:28:59 -0500 Subject: [PATCH 65/95] NFSv4: Fix a race in NFSv4.1 server trunking discovery We do not want to allow a race with another NFS mount to cause nfs41_walk_client_list() to establish a lease on our nfs_client before we're done checking for trunking. Signed-off-by: Trond Myklebust --- fs/nfs/client.c | 2 +- fs/nfs/nfs4client.c | 9 ++++----- fs/nfs/nfs4state.c | 14 ++++++++++++-- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index f9f4845db989e5..19874151e95c99 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -433,7 +433,7 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat static bool nfs_client_init_is_complete(const struct nfs_client *clp) { - return clp->cl_cons_state != NFS_CS_INITING; + return clp->cl_cons_state <= NFS_CS_READY; } int nfs_wait_client_init_complete(const struct nfs_client *clp) diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index 8646af9b11d2e1..86d6214ea022fe 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -621,6 +621,9 @@ int nfs41_walk_client_list(struct nfs_client *new, spin_lock(&nn->nfs_client_lock); list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) { + if (pos == new) + goto found; + if (pos->rpc_ops != new->rpc_ops) continue; @@ -639,10 +642,6 @@ int nfs41_walk_client_list(struct nfs_client *new, prev = pos; status = nfs_wait_client_init_complete(pos); - if (pos->cl_cons_state == NFS_CS_SESSION_INITING) { - nfs4_schedule_lease_recovery(pos); - status = nfs4_wait_clnt_recover(pos); - } spin_lock(&nn->nfs_client_lock); if (status < 0) break; @@ -668,7 +667,7 @@ int nfs41_walk_client_list(struct nfs_client *new, */ if (!nfs4_match_client_owner_id(pos, new)) continue; - +found: atomic_inc(&pos->cl_count); *result = pos; status = 0; diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 5ad908e9ce9c33..d8b43f0e08fc62 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -346,9 +346,19 @@ int nfs41_discover_server_trunking(struct nfs_client *clp, status = nfs4_proc_exchange_id(clp, cred); if (status != NFS4_OK) return status; - set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); - return nfs41_walk_client_list(clp, result, cred); + status = nfs41_walk_client_list(clp, result, cred); + if (status < 0) + return status; + if (clp != *result) + return 0; + + set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); + nfs4_schedule_state_manager(clp); + status = nfs_wait_client_init_complete(clp); + if (status < 0) + nfs_put_client(clp); + return status; } #endif /* CONFIG_NFS_V4_1 */ From e11259f920d8cb3550e0f311c064bdabe1bc3aaf Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 3 Mar 2015 20:35:31 -0500 Subject: [PATCH 66/95] NFSv4.1: Clear the old state by our client id before establishing a new lease If the call to exchange-id returns with the EXCHGID4_FLAG_CONFIRMED_R flag set, then that means our lease was established by a previous mount instance. Ensure that we detect this situation, and that we clear the state held by that mount. Reported-by: Jorge Mora Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 15 +++++++++++---- fs/nfs/nfs4session.h | 1 + fs/nfs/nfs4state.c | 6 +++++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 732526e04cd59b..627f37c4445675 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -6897,9 +6897,13 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred, if (status == 0) { clp->cl_clientid = res.clientid; - clp->cl_exchange_flags = (res.flags & ~EXCHGID4_FLAG_CONFIRMED_R); - if (!(res.flags & EXCHGID4_FLAG_CONFIRMED_R)) + clp->cl_exchange_flags = res.flags; + /* Client ID is not confirmed */ + if (!(res.flags & EXCHGID4_FLAG_CONFIRMED_R)) { + clear_bit(NFS4_SESSION_ESTABLISHED, + &clp->cl_session->session_state); clp->cl_seqid = res.seqid; + } kfree(clp->cl_serverowner); clp->cl_serverowner = res.server_owner; @@ -7231,6 +7235,9 @@ static void nfs4_update_session(struct nfs4_session *session, struct nfs41_create_session_res *res) { nfs4_copy_sessionid(&session->sess_id, &res->sessionid); + /* Mark client id and session as being confirmed */ + session->clp->cl_exchange_flags |= EXCHGID4_FLAG_CONFIRMED_R; + set_bit(NFS4_SESSION_ESTABLISHED, &session->session_state); session->flags = res->flags; memcpy(&session->fc_attrs, &res->fc_attrs, sizeof(session->fc_attrs)); if (res->flags & SESSION4_BACK_CHAN) @@ -7326,8 +7333,8 @@ int nfs4_proc_destroy_session(struct nfs4_session *session, dprintk("--> nfs4_proc_destroy_session\n"); /* session is still being setup */ - if (session->clp->cl_cons_state != NFS_CS_READY) - return status; + if (!test_and_clear_bit(NFS4_SESSION_ESTABLISHED, &session->session_state)) + return 0; status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); trace_nfs4_destroy_session(session->clp, status); diff --git a/fs/nfs/nfs4session.h b/fs/nfs/nfs4session.h index fc46c745589863..e3ea2c5324d68e 100644 --- a/fs/nfs/nfs4session.h +++ b/fs/nfs/nfs4session.h @@ -70,6 +70,7 @@ struct nfs4_session { enum nfs4_session_state { NFS4_SESSION_INITING, + NFS4_SESSION_ESTABLISHED, }; extern int nfs4_setup_slot_table(struct nfs4_slot_table *tbl, diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index d8b43f0e08fc62..f95e3b58bbc304 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -353,7 +353,11 @@ int nfs41_discover_server_trunking(struct nfs_client *clp, if (clp != *result) return 0; - set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); + /* Purge state if the client id was established in a prior instance */ + if (clp->cl_exchange_flags & EXCHGID4_FLAG_CONFIRMED_R) + set_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state); + else + set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); nfs4_schedule_state_manager(clp); status = nfs_wait_client_init_complete(clp); if (status < 0) From 63f1789ec71677dd285d43d6c79ca44808f16945 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Wed, 4 Mar 2015 16:47:11 +0800 Subject: [PATCH 67/95] x86/PCI/ACPI: Ignore resources consumed by host bridge itself When parsing resources for PCI host bridge, we should ignore resources consumed by host bridge itself and only report window resources available to child PCI busses. Fixes: 593669c2ac0f (x86/PCI/ACPI: Use common ACPI resource interfaces ...) Signed-off-by: Jiang Liu Signed-off-by: Rafael J. Wysocki --- arch/x86/pci/acpi.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 6ac273832f2846..e4695985f9de85 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -331,7 +331,7 @@ static void probe_pci_root_info(struct pci_root_info *info, struct list_head *list) { int ret; - struct resource_entry *entry; + struct resource_entry *entry, *tmp; sprintf(info->name, "PCI Bus %04x:%02x", domain, busnum); info->bridge = device; @@ -345,8 +345,13 @@ static void probe_pci_root_info(struct pci_root_info *info, dev_dbg(&device->dev, "no IO and memory resources present in _CRS\n"); else - resource_list_for_each_entry(entry, list) - entry->res->name = info->name; + resource_list_for_each_entry_safe(entry, tmp, list) { + if ((entry->res->flags & IORESOURCE_WINDOW) == 0 || + (entry->res->flags & IORESOURCE_DISABLED)) + resource_list_destroy_entry(entry); + else + entry->res->name = info->name; + } } struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) From aa714d286f2ea5fae3ca8c75acd03d8694fb657e Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Wed, 4 Mar 2015 16:47:12 +0800 Subject: [PATCH 68/95] x86/PCI/ACPI: Relax ACPI resource descriptor checks to work around BIOS bugs Some BIOSes report incorrect length for ACPI address space descriptors, so relax the checks to avoid regressions. This issue has appeared several times as: 3162b6f0c5e1 ("PNPACPI: truncate _CRS windows with _LEN > _MAX - _MIN + 1") d558b483d5a7 ("x86/PCI: truncate _CRS windows with _LEN > _MAX - _MIN + 1") f238b414a74a ("PNPACPI: compute Address Space length rather than using _LEN") 48728e077480 ("x86/PCI: compute Address Space length rather than using _LEN") Please refer to https://bugzilla.kernel.org/show_bug.cgi?id=94221 for more details and example malformed ACPI resource descriptors. Link: https://bugzilla.kernel.org/show_bug.cgi?id=94221 Fixes: 593669c2ac0f (x86/PCI/ACPI: Use common ACPI resource interfaces ...) Signed-off-by: Jiang Liu Tested-by: Dave Airlie Tested-by: Prakash Punnoor Signed-off-by: Rafael J. Wysocki --- drivers/acpi/resource.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index c723668e3e277d..5589a6e2a02346 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -42,8 +42,10 @@ static bool acpi_dev_resource_len_valid(u64 start, u64 end, u64 len, bool io) * CHECKME: len might be required to check versus a minimum * length as well. 1 for io is fine, but for memory it does * not make any sense at all. + * Note: some BIOSes report incorrect length for ACPI address space + * descriptor, so remove check of 'reslen == len' to avoid regression. */ - if (len && reslen && reslen == len && start <= end) + if (len && reslen && start <= end) return true; pr_debug("ACPI: invalid or unassigned resource %s [%016llx - %016llx] length [%016llx]\n", From 5877b4f4677b66f92b5ed94491d69680d6eac4dc Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 4 Mar 2015 12:56:20 +0100 Subject: [PATCH 69/95] cpufreq: ppc: Add missing #include If CONFIG_SMP=n, does not include , causing: drivers/cpufreq/ppc-corenet-cpufreq.c: In function 'corenet_cpufreq_cpu_init': drivers/cpufreq/ppc-corenet-cpufreq.c:173:3: error: implicit declaration of function 'get_hard_smp_processor_id' [-Werror=implicit-function-declaration] Signed-off-by: Geert Uytterhoeven Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/ppc-corenet-cpufreq.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c index bee5df7794d33d..7cb4b766cf948d 100644 --- a/drivers/cpufreq/ppc-corenet-cpufreq.c +++ b/drivers/cpufreq/ppc-corenet-cpufreq.c @@ -22,6 +22,8 @@ #include #include +#include /* for get_hard_smp_processor_id() in UP configs */ + /** * struct cpu_data - per CPU data struct * @parent: the parent node of cpu clock From 66a5ca4b2c62c44692316f27b0fa39a037cce295 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 2 Mar 2015 11:24:28 -0800 Subject: [PATCH 70/95] PM / Domains: cleanup: rename gpd -> genpd in debugfs interface To keep consisitency with the rest of the file, use 'genpd' as the name of the 'struct generic_pm_domain' pointer instead of 'gpd'. This is just a rename, no functional changes. Signed-off-by: Kevin Hilman Acked-by: Pavel Machek Reviewed-by: Ulf Hansson Signed-off-by: Rafael J. Wysocki --- drivers/base/power/domain.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index ba4abbe4693c3e..45937f88e77c88 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -2242,7 +2242,7 @@ static void rtpm_status_str(struct seq_file *s, struct device *dev) } static int pm_genpd_summary_one(struct seq_file *s, - struct generic_pm_domain *gpd) + struct generic_pm_domain *genpd) { static const char * const status_lookup[] = { [GPD_STATE_ACTIVE] = "on", @@ -2256,26 +2256,26 @@ static int pm_genpd_summary_one(struct seq_file *s, struct gpd_link *link; int ret; - ret = mutex_lock_interruptible(&gpd->lock); + ret = mutex_lock_interruptible(&genpd->lock); if (ret) return -ERESTARTSYS; - if (WARN_ON(gpd->status >= ARRAY_SIZE(status_lookup))) + if (WARN_ON(genpd->status >= ARRAY_SIZE(status_lookup))) goto exit; - seq_printf(s, "%-30s %-15s ", gpd->name, status_lookup[gpd->status]); + seq_printf(s, "%-30s %-15s ", genpd->name, status_lookup[genpd->status]); /* * Modifications on the list require holding locks on both * master and slave, so we are safe. - * Also gpd->name is immutable. + * Also genpd->name is immutable. */ - list_for_each_entry(link, &gpd->master_links, master_node) { + list_for_each_entry(link, &genpd->master_links, master_node) { seq_printf(s, "%s", link->slave->name); - if (!list_is_last(&link->master_node, &gpd->master_links)) + if (!list_is_last(&link->master_node, &genpd->master_links)) seq_puts(s, ", "); } - list_for_each_entry(pm_data, &gpd->dev_list, list_node) { + list_for_each_entry(pm_data, &genpd->dev_list, list_node) { kobj_path = kobject_get_path(&pm_data->dev->kobj, GFP_KERNEL); if (kobj_path == NULL) continue; @@ -2287,14 +2287,14 @@ static int pm_genpd_summary_one(struct seq_file *s, seq_puts(s, "\n"); exit: - mutex_unlock(&gpd->lock); + mutex_unlock(&genpd->lock); return 0; } static int pm_genpd_summary_show(struct seq_file *s, void *data) { - struct generic_pm_domain *gpd; + struct generic_pm_domain *genpd; int ret = 0; seq_puts(s, " domain status slaves\n"); @@ -2305,8 +2305,8 @@ static int pm_genpd_summary_show(struct seq_file *s, void *data) if (ret) return -ERESTARTSYS; - list_for_each_entry(gpd, &gpd_list, gpd_list_node) { - ret = pm_genpd_summary_one(s, gpd); + list_for_each_entry(genpd, &gpd_list, gpd_list_node) { + ret = pm_genpd_summary_one(s, genpd); if (ret) break; } From 6e17cb12881ba8d5e456b89f072dc6b70048af36 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 1 Mar 2015 10:41:37 +0000 Subject: [PATCH 71/95] ACPI / video: Load the module even if ACPI is disabled i915.ko depends upon the acpi/video.ko module and so refuses to load if ACPI is disabled at runtime if for example the BIOS is broken beyond repair. acpi/video provides an optional service for i915.ko and so we should just allow the modules to load, but do no nothing in order to let the machines boot correctly. Reported-by: Bill Augur Signed-off-by: Chris Wilson Cc: Daniel Vetter Cc: Jani Nikula Cc: All applicable Acked-by: Aaron Lu [ rjw: Fixed up the new comment in acpi_video_init() ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/video.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index debd30917010a1..5f98ac69729a85 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -2176,6 +2176,17 @@ EXPORT_SYMBOL(acpi_video_unregister_backlight); static int __init acpi_video_init(void) { + /* + * Let the module load even if ACPI is disabled (e.g. due to + * a broken BIOS) so that i915.ko can still be loaded on such + * old systems without an AcpiOpRegion. + * + * acpi_video_register() will report -ENODEV later as well due + * to acpi_disabled when i915.ko tries to register itself afterwards. + */ + if (acpi_disabled) + return 0; + dmi_check_system(video_dmi_table); if (intel_opregion_present()) From 28d634038d8fed8d25b92f21b728318a79c0be00 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 1 Mar 2015 10:41:38 +0000 Subject: [PATCH 72/95] ACPI / video: Propagate the error code for acpi_video_register Report the actual error code from acpi_bus_register_driver(), it may help future debugging (typically ENODEV as previously reported, but the unusual cases are where it may help most). Signed-off-by: Chris Wilson Acked-by: Aaron Lu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/video.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 5f98ac69729a85..26eb70c8f5184f 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -2110,7 +2110,8 @@ static int __init intel_opregion_present(void) int acpi_video_register(void) { - int result = 0; + int ret; + if (register_count) { /* * if the function of acpi_video_register is already called, @@ -2122,9 +2123,9 @@ int acpi_video_register(void) mutex_init(&video_list_lock); INIT_LIST_HEAD(&video_bus_head); - result = acpi_bus_register_driver(&acpi_video_bus); - if (result < 0) - return -ENODEV; + ret = acpi_bus_register_driver(&acpi_video_bus); + if (ret) + return ret; /* * When the acpi_video_bus is loaded successfully, increase From d51199a83a2cf82a291d19ee852c44caa511427d Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 3 Mar 2015 13:38:14 +0200 Subject: [PATCH 73/95] ASoC: omap-pcm: Correct dma mask DMA_BIT_MASK of 64 is not valid dma address mask for OMAPs, it should be set to 32. The 64 was introduced by commit (in 2009): a152ff24b978 ASoC: OMAP: Make DMA 64 aligned But the dma_mask and coherent_dma_mask can not be used to specify alignment. Fixes: a152ff24b978 (ASoC: OMAP: Make DMA 64 aligned) Reported-by: Grygorii Strashko Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/omap/omap-pcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index f4b05bc23e4bfb..1343ecbf0bd5ee 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -201,7 +201,7 @@ static int omap_pcm_new(struct snd_soc_pcm_runtime *rtd) struct snd_pcm *pcm = rtd->pcm; int ret; - ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(64)); + ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32)); if (ret) return ret; From 17f480342026e54000731acaa69bf32787ce46cb Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 27 Feb 2015 00:07:55 +0100 Subject: [PATCH 74/95] genirq / PM: Add flag for shared NO_SUSPEND interrupt lines It currently is required that all users of NO_SUSPEND interrupt lines pass the IRQF_NO_SUSPEND flag when requesting the IRQ or the WARN_ON_ONCE() in irq_pm_install_action() will trigger. That is done to warn about situations in which unprepared interrupt handlers may be run unnecessarily for suspended devices and may attempt to access those devices by mistake. However, it may cause drivers that have no technical reasons for using IRQF_NO_SUSPEND to set that flag just because they happen to share the interrupt line with something like a timer. Moreover, the generic handling of wakeup interrupts introduced by commit 9ce7a25849e8 (genirq: Simplify wakeup mechanism) only works for IRQs without any NO_SUSPEND users, so the drivers of wakeup devices needing to use shared NO_SUSPEND interrupt lines for signaling system wakeup generally have to detect wakeup in their interrupt handlers. Thus if they happen to share an interrupt line with a NO_SUSPEND user, they also need to request that their interrupt handlers be run after suspend_device_irqs(). In both cases the reason for using IRQF_NO_SUSPEND is not because the driver in question has a genuine need to run its interrupt handler after suspend_device_irqs(), but because it happens to share the line with some other NO_SUSPEND user. Otherwise, the driver would do without IRQF_NO_SUSPEND just fine. To make it possible to specify that condition explicitly, introduce a new IRQ action handler flag for shared IRQs, IRQF_COND_SUSPEND, that, when set, will indicate to the IRQ core that the interrupt user is generally fine with suspending the IRQ, but it also can tolerate handler invocations after suspend_device_irqs() and, in particular, it is capable of detecting system wakeup and triggering it as appropriate from its interrupt handler. That will allow us to work around a problem with a shared timer interrupt line on at91 platforms. Link: http://marc.info/?l=linux-kernel&m=142252777602084&w=2 Link: http://marc.info/?t=142252775300011&r=1&w=2 Link: https://lkml.org/lkml/2014/12/15/552 Reported-by: Boris Brezillon Signed-off-by: Rafael J. Wysocki Acked-by: Peter Zijlstra (Intel) Acked-by: Mark Rutland --- include/linux/interrupt.h | 5 +++++ include/linux/irqdesc.h | 1 + kernel/irq/manage.c | 7 ++++++- kernel/irq/pm.c | 7 ++++++- 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 606771c7cac2bf..2e88580194f023 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -59,6 +59,10 @@ * IRQF_NO_THREAD - Interrupt cannot be threaded * IRQF_EARLY_RESUME - Resume IRQ early during syscore instead of at device * resume time. + * IRQF_COND_SUSPEND - If the IRQ is shared with a NO_SUSPEND user, execute this + * interrupt handler after suspending interrupts. For system + * wakeup devices users need to implement wakeup detection in + * their interrupt handlers. */ #define IRQF_DISABLED 0x00000020 #define IRQF_SHARED 0x00000080 @@ -72,6 +76,7 @@ #define IRQF_FORCE_RESUME 0x00008000 #define IRQF_NO_THREAD 0x00010000 #define IRQF_EARLY_RESUME 0x00020000 +#define IRQF_COND_SUSPEND 0x00040000 #define IRQF_TIMER (__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD) diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h index faf433af425e41..dd1109fb241e42 100644 --- a/include/linux/irqdesc.h +++ b/include/linux/irqdesc.h @@ -78,6 +78,7 @@ struct irq_desc { #ifdef CONFIG_PM_SLEEP unsigned int nr_actions; unsigned int no_suspend_depth; + unsigned int cond_suspend_depth; unsigned int force_resume_depth; #endif #ifdef CONFIG_PROC_FS diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 196a06fbc122fe..886d09e691d5a8 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -1474,8 +1474,13 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler, * otherwise we'll have trouble later trying to figure out * which interrupt is which (messes up the interrupt freeing * logic etc). + * + * Also IRQF_COND_SUSPEND only makes sense for shared interrupts and + * it cannot be set along with IRQF_NO_SUSPEND. */ - if ((irqflags & IRQF_SHARED) && !dev_id) + if (((irqflags & IRQF_SHARED) && !dev_id) || + (!(irqflags & IRQF_SHARED) && (irqflags & IRQF_COND_SUSPEND)) || + ((irqflags & IRQF_NO_SUSPEND) && (irqflags & IRQF_COND_SUSPEND))) return -EINVAL; desc = irq_to_desc(irq); diff --git a/kernel/irq/pm.c b/kernel/irq/pm.c index 3ca53259270455..5204a6d1b9854f 100644 --- a/kernel/irq/pm.c +++ b/kernel/irq/pm.c @@ -43,9 +43,12 @@ void irq_pm_install_action(struct irq_desc *desc, struct irqaction *action) if (action->flags & IRQF_NO_SUSPEND) desc->no_suspend_depth++; + else if (action->flags & IRQF_COND_SUSPEND) + desc->cond_suspend_depth++; WARN_ON_ONCE(desc->no_suspend_depth && - desc->no_suspend_depth != desc->nr_actions); + (desc->no_suspend_depth + + desc->cond_suspend_depth) != desc->nr_actions); } /* @@ -61,6 +64,8 @@ void irq_pm_remove_action(struct irq_desc *desc, struct irqaction *action) if (action->flags & IRQF_NO_SUSPEND) desc->no_suspend_depth--; + else if (action->flags & IRQF_COND_SUSPEND) + desc->cond_suspend_depth--; } static bool suspend_device_irq(struct irq_desc *desc, int irq) From 432ec92b299e4bcbb0d9a116789563d53b2798e1 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 2 Mar 2015 10:18:13 +0100 Subject: [PATCH 75/95] PM / wakeup: export pm_system_wakeup symbol Export pm_system_wakeup function to allow irq handlers to deal with system wakeup. This is needed for shared IRQ lines where one of the handler is registered with IRQF_NO_SUSPEND, while the other ones want to configure it as a wakeup source. In this specific case, irq core does not handle the wakeup process and leave the decision to each irq handler. Signed-off-by: Boris Brezillon Reviewed-by: Alexandre Belloni Acked-by: Nicolas Ferre Acked-by: Mark Rutland Signed-off-by: Rafael J. Wysocki --- drivers/base/power/wakeup.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index c2744b30d5d92e..aab7158d2afea8 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -730,6 +730,7 @@ void pm_system_wakeup(void) pm_abort_suspend = true; freeze_wake(); } +EXPORT_SYMBOL_GPL(pm_system_wakeup); void pm_wakeup_clear(void) { From 603b1a232604dcd19a28eaddf70eee9fbe3edc88 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 2 Mar 2015 10:18:14 +0100 Subject: [PATCH 76/95] rtc: at91sam9: rework wakeup and interrupt handling The IRQ line used by the RTC device is usually shared with the system timer (PIT) on at91 platforms. Since timers are registering their handlers with IRQF_NO_SUSPEND, we should expect being called in suspended state, and properly wake the system up when this is the case. Set IRQF_COND_SUSPEND flag when registering the IRQ handler to inform irq core that it can safely be called while the system is suspended. Signed-off-by: Boris Brezillon Reviewed-by: Alexandre Belloni Acked-by: Nicolas Ferre Acked-by: Mark Rutland Signed-off-by: Rafael J. Wysocki --- drivers/rtc/rtc-at91sam9.c | 73 +++++++++++++++++++++++++++++++------- 1 file changed, 61 insertions(+), 12 deletions(-) diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index 2183fd2750abd9..5ccaee32df7223 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c @@ -23,6 +23,7 @@ #include #include #include +#include #include /* @@ -77,6 +78,9 @@ struct sam9_rtc { unsigned int gpbr_offset; int irq; struct clk *sclk; + bool suspended; + unsigned long events; + spinlock_t lock; }; #define rtt_readl(rtc, field) \ @@ -271,14 +275,9 @@ static int at91_rtc_proc(struct device *dev, struct seq_file *seq) return 0; } -/* - * IRQ handler for the RTC - */ -static irqreturn_t at91_rtc_interrupt(int irq, void *_rtc) +static irqreturn_t at91_rtc_cache_events(struct sam9_rtc *rtc) { - struct sam9_rtc *rtc = _rtc; u32 sr, mr; - unsigned long events = 0; /* Shared interrupt may be for another device. Note: reading * SR clears it, so we must only read it in this irq handler! @@ -290,18 +289,54 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *_rtc) /* alarm status */ if (sr & AT91_RTT_ALMS) - events |= (RTC_AF | RTC_IRQF); + rtc->events |= (RTC_AF | RTC_IRQF); /* timer update/increment */ if (sr & AT91_RTT_RTTINC) - events |= (RTC_UF | RTC_IRQF); + rtc->events |= (RTC_UF | RTC_IRQF); + + return IRQ_HANDLED; +} + +static void at91_rtc_flush_events(struct sam9_rtc *rtc) +{ + if (!rtc->events) + return; - rtc_update_irq(rtc->rtcdev, 1, events); + rtc_update_irq(rtc->rtcdev, 1, rtc->events); + rtc->events = 0; pr_debug("%s: num=%ld, events=0x%02lx\n", __func__, - events >> 8, events & 0x000000FF); + rtc->events >> 8, rtc->events & 0x000000FF); +} - return IRQ_HANDLED; +/* + * IRQ handler for the RTC + */ +static irqreturn_t at91_rtc_interrupt(int irq, void *_rtc) +{ + struct sam9_rtc *rtc = _rtc; + int ret; + + spin_lock(&rtc->lock); + + ret = at91_rtc_cache_events(rtc); + + /* We're called in suspended state */ + if (rtc->suspended) { + /* Mask irqs coming from this peripheral */ + rtt_writel(rtc, MR, + rtt_readl(rtc, MR) & + ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)); + /* Trigger a system wakeup */ + pm_system_wakeup(); + } else { + at91_rtc_flush_events(rtc); + } + + spin_unlock(&rtc->lock); + + return ret; } static const struct rtc_class_ops at91_rtc_ops = { @@ -421,7 +456,8 @@ static int at91_rtc_probe(struct platform_device *pdev) /* register irq handler after we know what name we'll use */ ret = devm_request_irq(&pdev->dev, rtc->irq, at91_rtc_interrupt, - IRQF_SHARED, dev_name(&rtc->rtcdev->dev), rtc); + IRQF_SHARED | IRQF_COND_SUSPEND, + dev_name(&rtc->rtcdev->dev), rtc); if (ret) { dev_dbg(&pdev->dev, "can't share IRQ %d?\n", rtc->irq); return ret; @@ -482,7 +518,12 @@ static int at91_rtc_suspend(struct device *dev) rtc->imr = mr & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); if (rtc->imr) { if (device_may_wakeup(dev) && (mr & AT91_RTT_ALMIEN)) { + unsigned long flags; + enable_irq_wake(rtc->irq); + spin_lock_irqsave(&rtc->lock, flags); + rtc->suspended = true; + spin_unlock_irqrestore(&rtc->lock, flags); /* don't let RTTINC cause wakeups */ if (mr & AT91_RTT_RTTINCIEN) rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN); @@ -499,10 +540,18 @@ static int at91_rtc_resume(struct device *dev) u32 mr; if (rtc->imr) { + unsigned long flags; + if (device_may_wakeup(dev)) disable_irq_wake(rtc->irq); mr = rtt_readl(rtc, MR); rtt_writel(rtc, MR, mr | rtc->imr); + + spin_lock_irqsave(&rtc->lock, flags); + rtc->suspended = false; + at91_rtc_cache_events(rtc); + at91_rtc_flush_events(rtc); + spin_unlock_irqrestore(&rtc->lock, flags); } return 0; From dd1f1f391dd7f3a39a3983df2ca076871111cec9 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 2 Mar 2015 10:18:15 +0100 Subject: [PATCH 77/95] rtc: at91rm9200: rework wakeup and interrupt handling The IRQ line used by the RTC device is usually shared with the system timer (PIT) on at91 platforms. Since timers are registering their handlers with IRQF_NO_SUSPEND, we should expect being called in suspended state, and properly wake the system up when this is the case. Set IRQF_COND_SUSPEND flag when registering the IRQ handler to inform irq core that it can safely be called while the system is suspended. Signed-off-by: Boris Brezillon Reviewed-by: Alexandre Belloni Acked-by: Nicolas Ferre Acked-by: Mark Rutland Signed-off-by: Rafael J. Wysocki --- drivers/rtc/rtc-at91rm9200.c | 62 ++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 14 deletions(-) diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index 70a5d94cc766af..b4f7744f67510b 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "rtc-at91rm9200.h" @@ -54,6 +55,10 @@ static void __iomem *at91_rtc_regs; static int irq; static DEFINE_SPINLOCK(at91_rtc_lock); static u32 at91_rtc_shadow_imr; +static bool suspended; +static DEFINE_SPINLOCK(suspended_lock); +static unsigned long cached_events; +static u32 at91_rtc_imr; static void at91_rtc_write_ier(u32 mask) { @@ -290,7 +295,9 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) struct rtc_device *rtc = platform_get_drvdata(pdev); unsigned int rtsr; unsigned long events = 0; + int ret = IRQ_NONE; + spin_lock(&suspended_lock); rtsr = at91_rtc_read(AT91_RTC_SR) & at91_rtc_read_imr(); if (rtsr) { /* this interrupt is shared! Is it ours? */ if (rtsr & AT91_RTC_ALARM) @@ -304,14 +311,22 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) at91_rtc_write(AT91_RTC_SCCR, rtsr); /* clear status reg */ - rtc_update_irq(rtc, 1, events); + if (!suspended) { + rtc_update_irq(rtc, 1, events); - dev_dbg(&pdev->dev, "%s(): num=%ld, events=0x%02lx\n", __func__, - events >> 8, events & 0x000000FF); + dev_dbg(&pdev->dev, "%s(): num=%ld, events=0x%02lx\n", + __func__, events >> 8, events & 0x000000FF); + } else { + cached_events |= events; + at91_rtc_write_idr(at91_rtc_imr); + pm_system_wakeup(); + } - return IRQ_HANDLED; + ret = IRQ_HANDLED; } - return IRQ_NONE; /* not handled */ + spin_lock(&suspended_lock); + + return ret; } static const struct at91_rtc_config at91rm9200_config = { @@ -401,8 +416,8 @@ static int __init at91_rtc_probe(struct platform_device *pdev) AT91_RTC_CALEV); ret = devm_request_irq(&pdev->dev, irq, at91_rtc_interrupt, - IRQF_SHARED, - "at91_rtc", pdev); + IRQF_SHARED | IRQF_COND_SUSPEND, + "at91_rtc", pdev); if (ret) { dev_err(&pdev->dev, "IRQ %d already in use.\n", irq); return ret; @@ -454,8 +469,6 @@ static void at91_rtc_shutdown(struct platform_device *pdev) /* AT91RM9200 RTC Power management control */ -static u32 at91_rtc_imr; - static int at91_rtc_suspend(struct device *dev) { /* this IRQ is shared with DBGU and other hardware which isn't @@ -464,21 +477,42 @@ static int at91_rtc_suspend(struct device *dev) at91_rtc_imr = at91_rtc_read_imr() & (AT91_RTC_ALARM|AT91_RTC_SECEV); if (at91_rtc_imr) { - if (device_may_wakeup(dev)) + if (device_may_wakeup(dev)) { + unsigned long flags; + enable_irq_wake(irq); - else + + spin_lock_irqsave(&suspended_lock, flags); + suspended = true; + spin_unlock_irqrestore(&suspended_lock, flags); + } else { at91_rtc_write_idr(at91_rtc_imr); + } } return 0; } static int at91_rtc_resume(struct device *dev) { + struct rtc_device *rtc = dev_get_drvdata(dev); + if (at91_rtc_imr) { - if (device_may_wakeup(dev)) + if (device_may_wakeup(dev)) { + unsigned long flags; + + spin_lock_irqsave(&suspended_lock, flags); + + if (cached_events) { + rtc_update_irq(rtc, 1, cached_events); + cached_events = 0; + } + + suspended = false; + spin_unlock_irqrestore(&suspended_lock, flags); + disable_irq_wake(irq); - else - at91_rtc_write_ier(at91_rtc_imr); + } + at91_rtc_write_ier(at91_rtc_imr); } return 0; } From 947f5b108543a6521728466ad5be6e2c4a35a65b Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 2 Mar 2015 10:18:16 +0100 Subject: [PATCH 78/95] clk: at91: implement suspend/resume for the PMC irqchip The irq line used by the PMC block is shared with several peripherals including the init timer which is registering its handler with IRQF_NO_SUSPEND. Implement the appropriate suspend/resume callback for the PMC irqchip, and inform irq core that PMC irq handler can be safely called while the system is suspended by setting IRQF_COND_SUSPEND. Signed-off-by: Boris Brezillon Reviewed-by: Alexandre Belloni Acked-by: Nicolas Ferre Acked-by: Mark Rutland Signed-off-by: Rafael J. Wysocki --- drivers/clk/at91/pmc.c | 20 +++++++++++++++++++- drivers/clk/at91/pmc.h | 1 + 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c index f07c8152e5cc42..3f27d21fb7297e 100644 --- a/drivers/clk/at91/pmc.c +++ b/drivers/clk/at91/pmc.c @@ -89,12 +89,29 @@ static int pmc_irq_set_type(struct irq_data *d, unsigned type) return 0; } +static void pmc_irq_suspend(struct irq_data *d) +{ + struct at91_pmc *pmc = irq_data_get_irq_chip_data(d); + + pmc->imr = pmc_read(pmc, AT91_PMC_IMR); + pmc_write(pmc, AT91_PMC_IDR, pmc->imr); +} + +static void pmc_irq_resume(struct irq_data *d) +{ + struct at91_pmc *pmc = irq_data_get_irq_chip_data(d); + + pmc_write(pmc, AT91_PMC_IER, pmc->imr); +} + static struct irq_chip pmc_irq = { .name = "PMC", .irq_disable = pmc_irq_mask, .irq_mask = pmc_irq_mask, .irq_unmask = pmc_irq_unmask, .irq_set_type = pmc_irq_set_type, + .irq_suspend = pmc_irq_suspend, + .irq_resume = pmc_irq_resume, }; static struct lock_class_key pmc_lock_class; @@ -224,7 +241,8 @@ static struct at91_pmc *__init at91_pmc_init(struct device_node *np, goto out_free_pmc; pmc_write(pmc, AT91_PMC_IDR, 0xffffffff); - if (request_irq(pmc->virq, pmc_irq_handler, IRQF_SHARED, "pmc", pmc)) + if (request_irq(pmc->virq, pmc_irq_handler, + IRQF_SHARED | IRQF_COND_SUSPEND, "pmc", pmc)) goto out_remove_irqdomain; return pmc; diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h index 52d2041fa3f635..69abb08cf14651 100644 --- a/drivers/clk/at91/pmc.h +++ b/drivers/clk/at91/pmc.h @@ -33,6 +33,7 @@ struct at91_pmc { spinlock_t lock; const struct at91_pmc_caps *caps; struct irq_domain *irqdomain; + u32 imr; }; static inline void pmc_lock(struct at91_pmc *pmc) From 0164bf0239777811bdc3e01f45501174dc6db19d Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Wed, 4 Mar 2015 17:34:32 -0500 Subject: [PATCH 79/95] locks: fix fasync_struct memory leak in lease upgrade/downgrade handling Commit 8634b51f6ca2 (locks: convert lease handling to file_lock_context) introduced a regression in the handling of lease upgrade/downgrades. In the event that we already have a lease on a file and are going to either upgrade or downgrade it, we skip doing any list insertion or deletion and simply re-call lm_setup on the existing lease. As of commit 8634b51f6ca2 however, we end up calling lm_setup on the lease that was passed in, instead of on the existing lease. This causes us to leak the fasync_struct that was allocated in the event that there was not already an existing one (as it always appeared that there wasn't one). Fixes: 8634b51f6ca2 (locks: convert lease handling to file_lock_context) Reported-and-Tested-by: Daniel Wagner Signed-off-by: Jeff Layton --- fs/locks.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/locks.c b/fs/locks.c index 365c82e1b3a9a6..f1bad681fc1ca3 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1665,7 +1665,8 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **pr } if (my_fl != NULL) { - error = lease->fl_lmops->lm_change(my_fl, arg, &dispose); + lease = my_fl; + error = lease->fl_lmops->lm_change(lease, arg, &dispose); if (error) goto out; goto out_setup; From 956421fbb74c3a6261903f3836c0740187cf038b Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Thu, 5 Mar 2015 01:09:44 +0100 Subject: [PATCH 80/95] x86/asm/entry/64: Remove a bogus 'ret_from_fork' optimization 'ret_from_fork' checks TIF_IA32 to determine whether 'pt_regs' and the related state make sense for 'ret_from_sys_call'. This is entirely the wrong check. TS_COMPAT would make a little more sense, but there's really no point in keeping this optimization at all. This fixes a return to the wrong user CS if we came from int 0x80 in a 64-bit task. Signed-off-by: Andy Lutomirski Cc: Borislav Petkov Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Thomas Gleixner Cc: Link: http://lkml.kernel.org/r/4710be56d76ef994ddf59087aad98c000fbab9a4.1424989793.git.luto@amacapital.net [ Backported from tip:x86/asm. ] Signed-off-by: Ingo Molnar --- arch/x86/kernel/entry_64.S | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 10074ad9ebf85e..1d74d161687c9f 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -269,11 +269,14 @@ ENTRY(ret_from_fork) testl $3, CS-ARGOFFSET(%rsp) # from kernel_thread? jz 1f - testl $_TIF_IA32, TI_flags(%rcx) # 32-bit compat task needs IRET - jnz int_ret_from_sys_call - - RESTORE_TOP_OF_STACK %rdi, -ARGOFFSET - jmp ret_from_sys_call # go to the SYSRET fastpath + /* + * By the time we get here, we have no idea whether our pt_regs, + * ti flags, and ti status came from the 64-bit SYSCALL fast path, + * the slow path, or one of the ia32entry paths. + * Use int_ret_from_sys_call to return, since it can safely handle + * all of the above. + */ + jmp int_ret_from_sys_call 1: subq $REST_SKIP, %rsp # leave space for volatiles From d5bce867778c8cb5ff655efe47fecb4b31f30406 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Mon, 2 Mar 2015 13:12:07 -0800 Subject: [PATCH 81/95] Thermal/int340x: Fix memleak for aux trip When thermal zone device register fails or on module exit, the memory for aux_trip is not freed. This change fixes this issue. Signed-off-by: Srinivas Pandruvada Signed-off-by: Eduardo Valentin --- drivers/thermal/int340x_thermal/int340x_thermal_zone.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/thermal/int340x_thermal/int340x_thermal_zone.c b/drivers/thermal/int340x_thermal/int340x_thermal_zone.c index f88b0887702568..1e25133d35e2cb 100644 --- a/drivers/thermal/int340x_thermal/int340x_thermal_zone.c +++ b/drivers/thermal/int340x_thermal/int340x_thermal_zone.c @@ -208,7 +208,7 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev, trip_cnt, GFP_KERNEL); if (!int34x_thermal_zone->aux_trips) { ret = -ENOMEM; - goto free_mem; + goto err_trip_alloc; } trip_mask = BIT(trip_cnt) - 1; int34x_thermal_zone->aux_trip_nr = trip_cnt; @@ -248,14 +248,15 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev, 0, 0); if (IS_ERR(int34x_thermal_zone->zone)) { ret = PTR_ERR(int34x_thermal_zone->zone); - goto free_lpat; + goto err_thermal_zone; } return int34x_thermal_zone; -free_lpat: +err_thermal_zone: acpi_lpat_free_conversion_table(int34x_thermal_zone->lpat_table); -free_mem: + kfree(int34x_thermal_zone->aux_trips); +err_trip_alloc: kfree(int34x_thermal_zone); return ERR_PTR(ret); } @@ -266,6 +267,7 @@ void int340x_thermal_zone_remove(struct int34x_thermal_zone { thermal_zone_device_unregister(int34x_thermal_zone->zone); acpi_lpat_free_conversion_table(int34x_thermal_zone->lpat_table); + kfree(int34x_thermal_zone->aux_trips); kfree(int34x_thermal_zone); } EXPORT_SYMBOL_GPL(int340x_thermal_zone_remove); From 2dc10f8963e6a03a1a75deafe1d1984bafab08dd Mon Sep 17 00:00:00 2001 From: Matthias Kaehlcke Date: Fri, 20 Feb 2015 18:10:08 -0800 Subject: [PATCH 82/95] thermal: Make sysfs attributes of cooling devices default attributes Default attributes are created when the device is registered. Attributes created after device registration can lead to race conditions, where user space (e.g. udev) sees the device but not the attributes. Signed-off-by: Matthias Kaehlcke Signed-off-by: Eduardo Valentin --- drivers/thermal/thermal_core.c | 37 ++++++++++++++++------------------ 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 48491d1a81d650..174d3bcf8bd7a1 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -899,6 +899,22 @@ thermal_cooling_device_trip_point_show(struct device *dev, return sprintf(buf, "%d\n", instance->trip); } +static struct attribute *cooling_device_attrs[] = { + &dev_attr_cdev_type.attr, + &dev_attr_max_state.attr, + &dev_attr_cur_state.attr, + NULL, +}; + +static const struct attribute_group cooling_device_attr_group = { + .attrs = cooling_device_attrs, +}; + +static const struct attribute_group *cooling_device_attr_groups[] = { + &cooling_device_attr_group, + NULL, +}; + /* Device management */ /** @@ -1130,6 +1146,7 @@ __thermal_cooling_device_register(struct device_node *np, cdev->ops = ops; cdev->updated = false; cdev->device.class = &thermal_class; + cdev->device.groups = cooling_device_attr_groups; cdev->devdata = devdata; dev_set_name(&cdev->device, "cooling_device%d", cdev->id); result = device_register(&cdev->device); @@ -1139,21 +1156,6 @@ __thermal_cooling_device_register(struct device_node *np, return ERR_PTR(result); } - /* sys I/F */ - if (type) { - result = device_create_file(&cdev->device, &dev_attr_cdev_type); - if (result) - goto unregister; - } - - result = device_create_file(&cdev->device, &dev_attr_max_state); - if (result) - goto unregister; - - result = device_create_file(&cdev->device, &dev_attr_cur_state); - if (result) - goto unregister; - /* Add 'this' new cdev to the global cdev list */ mutex_lock(&thermal_list_lock); list_add(&cdev->node, &thermal_cdev_list); @@ -1163,11 +1165,6 @@ __thermal_cooling_device_register(struct device_node *np, bind_cdev(cdev); return cdev; - -unregister: - release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id); - device_unregister(&cdev->device); - return ERR_PTR(result); } /** From 096a020a9ef5c947577d3b57199bfc9b7e686b49 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 5 Mar 2015 14:26:37 +0300 Subject: [PATCH 83/95] ALSA: msnd: add some missing curly braces There were some curly braces intended here. Signed-off-by: Dan Carpenter Signed-off-by: Takashi Iwai --- sound/isa/msnd/msnd_pinnacle_mixer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/isa/msnd/msnd_pinnacle_mixer.c b/sound/isa/msnd/msnd_pinnacle_mixer.c index 17e49a071af449..b408540798c164 100644 --- a/sound/isa/msnd/msnd_pinnacle_mixer.c +++ b/sound/isa/msnd/msnd_pinnacle_mixer.c @@ -306,11 +306,12 @@ int snd_msndmix_new(struct snd_card *card) spin_lock_init(&chip->mixer_lock); strcpy(card->mixername, "MSND Pinnacle Mixer"); - for (idx = 0; idx < ARRAY_SIZE(snd_msnd_controls); idx++) + for (idx = 0; idx < ARRAY_SIZE(snd_msnd_controls); idx++) { err = snd_ctl_add(card, snd_ctl_new1(snd_msnd_controls + idx, chip)); if (err < 0) return err; + } return 0; } From f44f07cf3910f84b15b2a78c4933d5946bf409cf Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 5 Mar 2015 13:03:28 +0100 Subject: [PATCH 84/95] ALSA: line6: Clamp values correctly The usages of clamp() macro in sound/usb/line6/playback.c are just wrong, the low and high values are swapped. Reported-by: Dan Carpenter Signed-off-by: Takashi Iwai --- sound/usb/line6/playback.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/usb/line6/playback.c b/sound/usb/line6/playback.c index 05dee690f48761..97ed593f6010f6 100644 --- a/sound/usb/line6/playback.c +++ b/sound/usb/line6/playback.c @@ -39,7 +39,7 @@ static void change_volume(struct urb *urb_out, int volume[], for (; p < buf_end; ++p) { short pv = le16_to_cpu(*p); int val = (pv * volume[chn & 1]) >> 8; - pv = clamp(val, 0x7fff, -0x8000); + pv = clamp(val, -0x8000, 0x7fff); *p = cpu_to_le16(pv); ++chn; } @@ -54,7 +54,7 @@ static void change_volume(struct urb *urb_out, int volume[], val = p[0] + (p[1] << 8) + ((signed char)p[2] << 16); val = (val * volume[chn & 1]) >> 8; - val = clamp(val, 0x7fffff, -0x800000); + val = clamp(val, -0x800000, 0x7fffff); p[0] = val; p[1] = val >> 8; p[2] = val >> 16; @@ -126,7 +126,7 @@ static void add_monitor_signal(struct urb *urb_out, unsigned char *signal, short pov = le16_to_cpu(*po); short piv = le16_to_cpu(*pi); int val = pov + ((piv * volume) >> 8); - pov = clamp(val, 0x7fff, -0x8000); + pov = clamp(val, -0x8000, 0x7fff); *po = cpu_to_le16(pov); } } From 9ab6eb51ef4ad63cb71533d3a4dfb09ea8f69b4c Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 5 Mar 2015 17:24:04 +0200 Subject: [PATCH 85/95] x86/intel/quark: Select COMMON_CLK The commit 8bbc2a135b63 ("x86/intel/quark: Add Intel Quark platform support") introduced a minimal support of Intel Quark SoC. That allows to use core parts of the SoC. However, the SPI, I2C, and GPIO drivers can't be selected by kernel configuration because they depend on COMMON_CLK. The patch adds a COMMON_CLK selection to the platfrom definition to allow user choose the drivers. Signed-off-by: Andy Shevchenko Acked-by: Ong, Boon Leong Cc: Bryan O'Donoghue Cc: Darren Hart Fixes: 8bbc2a135b63 ("x86/intel/quark: Add Intel Quark platform support") Link: http://lkml.kernel.org/r/1425569044-2867-1-git-send-email-andriy.shevchenko@linux.intel.com Signed-off-by: Ingo Molnar --- arch/x86/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index c2fb8a87dccb29..b7d31ca5518744 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -499,6 +499,7 @@ config X86_INTEL_QUARK depends on X86_IO_APIC select IOSF_MBI select INTEL_IMR + select COMMON_CLK ---help--- Select to include support for Quark X1000 SoC. Say Y here if you have a Quark based system such as the Arduino From 06c8173eb92bbfc03a0fe8bb64315857d0badd06 Mon Sep 17 00:00:00 2001 From: Quentin Casasnovas Date: Thu, 5 Mar 2015 13:19:22 +0100 Subject: [PATCH 86/95] x86/fpu/xsaves: Fix improper uses of __ex_table Commit: f31a9f7c7169 ("x86/xsaves: Use xsaves/xrstors to save and restore xsave area") introduced alternative instructions for XSAVES/XRSTORS and commit: adb9d526e982 ("x86/xsaves: Add xsaves and xrstors support for booting time") added support for the XSAVES/XRSTORS instructions at boot time. Unfortunately both failed to properly protect them against faulting: The 'xstate_fault' macro will use the closest label named '1' backward and that ends up in the .altinstr_replacement section rather than in .text. This means that the kernel will never find in the __ex_table the .text address where this instruction might fault, leading to serious problems if userspace manages to trigger the fault. Signed-off-by: Quentin Casasnovas Signed-off-by: Jamie Iles [ Improved the changelog, fixed some whitespace noise. ] Acked-by: Borislav Petkov Acked-by: Linus Torvalds Cc: Cc: Allan Xavier Cc: H. Peter Anvin Cc: Thomas Gleixner Fixes: adb9d526e982 ("x86/xsaves: Add xsaves and xrstors support for booting time") Fixes: f31a9f7c7169 ("x86/xsaves: Use xsaves/xrstors to save and restore xsave area") Signed-off-by: Ingo Molnar --- arch/x86/include/asm/xsave.h | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/arch/x86/include/asm/xsave.h b/arch/x86/include/asm/xsave.h index 5fa9770035dc93..c9a6d68b8d623b 100644 --- a/arch/x86/include/asm/xsave.h +++ b/arch/x86/include/asm/xsave.h @@ -82,18 +82,15 @@ static inline int xsave_state_booting(struct xsave_struct *fx, u64 mask) if (boot_cpu_has(X86_FEATURE_XSAVES)) asm volatile("1:"XSAVES"\n\t" "2:\n\t" - : : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) + xstate_fault + : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) : "memory"); else asm volatile("1:"XSAVE"\n\t" "2:\n\t" - : : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) + xstate_fault + : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) : "memory"); - - asm volatile(xstate_fault - : "0" (0) - : "memory"); - return err; } @@ -112,18 +109,15 @@ static inline int xrstor_state_booting(struct xsave_struct *fx, u64 mask) if (boot_cpu_has(X86_FEATURE_XSAVES)) asm volatile("1:"XRSTORS"\n\t" "2:\n\t" - : : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) + xstate_fault + : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) : "memory"); else asm volatile("1:"XRSTOR"\n\t" "2:\n\t" - : : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) + xstate_fault + : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) : "memory"); - - asm volatile(xstate_fault - : "0" (0) - : "memory"); - return err; } @@ -149,9 +143,9 @@ static inline int xsave_state(struct xsave_struct *fx, u64 mask) */ alternative_input_2( "1:"XSAVE, - "1:"XSAVEOPT, + XSAVEOPT, X86_FEATURE_XSAVEOPT, - "1:"XSAVES, + XSAVES, X86_FEATURE_XSAVES, [fx] "D" (fx), "a" (lmask), "d" (hmask) : "memory"); @@ -178,7 +172,7 @@ static inline int xrstor_state(struct xsave_struct *fx, u64 mask) */ alternative_input( "1: " XRSTOR, - "1: " XRSTORS, + XRSTORS, X86_FEATURE_XSAVES, "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) : "memory"); From ef2b22ac540c018bd574d1846ab95b9bfcf38702 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 2 Mar 2015 22:26:55 +0100 Subject: [PATCH 87/95] cpuidle / sleep: Use broadcast timer for states that stop local timer Commit 381063133246 (PM / sleep: Re-implement suspend-to-idle handling) overlooked the fact that entering some sufficiently deep idle states by CPUs may cause their local timers to stop and in those cases it is necessary to switch over to a broadcast timer prior to entering the idle state. If the cpuidle driver in use does not provide the new ->enter_freeze callback for any of the idle states, that problem affects suspend-to-idle too, but it is not taken into account after the changes made by commit 381063133246. Fix that by changing the definition of cpuidle_enter_freeze() and re-arranging of the code in cpuidle_idle_call(), so the former does not call cpuidle_enter() any more and the fallback case is handled by cpuidle_idle_call() directly. Fixes: 381063133246 (PM / sleep: Re-implement suspend-to-idle handling) Reported-and-tested-by: Lorenzo Pieralisi Signed-off-by: Rafael J. Wysocki Acked-by: Peter Zijlstra (Intel) --- drivers/cpuidle/cpuidle.c | 62 ++++++++++++++------------------------- include/linux/cpuidle.h | 17 +++++++++-- kernel/sched/idle.c | 30 +++++++++++++------ 3 files changed, 58 insertions(+), 51 deletions(-) diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 8b3e132b6a0139..080bd2dbde4ba5 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -44,8 +44,8 @@ void disable_cpuidle(void) off = 1; } -static bool cpuidle_not_available(struct cpuidle_driver *drv, - struct cpuidle_device *dev) +bool cpuidle_not_available(struct cpuidle_driver *drv, + struct cpuidle_device *dev) { return off || !initialized || !drv || !dev || !dev->enabled; } @@ -72,14 +72,8 @@ int cpuidle_play_dead(void) return -ENODEV; } -/** - * cpuidle_find_deepest_state - Find deepest state meeting specific conditions. - * @drv: cpuidle driver for the given CPU. - * @dev: cpuidle device for the given CPU. - * @freeze: Whether or not the state should be suitable for suspend-to-idle. - */ -static int cpuidle_find_deepest_state(struct cpuidle_driver *drv, - struct cpuidle_device *dev, bool freeze) +static int find_deepest_state(struct cpuidle_driver *drv, + struct cpuidle_device *dev, bool freeze) { unsigned int latency_req = 0; int i, ret = freeze ? -1 : CPUIDLE_DRIVER_STATE_START - 1; @@ -98,6 +92,17 @@ static int cpuidle_find_deepest_state(struct cpuidle_driver *drv, return ret; } +/** + * cpuidle_find_deepest_state - Find the deepest available idle state. + * @drv: cpuidle driver for the given CPU. + * @dev: cpuidle device for the given CPU. + */ +int cpuidle_find_deepest_state(struct cpuidle_driver *drv, + struct cpuidle_device *dev) +{ + return find_deepest_state(drv, dev, false); +} + static void enter_freeze_proper(struct cpuidle_driver *drv, struct cpuidle_device *dev, int index) { @@ -119,46 +124,26 @@ static void enter_freeze_proper(struct cpuidle_driver *drv, /** * cpuidle_enter_freeze - Enter an idle state suitable for suspend-to-idle. + * @drv: cpuidle driver for the given CPU. + * @dev: cpuidle device for the given CPU. * * If there are states with the ->enter_freeze callback, find the deepest of - * them and enter it with frozen tick. Otherwise, find the deepest state - * available and enter it normally. - * - * Returns with enabled interrupts. + * them and enter it with frozen tick. */ -void cpuidle_enter_freeze(void) +int cpuidle_enter_freeze(struct cpuidle_driver *drv, struct cpuidle_device *dev) { - struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); - struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); int index; - if (cpuidle_not_available(drv, dev)) - goto fallback; - /* * Find the deepest state with ->enter_freeze present, which guarantees * that interrupts won't be enabled when it exits and allows the tick to * be frozen safely. */ - index = cpuidle_find_deepest_state(drv, dev, true); - if (index >= 0) { + index = find_deepest_state(drv, dev, true); + if (index >= 0) enter_freeze_proper(drv, dev, index); - local_irq_enable(); - return; - } - /* - * It is not safe to freeze the tick, find the deepest state available - * at all and try to enter it normally. - */ - index = cpuidle_find_deepest_state(drv, dev, false); - if (index >= 0) { - cpuidle_enter(drv, dev, index); - return; - } - - fallback: - arch_cpu_idle(); + return index; } /** @@ -217,9 +202,6 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, */ int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) { - if (cpuidle_not_available(drv, dev)) - return -ENODEV; - return cpuidle_curr_governor->select(drv, dev); } diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index f551a9299ac987..306178d7309f19 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h @@ -126,6 +126,8 @@ struct cpuidle_driver { #ifdef CONFIG_CPU_IDLE extern void disable_cpuidle(void); +extern bool cpuidle_not_available(struct cpuidle_driver *drv, + struct cpuidle_device *dev); extern int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev); @@ -150,11 +152,17 @@ extern void cpuidle_resume(void); extern int cpuidle_enable_device(struct cpuidle_device *dev); extern void cpuidle_disable_device(struct cpuidle_device *dev); extern int cpuidle_play_dead(void); -extern void cpuidle_enter_freeze(void); +extern int cpuidle_find_deepest_state(struct cpuidle_driver *drv, + struct cpuidle_device *dev); +extern int cpuidle_enter_freeze(struct cpuidle_driver *drv, + struct cpuidle_device *dev); extern struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev); #else static inline void disable_cpuidle(void) { } +static inline bool cpuidle_not_available(struct cpuidle_driver *drv, + struct cpuidle_device *dev) +{return true; } static inline int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) {return -ENODEV; } @@ -183,7 +191,12 @@ static inline int cpuidle_enable_device(struct cpuidle_device *dev) {return -ENODEV; } static inline void cpuidle_disable_device(struct cpuidle_device *dev) { } static inline int cpuidle_play_dead(void) {return -ENODEV; } -static inline void cpuidle_enter_freeze(void) { } +static inline int cpuidle_find_deepest_state(struct cpuidle_driver *drv, + struct cpuidle_device *dev) +{return -ENODEV; } +static inline int cpuidle_enter_freeze(struct cpuidle_driver *drv, + struct cpuidle_device *dev) +{return -ENODEV; } static inline struct cpuidle_driver *cpuidle_get_cpu_driver( struct cpuidle_device *dev) {return NULL; } #endif diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c index 84b93b68482a8c..80014a17834214 100644 --- a/kernel/sched/idle.c +++ b/kernel/sched/idle.c @@ -82,6 +82,7 @@ static void cpuidle_idle_call(void) struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); int next_state, entered_state; unsigned int broadcast; + bool reflect; /* * Check if the idle task must be rescheduled. If it is the @@ -105,6 +106,9 @@ static void cpuidle_idle_call(void) */ rcu_idle_enter(); + if (cpuidle_not_available(drv, dev)) + goto use_default; + /* * Suspend-to-idle ("freeze") is a system state in which all user space * has been frozen, all I/O devices have been suspended and the only @@ -115,15 +119,22 @@ static void cpuidle_idle_call(void) * until a proper wakeup interrupt happens. */ if (idle_should_freeze()) { - cpuidle_enter_freeze(); - goto exit_idle; - } + entered_state = cpuidle_enter_freeze(drv, dev); + if (entered_state >= 0) { + local_irq_enable(); + goto exit_idle; + } - /* - * Ask the cpuidle framework to choose a convenient idle state. - * Fall back to the default arch idle method on errors. - */ - next_state = cpuidle_select(drv, dev); + reflect = false; + next_state = cpuidle_find_deepest_state(drv, dev); + } else { + reflect = true; + /* + * Ask the cpuidle framework to choose a convenient idle state. + */ + next_state = cpuidle_select(drv, dev); + } + /* Fall back to the default arch idle method on errors. */ if (next_state < 0) goto use_default; @@ -170,7 +181,8 @@ static void cpuidle_idle_call(void) /* * Give the governor an opportunity to reflect on the outcome */ - cpuidle_reflect(dev, entered_state); + if (reflect) + cpuidle_reflect(dev, entered_state); exit_idle: __current_set_polling(); From d677772e1358924bf487cd833bdc4d50f3f6f64d Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 2 Mar 2015 10:18:17 +0100 Subject: [PATCH 88/95] watchdog: at91sam9: request the irq with IRQF_NO_SUSPEND The watchdog interrupt (only used when activating software watchdog) shouldn't be suspended when entering suspend mode, because it is shared with a timer device (which request the line with IRQF_NO_SUSPEND) and once the watchdog "Mode Register" has been written, it cannot be changed (which means we cannot disable the watchdog interrupt when entering suspend). Signed-off-by: Boris Brezillon Reviewed-by: Alexandre Belloni Acked-by: Guenter Roeck Acked-by: Nicolas Ferre Signed-off-by: Rafael J. Wysocki --- drivers/watchdog/at91sam9_wdt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c index 6df940528fd21b..1443b3c391de49 100644 --- a/drivers/watchdog/at91sam9_wdt.c +++ b/drivers/watchdog/at91sam9_wdt.c @@ -208,7 +208,8 @@ static int at91_wdt_init(struct platform_device *pdev, struct at91wdt *wdt) if ((tmp & AT91_WDT_WDFIEN) && wdt->irq) { err = request_irq(wdt->irq, wdt_interrupt, - IRQF_SHARED | IRQF_IRQPOLL, + IRQF_SHARED | IRQF_IRQPOLL | + IRQF_NO_SUSPEND, pdev->name, wdt); if (err) return err; From 2c7af5ba65cfb0145ad8e11f856035c10ba0d22c Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 2 Mar 2015 10:18:18 +0100 Subject: [PATCH 89/95] tty: serial: atmel: rework interrupt and wakeup handling The IRQ line connected to the DBGU UART is often shared with a timer device which request the IRQ with IRQF_NO_SUSPEND. Since the UART driver is correctly disabling IRQs when entering suspend we can safely request the IRQ with IRQF_COND_SUSPEND so that irq core will not complain about mixing IRQF_NO_SUSPEND and !IRQF_NO_SUSPEND. Rework the interrupt handler to wake the system up when an interrupt happens on the DEBUG_UART while the system is suspended. Signed-off-by: Boris Brezillon Reviewed-by: Alexandre Belloni Acked-by: Nicolas Ferre Acked-by: Mark Rutland Signed-off-by: Rafael J. Wysocki --- drivers/tty/serial/atmel_serial.c | 49 ++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 846552bff67d6f..4e959c43f6804d 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -173,6 +174,12 @@ struct atmel_uart_port { bool ms_irq_enabled; bool is_usart; /* usart or uart */ struct timer_list uart_timer; /* uart timer */ + + bool suspended; + unsigned int pending; + unsigned int pending_status; + spinlock_t lock_suspended; + int (*prepare_rx)(struct uart_port *port); int (*prepare_tx)(struct uart_port *port); void (*schedule_rx)(struct uart_port *port); @@ -1179,12 +1186,15 @@ static irqreturn_t atmel_interrupt(int irq, void *dev_id) { struct uart_port *port = dev_id; struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); - unsigned int status, pending, pass_counter = 0; + unsigned int status, pending, mask, pass_counter = 0; bool gpio_handled = false; + spin_lock(&atmel_port->lock_suspended); + do { status = atmel_get_lines_status(port); - pending = status & UART_GET_IMR(port); + mask = UART_GET_IMR(port); + pending = status & mask; if (!gpio_handled) { /* * Dealing with GPIO interrupt @@ -1206,11 +1216,21 @@ static irqreturn_t atmel_interrupt(int irq, void *dev_id) if (!pending) break; + if (atmel_port->suspended) { + atmel_port->pending |= pending; + atmel_port->pending_status = status; + UART_PUT_IDR(port, mask); + pm_system_wakeup(); + break; + } + atmel_handle_receive(port, pending); atmel_handle_status(port, pending, status); atmel_handle_transmit(port, pending); } while (pass_counter++ < ATMEL_ISR_PASS_LIMIT); + spin_unlock(&atmel_port->lock_suspended); + return pass_counter ? IRQ_HANDLED : IRQ_NONE; } @@ -1742,7 +1762,8 @@ static int atmel_startup(struct uart_port *port) /* * Allocate the IRQ */ - retval = request_irq(port->irq, atmel_interrupt, IRQF_SHARED, + retval = request_irq(port->irq, atmel_interrupt, + IRQF_SHARED | IRQF_COND_SUSPEND, tty ? tty->name : "atmel_serial", port); if (retval) { dev_err(port->dev, "atmel_startup - Can't get irq\n"); @@ -2513,8 +2534,14 @@ static int atmel_serial_suspend(struct platform_device *pdev, /* we can not wake up if we're running on slow clock */ atmel_port->may_wakeup = device_may_wakeup(&pdev->dev); - if (atmel_serial_clk_will_stop()) + if (atmel_serial_clk_will_stop()) { + unsigned long flags; + + spin_lock_irqsave(&atmel_port->lock_suspended, flags); + atmel_port->suspended = true; + spin_unlock_irqrestore(&atmel_port->lock_suspended, flags); device_set_wakeup_enable(&pdev->dev, 0); + } uart_suspend_port(&atmel_uart, port); @@ -2525,6 +2552,18 @@ static int atmel_serial_resume(struct platform_device *pdev) { struct uart_port *port = platform_get_drvdata(pdev); struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); + unsigned long flags; + + spin_lock_irqsave(&atmel_port->lock_suspended, flags); + if (atmel_port->pending) { + atmel_handle_receive(port, atmel_port->pending); + atmel_handle_status(port, atmel_port->pending, + atmel_port->pending_status); + atmel_handle_transmit(port, atmel_port->pending); + atmel_port->pending = 0; + } + atmel_port->suspended = false; + spin_unlock_irqrestore(&atmel_port->lock_suspended, flags); uart_resume_port(&atmel_uart, port); device_set_wakeup_enable(&pdev->dev, atmel_port->may_wakeup); @@ -2593,6 +2632,8 @@ static int atmel_serial_probe(struct platform_device *pdev) port->backup_imr = 0; port->uart.line = ret; + spin_lock_init(&port->lock_suspended); + ret = atmel_init_gpios(port, &pdev->dev); if (ret < 0) dev_err(&pdev->dev, "%s", From 7438b633a6b073d66a3fa3678ec0dd5928caa4af Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Wed, 4 Mar 2015 20:00:40 +0000 Subject: [PATCH 90/95] genirq / PM: describe IRQF_COND_SUSPEND With certain restrictions it is possible for a wakeup device to share an IRQ with an IRQF_NO_SUSPEND user, and the warnings introduced by commit cab303be91dc47942bc25de33dc1140123540800 are spurious. The new IRQF_COND_SUSPEND flag allows drivers to tell the core when these restrictions are met, allowing spurious warnings to be silenced. This patch documents how IRQF_COND_SUSPEND is expected to be used, updating some of the text now made invalid by its addition. Signed-off-by: Mark Rutland Signed-off-by: Rafael J. Wysocki --- Documentation/power/suspend-and-interrupts.txt | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/Documentation/power/suspend-and-interrupts.txt b/Documentation/power/suspend-and-interrupts.txt index 50493c9284b417..8afb29a8604a55 100644 --- a/Documentation/power/suspend-and-interrupts.txt +++ b/Documentation/power/suspend-and-interrupts.txt @@ -112,8 +112,9 @@ any special interrupt handling logic for it to work. IRQF_NO_SUSPEND and enable_irq_wake() ------------------------------------- -There are no valid reasons to use both enable_irq_wake() and the IRQF_NO_SUSPEND -flag on the same IRQ. +There are very few valid reasons to use both enable_irq_wake() and the +IRQF_NO_SUSPEND flag on the same IRQ, and it is never valid to use both for the +same device. First of all, if the IRQ is not shared, the rules for handling IRQF_NO_SUSPEND interrupts (interrupt handlers are invoked after suspend_device_irqs()) are @@ -122,4 +123,13 @@ handlers are not invoked after suspend_device_irqs()). Second, both enable_irq_wake() and IRQF_NO_SUSPEND apply to entire IRQs and not to individual interrupt handlers, so sharing an IRQ between a system wakeup -interrupt source and an IRQF_NO_SUSPEND interrupt source does not make sense. +interrupt source and an IRQF_NO_SUSPEND interrupt source does not generally +make sense. + +In rare cases an IRQ can be shared between a wakeup device driver and an +IRQF_NO_SUSPEND user. In order for this to be safe, the wakeup device driver +must be able to discern spurious IRQs from genuine wakeup events (signalling +the latter to the core with pm_system_wakeup()), must use enable_irq_wake() to +ensure that the IRQ will function as a wakeup source, and must request the IRQ +with IRQF_COND_SUSPEND to tell the core that it meets these requirements. If +these requirements are not met, it is not valid to use IRQF_COND_SUSPEND. From f5c0a122800c301eecef93275b0c5d58bb4c15d9 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Mon, 2 Mar 2015 12:51:02 -0500 Subject: [PATCH 91/95] Btrfs: remove extra run_delayed_refs in update_cowonly_root This got added with my dirty_bgs patch, it's not needed. Thanks, Signed-off-by: Josef Bacik Signed-off-by: Chris Mason --- fs/btrfs/transaction.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 038fcf6051e001..323c6541d3dca1 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -1052,9 +1052,6 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans, ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); if (ret) return ret; - ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); - if (ret) - return ret; } return 0; From 3a8b36f378060d20062a0918e99fae39ff077bf0 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Sun, 1 Mar 2015 20:36:00 +0000 Subject: [PATCH 92/95] Btrfs: fix data loss in the fast fsync path When using the fast file fsync code path we can miss the fact that new writes happened since the last file fsync and therefore return without waiting for the IO to finish and write the new extents to the fsync log. Here's an example scenario where the fsync will miss the fact that new file data exists that wasn't yet durably persisted: 1. fs_info->last_trans_committed == N - 1 and current transaction is transaction N (fs_info->generation == N); 2. do a buffered write; 3. fsync our inode, this clears our inode's full sync flag, starts an ordered extent and waits for it to complete - when it completes at btrfs_finish_ordered_io(), the inode's last_trans is set to the value N (via btrfs_update_inode_fallback -> btrfs_update_inode -> btrfs_set_inode_last_trans); 4. transaction N is committed, so fs_info->last_trans_committed is now set to the value N and fs_info->generation remains with the value N; 5. do another buffered write, when this happens btrfs_file_write_iter sets our inode's last_trans to the value N + 1 (that is fs_info->generation + 1 == N + 1); 6. transaction N + 1 is started and fs_info->generation now has the value N + 1; 7. transaction N + 1 is committed, so fs_info->last_trans_committed is set to the value N + 1; 8. fsync our inode - because it doesn't have the full sync flag set, we only start the ordered extent, we don't wait for it to complete (only in a later phase) therefore its last_trans field has the value N + 1 set previously by btrfs_file_write_iter(), and so we have: inode->last_trans <= fs_info->last_trans_committed (N + 1) (N + 1) Which made us not log the last buffered write and exit the fsync handler immediately, returning success (0) to user space and resulting in data loss after a crash. This can actually be triggered deterministically and the following excerpt from a testcase I made for xfstests triggers the issue. It moves a dummy file across directories and then fsyncs the old parent directory - this is just to trigger a transaction commit, so moving files around isn't directly related to the issue but it was chosen because running 'sync' for example does more than just committing the current transaction, as it flushes/waits for all file data to be persisted. The issue can also happen at random periods, since the transaction kthread periodicaly commits the current transaction (about every 30 seconds by default). The body of the test is: _scratch_mkfs >> $seqres.full 2>&1 _init_flakey _mount_flakey # Create our main test file 'foo', the one we check for data loss. # By doing an fsync against our file, it makes btrfs clear the 'needs_full_sync' # bit from its flags (btrfs inode specific flags). $XFS_IO_PROG -f -c "pwrite -S 0xaa 0 8K" \ -c "fsync" $SCRATCH_MNT/foo | _filter_xfs_io # Now create one other file and 2 directories. We will move this second file # from one directory to the other later because it forces btrfs to commit its # currently open transaction if we fsync the old parent directory. This is # necessary to trigger the data loss bug that affected btrfs. mkdir $SCRATCH_MNT/testdir_1 touch $SCRATCH_MNT/testdir_1/bar mkdir $SCRATCH_MNT/testdir_2 # Make sure everything is durably persisted. sync # Write more 8Kb of data to our file. $XFS_IO_PROG -c "pwrite -S 0xbb 8K 8K" $SCRATCH_MNT/foo | _filter_xfs_io # Move our 'bar' file into a new directory. mv $SCRATCH_MNT/testdir_1/bar $SCRATCH_MNT/testdir_2/bar # Fsync our first directory. Because it had a file moved into some other # directory, this made btrfs commit the currently open transaction. This is # a condition necessary to trigger the data loss bug. $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/testdir_1 # Now fsync our main test file. If the fsync succeeds, we expect the 8Kb of # data we wrote previously to be persisted and available if a crash happens. # This did not happen with btrfs, because of the transaction commit that # happened when we fsynced the parent directory. $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/foo # Simulate a crash/power loss. _load_flakey_table $FLAKEY_DROP_WRITES _unmount_flakey _load_flakey_table $FLAKEY_ALLOW_WRITES _mount_flakey # Now check that all data we wrote before are available. echo "File content after log replay:" od -t x1 $SCRATCH_MNT/foo status=0 exit The expected golden output for the test, which is what we get with this fix applied (or when running against ext3/4 and xfs), is: wrote 8192/8192 bytes at offset 0 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 8192/8192 bytes at offset 8192 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) File content after log replay: 0000000 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa * 0020000 bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb * 0040000 Without this fix applied, the output shows the test file does not have the second 8Kb extent that we successfully fsynced: wrote 8192/8192 bytes at offset 0 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 8192/8192 bytes at offset 8192 XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) File content after log replay: 0000000 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa * 0020000 So fix this by skipping the fsync only if we're doing a full sync and if the inode's last_trans is <= fs_info->last_trans_committed, or if the inode is already in the log. Also remove setting the inode's last_trans in btrfs_file_write_iter since it's useless/unreliable. Also because btrfs_file_write_iter no longer sets inode->last_trans to fs_info->generation + 1, don't set last_trans to 0 if we bail out and don't bail out if last_trans is 0, otherwise something as simple as the following example wouldn't log the second write on the last fsync: 1. write to file 2. fsync file 3. fsync file |--> btrfs_inode_in_log() returns true and it set last_trans to 0 4. write to file |--> btrfs_file_write_iter() no longers sets last_trans, so it remained with a value of 0 5. fsync |--> inode->last_trans == 0, so it bails out without logging the second write A test case for xfstests will be sent soon. CC: Signed-off-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/file.c | 56 ++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index b476e5645034cb..6351947c9bb0f1 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1811,22 +1811,10 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb, mutex_unlock(&inode->i_mutex); /* - * we want to make sure fsync finds this change - * but we haven't joined a transaction running right now. - * - * Later on, someone is sure to update the inode and get the - * real transid recorded. - * - * We set last_trans now to the fs_info generation + 1, - * this will either be one more than the running transaction - * or the generation used for the next transaction if there isn't - * one running right now. - * * We also have to set last_sub_trans to the current log transid, * otherwise subsequent syncs to a file that's been synced in this * transaction will appear to have already occured. */ - BTRFS_I(inode)->last_trans = root->fs_info->generation + 1; BTRFS_I(inode)->last_sub_trans = root->log_transid; if (num_written > 0) { err = generic_write_sync(file, pos, num_written); @@ -1959,25 +1947,37 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) atomic_inc(&root->log_batch); /* - * check the transaction that last modified this inode - * and see if its already been committed - */ - if (!BTRFS_I(inode)->last_trans) { - mutex_unlock(&inode->i_mutex); - goto out; - } - - /* - * if the last transaction that changed this file was before - * the current transaction, we can bail out now without any - * syncing + * If the last transaction that changed this file was before the current + * transaction and we have the full sync flag set in our inode, we can + * bail out now without any syncing. + * + * Note that we can't bail out if the full sync flag isn't set. This is + * because when the full sync flag is set we start all ordered extents + * and wait for them to fully complete - when they complete they update + * the inode's last_trans field through: + * + * btrfs_finish_ordered_io() -> + * btrfs_update_inode_fallback() -> + * btrfs_update_inode() -> + * btrfs_set_inode_last_trans() + * + * So we are sure that last_trans is up to date and can do this check to + * bail out safely. For the fast path, when the full sync flag is not + * set in our inode, we can not do it because we start only our ordered + * extents and don't wait for them to complete (that is when + * btrfs_finish_ordered_io runs), so here at this point their last_trans + * value might be less than or equals to fs_info->last_trans_committed, + * and setting a speculative last_trans for an inode when a buffered + * write is made (such as fs_info->generation + 1 for example) would not + * be reliable since after setting the value and before fsync is called + * any number of transactions can start and commit (transaction kthread + * commits the current transaction periodically), and a transaction + * commit does not start nor waits for ordered extents to complete. */ smp_mb(); if (btrfs_inode_in_log(inode, root->fs_info->generation) || - BTRFS_I(inode)->last_trans <= - root->fs_info->last_trans_committed) { - BTRFS_I(inode)->last_trans = 0; - + (full_sync && BTRFS_I(inode)->last_trans <= + root->fs_info->last_trans_committed)) { /* * We'v had everything committed since the last time we were * modified so clear this flag in case it was set for whatever From dd9ef135e3542ffc621c4eb7f0091870ec7a1504 Mon Sep 17 00:00:00 2001 From: Quentin Casasnovas Date: Tue, 3 Mar 2015 16:31:38 +0100 Subject: [PATCH 93/95] Btrfs:__add_inode_ref: out of bounds memory read when looking for extended ref. Improper arithmetics when calculting the address of the extended ref could lead to an out of bounds memory read and kernel panic. Signed-off-by: Quentin Casasnovas Reviewed-by: David Sterba cc: stable@vger.kernel.org # v3.7+ Signed-off-by: Chris Mason --- fs/btrfs/tree-log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index f96996a1b70c92..9a1c1711f3601a 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -1012,7 +1012,7 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans, base = btrfs_item_ptr_offset(leaf, path->slots[0]); while (cur_offset < item_size) { - extref = (struct btrfs_inode_extref *)base + cur_offset; + extref = (struct btrfs_inode_extref *)(base + cur_offset); victim_name_len = btrfs_inode_extref_name_len(leaf, extref); From d124380674b58f62d0ef974630d74d67bb8afeb0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 5 Mar 2015 20:49:06 +0300 Subject: [PATCH 94/95] ALSA: opl3: small array underflow There is a missing lower bound check on "pitchbend" so it means we can read up to 6 elements before the start of the opl3_note_table[] array. Thanks to Clemens Ladisch for his help with this patch. Signed-off-by: Dan Carpenter Signed-off-by: Takashi Iwai --- sound/drivers/opl3/opl3_midi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/drivers/opl3/opl3_midi.c b/sound/drivers/opl3/opl3_midi.c index f62780ed64adcc..7821b07415a785 100644 --- a/sound/drivers/opl3/opl3_midi.c +++ b/sound/drivers/opl3/opl3_midi.c @@ -105,6 +105,8 @@ static void snd_opl3_calc_pitch(unsigned char *fnum, unsigned char *blocknum, int pitchbend = chan->midi_pitchbend; int segment; + if (pitchbend < -0x2000) + pitchbend = -0x2000; if (pitchbend > 0x1FFF) pitchbend = 0x1FFF; From 70658b99490dd86cfdbf4fca117bbe2ef9a80d03 Mon Sep 17 00:00:00 2001 From: Hui Wang Date: Fri, 6 Mar 2015 14:03:57 +0800 Subject: [PATCH 95/95] ALSA: hda - One more Dell macine needs DELL1_MIC_NO_PRESENCE quirk Cc: BugLink: https://bugs.launchpad.net/bugs/1428947 Signed-off-by: Hui Wang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b2b24a8b3dac8c..526398a4a4428d 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5209,6 +5209,13 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { {0x17, 0x40000000}, {0x1d, 0x40700001}, {0x21, 0x02211040}), + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + ALC255_STANDARD_PINS, + {0x12, 0x90a60170}, + {0x14, 0x90170140}, + {0x17, 0x40000000}, + {0x1d, 0x40700001}, + {0x21, 0x02211050}), SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4, {0x12, 0x90a60130}, {0x13, 0x40000000},