3.12.17-stable review
cover 3.12.17-stable review
This is the start of the stable review cycle for the 3.12.17 release. There are 40 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri Apr 4 20:06:31 2014 Anything received after that time might be too late.
The whole patch series can be found in one patch at:
http://kernel.org/pub/linux/kernel/people/jirislaby/stable-review/patch-3.12.17-rc1.xz
and the diffstat can be found below.
thanks,
js
===============
Al Viro (1):
make prepend_name() work correctly when called with negative *buflen
Alexander Aring (1):
nfs: fix dead code of ipv6_addr_scope
Andy Adamson (2):
SUNRPC: do not fail gss proc NULL calls with EACCES NFSv4.1 free slot before resending I/O to MDS
Artem Fetishev (1):
x86: fix boot on uniprocessor systems
Benjamin Tissoires (1):
Input: synaptics - add manual min/max quirk
Christoph Hellwig (3):
nfs: fix size updates for aio writes
nfs: defer inode_dio_done call until size update is done
nfs: increment i_dio_count for reads, too
Daniel Borkmann (1):
netfilter: nf_conntrack_dccp: fix skb_header_pointer API usages
Daniel Vetter (1):
drm/i915: Undo gtt scratch pte unmapping again
David Howells (2):
X.509: struct x509_certificate needs struct tm declaring
FS-Cache: Handle removal of unadded object to the fscache_object_list
rb tree
David Rientjes (1):
mm: close PageTail race
David Vrabel (1):
Revert "xen: properly account for _PAGE_NUMA during xen pte
translations"
Dmitry Torokhov (1):
Input: mousedev - fix race when creating mixed device
Dongmao Zhang (1):
dlm: set zero linger time on sctp socket
Hans de Goede (2):
Input: synaptics - add manual min/max quirk for ThinkPad X240
Input: cypress_ps2 - don't report as a button pads
J. Bruce Fields (1):
nfs: use IS_ROOT not DCACHE_DISCONNECTED
James Ralston (1):
i2c: i801: Add Device IDs for Intel Wildcat Point-LP PCH
Jeff Layton (2):
NFS: fix the handling of NFS_INO_INVALID_DATA flag in
nfs_revalidate_mapping
nfs: add memory barriers around NFS_INO_INVALID_DATA and
NFS_INO_INVALIDATING
Jeff Mahoney (1):
drm/nouveau: make vga_switcheroo code depend on VGA_SWITCHEROO
Len Brown (1):
intel_idle: Support Intel Atom Processor C2000 Product Family
Martin Schwidefsky (1):
s390/time,vdso: fix clock_gettime for CLOCK_MONOTONIC
Michal Kubecek (1):
ipvs: fix AF assignment in ip_vs_conn_new()
Olaf Hering (1):
fbmem: really support wildcard video=options for all fbdev drivers
Oliver Neukum (1):
crypto: sha256_ssse3 - also test for BMI2
Ping Cheng (1):
Input: wacom - add support for three new Intuos Pro devices
Scott Wood (1):
i2c: cpm: Fix build by adding of_address.h and of_irq.h
Takashi Iwai (1):
ALSA: hda - Fix inconsistent Mic mute LED
Theodore Ts'o (1):
ext4: atomically set inode->i_flags in ext4_set_inode_flags()
Thomas Petazzoni (2):
net: mvneta: rename MVNETA_GMAC2_PSC_ENABLE to MVNETA_GMAC2_PCS_ENABLE
net: mvneta: fix usage as a module on RGMII configurations
Toshi Kani (1):
arch/x86/mm/srat: Skip NUMA_NO_NODE while parsing SLIT
Trond Myklebust (2):
NFSv4.1: Prevent a 3-way deadlock between layoutreturn, open and state
recovery
NFS: Fix races in nfs_revalidate_mapping
Wei Liu (1):
xen/balloon: flush persistent kmaps in correct position
Weston Andros Adamson (1):
pnfs: fix BUG in filelayout_recover_commit_reqs
Documentation/i2c/busses/i2c-i801 | 1 + arch/s390/kernel/vdso32/clock_gettime.S | 9 +--- arch/s390/kernel/vdso64/clock_gettime.S | 6 +-- arch/x86/crypto/sha256_ssse3_glue.c | 2 +- arch/x86/include/asm/pgtable.h | 14 +------ arch/x86/include/asm/topology.h | 3 +- arch/x86/mm/srat.c | 16 ++++++-- arch/x86/xen/mmu.c | 4 +- crypto/asymmetric_keys/x509_parser.h | 1 + drivers/block/aoe/aoecmd.c | 4 +- drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +- drivers/gpu/drm/nouveau/nouveau_acpi.c | 6 +++ drivers/i2c/busses/Kconfig | 1 + drivers/i2c/busses/i2c-cpm.c | 2 + drivers/i2c/busses/i2c-i801.c | 3 ++ drivers/idle/intel_idle.c | 24 ++++++++++- drivers/input/mouse/cypress_ps2.c | 1 - drivers/input/mouse/synaptics.c | 55 +++++++++++++++++++++++++ drivers/input/mousedev.c | 73 +++++++++++++++++++-------------- drivers/input/tablet/wacom_sys.c | 10 ++++- drivers/input/tablet/wacom_wac.c | 61 ++++++++++++++++++++------- drivers/input/tablet/wacom_wac.h | 3 ++ drivers/net/ethernet/marvell/mvneta.c | 43 ++++--------------- drivers/vfio/vfio_iommu_type1.c | 4 +- drivers/video/fbmem.c | 3 ++ drivers/xen/balloon.c | 24 ++++++++--- fs/dcache.c | 4 +- fs/dlm/lowcomms.c | 8 ++++ fs/ext4/inode.c | 15 ++++--- fs/fscache/object-list.c | 5 +++ fs/fscache/object.c | 3 ++ fs/nfs/dir.c | 21 ++++++++-- fs/nfs/direct.c | 38 +++++++++++------ fs/nfs/inode.c | 51 +++++++++++++++++++---- fs/nfs/nfs4_fs.h | 1 + fs/nfs/nfs4filelayout.c | 18 +++++--- fs/nfs/nfs4filelayoutdev.c | 2 +- fs/nfs/nfs4proc.c | 12 +++++- fs/nfs/nfstrace.h | 1 + fs/nfs/write.c | 7 +++- fs/proc/page.c | 2 +- include/linux/bitops.h | 15 +++++++ include/linux/huge_mm.h | 18 -------- include/linux/mm.h | 14 ++++++- include/linux/nfs_fs.h | 1 + mm/ksm.c | 2 +- mm/memory-failure.c | 2 +- mm/page_alloc.c | 4 +- mm/swap.c | 4 +- net/netfilter/ipvs/ip_vs_conn.c | 8 ++-- net/netfilter/nf_conntrack_proto_dccp.c | 6 +-- net/sunrpc/auth_gss/auth_gss.c | 2 +- sound/pci/hda/hda_generic.c | 8 ++-- sound/pci/hda/hda_generic.h | 1 + sound/pci/hda/patch_conexant.c | 3 +- sound/pci/hda/patch_realtek.c | 9 ++-- sound/pci/hda/patch_sigmatel.c | 27 +++++++----- 57 files changed, 469 insertions(+), 218 deletions(-)
Signature · 1 line
1.9.1
PATCH 1/40 ALSA: hda - Fix inconsistent Mic mute LED
From: Takashi Iwai <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 7fe307117db5bd7ec6efb93c563dcf44577b6d2b upstream.
The current code for controlling mic mute LED in patch_sigmatel.c blindly assumes that there is a single capture switch. But, there can be multiple multiple ones, and each of them flips the state, ended up in an inconsistent state.
For fixing this problem, this patch adds kcontrol to be passed to the hook function so that the callee can check which switch is being accessed. In stac_capture_led_hook(), the state is checked as a bitmask, and turns on the LED when all capture switches are off.
--- sound/pci/hda/hda_generic.c | 8 ++++---- sound/pci/hda/hda_generic.h | 1 + sound/pci/hda/patch_conexant.c | 3 ++- sound/pci/hda/patch_realtek.c | 9 ++++++--- sound/pci/hda/patch_sigmatel.c | 27 +++++++++++++++++---------- 5 files changed, 30 insertions(+), 18 deletions(-)
sound/pci/hda/hda_generic.c +4 -4
@@ -3264,7 +3264,7 @@ static int cap_put_caller(struct snd_kcontrol *kcontrol,mutex_unlock (&codec->control_mutex);snd_hda_codec_flush_cache (codec);/* flush the updates */ if (err >=0 && spec->cap_sync_hook) - spec->cap_sync_hook (codec, ucontrol); + spec->cap_sync_hook (codec, kcontrol, ucontrol);return err; }
@@ -3385,7 +3385,7 @@ static int cap_single_sw_put(struct snd_kcontrol *kcontrol,return ret;if (spec->cap_sync_hook) - spec->cap_sync_hook (codec, ucontrol); + spec->cap_sync_hook (codec, kcontrol, ucontrol);return ret; }
@@ -3790,7 +3790,7 @@ static int mux_select(struct hda_codec *codec, unsigned int adc_idx,return 0 ;snd_hda_activate_path (codec, path, true, false);if (spec->cap_sync_hook) - spec->cap_sync_hook (codec,NULL ); + spec->cap_sync_hook (codec,NULL ,NULL );path_power_down_sync (codec, old_path);return 1 ; }
@@ -5233,7 +5233,7 @@ static void init_input_src(struct hda_codec *codec) }if (spec->cap_sync_hook) - spec->cap_sync_hook (codec,NULL ); + spec->cap_sync_hook (codec,NULL ,NULL ); }/* set right pin controls for digital I/O */
sound/pci/hda/hda_generic.h +1 -0
@@ -274,6 +274,7 @@ struct hda_gen_spec {void (*init_hook)(struct hda_codec *codec);void (*automute_hook)(struct hda_codec *codec);void (*cap_sync_hook)(struct hda_codec *codec, +struct snd_kcontrol *kcontrol,struct snd_ctl_elem_value *ucontrol);/* PCM hooks */
sound/pci/hda/patch_conexant.c +2 -1
@@ -3282,7 +3282,8 @@ static void cxt_update_headset_mode(struct hda_codec *codec) }static void cxt_update_headset_mode_hook (struct hda_codec *codec, -struct snd_ctl_elem_value *ucontrol) +struct snd_kcontrol *kcontrol, +struct snd_ctl_elem_value *ucontrol) {cxt_update_headset_mode (codec); }
sound/pci/hda/patch_realtek.c +6 -3
@@ -695,7 +695,8 @@ static void alc_inv_dmic_sync(struct hda_codec *codec, bool force) }static void alc_inv_dmic_hook (struct hda_codec *codec, -struct snd_ctl_elem_value *ucontrol) +struct snd_kcontrol *kcontrol, +struct snd_ctl_elem_value *ucontrol) {alc_inv_dmic_sync (codec, false); }
@@ -3141,7 +3142,8 @@ static void alc269_fixup_hp_gpio_mute_hook(void *private_data, int enabled)/* turn on/off mic-mute LED per capture hook */ static void alc269_fixup_hp_gpio_mic_mute_hook (struct hda_codec *codec, -struct snd_ctl_elem_value *ucontrol) +struct snd_kcontrol *kcontrol, +struct snd_ctl_elem_value *ucontrol) {struct alc_spec *spec = codec->spec;unsigned int oldval = spec->gpio_led;
@@ -3403,7 +3405,8 @@ static void alc_update_headset_mode(struct hda_codec *codec) }static void alc_update_headset_mode_hook (struct hda_codec *codec, -struct snd_ctl_elem_value *ucontrol) +struct snd_kcontrol *kcontrol, +struct snd_ctl_elem_value *ucontrol) {alc_update_headset_mode (codec); }
sound/pci/hda/patch_sigmatel.c +17 -10
@@ -195,7 +195,7 @@ struct sigmatel_spec {int default_polarity;unsigned int mic_mute_led_gpio;/* capture mute LED GPIO */ -bool mic_mute_led_on;/* current mic mute state */ +unsigned int mic_enabled;/* current mic mute state (bitmask) */ /* stream */ unsigned int stream_delay;
@@ -325,19 +325,26 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,/* hook for controlling mic-mute LED GPIO */ static void stac_capture_led_hook (struct hda_codec *codec, -struct snd_ctl_elem_value *ucontrol) +struct snd_kcontrol *kcontrol, +struct snd_ctl_elem_value *ucontrol) {struct sigmatel_spec *spec = codec->spec; -bool mute; +unsigned int mask; +bool cur_mute, prev_mute; -if (!ucontrol) +if (!kcontrol || !ucontrol)return ; - mute = !(ucontrol->value.integer.value[0 ] || - ucontrol->value.integer.value[1 ]); -if (spec->mic_mute_led_on != mute) { - spec->mic_mute_led_on = mute; -if (mute) + mask =1U <<snd_ctl_get_ioffidx (kcontrol, &ucontrol->id); + prev_mute = !spec->mic_enabled; +if (ucontrol->value.integer.value[0 ] || + ucontrol->value.integer.value[1 ]) + spec->mic_enabled |= mask; +else + spec->mic_enabled &= ~mask; + cur_mute = !spec->mic_enabled; +if (cur_mute != prev_mute) { +if (cur_mute) spec->gpio_data |= spec->mic_mute_led_gpio;else spec->gpio_data &= ~spec->mic_mute_led_gpio;
@@ -3974,7 +3981,7 @@ static void stac_setup_gpio(struct hda_codec *codec)if (spec->mic_mute_led_gpio) { spec->gpio_mask |= spec->mic_mute_led_gpio; spec->gpio_dir |= spec->mic_mute_led_gpio; - spec->mic_mute_led_on = true; + spec->mic_enabled =0 ; spec->gpio_data |= spec->mic_mute_led_gpio; spec->gen.cap_sync_hook = stac_capture_led_hook;
Signature · 1 line
1.9.1
PATCH 2/40 i2c: i801: Add Device IDs for Intel Wildcat Point-LP PCH
From: James Ralston <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit afc659241258b40b683998ec801d25d276529f43 upstream.
This patch adds the SMBus Device IDs for the Intel Wildcat Point-LP PCH.
--- Documentation/i2c/busses/i2c-i801 | 1 + drivers/i2c/busses/Kconfig | 1 + drivers/i2c/busses/i2c-i801.c | 3 +++ 3 files changed, 5 insertions(+)
Documentation/i2c/busses/i2c-i801 +1 -0
@@ -25,6 +25,7 @@ Supported adapters: * Intel Avoton (SOC) * Intel Wellsburg (PCH) * Intel Coleto Creek (PCH) + * Intel Wildcat Point-LP (PCH) Datasheets: Publicly available at the Intel website On Intel Patsburg and later chipsets, both the normal host SMBus controller
drivers/i2c/busses/Kconfig +1 -0
@@ -109,6 +109,7 @@ config I2C_I801 Avoton (SOC) Wellsburg (PCH) Coleto Creek (PCH) + Wildcat Point-LP (PCH) This driver can also be built as a module. If so, the module will be called i2c-i801.
drivers/i2c/busses/i2c-i801.c +3 -0
@@ -59,6 +59,7 @@ Wellsburg (PCH) MS 0x8d7e 32 hard yes yes yes Wellsburg (PCH) MS 0x8d7f 32 hard yes yes yes Coleto Creek (PCH) 0x23b0 32 hard yes yes yes + Wildcat Point-LP (PCH) 0x9ca2 32 hard yes yes yes Features supported by this driver: Software PEC no
@@ -177,6 +178,7 @@#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1 0x8d7e#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2 0x8d7f#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS 0x9c22 +#define PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS 0x9ca2struct i801_mux_config {char *gpio_chip;
@@ -819,6 +821,7 @@ static DEFINE_PCI_DEVICE_TABLE(i801_ids) = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COLETOCREEK_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS) }, { 0, } };
Signature · 1 line
1.9.1
PATCH 3/40 intel_idle: Support Intel Atom Processor C2000 Product Family
In reply to Jiri SlabyFrom: Len Brown <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit fab04b2208dd1d4121319f0096c5a5f4b70abc54 upstream.
Support the "Intel(R) Atom(TM) Processor C2000 Product Family", formerly code-named Avoton. It is based on the next generation Intel Atom processor architecture, formerly code-named Silvermont.
--- drivers/idle/intel_idle.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-)
drivers/idle/intel_idle.c +23 -1
@@ -1,7 +1,7 @@/* * intel_idle.c - native hardware idle loop for modern Intel processors * -* Copyright (c) 2010, Intel Corporation. +* Copyright (c) 2013, Intel Corporation. * Len Brown <[email protected]> * * This program is free software; you can redistribute it and/or modify it
@@ -329,6 +329,22 @@ static struct cpuidle_state atom_cstates[CPUIDLE_STATE_MAX] = { { .enter = NULL } }; +static struct cpuidle_state avn_cstates[CPUIDLE_STATE_MAX ] = { + { + .name ="C1-AVN" , + .desc ="MWAIT 0x00" , + .flags =MWAIT2flg (0x00 ) |CPUIDLE_FLAG_TIME_VALID , + .exit_latency =2 , + .target_residency =2 , + .enter = &intel_idle }, + { + .name ="C6-AVN" , + .desc ="MWAIT 0x51" , + .flags =MWAIT2flg (0x58 ) |CPUIDLE_FLAG_TIME_VALID |CPUIDLE_FLAG_TLB_FLUSHED , + .exit_latency =15 , + .target_residency =45 , + .enter = &intel_idle }, +};/** * intel_idle
@@ -465,6 +481,11 @@ static const struct idle_cpu idle_cpu_hsw = { .disable_promotion_to_c1e = true, }; +static const struct idle_cpu idle_cpu_avn = { + .state_table = avn_cstates, + .disable_promotion_to_c1e = true, +}; +#define ICPU (model, cpu) \ { X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long)&cpu }
@@ -486,6 +507,7 @@ static const struct x86_cpu_id intel_idle_ids[] = {ICPU (0x3f , idle_cpu_hsw),ICPU (0x45 , idle_cpu_hsw),ICPU (0x46 , idle_cpu_hsw), +ICPU (0x4D , idle_cpu_avn), {} };MODULE_DEVICE_TABLE (x86cpu, intel_idle_ids);
Signature · 1 line
1.9.1
Re: [PATCH 3.12 03/40] intel_idle: Support Intel Atom Processor C2000 Product Family
Quoted 68 lines
From: Len Brown <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit
fab04b2208dd1d4121319f0096c5a5f4b70abc54upstream.Support the "Intel(R) Atom(TM) Processor C2000 Product Family", formerly code-named Avoton. It is based on the next generation Intel Atom processor architecture, formerly code-named Silvermont.
Signed-off-by Len Brown <[email protected]>Signed-off-by Rafael J. Wysocki <[email protected]>Signed-off-by Jiri Slaby <[email protected]>--- drivers/idle/intel_idle.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-)drivers/idle/intel_idle.c +22
-1@@ -1,7 +1,7 @@/* * intel_idle.c - native hardware idle loop for modern Intel processors * -* Copyright (c) 2010, Intel Corporation. +* Copyright (c) 2013, Intel Corporation. * Len Brown <[email protected]> * * This program is free software; you can redistribute it and/or modify it @@ -329,6 +329,22 @@ static struct cpuidle_state atom_cstates[CPUIDLE_STATE_MAX] = { { .enter = NULL } }; +static struct cpuidle_state avn_cstates[CPUIDLE_STATE_MAX ] = { + { + .name ="C1-AVN" , + .desc ="MWAIT 0x00" , + .flags =MWAIT2flg (0x00 ) |CPUIDLE_FLAG_TIME_VALID , + .exit_latency =2 , + .target_residency =2 , + .enter = &intel_idle }, + { + .name ="C6-AVN" , + .desc ="MWAIT 0x51" , + .flags =MWAIT2flg (0x58 ) |CPUIDLE_FLAG_TIME_VALID |CPUIDLE_FLAG_TLB_FLUSHED , + .exit_latency =15 , + .target_residency =45 , + .enter = &intel_idle }, +};/** * intel_idle @@ -465,6 +481,11 @@ static const struct idle_cpu idle_cpu_hsw = { .disable_promotion_to_c1e = true, }; +static const struct idle_cpu idle_cpu_avn = { + .state_table = avn_cstates, + .disable_promotion_to_c1e = true, +}; +#define ICPU (model, cpu) \ { X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long)&cpu }
drivers/idle/intel_idle.c static const struct x86_cpu_id intel_idle_ids[] = { · line 513
Quoted 7 lines
drivers/idle/intel_idle.c +1
-0@@ -486,6 +507,7 @@ static const struct x86_cpu_id intel_idle_ids[] = {ICPU (0x3f , idle_cpu_hsw),ICPU (0x45 , idle_cpu_hsw),ICPU (0x46 , idle_cpu_hsw), +ICPU (0x4D , idle_cpu_avn), {} };MODULE_DEVICE_TABLE (x86cpu, intel_idle_ids);
Ahoj !
For this one you also need the upstream patch 22e580d07f6529a395c129575127ea6d860aed3a to make the C-States work on C2000 series.
Arne
PATCH 4/40 X.509: struct x509_certificate needs struct tm declaring
In reply to Jiri SlabyFrom: David Howells <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 57be4a784bf58eb41784aa3431165b455cf7e9c6 upstream.
struct x509_certificate needs struct tm declaring by #inclusion of linux/time.h prior to its definition.
--- crypto/asymmetric_keys/x509_parser.h | 1 + 1 file changed, 1 insertion(+)
crypto/asymmetric_keys/x509_parser.h +1 -0
@@ -9,6 +9,7 @@* 2 of the Licence, or (at your option) any later version. */ +#include <linux/time.h> #include <crypto/public_key.h> struct x509_certificate {
Signature · 1 line
1.9.1
PATCH 5/40 nfs: use IS_ROOT not DCACHE_DISCONNECTED
In reply to Jiri SlabyFrom: "J. Bruce Fields" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit a3f432bfd06a4ec3b812e32d3266e0d1ad75d008 upstream.
This check was added by Al Viro with d9e80b7de91db05c1c4d2e5ebbfd70b3b3ba0e0f "nfs d_revalidate() is too trigger-happy with d_drop()", with the explanation that we don't want to remove the root of a disconnected tree, which will still be included on the s_anon list.
But DCACHE_DISCONNECTED does *not* actually identify dentries that are disconnected from the dentry tree or hashed on s_anon. IS_ROOT() is the way to do that.
Also add a comment from Al's commit to remind us why this check is there.
--- fs/nfs/dir.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
fs/nfs/dir.c +7 -1
@@ -1139,7 +1139,13 @@ out_zap_parent:if (inode &&S_ISDIR (inode->i_mode)) {/* Purge readdir caches. */ nfs_zap_caches (inode); -if (dentry->d_flags &DCACHE_DISCONNECTED ) +/* +* We can't d_drop the root of a disconnected tree: +* its d_hash is on the s_anon list and d_drop() would hide +* it from shrink_dcache_for_unmount(), leading to busy +* inodes on unmount and further oopses. +*/ +if (IS_ROOT (dentry)) goto out_valid; }/* If we have submounts, don't unhash ! */
Signature · 1 line
1.9.1
PATCH 6/40 drm/nouveau: make vga_switcheroo code depend on VGA_SWITCHEROO
In reply to Jiri SlabyFrom: Jeff Mahoney <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit d0ce7b8567ae76b8a6c0eb8361d121deb98c1b3f upstream.
Commit 8116188fdef594 ("nouveau/acpi: hook up to the MXM method for mux switching.") broke the build on non-x86 architectures due to the new dependency on MXM and MXM being an x86 platform driver.
It built previously since the vga switcheroo registration routines were zereod out on !X86. The code was built in but unused.
This patch makes all of the DSM code depend on CONFIG_VGA_SWITCHEROO, allowing it to build on non-x86 and shrinking the module size as well.
--- drivers/gpu/drm/nouveau/nouveau_acpi.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/gpu/drm/nouveau/nouveau_acpi.c +6 -0
@@ -66,6 +66,7 @@ bool nouveau_is_v1_dsm(void) {#define NOUVEAU_DSM_HAS_MUX 0x1#define NOUVEAU_DSM_HAS_OPT 0x2 +#ifdef CONFIG_VGA_SWITCHEROO static const char nouveau_dsm_muid[] = {0xA0 ,0xA0 ,0x95 ,0x9D ,0x60 ,0x00 ,0x48 ,0x4D , 0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4,
@@ -378,6 +379,11 @@ void nouveau_unregister_dsm_handler(void)if (nouveau_dsm_priv.optimus_detected || nouveau_dsm_priv.dsm_detected)vga_switcheroo_unregister_handler (); } +#else +void nouveau_register_dsm_handler (void ) {} +void nouveau_unregister_dsm_handler (void ) {} +void nouveau_switcheroo_optimus_dsm (void ) {} +#endif /* retrieve the ROM in 4k blocks */ static int nouveau_rom_call(acpi_handle rom_handle, uint8_t *bios,
Signature · 1 line
1.9.1
PATCH 7/40 crypto: sha256_ssse3 - also test for BMI2
In reply to Jiri SlabyFrom: Oliver Neukum <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 16c0c4e1656c14ef9deac189a4240b5ca19c6919 upstream.
The AVX2 implementation also uses BMI2 instructions, but doesn't test for their availability. The assumption that AVX2 and BMI2 always go together is false. Some Haswells have AVX2 but not BMI2.
--- arch/x86/crypto/sha256_ssse3_glue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/crypto/sha256_ssse3_glue.c +1 -1
@@ -281,7 +281,7 @@ static int __init sha256_ssse3_mod_init(void)/* allow AVX to override SSSE3, it's a little faster */ if (avx_usable ()) {#ifdef CONFIG_AS_AVX2 -if (boot_cpu_has (X86_FEATURE_AVX2 )) +if (boot_cpu_has (X86_FEATURE_AVX2 ) &&boot_cpu_has (X86_FEATURE_BMI2 )) sha256_transform_asm = sha256_transform_rorx; else#endif
Signature · 1 line
1.9.1
PATCH 8/40 arch/x86/mm/srat: Skip NUMA_NO_NODE while parsing SLIT
In reply to Jiri SlabyFrom: Toshi Kani <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit a85eba8814631d0d48361c8b9a7ee0984e80c03c upstream.
When ACPI SLIT table has an I/O locality (i.e. a locality unique to an I/O device), numa_set_distance() emits this warning message:
NUMA: Warning: node ids are out of bound, from=-1 to=-1 distance=10
acpi_numa_slit_init() calls numa_set_distance() with pxm_to_node(), which assumes that all localities have been parsed with SRAT previously. SRAT does not list I/O localities, where as SLIT lists all localities including I/Os. Hence, pxm_to_node() returns NUMA_NO_NODE (-1) for an I/O locality.
I/O localities are not supported and are ignored today, but emitting such warning message leads to unnecessary confusion.
Change acpi_numa_slit_init() to avoid callingnuma_set_distance() with NUMA_NO_NODE.
--- arch/x86/mm/srat.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
arch/x86/mm/srat.c +13 -3
@@ -42,15 +42,25 @@ static __init inline int srat_disabled(void)return acpi_numa <0 ; } -/* Callback for SLIT parsing */ +/* +* Callback for SLIT parsing. pxm_to_node() returns NUMA_NO_NODE for +* I/O localities since SRAT does not list them. I/O localities are +* not supported at this point. +*/ void __init acpi_numa_slit_init (struct acpi_table_slit *slit) {int i, j; -for (i =0 ; i < slit->locality_count; i++) -for (j =0 ; j < slit->locality_count; j++) +for (i =0 ; i < slit->locality_count; i++) { +if (pxm_to_node (i) ==NUMA_NO_NODE ) +continue ; +for (j =0 ; j < slit->locality_count; j++) { +if (pxm_to_node (j) ==NUMA_NO_NODE ) +continue ;numa_set_distance (pxm_to_node (i),pxm_to_node (j), slit->entry[slit->locality_count * i + j]); + } + } }/* Callback for Proximity Domain -> x2APIC mapping */
Signature · 1 line
1.9.1
PATCH 9/40 fbmem: really support wildcard video=options for all fbdev drivers
In reply to Jiri SlabyFrom: Olaf Hering <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit f5d2b7c28b67d627646b6a0142bc201a7b1516b0 upstream.
Documentation/fb/modedb.txt states that video=option should be considered a global option. But video_setup and fb_get_options are not coded that way. Instead its required to boot with video=driver:option to set a given option in drvier. This is cumbersome because it requires to know in advance which driver will be active for a given board/kernel.
The following patch implements the documented catchall for the fbdev drivers. It is now possible to boot with video=XxY without the need to know the active driver in advance. The specific case it tries to fix is syslinux in the SUSE installer which offers a menu to set a display resolution. Right now this just appends the vga= option the kernel. But in addition to vga= it should be possible to pass a generic video=XxY for all framebuffer/drm drivers. With this change forcing a certain window size of VM displays is now much easier.
Today the video= option is stored in a global fb_mode_option. But unfortunately only drm uses it.
Note: this change introduces a small memleak if video=option is actually used because fb_mode_option is const. Most drivers use strsep to get to individual options. This could be fixed in a followup patch which always releases the option string in every caller of fb_get_options.
--- drivers/video/fbmem.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/video/fbmem.c +3 -0
@@ -1916,6 +1916,9 @@ int fb_get_options(const char *name, char **option) options = opt + name_len +1 ; } } +/* No match, pass global option */ +if (!options && option && fb_mode_option) + options =kstrdup (fb_mode_option,GFP_KERNEL );if (options && !strncmp (options,"off" ,3 )) retval =1 ;
Signature · 1 line
1.9.1
PATCH 10/40 SUNRPC: do not fail gss proc NULL calls with EACCES
In reply to Jiri SlabyFrom: Andy Adamson <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit c297c8b99b07f496ff69a719cfb8e8fe852832ed upstream.
Otherwise RPCSEC_GSS_DESTROY messages are not sent.
--- net/sunrpc/auth_gss/auth_gss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/sunrpc/auth_gss/auth_gss.c +1 -1
@@ -1508,7 +1508,7 @@ out:static int gss_refresh_null (struct rpc_task *task) { -return -EACCES ; +return 0 ; } static __be32 *
Signature · 1 line
1.9.1
PATCH 11/40 NFSv4.1: Prevent a 3-way deadlock between layoutreturn, open and state recovery
In reply to Jiri SlabyFrom: Trond Myklebust <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit f22e5edd2244609aed3906207a62223e7707a34d upstream.
Andy Adamson reports:
The state manager is recovering expired state and recovery OPENs are being processed. If kswapd is pruning inodes at the same time, a deadlock can occur when kswapd calls evict_inode on an NFSv4.1 inode with a layout, and the resultant layoutreturn gets an error that the state mangager is to handle, causing the layoutreturn to wait on the (NFS client) cl_rpcwaitq.
At the same time an open is waiting for the inode deletion to complete in __wait_on_freeing_inode.
If the open is either the open called by the state manager, or an open from the same open owner that is holding the NFSv4 sequence id which causes the OPEN from the state manager to wait for the sequence id on the Seqid_waitqueue, then the state is deadlocked with kswapd.
The fix is simply to have layoutreturn ignore all errors except NFS4ERR_DELAY. We already know that layouts are dropped on all server reboots, and that it has to be coded to deal with the "forgetful client model" that doesn't send layoutreturns.
--- fs/nfs/nfs4proc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
fs/nfs/nfs4proc.c +8 -1
@@ -7273,7 +7273,14 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)return ; server =NFS_SERVER (lrp->args.inode); -if (nfs4_async_handle_error (task, server,NULL ) == -EAGAIN ) { +switch (task->tk_status) { +default : + task->tk_status =0 ; +case 0 : +break ; +case -NFS4ERR_DELAY : +if (nfs4_async_handle_error (task, server,NULL ) != -EAGAIN ) +break ;rpc_restart_call_prepare (task);return ; }
Signature · 1 line
1.9.1
PATCH 12/40 nfs: fix dead code of ipv6_addr_scope
In reply to Jiri SlabyFrom: Alexander Aring <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit a8c2275493b866961f4429a741251c630c4fc6d7 upstream.
The correct way to check on IPV6_ADDR_SCOPE_LINKLOCAL is to check with the ipv6_addr_src_scope function.
Currently this can't be work, because ipv6_addr_scope returns a int with a mask of IPV6_ADDR_SCOPE_MASK (0x00f0U) and IPV6_ADDR_SCOPE_LINKLOCAL is 0x02. So the condition is always false.
--- fs/nfs/nfs4filelayoutdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfs/nfs4filelayoutdev.c +1 -1
@@ -95,7 +95,7 @@ same_sockaddr(struct sockaddr *addr1, struct sockaddr *addr2) b6 = (struct sockaddr_in6 *)addr2;/* LINKLOCAL addresses must have matching scope_id */ -if (ipv6_addr_scope (&a6->sin6_addr) == +if (ipv6_addr_src_scope (&a6->sin6_addr) ==IPV6_ADDR_SCOPE_LINKLOCAL && a6->sin6_scope_id != b6->sin6_scope_id)return false;
Signature · 1 line
1.9.1
PATCH 13/40 nfs: fix size updates for aio writes
In reply to Jiri SlabyFrom: Christoph Hellwig <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 9811cd57f4c6b5b60ec104de68a88303717e3106 upstream.
nfs_file_direct_write only updates the inode size if it succeeded and returned the number of bytes written. But in the AIO case nfs_direct_wait turns the return value into -EIOCBQUEUED and we skip the size update.
Instead the aio completion path should updated it, which this patch does. The implementation is a little hacky because there is no obvious way to find out we are called for a write in nfs_direct_complete.
--- fs/nfs/direct.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-)
fs/nfs/direct.c +16 -5
@@ -223,12 +223,23 @@ out:* Synchronous I/O uses a stack-allocated iocb. Thus we can't trust * the iocb is still valid here if this is a synchronous request. */ -static void nfs_direct_complete (struct nfs_direct_req *dreq) +static void nfs_direct_complete (struct nfs_direct_req *dreq,bool write) { +struct inode *inode = dreq->inode; +if (dreq->iocb) { +loff_t pos = dreq->iocb->ki_pos + dreq->count;long res = (long ) dreq->error;if (!res) res = (long ) dreq->count; + +if (write) { +spin_lock (&inode->i_lock); +if (i_size_read (inode) < pos) +i_size_write (inode, pos); +spin_unlock (&inode->i_lock); + } +aio_complete (dreq->iocb, res,0 ); }complete_all (&dreq->completion);
@@ -273,7 +284,7 @@ static void nfs_direct_read_completion(struct nfs_pgio_header *hdr) } out_put:if (put_dreq (dreq)) -nfs_direct_complete (dreq); +nfs_direct_complete (dreq, false); hdr->release (hdr); }
@@ -435,7 +446,7 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq, }if (put_dreq (dreq)) -nfs_direct_complete (dreq); +nfs_direct_complete (dreq, false);return 0 ; }
@@ -595,7 +606,7 @@ static void nfs_direct_write_schedule_work(struct work_struct *work)break ;default :nfs_inode_dio_write_done (dreq->inode); -nfs_direct_complete (dreq); +nfs_direct_complete (dreq, true); } }
@@ -612,7 +623,7 @@ static void nfs_direct_write_schedule_work(struct work_struct *work)static void nfs_direct_write_complete (struct nfs_direct_req *dreq,struct inode *inode) {nfs_inode_dio_write_done (inode); -nfs_direct_complete (dreq); +nfs_direct_complete (dreq, true); }#endif
Signature · 1 line
1.9.1
PATCH 14/40 nfs: defer inode_dio_done call until size update is done
In reply to Jiri SlabyFrom: Christoph Hellwig <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 2a009ec98cce440c0992fc9a2353e96cdb0b048b upstream.
We need to have the I/O fully finished before telling the truncate code that we are done.
--- fs/nfs/direct.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-)
fs/nfs/direct.c +15 -17
@@ -227,21 +227,27 @@ static void nfs_direct_complete(struct nfs_direct_req *dreq, bool write) {struct inode *inode = dreq->inode; -if (dreq->iocb) { +if (dreq->iocb && write) {loff_t pos = dreq->iocb->ki_pos + dreq->count; + +spin_lock (&inode->i_lock); +if (i_size_read (inode) < pos) +i_size_write (inode, pos); +spin_unlock (&inode->i_lock); + } + +if (write) { +nfs_zap_mapping (inode, inode->i_mapping); +inode_dio_done (inode); + } + +if (dreq->iocb) {long res = (long ) dreq->error;if (!res) res = (long ) dreq->count; - -if (write) { -spin_lock (&inode->i_lock); -if (i_size_read (inode) < pos) -i_size_write (inode, pos); -spin_unlock (&inode->i_lock); - } -aio_complete (dreq->iocb, res,0 ); } +complete_all (&dreq->completion);nfs_direct_req_release (dreq);
@@ -484,12 +490,6 @@ out:return result; } -static void nfs_inode_dio_write_done (struct inode *inode) -{ -nfs_zap_mapping (inode, inode->i_mapping); -inode_dio_done (inode); -} -#if IS_ENABLED (CONFIG_NFS_V3 ) ||IS_ENABLED (CONFIG_NFS_V4 )static void nfs_direct_write_reschedule (struct nfs_direct_req *dreq) {
@@ -605,7 +605,6 @@ static void nfs_direct_write_schedule_work(struct work_struct *work)nfs_direct_write_reschedule (dreq);break ;default : -nfs_inode_dio_write_done (dreq->inode);nfs_direct_complete (dreq, true); } }
@@ -622,7 +621,6 @@ static void nfs_direct_write_schedule_work(struct work_struct *work)static void nfs_direct_write_complete (struct nfs_direct_req *dreq,struct inode *inode) { -nfs_inode_dio_write_done (inode);nfs_direct_complete (dreq, true); }#endif
Signature · 1 line
1.9.1
PATCH 15/40 nfs: increment i_dio_count for reads, too
In reply to Jiri SlabyFrom: Christoph Hellwig <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 1f90ee27461e31a1c18e5d819f6ea6f5c7304b16 upstream.
i_dio_count is used to protect dio access against truncate. We want to make sure there are no dio reads pending either when doing a truncate. I suspect on plain NFS things might work even without this, but once we use a pnfs layout driver that access backing devices directly things will go bad without the proper synchronization.
--- fs/nfs/direct.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
fs/nfs/direct.c +6 -3
@@ -236,10 +236,10 @@ static void nfs_direct_complete(struct nfs_direct_req *dreq, bool write)spin_unlock (&inode->i_lock); } -if (write) { +if (write)nfs_zap_mapping (inode, inode->i_mapping); -inode_dio_done (inode); - } + +inode_dio_done (inode);if (dreq->iocb) {long res = (long ) dreq->error;
@@ -420,6 +420,7 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq, loff_t pos, bool uio) {struct nfs_pageio_descriptor desc; +struct inode *inode = dreq->inode;ssize_t result = -EINVAL ;size_t requested_bytes =0 ;unsigned long seg;
@@ -428,6 +429,7 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq, &nfs_direct_read_completion_ops);get_dreq (dreq); desc.pg_dreq = dreq; +atomic_inc (&inode->i_dio_count);for (seg =0 ; seg < nr_segs; seg++) {const struct iovec *vec = &iov[seg];
@@ -447,6 +449,7 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,* generic layer handle the completion. */ if (requested_bytes ==0 ) { +inode_dio_done (inode);nfs_direct_req_release (dreq);return result <0 ? result : -EIO ; }
Signature · 1 line
1.9.1
PATCH 16/40 pnfs: fix BUG in filelayout_recover_commit_reqs
In reply to Jiri SlabyFrom: Weston Andros Adamson <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 471252cd8b34b0609973740b25dcd1ff01dc1889 upstream.
cond_resched_lock(cinfo->lock) is called everywhere else while holding the cinfo->lock spinlock. Not holding this lock while calling transfer_commit_list in filelayout_recover_commit_reqs causes the BUG below.
It's true that we can't hold this lock while calling pnfs_put_lseg, because that might try to lock the inode lock - which might be the same lock as cinfo->lock.
To reproduce, mount a 2 DS pynfs server and run an O_DIRECT command that crosses a stripe boundary and is not page aligned, such as:
dd if=/dev/zero of=/mnt/f bs=17000 count=1 oflag=direct
BUG: sleeping function called from invalid context at linux/fs/nfs/nfs4filelayout.c:1161
in_atomic(): 0, irqs_disabled(): 0, pid: 27, name: kworker/0:1
2 locks held by kworker/0:1/27:
#0: (events){.+.+.+}, at: [<ffffffff810501d7>] process_one_work+0x175/0x3a5 #1: ((&dreq->work)){+.+...}, at: [<ffffffff810501d7>] process_one_work+0x175/0x3a5
CPU: 0 PID: 27 Comm: kworker/0:1 Not tainted 3.13.0-rc3-branch-dros_testing+ #21 Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/31/2013 Workqueue: events nfs_direct_write_schedule_work [nfs] 0000000000000000 ffff88007a39bbb8 ffffffff81491256 ffff88007b87a130 ffff88007a39bbd8 ffffffff8105f103 ffff880079614000 ffff880079617d40 ffff88007a39bc20 ffffffffa011603e ffff880078988b98 0000000000000000 Call Trace: [<ffffffff81491256>] dump_stack+0x4d/0x66 [<ffffffff8105f103>] __might_sleep+0x100/0x105 [<ffffffffa011603e>] transfer_commit_list+0x94/0xf1 [nfs_layout_nfsv41_files] [<ffffffffa01160d6>] filelayout_recover_commit_reqs+0x3b/0x68 [nfs_layout_nfsv41_files] [<ffffffffa00ba53a>] nfs_direct_write_reschedule+0x9f/0x1d6 [nfs] [<ffffffff810705df>] ? mark_lock+0x1df/0x224 [<ffffffff8106e617>] ? trace_hardirqs_off_caller+0x37/0xa4 [<ffffffff8106e691>] ? trace_hardirqs_off+0xd/0xf [<ffffffffa00ba8f8>] nfs_direct_write_schedule_work+0x9d/0xb7 [nfs] [<ffffffff810501d7>] ? process_one_work+0x175/0x3a5 [<ffffffff81050258>] process_one_work+0x1f6/0x3a5 [<ffffffff810501d7>] ? process_one_work+0x175/0x3a5 [<ffffffff8105187e>] worker_thread+0x149/0x1f5 [<ffffffff81051735>] ? rescuer_thread+0x28d/0x28d [<ffffffff81056d74>] kthread+0xd2/0xda [<ffffffff81056ca2>] ? __kthread_parkme+0x61/0x61 [<ffffffff8149e66c>] ret_from_fork+0x7c/0xb0 [<ffffffff81056ca2>] ? __kthread_parkme+0x61/0x61
--- fs/nfs/nfs4filelayout.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
fs/nfs/nfs4filelayout.c +4 -4
@@ -1216,17 +1216,17 @@ static void filelayout_recover_commit_reqs(struct list_head *dst,struct pnfs_commit_bucket *b;int i; -/* NOTE cinfo->lock is NOT held, relying on fact that this is -* only called on single thread per dreq. -* Can't take the lock because need to do pnfs_put_lseg -*/ +spin_lock (cinfo->lock);for (i =0 , b = cinfo->ds->buckets; i < cinfo->ds->nbuckets; i++, b++) {if (transfer_commit_list (&b->written, dst, cinfo,0 )) { +spin_unlock (cinfo->lock);pnfs_put_lseg (b->wlseg); b->wlseg =NULL ; +spin_lock (cinfo->lock); } } cinfo->ds->nwritten =0 ; +spin_unlock (cinfo->lock); } static unsigned int
Signature · 1 line
1.9.1
PATCH 17/40 NFS: fix the handling of NFS_INO_INVALID_DATA flag in nfs_revalidate_mapping
In reply to Jiri SlabyFrom: Jeff Layton <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit d529ef83c355f97027ff85298a9709fe06216a66 upstream.
There is a possible race in how the nfs_invalidate_mapping function is handled. Currently, we go and invalidate the pages in the file and then clear NFS_INO_INVALID_DATA.
The problem is that it's possible for a stale page to creep into the mapping after the page was invalidated (i.e., via readahead). If another writer comes along and sets the flag after that happens but before invalidate_inode_pages2 returns then we could clear the flag without the cache having been properly invalidated.
So, we must clear the flag first and then invalidate the pages. Doing this however, opens another race:
It's possible to have two concurrent read() calls that end up in nfs_revalidate_mapping at the same time. The first one clears the NFS_INO_INVALID_DATA flag and then goes to call nfs_invalidate_mapping.
Just before calling that though, the other task races in, checks the flag and finds it cleared. At that point, it trusts that the mapping is good and gets the lock on the page, allowing the read() to be satisfied from the cache even though the data is no longer valid.
These effects are easily manifested by running diotest3 from the LTP test suite on NFS. That program does a series of DIO writes and buffered reads. The operations are serialized and page-aligned but the existing code fails the test since it occasionally allows a read to come out of the cache incorrectly. While mixing direct and buffered I/O isn't recommended, I believe it's possible to hit this in other ways that just use buffered I/O, though that situation is much harder to reproduce.
The problem is that the checking/clearing of that flag and the invalidation of the mapping really need to be atomic. Fix this by serializing concurrent invalidations with a bitlock.
At the same time, we also need to allow other places that check NFS_INO_INVALID_DATA to check whether we might be in the middle of invalidating the file, so fix up a couple of places that do that to look for the new NFS_INO_INVALIDATING flag.
Doing this requires us to be careful not to set the bitlock unnecessarily, so this code only does that if it believes it will be doing an invalidation.
--- fs/nfs/dir.c | 3 ++- fs/nfs/inode.c | 42 ++++++++++++++++++++++++++++++++++++++---- fs/nfs/nfstrace.h | 1 + fs/nfs/write.c | 6 +++++- include/linux/nfs_fs.h | 1 + 5 files changed, 47 insertions(+), 6 deletions(-)
fs/nfs/dir.c +2 -1
@@ -290,7 +290,8 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_des new_pos = desc->current_index + i;if (ctx->attr_gencount != nfsi->attr_gencount - || (nfsi->cache_validity & (NFS_INO_INVALID_ATTR |NFS_INO_INVALID_DATA ))) { + || (nfsi->cache_validity & (NFS_INO_INVALID_ATTR |NFS_INO_INVALID_DATA )) + ||test_bit (NFS_INO_INVALIDATING , &nfsi->flags)) { ctx->duped =0 ; ctx->attr_gencount = nfsi->attr_gencount; }else if (new_pos < desc->ctx->pos) {
fs/nfs/inode.c +38 -4
67 lines not on this page · raw message
fs/nfs/nfstrace.h +1 -0
@@ -36,6 +36,7 @@ __print_flags(v, "|", \ { 1 << NFS_INO_ADVISE_RDPLUS, "ADVISE_RDPLUS" }, \ { 1 << NFS_INO_STALE, "STALE" }, \ + { 1 << NFS_INO_INVALIDATING, "INVALIDATING" }, \ { 1 << NFS_INO_FLUSHING, "FLUSHING" }, \ { 1 << NFS_INO_FSCACHE, "FSCACHE" }, \ { 1 << NFS_INO_COMMIT, "COMMIT" }, \
fs/nfs/write.c +5 -1
@@ -909,9 +909,13 @@ bool nfs_ctx_key_to_expire(struct nfs_open_context *ctx)*/ static bool nfs_write_pageuptodate (struct page *page,struct inode *inode) { +struct nfs_inode *nfsi =NFS_I (inode); +if (nfs_have_delegated_attributes (inode)) goto out; -if (NFS_I (inode)->cache_validity & (NFS_INO_INVALID_DATA |NFS_INO_REVAL_PAGECACHE )) +if (nfsi->cache_validity & (NFS_INO_INVALID_DATA |NFS_INO_REVAL_PAGECACHE )) +return false; +if (test_bit (NFS_INO_INVALIDATING , &nfsi->flags))return false; out:return PageUptodate (page) !=0 ;
include/linux/nfs_fs.h +1 -0
@@ -215,6 +215,7 @@ struct nfs_inode {#define NFS_INO_ADVISE_RDPLUS (0)/* advise readdirplus */ #define NFS_INO_STALE (1)/* possible stale inode */ #define NFS_INO_ACL_LRU_SET (2)/* Inode is on the LRU list */ +#define NFS_INO_INVALIDATING (3)/* inode is being invalidated */ #define NFS_INO_FLUSHING (4)/* inode is flushing out data */ #define NFS_INO_FSCACHE (5)/* inode can be cached by FS-Cache */ #define NFS_INO_FSCACHE_LOCK (6)/* FS-Cache cookie management lock */
Signature · 1 line
1.9.1
PATCH 18/40 NFS: Fix races in nfs_revalidate_mapping
In reply to Jiri SlabyFrom: Trond Myklebust <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 17dfeb9113397a6119091a491ef7182649f0c5a9 upstream.
Commit d529ef83c355f97027ff85298a9709fe06216a66 (NFS: fix the handling of NFS_INO_INVALID_DATA flag in nfs_revalidate_mapping) introduces a potential race, since it doesn't test the value of nfsi->cache_validity and set the bitlock in nfsi->flags atomically.
--- fs/nfs/inode.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-)
fs/nfs/inode.c +14 -14
@@ -1048,24 +1048,24 @@ int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping) nfs_wait_bit_killable, TASK_KILLABLE);if (ret) goto out; -if (!(nfsi->cache_validity &NFS_INO_INVALID_DATA )) - goto out; -if (!test_and_set_bit_lock (NFS_INO_INVALIDATING , bitlock)) +spin_lock (&inode->i_lock); +if (test_bit (NFS_INO_INVALIDATING , bitlock)) { +spin_unlock (&inode->i_lock); +continue ; + } +if (nfsi->cache_validity &NFS_INO_INVALID_DATA )break ; - } - -spin_lock (&inode->i_lock); -if (nfsi->cache_validity &NFS_INO_INVALID_DATA ) { - nfsi->cache_validity &= ~NFS_INO_INVALID_DATA ; -spin_unlock (&inode->i_lock); -trace_nfs_invalidate_mapping_enter (inode); - ret =nfs_invalidate_mapping (inode, mapping); -trace_nfs_invalidate_mapping_exit (inode, ret); - }else { -/* something raced in and cleared the flag */ spin_unlock (&inode->i_lock); + goto out; } +set_bit (NFS_INO_INVALIDATING , bitlock); + nfsi->cache_validity &= ~NFS_INO_INVALID_DATA ; +spin_unlock (&inode->i_lock); +trace_nfs_invalidate_mapping_enter (inode); + ret =nfs_invalidate_mapping (inode, mapping); +trace_nfs_invalidate_mapping_exit (inode, ret); +clear_bit_unlock (NFS_INO_INVALIDATING , bitlock);smp_mb__after_clear_bit ();wake_up_bit (bitlock,NFS_INO_INVALIDATING );
Signature · 1 line
1.9.1
PATCH 19/40 nfs: add memory barriers around NFS_INO_INVALID_DATA and NFS_INO_INVALIDATING
In reply to Jiri SlabyFrom: Jeff Layton <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 4db72b40fdbc706f8957e9773ae73b1574b8c694 upstream.
If the setting of NFS_INO_INVALIDATING gets reordered to before the clearing of NFS_INO_INVALID_DATA, then another task may hit a race window where both appear to be clear, even though the inode's pages are still in need of invalidation. Fix this by adding the appropriate memory barriers.
--- fs/nfs/dir.c | 14 +++++++++++--- fs/nfs/inode.c | 1 + fs/nfs/write.c | 1 + 3 files changed, 13 insertions(+), 3 deletions(-)
fs/nfs/dir.c +11 -3
@@ -276,6 +276,15 @@ out_eof:return -EBADCOOKIE ; } +static bool +nfs_readdir_inode_mapping_valid (struct nfs_inode *nfsi) +{ +if (nfsi->cache_validity & (NFS_INO_INVALID_ATTR |NFS_INO_INVALID_DATA )) +return false; +smp_rmb (); +return !test_bit (NFS_INO_INVALIDATING , &nfsi->flags); +} +static int nfs_readdir_search_for_cookie (struct nfs_cache_array *array,nfs_readdir_descriptor_t *desc) {
@@ -289,9 +298,8 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_desstruct nfs_open_dir_context *ctx = desc->file->private_data; new_pos = desc->current_index + i; -if (ctx->attr_gencount != nfsi->attr_gencount - || (nfsi->cache_validity & (NFS_INO_INVALID_ATTR |NFS_INO_INVALID_DATA )) - ||test_bit (NFS_INO_INVALIDATING , &nfsi->flags)) { +if (ctx->attr_gencount != nfsi->attr_gencount || + !nfs_readdir_inode_mapping_valid (nfsi)) { ctx->duped =0 ; ctx->attr_gencount = nfsi->attr_gencount; }else if (new_pos < desc->ctx->pos) {
fs/nfs/inode.c +1 -0
@@ -1060,6 +1060,7 @@ int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping) }set_bit (NFS_INO_INVALIDATING , bitlock); +smp_wmb (); nfsi->cache_validity &= ~NFS_INO_INVALID_DATA ;spin_unlock (&inode->i_lock);trace_nfs_invalidate_mapping_enter (inode);
fs/nfs/write.c +1 -0
@@ -915,6 +915,7 @@ static bool nfs_write_pageuptodate(struct page *page, struct inode *inode) goto out;if (nfsi->cache_validity & (NFS_INO_INVALID_DATA |NFS_INO_REVAL_PAGECACHE ))return false; +smp_rmb ();if (test_bit (NFS_INO_INVALIDATING , &nfsi->flags))return false; out:
Signature · 1 line
1.9.1
PATCH 20/40 NFSv4.1 free slot before resending I/O to MDS
In reply to Jiri SlabyFrom: Andy Adamson <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit f9c96fcc501a43dbc292b17fc0ded4b54e63b79d upstream.
Fix a dynamic session slot leak where a slot is preallocated and I/O is resent through the MDS.
--- fs/nfs/nfs4_fs.h | 1 + fs/nfs/nfs4filelayout.c | 10 ++++++++-- fs/nfs/nfs4proc.c | 3 ++- 3 files changed, 11 insertions(+), 3 deletions(-)
fs/nfs/nfs4_fs.h +1 -0
@@ -249,6 +249,7 @@ static inline struct nfs4_session *nfs4_get_session(const struct nfs_server *serextern int nfs41_setup_sequence (struct nfs4_session *session,struct nfs4_sequence_args *args,struct nfs4_sequence_res *res,struct rpc_task *task); +extern int nfs41_sequence_done (struct rpc_task *,struct nfs4_sequence_res *);extern int nfs4_proc_create_session (struct nfs_client *,struct rpc_cred *);extern int nfs4_proc_destroy_session (struct nfs4_session *,struct rpc_cred *); extern int nfs4_proc_get_lease_time(struct nfs_client *clp,
fs/nfs/nfs4filelayout.c +8 -2
@@ -335,8 +335,11 @@ static void filelayout_read_call_done(struct rpc_task *task, void *data)dprintk ("--> %s task->tk_status %d\n" , __func__, task->tk_status);if (test_bit (NFS_IOHDR_REDO , &rdata->header->flags) && - task->tk_status ==0 ) + task->tk_status ==0 ) { +if (rdata->res.seq_res.sr_slot !=NULL ) +nfs41_sequence_done (task, &rdata->res.seq_res);return ; + }/* Note this may cause RPC to be resent */ rdata->header->mds_ops->rpc_call_done (task, data);
@@ -442,8 +445,11 @@ static void filelayout_write_call_done(struct rpc_task *task, void *data)struct nfs_write_data *wdata = data;if (test_bit (NFS_IOHDR_REDO , &wdata->header->flags) && - task->tk_status ==0 ) + task->tk_status ==0 ) { +if (wdata->res.seq_res.sr_slot !=NULL ) +nfs41_sequence_done (task, &wdata->res.seq_res);return ; + }/* Note this may cause RPC to be resent */ wdata->header->mds_ops->rpc_call_done (task, data);
fs/nfs/nfs4proc.c +2 -1
@@ -585,7 +585,7 @@ out_unlock:nfs41_server_notify_highest_slotid_update (session->clp); } -static int nfs41_sequence_done (struct rpc_task *task,struct nfs4_sequence_res *res) +int nfs41_sequence_done (struct rpc_task *task,struct nfs4_sequence_res *res) {struct nfs4_session *session;struct nfs4_slot *slot;
@@ -685,6 +685,7 @@ out_retry:rpc_delay (task,NFS4_POLL_RETRY_MAX );return 0 ; } +EXPORT_SYMBOL_GPL (nfs41_sequence_done);static int nfs4_sequence_done (struct rpc_task *task,struct nfs4_sequence_res *res)
Signature · 1 line
1.9.1
PATCH 21/40 dlm: set zero linger time on sctp socket
In reply to Jiri SlabyFrom: Dongmao Zhang <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit ece35848c1847cdf3dd07954578d3e99238ebbae upstream.
The recovery time for a failed node was taking a long time because the failed node could not perform the full shutdown process. Removing the linger time speeds this up. The dlm does not care what happens to messages to or from the failed node.
--- fs/dlm/lowcomms.c | 8 ++++++++ 1 file changed, 8 insertions(+)
fs/dlm/lowcomms.c +8 -0
@@ -649,6 +649,7 @@ static void process_sctp_notification(struct connection *con, struct msghdr *msg, char *buf) { union sctp_notification *sn = (union sctp_notification *)buf; +struct linger linger;switch (sn->sn_header.sn_type) {case SCTP_SEND_FAILED :
@@ -727,6 +728,13 @@ static void process_sctp_notification(struct connection *con, }add_sock (new_con->sock, new_con); + linger.l_onoff =1 ; + linger.l_linger =0 ; + ret =kernel_setsockopt (new_con->sock,SOL_SOCKET ,SO_LINGER , + (char *)&linger,sizeof (linger)); +if (ret <0 ) +log_print ("set socket option SO_LINGER failed" ); +log_print ("connecting to %d sctp association %d" , nodeid, (int )sn->sn_assoc_change.sac_assoc_id);
Signature · 1 line
1.9.1
PATCH 22/40 FS-Cache: Handle removal of unadded object to the fscache_object_list rb tree
In reply to Jiri SlabyFrom: David Howells <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 7026f1929e18921fd67bf478f475a8fdfdff16ae upstream.
When FS-Cache allocates an object, the following sequence of events can occur:
-->fscache_alloc_object()
-->cachefiles_alloc_object() [via cache->ops->alloc_object]
<--[returns new object]
-->fscache_attach_object()
<--[failed]
-->cachefiles_put_object() [via cache->ops->put_object]
-->fscache_object_destroy()
-->fscache_objlist_remove()
-->rb_erase() to remove the object from fscache_object_list.resulting in a crash in the rbtree code.
The problem is that the object is only added to fscache_object_list on the success path of fscache_attach_object() where it calls fscache_objlist_add().
So if fscache_attach_object() fails, the object won't have been added to the objlist rbtree. We do, however, unconditionally try to remove the object from the tree.
Thanks to NeilBrown for finding this and suggesting this solution.
--- fs/fscache/object-list.c | 5 +++++ fs/fscache/object.c | 3 +++ 2 files changed, 8 insertions(+)
fs/fscache/object-list.c +5 -0
@@ -50,6 +50,8 @@ void fscache_objlist_add(struct fscache_object *obj)struct fscache_object *xobj;struct rb_node **p = &fscache_object_list.rb_node, *parent =NULL ; +ASSERT (RB_EMPTY_NODE (&obj->objlist_link)); +write_lock (&fscache_object_list_lock);while (*p) {
@@ -75,6 +77,9 @@ void fscache_objlist_add(struct fscache_object *obj)*/ void fscache_objlist_remove (struct fscache_object *obj) { +if (RB_EMPTY_NODE (&obj->objlist_link)) +return ; +write_lock (&fscache_object_list_lock);BUG_ON (RB_EMPTY_ROOT (&fscache_object_list));
fs/fscache/object.c +3 -0
@@ -314,6 +314,9 @@ void fscache_object_init(struct fscache_object *object, object->cache = cache; object->cookie = cookie; object->parent =NULL ; +#ifdef CONFIG_FSCACHE_OBJECT_LIST +RB_CLEAR_NODE (&object->objlist_link); +#endif object->oob_event_mask =0 ;for (t = object->oob_table; t->events; t++)
Signature · 1 line
1.9.1
PATCH 23/40 ipvs: fix AF assignment in ip_vs_conn_new()
In reply to Jiri SlabyFrom: Michal Kubecek <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 2a971354e74f3837d14b9c8d7f7983b0c9c330e4 upstream.
If a fwmark is passed to ip_vs_conn_new(), it is passed in vaddr, not daddr. Therefore we should set AF to AF_UNSPEC in vaddr assignment (like we do in ip_vs_ct_in_get()), otherwise we may copy only first 4 bytes of an IPv6 address into cp->daddr.
--- net/netfilter/ipvs/ip_vs_conn.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
net/netfilter/ipvs/ip_vs_conn.c +4 -4
@@ -871,11 +871,11 @@ ip_vs_conn_new(const struct ip_vs_conn_param *p, cp->protocol = p->protocol;ip_vs_addr_set (p->af, &cp->caddr, p->caddr); cp->cport = p->cport; -ip_vs_addr_set (p->af, &cp->vaddr, p->vaddr); - cp->vport = p->vport; -/* proto should only be IPPROTO_IP if d_addr is a fwmark */ +/* proto should only be IPPROTO_IP if p->vaddr is a fwmark */ ip_vs_addr_set (p->protocol ==IPPROTO_IP ?AF_UNSPEC : p->af, - &cp->daddr, daddr); + &cp->vaddr, p->vaddr); + cp->vport = p->vport; +ip_vs_addr_set (p->af, &cp->daddr, daddr); cp->dport = dport; cp->flags = flags; cp->fwmark = fwmark;
Signature · 1 line
1.9.1
PATCH 24/40 Input: wacom - add support for three new Intuos Pro devices
In reply to Jiri SlabyFrom: Ping Cheng <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit b5fd2a3e92ca5c8c1f3c20d31ac5daed3ec4d604 upstream.
Two tablets in this series support both pen and touch. One (Intuos S) only supports pen. This patch also updates the driver to process wireless devices that do not support touch interface.
--- drivers/input/tablet/wacom_sys.c | 10 +++++-- drivers/input/tablet/wacom_wac.c | 61 +++++++++++++++++++++++++++++++--------- drivers/input/tablet/wacom_wac.h | 3 ++ 3 files changed, 58 insertions(+), 16 deletions(-)
drivers/input/tablet/wacom_sys.c +8 -2
@@ -722,7 +722,7 @@ static int wacom_led_control(struct wacom *wacom)return -ENOMEM ;if (wacom->wacom_wac.features.type >=INTUOS5S && - wacom->wacom_wac.features.type <=INTUOS5L ) { + wacom->wacom_wac.features.type <=INTUOSPL ) {/* * Touch Ring and crop mark LED luminance may take on * one of four values:
@@ -984,6 +984,9 @@ static int wacom_initialize_leds(struct wacom *wacom)case INTUOS5S :case INTUOS5 :case INTUOS5L : +case INTUOSPS : +case INTUOSPM : +case INTUOSPL : wacom->led.select[0 ] =0 ; wacom->led.select[1 ] =0 ; wacom->led.llv =32 ;
@@ -1027,6 +1030,9 @@ static void wacom_destroy_leds(struct wacom *wacom)case INTUOS5S :case INTUOS5 :case INTUOS5L : +case INTUOSPS : +case INTUOSPM : +case INTUOSPL :sysfs_remove_group (&wacom->intf->dev.kobj, &intuos5_led_attr_group);break ;
@@ -1305,7 +1311,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i* HID descriptor. If this is the touch interface (wMaxPacketSize * of WACOM_PKGLEN_BBTOUCH3), override the table values. */ -if (features->type >=INTUOS5S && features->type <=INTUOS5L ) { +if (features->type >=INTUOS5S && features->type <=INTUOSPL ) {if (endpoint->wMaxPacketSize ==WACOM_PKGLEN_BBTOUCH3 ) { features->device_type =BTN_TOOL_FINGER ; features->pktlen =WACOM_PKGLEN_BBTOUCH3 ;
drivers/input/tablet/wacom_wac.c +47 -14
140 lines not on this page · raw message
drivers/input/tablet/wacom_wac.h +3 -0
@@ -76,6 +76,9 @@ enum {INTUOS5S ,INTUOS5 ,INTUOS5L , +INTUOSPS , +INTUOSPM , +INTUOSPL ,WACOM_21UX2 ,WACOM_22HD , DTK,
Signature · 1 line
1.9.1
PATCH 25/40 s390/time,vdso: fix clock_gettime for CLOCK_MONOTONIC
In reply to Jiri SlabyFrom: Martin Schwidefsky <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit ca5de58ba746b08c920b2024aaf01aa1500b110d upstream.
With git commit 79c74ecbebf76732f91b82a62ce7fc8a88326962 "s390/time,vdso: convert to the new update_vsyscall interface" the new update_vsyscall function already does the sum of xtime and wall_to_monotonic. The old update_vsyscall function only copied the wall_to_monotonic offset. The vdso code needs to be modified to take this into consideration.
--- arch/s390/kernel/vdso32/clock_gettime.S | 9 ++------- arch/s390/kernel/vdso64/clock_gettime.S | 6 ++---- 2 files changed, 4 insertions(+), 11 deletions(-)
arch/s390/kernel/vdso32/clock_gettime.S +2 -7
@@ -46,18 +46,13 @@ __kernel_clock_gettime: jnm 3f a %r0,__VDSO_TK_MULT(%r5) 3: alr %r0,%r2 - al %r0,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */ - al %r1,__VDSO_XTIME_NSEC+4(%r5) - brc 12,4f - ahi %r0,1 -4: al %r0,__VDSO_WTOM_NSEC(%r5) /* + wall_to_monotonic.nsec */ + al %r0,__VDSO_WTOM_NSEC(%r5) al %r1,__VDSO_WTOM_NSEC+4(%r5) brc 12,5f ahi %r0,1 5: l %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ srdl %r0,0(%r2) /* >> tk->shift */ - l %r2,__VDSO_XTIME_SEC+4(%r5) - al %r2,__VDSO_WTOM_SEC+4(%r5) + l %r2,__VDSO_WTOM_SEC+4(%r5) cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */ jne 1b basr %r5,0
arch/s390/kernel/vdso64/clock_gettime.S +2 -4
@@ -35,13 +35,11 @@ __kernel_clock_gettime: jnz 0b stck 48(%r15) /* Store TOD clock */ lgf %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ - lg %r0,__VDSO_XTIME_SEC(%r5) /* tk->xtime_sec */ - alg %r0,__VDSO_WTOM_SEC(%r5) /* + wall_to_monotonic.sec */ + lg %r0,__VDSO_WTOM_SEC(%r5) lg %r1,48(%r15) sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */ - alg %r1,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */ - alg %r1,__VDSO_WTOM_NSEC(%r5) /* + wall_to_monotonic.nsec */ + alg %r1,__VDSO_WTOM_NSEC(%r5) srlg %r1,%r1,0(%r2) /* >> tk->shift */ clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */ jne 0b
Signature · 1 line
1.9.1
PATCH 26/40 ext4: atomically set inode->i_flags in ext4_set_inode_flags()
In reply to Jiri SlabyFrom: Theodore Ts'o <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 00a1a053ebe5febcfc2ec498bd894f035ad2aa06 upstream.
Use cmpxchg() to atomically set i_flags instead of clearing out the S_IMMUTABLE, S_APPEND, etc. flags and then setting them from the EXT4_IMMUTABLE_FL, EXT4_APPEND_FL flags, since this opens up a race where an immutable file has the immutable flag cleared for a brief window of time.
--- fs/ext4/inode.c | 15 +++++++++------ include/linux/bitops.h | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 6 deletions(-)
fs/ext4/inode.c +9 -6
@@ -38,6 +38,7 @@#include <linux/slab.h> #include <linux/ratelimit.h> #include <linux/aio.h> +#include <linux/bitops.h> #include "ext4_jbd2.h" #include "xattr.h"
@@ -3922,18 +3923,20 @@ int ext4_get_inode_loc(struct inode *inode, struct ext4_iloc *iloc)void ext4_set_inode_flags (struct inode *inode) {unsigned int flags =EXT4_I (inode)->i_flags; +unsigned int new_fl =0 ; - inode->i_flags &= ~(S_SYNC |S_APPEND |S_IMMUTABLE |S_NOATIME |S_DIRSYNC );if (flags &EXT4_SYNC_FL ) - inode->i_flags |=S_SYNC ; + new_fl |=S_SYNC ;if (flags &EXT4_APPEND_FL ) - inode->i_flags |=S_APPEND ; + new_fl |=S_APPEND ;if (flags &EXT4_IMMUTABLE_FL ) - inode->i_flags |=S_IMMUTABLE ; + new_fl |=S_IMMUTABLE ;if (flags &EXT4_NOATIME_FL ) - inode->i_flags |=S_NOATIME ; + new_fl |=S_NOATIME ;if (flags &EXT4_DIRSYNC_FL ) - inode->i_flags |=S_DIRSYNC ; + new_fl |=S_DIRSYNC ; +set_mask_bits (&inode->i_flags, +S_SYNC |S_APPEND |S_IMMUTABLE |S_NOATIME |S_DIRSYNC , new_fl); }/* Propagate flags from i_flags to EXT4_I(inode)->i_flags */
include/linux/bitops.h +15 -0
@@ -185,6 +185,21 @@ static inline unsigned long __ffs64(u64 word)#ifdef __KERNEL__ +#ifndef set_mask_bits +#define set_mask_bits (ptr, _mask, _bits) \ +({ \ + const typeof(*ptr) mask = (_mask), bits = (_bits); \ + typeof(*ptr) old, new; \ + \ + do { \ + old = ACCESS_ONCE(*ptr); \ + new = (old & ~mask) | bits; \ + } while (cmpxchg(ptr, old, new) != old); \ + \ + new; \ +}) +#endif +#ifndef find_last_bit/** * find_last_bit - find the last set bit in a memory region
Signature · 1 line
1.9.1
PATCH 27/40 Input: mousedev - fix race when creating mixed device
In reply to Jiri SlabyFrom: Dmitry Torokhov <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit e4dbedc7eac7da9db363a36f2bd4366962eeefcc upstream.
We should not be using static variable mousedev_mix in methods that can be called before that singleton gets assigned. While at it let's add open and close methods to mousedev structure so that we do not need to test if we are dealing with multiplexor or normal device and simply call appropriate method directly.
This fixes: https://bugzilla.kernel.org/show_bug.cgi?id=71551
--- drivers/input/mousedev.c | 73 ++++++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 31 deletions(-)
drivers/input/mousedev.c +42 -31
@@ -67,7 +67,6 @@ struct mousedev {struct device dev;struct cdev cdev;bool exist; -bool is_mixdev;struct list_head mixdev_node;bool opened_by_mixdev;
@@ -77,6 +76,9 @@ struct mousedev {int old_x[4 ], old_y[4 ];int frac_dx, frac_dy;unsigned long touch; + +int (*open_device)(struct mousedev *mousedev); +void (*close_device)(struct mousedev *mousedev); };enum mousedev_emul {
@@ -116,9 +118,6 @@ static unsigned char mousedev_imex_seq[] = { 0xf3, 200, 0xf3, 200, 0xf3, 80 };static struct mousedev *mousedev_mix;static LIST_HEAD (mousedev_mix_list); -static void mixdev_open_devices (void ); -static void mixdev_close_devices (void ); -#define fx (i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03])#define fy (i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03])
@@ -428,9 +427,7 @@ static int mousedev_open_device(struct mousedev *mousedev)if (retval)return retval; -if (mousedev->is_mixdev) -mixdev_open_devices (); -else if (!mousedev->exist) +if (!mousedev->exist) retval = -ENODEV ;else if (!mousedev->open++) { retval =input_open_device (&mousedev->handle);
@@ -446,9 +443,7 @@ static void mousedev_close_device(struct mousedev *mousedev) {mutex_lock (&mousedev->mutex); -if (mousedev->is_mixdev) -mixdev_close_devices (); -else if (mousedev->exist && !--mousedev->open) +if (mousedev->exist && !--mousedev->open)input_close_device (&mousedev->handle);mutex_unlock (&mousedev->mutex);
@@ -459,21 +454,29 @@ static void mousedev_close_device(struct mousedev *mousedev)* stream. Note that this function is called with mousedev_mix->mutex * held. */ -static void mixdev_open_devices (void ) +static int mixdev_open_devices (struct mousedev *mixdev) { -struct mousedev *mousedev; +int error; + + error =mutex_lock_interruptible (&mixdev->mutex); +if (error) +return error; -if (mousedev_mix->open++) -return ; +if (!mixdev->open++) { +struct mousedev *mousedev; -list_for_each_entry (mousedev, &mousedev_mix_list, mixdev_node) { -if (!mousedev->opened_by_mixdev) { -if (mousedev_open_device (mousedev)) -continue ; +list_for_each_entry (mousedev, &mousedev_mix_list, mixdev_node) { +if (!mousedev->opened_by_mixdev) { +if (mousedev_open_device (mousedev)) +continue ; - mousedev->opened_by_mixdev = true; + mousedev->opened_by_mixdev = true; + } } } + +mutex_unlock (&mixdev->mutex); +return 0 ; }/*
@@ -481,19 +484,22 @@ static void mixdev_open_devices(void)* device. Note that this function is called with mousedev_mix->mutex * held. */ -static void mixdev_close_devices (void ) +static void mixdev_close_devices (struct mousedev *mixdev) { -struct mousedev *mousedev; +mutex_lock (&mixdev->mutex); -if (--mousedev_mix->open) -return ; +if (!--mixdev->open) { +struct mousedev *mousedev; -list_for_each_entry (mousedev, &mousedev_mix_list, mixdev_node) { -if (mousedev->opened_by_mixdev) { - mousedev->opened_by_mixdev = false; -mousedev_close_device (mousedev); +list_for_each_entry (mousedev, &mousedev_mix_list, mixdev_node) { +if (mousedev->opened_by_mixdev) { + mousedev->opened_by_mixdev = false; +mousedev_close_device (mousedev); + } } } + +mutex_unlock (&mixdev->mutex); }
@@ -522,7 +528,7 @@ static int mousedev_release(struct inode *inode, struct file *file)mousedev_detach_client (mousedev, client);kfree (client); -mousedev_close_device (mousedev); + mousedev->close_device (mousedev);return 0 ; }
@@ -550,7 +556,7 @@ static int mousedev_open(struct inode *inode, struct file *file) client->mousedev = mousedev;mousedev_attach_client (mousedev, client); - error =mousedev_open_device (mousedev); + error = mousedev->open_device (mousedev);if (error) goto err_free_client;
@@ -861,16 +867,21 @@ static struct mousedev *mousedev_create(struct input_dev *dev,if (mixdev) {dev_set_name (&mousedev->dev,"mice" ); + + mousedev->open_device = mixdev_open_devices; + mousedev->close_device = mixdev_close_devices; }else {int dev_no = minor;/* Normalize device number if it falls into legacy range */ if (dev_no <MOUSEDEV_MINOR_BASE +MOUSEDEV_MINORS ) dev_no -=MOUSEDEV_MINOR_BASE ;dev_set_name (&mousedev->dev,"mouse%d" , dev_no); + + mousedev->open_device = mousedev_open_device; + mousedev->close_device = mousedev_close_device; } mousedev->exist = true; - mousedev->is_mixdev = mixdev; mousedev->handle.dev =input_get_device (dev); mousedev->handle.name =dev_name (&mousedev->dev); mousedev->handle.handler = handler;
@@ -919,7 +930,7 @@ static void mousedev_destroy(struct mousedev *mousedev)device_del (&mousedev->dev);mousedev_cleanup (mousedev);input_free_minor (MINOR (mousedev->dev.devt)); -if (!mousedev->is_mixdev) +if (mousedev != mousedev_mix)input_unregister_handle (&mousedev->handle);put_device (&mousedev->dev); }
Signature · 1 line
1.9.1
PATCH 28/40 Input: synaptics - add manual min/max quirk
In reply to Jiri SlabyFrom: Benjamin Tissoires <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 421e08c41fda1f0c2ff6af81a67b491389b653a5 upstream.
The new Lenovo Haswell series (-40's) contains a new Synaptics touchpad. However, these new Synaptics devices report bad axis ranges. Under Windows, it is not a problem because the Windows driver uses RMI4 over SMBus to talk to the device. Under Linux, we are using the PS/2 fallback interface and it occurs the reported ranges are wrong.
Of course, it would be too easy to have only one range for the whole series, each touchpad seems to be calibrated in a different way.
We can not use SMBus to get the actual range because I suspect the firmware will switch into the SMBus mode and stop talking through PS/2 (this is the case for hybrid HID over I2C / PS/2 Synaptics touchpads).
So as a temporary solution (until RMI4 land into upstream), start a new list of quirks with the min/max manually set.
--- drivers/input/mouse/synaptics.c | 47 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+)
drivers/input/mouse/synaptics.c +47 -0
@@ -265,11 +265,22 @@ static int synaptics_identify(struct psmouse *psmouse)* Read touchpad resolution and maximum reported coordinates * Resolution is left zero if touchpad does not support the query */ + +static const int *quirk_min_max; +static int synaptics_resolution (struct psmouse *psmouse) {struct synaptics_data *priv = psmouse->private;unsigned char resp[3 ]; +if (quirk_min_max) { + priv->x_min = quirk_min_max[0 ]; + priv->x_max = quirk_min_max[1 ]; + priv->y_min = quirk_min_max[2 ]; + priv->y_max = quirk_min_max[3 ]; +return 0 ; + } +if (SYN_ID_MAJOR (priv->identity) <4 )return 0 ;
@@ -1485,10 +1496,46 @@ static const struct dmi_system_id olpc_dmi_table[] __initconst = { { } }; +static const struct dmi_system_id min_max_dmi_table[]__initconst = { +#if defined(CONFIG_DMI) + { +/* Lenovo ThinkPad Helix */ + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"LENOVO" ), +DMI_MATCH (DMI_PRODUCT_VERSION ,"ThinkPad Helix" ), + }, + .driver_data = (int []){1024 ,5052 ,2258 ,4832 }, + }, + { +/* Lenovo ThinkPad T440s */ + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"LENOVO" ), +DMI_MATCH (DMI_PRODUCT_VERSION ,"ThinkPad T440" ), + }, + .driver_data = (int []){1024 ,5112 ,2024 ,4832 }, + }, + { +/* Lenovo ThinkPad T540p */ + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"LENOVO" ), +DMI_MATCH (DMI_PRODUCT_VERSION ,"ThinkPad T540" ), + }, + .driver_data = (int []){1024 ,5056 ,2058 ,4832 }, + }, +#endif + { } +}; +void __init synaptics_module_init (void ) { +const struct dmi_system_id *min_max_dmi; + impaired_toshiba_kbc =dmi_check_system (toshiba_dmi_table); broken_olpc_ec =dmi_check_system (olpc_dmi_table); + + min_max_dmi =dmi_first_match (min_max_dmi_table); +if (min_max_dmi) + quirk_min_max = min_max_dmi->driver_data; }static int __synaptics_init (struct psmouse *psmouse,bool absolute_mode)
Signature · 1 line
1.9.1
PATCH 29/40 Input: synaptics - add manual min/max quirk for ThinkPad X240
In reply to Jiri SlabyFrom: Hans de Goede <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 8a0435d958fb36d93b8df610124a0e91e5675c82 upstream.
This extends Benjamin Tissoires manual min/max quirk table with support for the ThinkPad X240.
--- drivers/input/mouse/synaptics.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/input/mouse/synaptics.c +8 -0
@@ -1507,6 +1507,14 @@ static const struct dmi_system_id min_max_dmi_table[] __initconst = { .driver_data = (int []){1024, 5052, 2258, 4832}, }, { +/* Lenovo ThinkPad X240 */ + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"LENOVO" ), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X240"), + }, + .driver_data = (int []){1232, 5710, 1156, 4696}, + }, + {/* Lenovo ThinkPad T440s */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
Signature · 1 line
1.9.1
PATCH 30/40 Input: cypress_ps2 - don't report as a button pads
In reply to Jiri SlabyFrom: Hans de Goede <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 6797b39e6f6f34c74177736e146406e894b9482b upstream.
The cypress PS/2 trackpad models supported by the cypress_ps2 driver emulate BTN_RIGHT events in firmware based on the finger position, as part of this no motion events are sent when the finger is in the button area.
The INPUT_PROP_BUTTONPAD property is there to indicate to userspace that BTN_RIGHT events should be emulated in userspace, which is not necessary in this case.
When INPUT_PROP_BUTTONPAD is advertised userspace will wait for a motion event before propagating the button event higher up the stack, as it needs current abs x + y data for its BTN_RIGHT emulation. Since in the cypress_ps2 pads don't report motion events in the button area, this means that clicks in the button area end up being ignored, so INPUT_PROP_BUTTONPAD actually causes problems for these touchpads, and removing it fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=76341
--- drivers/input/mouse/cypress_ps2.c | 1 - 1 file changed, 1 deletion(-)
drivers/input/mouse/cypress_ps2.c +0 -1
@@ -410,7 +410,6 @@ static int cypress_set_input_params(struct input_dev *input,__clear_bit (REL_X , input->relbit);__clear_bit (REL_Y , input->relbit); -__set_bit (INPUT_PROP_BUTTONPAD , input->propbit);__set_bit (EV_KEY , input->evbit);__set_bit (BTN_LEFT , input->keybit);__set_bit (BTN_RIGHT , input->keybit);
Signature · 1 line
1.9.1
PATCH 31/40 xen/balloon: flush persistent kmaps in correct position
In reply to Jiri SlabyFrom: Wei Liu <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 09ed3d5ba06137913960f9c9385f71fc384193ab upstream.
Xen balloon driver will update ballooned out pages' P2M entries to point to scratch page for PV guests. In 24f69373e2 ("xen/balloon: don't alloc page while non-preemptible", kmap_flush_unused was moved after updating P2M table. In that case for 32 bit PV guest we might end up with
P2M X -----> S (S is mfn of balloon scratch page) M2P Y -----> X (Y is mfn in persistent kmap entry)
kmap_flush_unused() iterates through all the PTEs in the kmap address space, using pte_to_page() to obtain the page. If the p2m and the m2p are inconsistent the incorrect page is returned. This will clear page->address on the wrong page which may cause subsequent oopses if that page is currently kmap'ed.
Move the flush back between get_page and __set_phys_to_machine to fix this.
--- drivers/xen/balloon.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-)
drivers/xen/balloon.c +18 -6
@@ -405,11 +405,25 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp) state =BP_EAGAIN ;break ; } +scrub_page (page); - pfn =page_to_pfn (page); - frame_list[i] =pfn_to_mfn (pfn); + frame_list[i] =page_to_pfn (page); + } -scrub_page (page); +/* +* Ensure that ballooned highmem pages don't have kmaps. +* +* Do this before changing the p2m as kmap_flush_unused() +* reads PTEs to obtain pages (and hence needs the original +* p2m entry). +*/ +kmap_flush_unused (); + +/* Update direct mapping, invalidate P2M, and add to balloon. */ +for (i =0 ; i < nr_pages; i++) { + pfn = frame_list[i]; + frame_list[i] =pfn_to_mfn (pfn); + page =pfn_to_page (pfn);/* * Ballooned out frames are effectively replaced with
@@ -433,11 +447,9 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp) }put_balloon_scratch_page (); -balloon_append (pfn_to_page (pfn)); +balloon_append (page); } -/* Ensure that ballooned highmem pages don't have kmaps. */ -kmap_flush_unused ();flush_tlb_all ();set_xen_guest_handle (reservation.extent_start, frame_list);
Signature · 1 line
1.9.1
PATCH 32/40 Revert "xen: properly account for _PAGE_NUMA during xen pte translations"
In reply to Jiri SlabyFrom: David Vrabel <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 5926f87fdaad4be3ed10cec563bf357915e55a86 upstream.
This reverts commit a9c8e4beeeb64c22b84c803747487857fe424b68.
PTEs in Xen PV guests must contain machine addresses if _PAGE_PRESENT is set and pseudo-physical addresses is _PAGE_PRESENT is clear.
This is because during a domain save/restore (migration) the page table entries are "canonicalised" and uncanonicalised". i.e., MFNs are converted to PFNs during domain save so that on a restore the page table entries may be rewritten with the new MFNs on the destination. This canonicalisation is only done for PTEs that are present.
This change resulted in writing PTEs with MFNs if _PAGE_PROTNONE (or _PAGE_NUMA) was set but _PAGE_PRESENT was clear. These PTEs would be migrated as-is which would result in unexpected behaviour in the destination domain. Either a) the MFN would be translated to the wrong PFN/page; b) setting the _PAGE_PRESENT bit would clear the PTE because the MFN is no longer owned by the domain; or c) the present bit would not get set.
Symptoms include "Bad page" reports when munmapping after migrating a domain.
--- arch/x86/include/asm/pgtable.h | 14 ++------------ arch/x86/xen/mmu.c | 4 ++-- 2 files changed, 4 insertions(+), 14 deletions(-)
arch/x86/include/asm/pgtable.h +2 -12
@@ -445,20 +445,10 @@ static inline int pte_same(pte_t a, pte_t b)return a.pte == b.pte; } -static inline int pteval_present (pteval_t pteval) -{ -/* -* Yes Linus, _PAGE_PROTNONE == _PAGE_NUMA. Expressing it this -* way clearly states that the intent is that protnone and numa -* hinting ptes are considered present for the purposes of -* pagetable operations like zapping, protection changes, gup etc. -*/ -return pteval & (_PAGE_PRESENT | _PAGE_PROTNONE | _PAGE_NUMA); -} -static inline int pte_present (pte_t a) { -return pteval_present (pte_flags (a)); +return pte_flags (a) & (_PAGE_PRESENT | _PAGE_PROTNONE | + _PAGE_NUMA); }#define pte_accessible pte_accessible
arch/x86/xen/mmu.c +2 -2
@@ -365,7 +365,7 @@ void xen_ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr,/* Assume pteval_t is equivalent to all the other *val_t types. */ static pteval_t pte_mfn_to_pfn (pteval_t val) { -if (pteval_present (val)) { +if (val & _PAGE_PRESENT) {unsigned long mfn = (val &PTE_PFN_MASK ) >>PAGE_SHIFT ;unsigned long pfn =mfn_to_pfn (mfn);
@@ -381,7 +381,7 @@ static pteval_t pte_mfn_to_pfn(pteval_t val)static pteval_t pte_pfn_to_mfn (pteval_t val) { -if (pteval_present (val)) { +if (val & _PAGE_PRESENT) {unsigned long pfn = (val &PTE_PFN_MASK ) >>PAGE_SHIFT ;pteval_t flags = val &PTE_FLAGS_MASK ;unsigned long mfn;
Signature · 1 line
1.9.1
PATCH 33/40 i2c: cpm: Fix build by adding of_address.h and of_irq.h
In reply to Jiri SlabyFrom: Scott Wood <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 5f12c5eca6e6b7aeb4b2028d579f614b4fe7a81f upstream.
Fixes a build break due to the undeclared use of irq_of_parse_and_map() and of_iomap(). This build break was apparently introduced while the driver was unbuildable due to the bug fixed by 62c19c9d29e65086e5ae76df371ed2e6b23f00cd ("i2c: Remove usage of orphaned symbol OF_I2C"). When 62c19c was added in v3.14-rc7, the driver was enabled again, breaking the powerpc mpc85xx_defconfig and mpc85xx_smp_defconfig.
62c19c is marked for stable, so this should go there as well.
--- drivers/i2c/busses/i2c-cpm.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/i2c/busses/i2c-cpm.c +2 -0
@@ -40,7 +40,9 @@#include <linux/i2c.h> #include <linux/io.h> #include <linux/dma-mapping.h> +#include <linux/of_address.h> #include <linux/of_device.h> +#include <linux/of_irq.h> #include <linux/of_platform.h> #include <sysdev/fsl_soc.h> #include <asm/cpm.h>
Signature · 1 line
1.9.1
PATCH 34/40 drm/i915: Undo gtt scratch pte unmapping again
In reply to Jiri SlabyFrom: Daniel Vetter <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 8ee661b505613ef2747b350ca2871a31b3781bee upstream.
It apparently blows up on some machines. This functionally reverts
commit 828c79087cec61eaf4c76bb32c222fbe35ac3930
Author: Ben Widawsky <[email protected]> Date: Wed Oct 16 09:21:30 2013 -0700
drm/i915: Disable GGTT PTEs on GEN6+ suspend
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=64841
--- drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/i915/i915_gem_gtt.c +1 -1
@@ -536,7 +536,7 @@ void i915_gem_suspend_gtt_mappings(struct drm_device *dev) dev_priv->gtt.base.clear_range (&dev_priv->gtt.base, dev_priv->gtt.base.start /PAGE_SIZE , dev_priv->gtt.base.total /PAGE_SIZE , - false); + true); }void i915_gem_restore_gtt_mappings (struct drm_device *dev)
Signature · 1 line
1.9.1
PATCH 35/40 x86: fix boot on uniprocessor systems
In reply to Jiri SlabyFrom: Artem Fetishev <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 825600c0f20e595daaa7a6dd8970f84fa2a2ee57 upstream.
On x86 uniprocessor systems topology_physical_package_id() returns -1 which causes rapl_cpu_prepare() to leave rapl_pmu variable uninitialized which leads to GPF in rapl_pmu_init().
See arch/x86/kernel/cpu/perf_event_intel_rapl.c.
It turns out that physical_package_id and core_id can actually be retreived for uniprocessor systems too. Enabling them also fixes rapl_pmu code.
--- arch/x86/include/asm/topology.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/x86/include/asm/topology.h +2 -1
@@ -119,9 +119,10 @@ static inline void setup_node_to_cpumask_map(void) { }extern const struct cpumask *cpu_coregroup_mask (int cpu); -#ifdef ENABLE_TOPO_DEFINES #define topology_physical_package_id (cpu) (cpu_data(cpu).phys_proc_id)#define topology_core_id (cpu) (cpu_data(cpu).cpu_core_id) + +#ifdef ENABLE_TOPO_DEFINES #define topology_core_cpumask (cpu) (per_cpu(cpu_core_map, cpu))#define topology_thread_cpumask (cpu) (per_cpu(cpu_sibling_map, cpu))#endif
Signature · 1 line
1.9.1
PATCH 36/40 make prepend_name() work correctly when called with negative *buflen
In reply to Jiri SlabyFrom: Al Viro <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit e825196d48d2b89a6ec3a8eff280098d2a78207e upstream.
In all callchains leading to prepend_name(), the value left in *buflen is eventually discarded unused if prepend_name() has returned a negative. So we are free to do what prepend() does, and subtract from *buflen *before* checking for underflow (which turns into checking the sign of subtraction result, of course).
--- fs/dcache.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/dcache.c +2 -2
@@ -2846,9 +2846,9 @@ static int prepend_name(char **buffer, int *buflen, struct qstr *name)u32 dlen =ACCESS_ONCE (name->len);char *p; -if (*buflen < dlen +1 ) -return -ENAMETOOLONG ; *buflen -= dlen +1 ; +if (*buflen <0 ) +return -ENAMETOOLONG ; p = *buffer -= dlen +1 ; *p++ ='/' ;while (dlen--) {
Signature · 1 line
1.9.1
PATCH 37/40 net: mvneta: rename MVNETA_GMAC2_PSC_ENABLE to MVNETA_GMAC2_PCS_ENABLE
In reply to Jiri SlabyFrom: Thomas Petazzoni <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit a79121d3b57e7ad61f0b5d23eae05214054f3ccd upstream.
Bit 3 of the MVNETA_GMAC_CTRL_2 is actually used to enable the PCS, not the PSC: there was a typo in the name of the define, which this commit fixes.
--- drivers/net/ethernet/marvell/mvneta.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/marvell/mvneta.c +2 -2
@@ -121,7 +121,7 @@#define MVNETA_GMAC_MAX_RX_SIZE_MASK 0x7ffc#define MVNETA_GMAC0_PORT_ENABLE BIT(0)#define MVNETA_GMAC_CTRL_2 0x2c08 -#define MVNETA_GMAC2_PSC_ENABLE BIT(3) +#define MVNETA_GMAC2_PCS_ENABLE BIT(3)#define MVNETA_GMAC2_PORT_RGMII BIT(4)#define MVNETA_GMAC2_PORT_RESET BIT(6)#define MVNETA_GMAC_STATUS 0x2c10
@@ -688,7 +688,7 @@ static void mvneta_port_sgmii_config(struct mvneta_port *pp)u32 val; val =mvreg_read (pp,MVNETA_GMAC_CTRL_2 ); - val |=MVNETA_GMAC2_PSC_ENABLE ; + val |=MVNETA_GMAC2_PCS_ENABLE ;mvreg_write (pp,MVNETA_GMAC_CTRL_2 , val);mvreg_write (pp,MVNETA_SGMII_SERDES_CFG ,MVNETA_SGMII_SERDES_PROTO );
Signature · 1 line
1.9.1
PATCH 38/40 net: mvneta: fix usage as a module on RGMII configurations
In reply to Jiri SlabyFrom: Thomas Petazzoni <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit e3a8786c10e75903f1269474e21fe8cb49c3a670 upstream.
Commit 5445eaf309ff ('mvneta: Try to fix mvneta when compiled as module') fixed the mvneta driver to make it work properly when loaded as a module in SGMII configuration, which was tested successful by the author on the Armada XP OpenBlocks AX3, which uses SGMII.
However, it turns out that the Armada XP GP, which uses RGMII, is affected by a similar problem: its SERDES configuration is lost when mvneta is loaded as a module, because this configuration is set by the bootloader, and then lost because the clock is gated by the clock framework until the mvneta driver is loaded again and the clock is re-enabled.
However, it turns out that for the RGMII case, setting the SERDES configuration is not sufficient: the PCS enable bit in the MVNETA_GMAC_CTRL_2 register must also be set, like in the SGMII configuration.
Therefore, this commit reworks the SGMII/RGMII initialization: the only difference between the two now is a different SERDES configuration, all the rest is identical.
In detail, to achieve this, the commit:
* Renames MVNETA_SGMII_SERDES_CFG to MVNETA_SERDES_CFG because it is not specific to SGMII, but also used on RGMII configurations.
* Adds a MVNETA_RGMII_SERDES_PROTO definition, that must be used as the MVNETA_SERDES_CFG value in RGMII configurations.
* Removes the mvneta_gmac_rgmii_set() and mvneta_port_sgmii_config() functions, and instead directly do the SGMII/RGMII configuration in mvneta_port_up(), from where those functions where called. It is worth mentioning that mvneta_gmac_rgmii_set() had an 'enable' parameter that was always passed as '1', so it was pretty useless.
* Reworks the mvneta_port_up() function to set the MVNETA_SERDES_CFG register to the appropriate value depending on the RGMII vs. SGMII configuration. It also unconditionally set the PCS_ENABLE bit (was already done for SGMII, but is now also needed for RGMII), and sets the PORT_RGMII bit (which was already done for both SGMII and RGMII).
This commit was successfully tested with mvneta compiled as a module, on both the OpenBlocks AX3 (SGMII configuration) and the Armada XP GP (RGMII configuration).
--- drivers/net/ethernet/marvell/mvneta.c | 41 +++++++---------------------------- 1 file changed, 8 insertions(+), 33 deletions(-)
drivers/net/ethernet/marvell/mvneta.c +8 -33
@@ -88,8 +88,9 @@#define MVNETA_TX_IN_PRGRS BIT(1)#define MVNETA_TX_FIFO_EMPTY BIT(8)#define MVNETA_RX_MIN_FRAME_SIZE 0x247c -#define MVNETA_SGMII_SERDES_CFG 0x24A0 +#define MVNETA_SERDES_CFG 0x24A0#define MVNETA_SGMII_SERDES_PROTO 0x0cc7 +#define MVNETA_RGMII_SERDES_PROTO 0x0667#define MVNETA_TYPE_PRIO 0x24bc#define MVNETA_FORCE_UNI BIT(21)#define MVNETA_TXQ_CMD_1 0x24e4
@@ -665,35 +666,6 @@ static void mvneta_rxq_bm_disable(struct mvneta_port *pp,mvreg_write (pp,MVNETA_RXQ_CONFIG_REG (rxq->id), val); } - - -/* Sets the RGMII Enable bit (RGMIIEn) in port MAC control register */ -static void mvneta_gmac_rgmii_set (struct mvneta_port *pp,int enable) -{ -u32 val; - - val =mvreg_read (pp,MVNETA_GMAC_CTRL_2 ); - -if (enable) - val |=MVNETA_GMAC2_PORT_RGMII ; -else - val &= ~MVNETA_GMAC2_PORT_RGMII ; - -mvreg_write (pp,MVNETA_GMAC_CTRL_2 , val); -} - -/* Config SGMII port */ -static void mvneta_port_sgmii_config (struct mvneta_port *pp) -{ -u32 val; - - val =mvreg_read (pp,MVNETA_GMAC_CTRL_2 ); - val |=MVNETA_GMAC2_PCS_ENABLE ; -mvreg_write (pp,MVNETA_GMAC_CTRL_2 , val); - -mvreg_write (pp,MVNETA_SGMII_SERDES_CFG ,MVNETA_SGMII_SERDES_PROTO ); -} -/* Start the Ethernet port RX and TX activity */ static void mvneta_port_up (struct mvneta_port *pp) {
@@ -2723,12 +2695,15 @@ static void mvneta_port_power_up(struct mvneta_port *pp, int phy_mode)mvreg_write (pp,MVNETA_UNIT_INTR_CAUSE ,0 );if (phy_mode ==PHY_INTERFACE_MODE_SGMII ) -mvneta_port_sgmii_config (pp); +mvreg_write (pp,MVNETA_SERDES_CFG ,MVNETA_SGMII_SERDES_PROTO ); +else +mvreg_write (pp,MVNETA_SERDES_CFG ,MVNETA_RGMII_SERDES_PROTO ); -mvneta_gmac_rgmii_set (pp,1 ); + val =mvreg_read (pp,MVNETA_GMAC_CTRL_2 ); + + val |=MVNETA_GMAC2_PCS_ENABLE |MVNETA_GMAC2_PORT_RGMII ;/* Cancel Port Reset */ - val =mvreg_read (pp,MVNETA_GMAC_CTRL_2 ); val &= ~MVNETA_GMAC2_PORT_RESET ;mvreg_write (pp,MVNETA_GMAC_CTRL_2 , val);
Signature · 1 line
1.9.1
PATCH 39/40 mm: close PageTail race
In reply to Jiri SlabyFrom: David Rientjes <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 668f9abbd4334e6c29fa8acd71635c4f9101caa7 upstream.
Commit bf6bddf1924e ("mm: introduce compaction and migration for ballooned pages") introduces page_count(page) into memory compaction which dereferences page->first_page if PageTail(page).
This results in a very rare NULL pointer dereference on the aforementioned page_count(page). Indeed, anything that does compound_head(), including page_count() is susceptible to racing with prep_compound_page() and seeing a NULL or dangling page->first_page pointer.
This patch uses Andrea's implementation of compound_trans_head() that deals with such a race and makes it the default compound_head() implementation. This includes a read memory barrier that ensures that if PageTail(head) is true that we return a head page that is neither NULL nor dangling. The patch then adds a store memory barrier to prep_compound_page() to ensure page->first_page is set.
This is the safest way to ensure we see the head page that we are expecting, PageTail(page) is already in the unlikely() path and the memory barriers are unfortunately required.
Hugetlbfs is the exception, we don't enforce a store memory barrier during init since no race is possible.
--- drivers/block/aoe/aoecmd.c | 4 ++-- drivers/vfio/vfio_iommu_type1.c | 4 ++-- fs/proc/page.c | 2 +- include/linux/huge_mm.h | 18 ------------------ include/linux/mm.h | 14 ++++++++++++-- mm/ksm.c | 2 +- mm/memory-failure.c | 2 +- mm/page_alloc.c | 4 +++- mm/swap.c | 4 ++-- 9 files changed, 24 insertions(+), 30 deletions(-)
drivers/block/aoe/aoecmd.c +2 -2
@@ -905,7 +905,7 @@ bio_pageinc(struct bio *bio)/* Non-zero page count for non-head members of * compound pages is no longer allowed by the kernel. */ - page =compound_trans_head (bv->bv_page); + page =compound_head (bv->bv_page);atomic_inc (&page->_count); } }
@@ -918,7 +918,7 @@ bio_pagedec(struct bio *bio)int i;bio_for_each_segment (bv, bio, i) { - page =compound_trans_head (bv->bv_page); + page =compound_head (bv->bv_page);atomic_dec (&page->_count); } }
drivers/vfio/vfio_iommu_type1.c +2 -2
@@ -186,12 +186,12 @@ static bool is_invalid_reserved_pfn(unsigned long pfn)if (pfn_valid (pfn)) {bool reserved;struct page *tail =pfn_to_page (pfn); -struct page *head =compound_trans_head (tail); +struct page *head =compound_head (tail); reserved = !!(PageReserved (head));if (head != tail) {/* * "head" is not a dangling pointer -* (compound_trans_head takes care of that) +* (compound_head takes care of that) * but the hugepage may have been split * from under us (and we may not hold a * reference count on the head page so it can
fs/proc/page.c +1 -1
@@ -121,7 +121,7 @@ u64 stable_page_flags(struct page *page)* just checks PG_head/PG_tail, so we need to check PageLRU to make * sure a given page is a thp, not a non-huge compound page. */ - else if (PageTransCompound(page) && PageLRU(compound_trans_head(page))) + else if (PageTransCompound(page) && PageLRU(compound_head(page))) u |= 1 << KPF_THP;/*
include/linux/huge_mm.h +0 -18
@@ -156,23 +156,6 @@ static inline int hpage_nr_pages(struct page *page)return HPAGE_PMD_NR ;return 1 ; } -static inline struct page *compound_trans_head (struct page *page) -{ -if (PageTail (page)) { -struct page *head; - head = page->first_page; -smp_rmb (); -/* -* head may be a dangling pointer. -* __split_huge_page_refcount clears PageTail before -* overwriting first_page, so if PageTail is still -* there it means the head pointer isn't dangling. -*/ -if (PageTail (page)) -return head; - } -return page; -}extern int do_huge_pmd_numa_page (struct mm_struct *mm,struct vm_area_struct *vma,unsigned long addr,pmd_t pmd,pmd_t *pmdp);
@@ -202,7 +185,6 @@ static inline int split_huge_page(struct page *page) do { } while (0)#define split_huge_page_pmd_mm (__mm, __address, __pmd) \ do { } while (0) -#define compound_trans_head (page) compound_head(page)static inline int hugepage_madvise (struct vm_area_struct *vma,unsigned long *vm_flags,int advice) {
include/linux/mm.h +12 -2
@@ -371,8 +371,18 @@ static inline void compound_unlock_irqrestore(struct page *page,static inline struct page *compound_head (struct page *page) { -if (unlikely (PageTail (page))) -return page->first_page; +if (unlikely (PageTail (page))) { +struct page *head = page->first_page; + +/* +* page->first_page may be a dangling pointer to an old +* compound page, so recheck that it is still a tail +* page before returning. +*/ +smp_rmb (); +if (likely (PageTail (page))) +return head; + }return page; }
mm/ksm.c +1 -1
@@ -444,7 +444,7 @@ static void break_cow(struct rmap_item *rmap_item)static struct page *page_trans_compound_anon (struct page *page) {if (PageTransCompound (page)) { -struct page *head =compound_trans_head (page); +struct page *head =compound_head (page);/* * head may actually be splitted and freed from under * us but it's ok here.
mm/memory-failure.c +1 -1
@@ -1659,7 +1659,7 @@ int soft_offline_page(struct page *page, int flags) {int ret;unsigned long pfn =page_to_pfn (page); -struct page *hpage =compound_trans_head (page); +struct page *hpage =compound_head (page);if (PageHWPoison (page)) {pr_info ("soft offline: %#lx page already poisoned\n" , pfn);
mm/page_alloc.c +3 -1
@@ -369,9 +369,11 @@ void prep_compound_page(struct page *page, unsigned long order)__SetPageHead (page);for (i =1 ; i < nr_pages; i++) {struct page *p = page + i; -__SetPageTail (p);set_page_count (p,0 ); p->first_page = page; +/* Make sure p->first_page is always valid for PageTail() */ +smp_wmb (); +__SetPageTail (p); } }
mm/swap.c +2 -2
@@ -84,7 +84,7 @@ static void put_compound_page(struct page *page) {if (unlikely (PageTail (page))) {/* __split_huge_page_refcount can run under us */ -struct page *page_head =compound_trans_head (page); +struct page *page_head =compound_head (page);if (likely (page != page_head &&get_page_unless_zero (page_head))) {
@@ -222,7 +222,7 @@ bool __get_page_tail(struct page *page)*/ unsigned long flags;bool got = false; -struct page *page_head =compound_trans_head (page); +struct page *page_head =compound_head (page);if (likely (page != page_head &&get_page_unless_zero (page_head))) {/* Ref to put_compound_page() comment. */
Signature · 1 line
1.9.1
PATCH 40/40 netfilter: nf_conntrack_dccp: fix skb_header_pointer API usages
In reply to Jiri SlabyFrom: Daniel Borkmann <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit b22f5126a24b3b2f15448c3f2a254fc10cbc2b92 upstream.
Some occurences in the netfilter tree use skb_header_pointer() in the following way ...
struct dccp_hdr _dh, *dh; ... skb_header_pointer(skb, dataoff, sizeof(_dh), &dh);
... where dh itself is a pointer that is being passed as the copy buffer. Instead, we need to use &_dh as the forth argument so that we're copying the data into an actual buffer that sits on the stack.
Currently, we probably could overwrite memory on the stack (e.g. with a possibly mal-formed DCCP packet), but unintentionally, as we only want the buffer to be placed into _dh variable.
--- net/netfilter/nf_conntrack_proto_dccp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
net/netfilter/nf_conntrack_proto_dccp.c +3 -3
@@ -428,7 +428,7 @@ static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb,const char *msg;u_int8_t state; - dh =skb_header_pointer (skb, dataoff,sizeof (_dh), &dh); + dh =skb_header_pointer (skb, dataoff,sizeof (_dh), &_dh);BUG_ON (dh ==NULL ); state = dccp_state_table[CT_DCCP_ROLE_CLIENT ][dh->dccph_type][CT_DCCP_NONE ];
@@ -486,7 +486,7 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,u_int8_t type, old_state, new_state;enum ct_dccp_roles role; - dh =skb_header_pointer (skb, dataoff,sizeof (_dh), &dh); + dh =skb_header_pointer (skb, dataoff,sizeof (_dh), &_dh);BUG_ON (dh ==NULL ); type = dh->dccph_type;
@@ -577,7 +577,7 @@ static int dccp_error(struct net *net, struct nf_conn *tmpl,unsigned int cscov;const char *msg; - dh =skb_header_pointer (skb, dataoff,sizeof (_dh), &dh); + dh =skb_header_pointer (skb, dataoff,sizeof (_dh), &_dh);if (dh ==NULL ) { msg ="nf_ct_dccp: short packet " ; goto out_invalid;
Signature · 1 line
1.9.1
Quoted 8 lines · Jiri Slaby
This is the start of the stable review cycle for the 3.12.17 release. There are 40 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri Apr 4 20:06:31 2014 Anything received after that time might be too late.
Build results:
total: 126 pass: 121 skipped: 5 fail: 0
qemu tests all passed. Results are as expected.
Details are available at http://server.roeck-us.net:8010/builders.
Guenter
PATCH 4/41 intel_idle: Fixed C6 state on Avoton/Rangeley processors
In reply to Jiri SlabyFrom: Bockholdt Arne <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 22e580d07f6529a395c129575127ea6d860aed3a upstream.
Corrected the MWAIT flag for C-State C6 on Intel Avoton/Rangeley processors.
--- drivers/idle/intel_idle.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/idle/intel_idle.c +2 -2
@@ -329,7 +329,7 @@ static struct cpuidle_state atom_cstates[CPUIDLE_STATE_MAX] = { { .enter = NULL } }; -static struct cpuidle_state avn_cstates[CPUIDLE_STATE_MAX ] = { +static struct cpuidle_state avn_cstates[]__initdata = { { .name ="C1-AVN" , .desc ="MWAIT 0x00" ,
@@ -340,7 +340,7 @@ static struct cpuidle_state avn_cstates[CPUIDLE_STATE_MAX] = { { .name = "C6-AVN", .desc = "MWAIT 0x51", - .flags = MWAIT2flg(0x58) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, + .flags = MWAIT2flg(0x51) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 15, .target_residency = 45, .enter = &intel_idle },
Signature · 1 line
1.9.1
Quoted 8 lines · Jiri Slaby
This is the start of the stable review cycle for the 3.12.17 release. There are 40 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri Apr 4 20:06:31 2014 Anything received after that time might be too late.
Quoted 7 lines
The whole patch series can be found in one patch at:
http://kernel.org/pub/linux/kernel/people/jirislaby/stable-review/patch-3.12.17-rc1.xzand the diffstat can be found below.
thanks,
js
Compiled and booted on all my test systems. No dmesg regressions.
-- Shuah
Signature · 4 lines
Shuah Khan Senior Linux Kernel Developer - Open Source Group Samsung Research America(Silicon Valley) [email protected] | (970) 672-0658