3.14.31-stable review
Subsystems (2)
Greg Kroah-Hartman
maintainercover 3.14.31-stable review
This is the start of the stable review cycle for the 3.14.31 release. There are 77 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 Jan 30 01:27:34 UTC 2015. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v3.0/stable-review/patch-3.14.31-rc1.gz
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 3.14.31-rc1
NeilBrown <[email protected]>
md/raid5: fetch_block must fetch all the blocks handle_stripe_dirtying wants.
Michal Hocko <[email protected]>
mm: get rid of radix tree gfp mask for pagecache_get_page
Mel Gorman <[email protected]>
mm: page_alloc: reduce cost of the fair zone allocation policy
Mel Gorman <[email protected]>
mm: page_alloc: abort fair zone allocation policy when remotes nodes are encountered
Mel Gorman <[email protected]>
mm: vmscan: only update per-cpu thresholds for online CPU
Mel Gorman <[email protected]>
mm: move zone->pages_scanned into a vmstat counter
Mel Gorman <[email protected]>
mm: rearrange zone fields into read-only, page alloc, statistics and page reclaim lines
Mel Gorman <[email protected]>
mm: pagemap: avoid unnecessary overhead when tracepoints are deactivated
Jerome Marchand <[email protected]>
memcg, vmscan: Fix forced scan of anonymous pages
Joonsoo Kim <[email protected]>
vmalloc: use rcu list iterator to reduce vmap_area_lock contention
Jerome Marchand <[email protected]>
mm: make copy_pte_range static again
David Rientjes <[email protected]>
mm, thp: only collapse hugepages to nodes with affinity for zone_reclaim_mode
Hugh Dickins <[email protected]>
mm/memory.c: use entry = ACCESS_ONCE(*pte) in handle_pte_fault()
Hugh Dickins <[email protected]>
shmem: fix init_page_accessed use to stop !PageLRU bug
Mel Gorman <[email protected]>
mm: avoid unnecessary atomic operations during end_page_writeback()
Mel Gorman <[email protected]>
mm: non-atomically mark page accessed during page cache allocation where possible
Mel Gorman <[email protected]>
fs: buffer: do not use unnecessary atomic operations when discarding buffers
Mel Gorman <[email protected]>
mm: do not use unnecessary atomic operations when adding pages to the LRU
Mel Gorman <[email protected]>
mm: do not use atomic operations when releasing pages
Mel Gorman <[email protected]>
mm: shmem: avoid atomic operation during shmem_getpage_gfp
Mel Gorman <[email protected]>
mm: page_alloc: lookup pageblock migratetype with IRQs enabled during free
Mel Gorman <[email protected]>
mm: page_alloc: convert hot/cold parameter and immediate callers to bool
Mel Gorman <[email protected]>
mm: page_alloc: reduce number of times page_to_pfn is called
Mel Gorman <[email protected]>
mm: page_alloc: use unsigned int for order in more places
Mel Gorman <[email protected]>
mm: page_alloc: take the ALLOC_NO_WATERMARK check out of the fast path
Mel Gorman <[email protected]>
mm: page_alloc: only check the alloc flags and gfp_mask for dirty once
Mel Gorman <[email protected]>
mm: page_alloc: only check the zone id check if pages are buddies
Mel Gorman <[email protected]>
mm: page_alloc: calculate classzone_idx once from the zonelist ref
Mel Gorman <[email protected]>
mm: page_alloc: use jump labels to avoid checking number_of_cpusets
Mel Gorman <[email protected]>
include/linux/jump_label.h: expose the reference count
Mel Gorman <[email protected]>
mm: page_alloc: do not treat a zone that cannot be used for dirty pages as "full"
Mel Gorman <[email protected]>
mm: page_alloc: do not update zlc unless the zlc is active
Jianyu Zhan <[email protected]>
mm/swap.c: clean up *lru_cache_add* functions
Sjoerd Simons <[email protected]>
mmc: sdhci: Don't signal the sdio irq if it's not setup
Francesco Ruggeri <[email protected]>
tty: Fix pty master poll() after slave closes v2
Dmitry Torokhov <[email protected]>
Input: evdev - fix EVIOCG{type} ioctl
Vineet Gupta <[email protected]>
ARC: Fix build breakage for !CONFIG_ARC_DW2_UNWIND
Vineet Gupta <[email protected]>
ARC: Delete stale barrier.h
Mathias Krause <[email protected]>
crypto: add missing crypto module aliases
Kees Cook <[email protected]>
crypto: include crypto- module prefix in template
Kees Cook <[email protected]>
crypto: prefix module autoloading with "crypto-"
Lars Ellenberg <[email protected]>
drbd: merge_bvec_fn: properly remap bvm->bi_bdev
David Vrabel <[email protected]>
Revert "swiotlb-xen: pass dev_addr to swiotlb_tbl_unmap_single"
Dan Carpenter <[email protected]>
ipvs: uninitialized data with IP_VS_IPV6
Pablo Neira Ayuso <[email protected]>
netfilter: nfnetlink: validate nfnetlink header from batch
Sasha Levin <[email protected]>
KEYS: close race between key lookup and freeing
Andy Shevchenko <[email protected]>
sata_dwc_460ex: fix resource leak on error path
Andy Lutomirski <[email protected]>
x86/asm/traps: Disable tracing and kprobes in fixup_bad_iret and sync_regs
Bryan O'Donoghue <[email protected]>
x86/apic: Re-enable PCI_MSI support for non-SMP X86_32
Andy Lutomirski <[email protected]>
x86, tls: Interpret an all-zero struct user_desc as "no segment"
Andy Lutomirski <[email protected]>
x86, tls, ldt: Stop checking lm in LDT_empty
Nadav Amit <[email protected]>
KVM: x86: Fix of previously incomplete fix for CVE-2014-8480
Kees Cook <[email protected]>
x86, boot: Skip relocs when load address unchanged
Alexandre Demers <[email protected]>
x86/tsc: Change Fast TSC calibration failed from error to info
K. Y. Srinivasan <[email protected]>
x86, hyperv: Mark the Hyper-V clocksource as being continuous
Tobias Jakobi <[email protected]>
clocksource: exynos_mct: Fix bitmask regression for exynos4_mct_write
Oliver Hartkopp <[email protected]>
can: dev: fix crtlmode_supported check
Al Viro <[email protected]>
fix deadlock in cifs_ioctl_clone()
Andrew Lunn <[email protected]>
bus: mvebu-mbus: fix support of MBus window 13
Fabio Estevam <[email protected]>
ARM: dts: imx25: Fix PWM "per" clocks
Sasha Levin <[email protected]>
time: adjtimex: Validate the ADJ_FREQUENCY values
Sasha Levin <[email protected]>
time: settimeofday: Validate the values of tv from user
Joe Thornber <[email protected]>
dm cache: fix problematic dual use of a single migration count variable
Joe Thornber <[email protected]>
dm cache: share cache-metadata object across inactive and active DM tables
Brian King <[email protected]>
ipr: wait for aborted command responses
Alex Williamson <[email protected]>
PCI: Mark Atheros AR93xx to avoid bus reset
Alex Williamson <[email protected]>
PCI: Add flag for devices where we can't use bus reset
Alex Deucher <[email protected]>
drm/radeon: use rv515_ring_start on r5xx
Alex Deucher <[email protected]>
drm/radeon: add si dpm quirk list
Alex Deucher <[email protected]>
drm/radeon: add a dpm quirk list
Chris Wilson <[email protected]>
drm/i915: Fix mutex->owner inspection race under DEBUG_MUTEXES
Michael Karcher <[email protected]>
scripts/recordmcount.pl: There is no -m32 gcc option on Super-H anymore
Jason Lee Cragg <[email protected]>
ALSA: usb-audio: Add mic volume fix quirk for Logitech Webcam C210
David Jeffery <[email protected]>
libata: prevent HSM state change race between ISR and PIO
Jim Lin <[email protected]>
pinctrl: Fix two deadlocks
Johan Hovold <[email protected]>
gpio: sysfs: fix gpio device-attribute leak
Johan Hovold <[email protected]>
gpio: sysfs: fix gpio-chip device-attribute leak
-------------
Diffstat:
Makefile | 4 +- arch/arc/include/asm/barrier.h | 37 ---- arch/arc/kernel/ctx_sw_asm.S | 2 +- arch/arm/boot/dts/imx25.dtsi | 8 +- arch/arm/crypto/aes_glue.c | 4 +- arch/arm/crypto/sha1_glue.c | 2 +- arch/powerpc/crypto/sha1.c | 3 +- arch/s390/crypto/aes_s390.c | 2 +- arch/s390/crypto/des_s390.c | 4 +- arch/s390/crypto/ghash_s390.c | 2 +- arch/s390/crypto/sha1_s390.c | 2 +- arch/s390/crypto/sha256_s390.c | 4 +- arch/s390/crypto/sha512_s390.c | 4 +- arch/sparc/crypto/aes_glue.c | 2 +- arch/sparc/crypto/camellia_glue.c | 2 +- arch/sparc/crypto/crc32c_glue.c | 2 +- arch/sparc/crypto/des_glue.c | 2 +- arch/sparc/crypto/md5_glue.c | 2 +- arch/sparc/crypto/sha1_glue.c | 2 +- arch/sparc/crypto/sha256_glue.c | 4 +- arch/sparc/crypto/sha512_glue.c | 4 +- arch/tile/mm/homecache.c | 2 +- arch/x86/Kconfig | 6 +- arch/x86/boot/compressed/misc.c | 9 +- arch/x86/crypto/aes_glue.c | 4 +- arch/x86/crypto/aesni-intel_glue.c | 2 +- arch/x86/crypto/blowfish_glue.c | 4 +- arch/x86/crypto/camellia_aesni_avx2_glue.c | 4 +- arch/x86/crypto/camellia_aesni_avx_glue.c | 4 +- arch/x86/crypto/camellia_glue.c | 4 +- arch/x86/crypto/cast5_avx_glue.c | 2 +- arch/x86/crypto/cast6_avx_glue.c | 2 +- arch/x86/crypto/crc32-pclmul_glue.c | 4 +- arch/x86/crypto/crc32c-intel_glue.c | 4 +- arch/x86/crypto/crct10dif-pclmul_glue.c | 4 +- arch/x86/crypto/fpu.c | 3 + arch/x86/crypto/ghash-clmulni-intel_glue.c | 2 +- arch/x86/crypto/salsa20_glue.c | 4 +- arch/x86/crypto/serpent_avx2_glue.c | 4 +- arch/x86/crypto/serpent_avx_glue.c | 2 +- arch/x86/crypto/serpent_sse2_glue.c | 2 +- arch/x86/crypto/sha1_ssse3_glue.c | 2 +- arch/x86/crypto/sha256_ssse3_glue.c | 4 +- arch/x86/crypto/sha512_ssse3_glue.c | 4 +- arch/x86/crypto/twofish_avx_glue.c | 2 +- arch/x86/crypto/twofish_glue.c | 4 +- arch/x86/crypto/twofish_glue_3way.c | 4 +- arch/x86/include/asm/desc.h | 20 +- arch/x86/kernel/cpu/mshyperv.c | 1 + arch/x86/kernel/tls.c | 25 ++- arch/x86/kernel/traps.c | 4 +- arch/x86/kernel/tsc.c | 2 +- arch/x86/kvm/emulate.c | 4 +- crypto/842.c | 1 + crypto/aes_generic.c | 3 +- crypto/algapi.c | 4 +- crypto/ansi_cprng.c | 3 +- crypto/anubis.c | 1 + crypto/api.c | 4 +- crypto/arc4.c | 1 + crypto/authenc.c | 1 + crypto/authencesn.c | 1 + crypto/blowfish_generic.c | 3 +- crypto/camellia_generic.c | 3 +- crypto/cast5_generic.c | 3 +- crypto/cast6_generic.c | 3 +- crypto/cbc.c | 1 + crypto/ccm.c | 5 +- crypto/chainiv.c | 1 + crypto/cmac.c | 1 + crypto/crc32.c | 1 + crypto/crct10dif_generic.c | 3 +- crypto/cryptd.c | 1 + crypto/crypto_null.c | 6 +- crypto/ctr.c | 3 +- crypto/cts.c | 1 + crypto/deflate.c | 2 +- crypto/des_generic.c | 7 +- crypto/ecb.c | 1 + crypto/eseqiv.c | 1 + crypto/fcrypt.c | 1 + crypto/gcm.c | 7 +- crypto/ghash-generic.c | 3 +- crypto/hmac.c | 1 + crypto/khazad.c | 1 + crypto/krng.c | 3 +- crypto/lrw.c | 1 + crypto/lz4.c | 1 + crypto/lz4hc.c | 1 + crypto/lzo.c | 1 + crypto/md4.c | 2 +- crypto/md5.c | 1 + crypto/michael_mic.c | 1 + crypto/pcbc.c | 1 + crypto/pcrypt.c | 1 + crypto/rmd128.c | 1 + crypto/rmd160.c | 1 + crypto/rmd256.c | 1 + crypto/rmd320.c | 1 + crypto/salsa20_generic.c | 3 +- crypto/seed.c | 1 + crypto/seqiv.c | 1 + crypto/serpent_generic.c | 5 +- crypto/sha1_generic.c | 3 +- crypto/sha256_generic.c | 6 +- crypto/sha512_generic.c | 6 +- crypto/tea.c | 5 +- crypto/tgr192.c | 5 +- crypto/twofish_generic.c | 3 +- crypto/vmac.c | 1 + crypto/wp512.c | 5 +- crypto/xcbc.c | 1 + crypto/xts.c | 1 + crypto/zlib.c | 1 + drivers/ata/libata-sff.c | 12 ++ drivers/ata/sata_dwc_460ex.c | 26 ++- drivers/block/drbd/drbd_req.c | 1 + drivers/bus/mvebu-mbus.c | 13 ++ drivers/clocksource/exynos_mct.c | 4 +- drivers/crypto/padlock-aes.c | 2 +- drivers/crypto/padlock-sha.c | 8 +- drivers/crypto/ux500/cryp/cryp_core.c | 4 +- drivers/crypto/ux500/hash/hash_core.c | 8 +- drivers/gpio/gpiolib.c | 46 ++--- drivers/gpu/drm/i915/i915_gem.c | 2 +- drivers/gpu/drm/radeon/radeon_asic.c | 18 +- drivers/gpu/drm/radeon/radeon_pm.c | 33 +++ drivers/gpu/drm/radeon/si_dpm.c | 39 ++++ drivers/input/evdev.c | 13 +- drivers/md/dm-cache-metadata.c | 101 +++++++++- drivers/md/dm-cache-target.c | 89 ++++---- drivers/md/raid5.c | 3 +- drivers/mmc/host/sdhci.c | 2 +- drivers/net/can/dev.c | 8 +- drivers/pci/pci.c | 40 +++- drivers/pci/quirks.c | 14 ++ drivers/pinctrl/core.c | 5 +- drivers/s390/crypto/ap_bus.c | 3 +- drivers/scsi/ipr.c | 92 +++++++++ drivers/scsi/ipr.h | 1 + drivers/tty/n_tty.c | 9 +- drivers/xen/swiotlb-xen.c | 2 +- fs/btrfs/extent_io.c | 11 +- fs/btrfs/file.c | 5 +- fs/buffer.c | 28 ++- fs/cifs/ioctl.c | 21 +- fs/ext4/mballoc.c | 14 +- fs/f2fs/checkpoint.c | 1 - fs/f2fs/node.c | 2 - fs/fuse/dev.c | 2 +- fs/fuse/file.c | 2 - fs/gfs2/aops.c | 1 - fs/gfs2/meta_io.c | 4 +- fs/ntfs/attrib.c | 1 - fs/ntfs/file.c | 1 - include/linux/cpuset.h | 29 ++- include/linux/crypto.h | 13 ++ include/linux/gfp.h | 4 +- include/linux/huge_mm.h | 4 - include/linux/jump_label.h | 20 +- include/linux/mmzone.h | 228 +++++++++++---------- include/linux/page-flags.h | 2 + include/linux/pageblock-flags.h | 33 ++- include/linux/pagemap.h | 108 +++++++++- include/linux/pci.h | 2 + include/linux/swap.h | 22 +- include/linux/time.h | 13 ++ include/trace/events/pagemap.h | 16 +- kernel/cpuset.c | 14 +- kernel/time.c | 4 + kernel/time/ntp.c | 7 + mm/filemap.c | 209 ++++++++----------- mm/huge_memory.c | 26 +++ mm/memory.c | 4 +- mm/page_alloc.c | 313 ++++++++++++++++------------- mm/shmem.c | 11 +- mm/swap.c | 50 ++++- mm/swap_state.c | 2 +- mm/vmalloc.c | 6 +- mm/vmscan.c | 36 ++-- mm/vmstat.c | 9 +- net/netfilter/ipvs/ip_vs_ftp.c | 10 +- net/netfilter/nfnetlink.c | 3 +- scripts/recordmcount.pl | 1 - security/keys/gc.c | 4 +- sound/usb/mixer.c | 1 + 186 files changed, 1461 insertions(+), 822 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/77 gpio: sysfs: fix gpio-chip device-attribute leak
3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 121b6a79955a3a3fd7bbb9b8cb88d5b9dad6283d upstream.
The gpio-chip device attributes were never destroyed when the device was removed.
Fix by using device_create_with_groups() to create the device attributes of the chip class device.
Note that this also fixes the attribute-creation race with userspace.
--- drivers/gpio/gpiolib.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-)
drivers/gpio/gpiolib.c +8 -11
@@ -680,16 +680,13 @@ static ssize_t chip_ngpio_show(struct de } static DEVICE_ATTR(ngpio, 0444, chip_ngpio_show, NULL); -static const struct attribute *gpiochip_attrs[] = { +static struct attribute *gpiochip_attrs[] = { &dev_attr_base.attr, &dev_attr_label.attr, &dev_attr_ngpio.attr,NULL , }; - -static const struct attribute_group gpiochip_attr_group = { - .attrs = (struct attribute **) gpiochip_attrs, -}; +ATTRIBUTE_GROUPS (gpiochip);/* * /sys/class/gpio/export ... write-only
@@ -1030,13 +1027,13 @@ static int gpiochip_export(struct gpio_c/* use chip->base for the ID; it's already known to be unique */ mutex_lock (&sysfs_lock); - dev =device_create (&gpio_class, chip->dev,MKDEV (0 ,0 ), chip, -"gpiochip%d" , chip->base); -if (!IS_ERR (dev)) { - status =sysfs_create_group (&dev->kobj, - &gpiochip_attr_group); - }else + dev =device_create_with_groups (&gpio_class, chip->dev,MKDEV (0 ,0 ), + chip, gpiochip_groups, +"gpiochip%d" , chip->base); +if (IS_ERR (dev)) status =PTR_ERR (dev); +else + status =0 ; chip->exported = (status ==0 );mutex_unlock (&sysfs_lock);
Greg Kroah-Hartman
maintainerPATCH 2/77 gpio: sysfs: fix gpio device-attribute leak
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 0915e6feb38de8d3601819992a5bd050201a56fa upstream.
The gpio device attributes were never destroyed when the gpio was unexported (or on export failures).
Use device_create_with_groups() to create the default device attributes of the gpio class device. Note that this also fixes the attribute-creation race with userspace for these attributes.
Remove contingent attributes in export error path and on unexport.
--- drivers/gpio/gpiolib.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-)
drivers/gpio/gpiolib.c +13 -14
@@ -408,7 +408,7 @@ static ssize_t gpio_value_store(struct dreturn status; } -static const DEVICE_ATTR(value, 0644, +static DEVICE_ATTR(value, 0644, gpio_value_show, gpio_value_store);static irqreturn_t gpio_sysfs_irq (int irq,void *priv)
@@ -633,18 +633,16 @@ static ssize_t gpio_active_low_store(strreturn status ? : size; } -static const DEVICE_ATTR(active_low, 0644, +static DEVICE_ATTR(active_low, 0644, gpio_active_low_show, gpio_active_low_store); -static const struct attribute *gpio_attrs[] = { +static struct attribute *gpio_attrs[] = { &dev_attr_value.attr, &dev_attr_active_low.attr,NULL , }; -static const struct attribute_group gpio_attr_group = { - .attrs = (struct attribute **) gpio_attrs, -}; +ATTRIBUTE_GROUPS (gpio);/* * /sys/class/gpio/gpiochipN/
@@ -841,18 +839,15 @@ int gpiod_export(struct gpio_desc *desc,if (desc->chip->names && desc->chip->names[offset]) ioname = desc->chip->names[offset]; - dev =device_create (&gpio_class, desc->chip->dev,MKDEV (0 ,0 ), - desc, ioname ? ioname :"gpio%u" , -desc_to_gpio (desc)); + dev =device_create_with_groups (&gpio_class, desc->chip->dev, +MKDEV (0 ,0 ), desc, gpio_groups, + ioname ? ioname :"gpio%u" , +desc_to_gpio (desc));if (IS_ERR (dev)) { status =PTR_ERR (dev); goto fail_unlock; } - status =sysfs_create_group (&dev->kobj, &gpio_attr_group); -if (status) - goto fail_unregister_device; -if (direction_may_change) { status =device_create_file (dev, &dev_attr_direction);if (status)
@@ -863,13 +858,15 @@ int gpiod_export(struct gpio_desc *desc, !test_bit(FLAG_IS_OUT, &desc->flags))) { status =device_create_file (dev, &dev_attr_edge);if (status) - goto fail_unregister_device; + goto fail_remove_attr_direction; }set_bit (FLAG_EXPORT , &desc->flags);mutex_unlock (&sysfs_lock);return 0 ; +fail_remove_attr_direction: +device_remove_file (dev, &dev_attr_direction); fail_unregister_device:device_unregister (dev); fail_unlock:
@@ -994,6 +991,8 @@ void gpiod_unexport(struct gpio_desc *de dev =class_find_device (&gpio_class,NULL , desc, match_export);if (dev) { +device_remove_file (dev, &dev_attr_edge); +device_remove_file (dev, &dev_attr_direction);gpio_setup_irq (desc, dev,0 );clear_bit (FLAG_EXPORT , &desc->flags); }else
Greg Kroah-Hartman
maintainerPATCH 3/77 pinctrl: Fix two deadlocks
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jim Lin <[email protected]>
commit db93facfb0ef542aa5d8079e47580b3e669a4d82 upstream.
This patch is to fix two deadlock cases. Deadlock 1:
CPU #1
pinctrl_register-> pinctrl_get -> create_pinctrl
(Holding lock pinctrl_maps_mutex)
-> get_pinctrl_dev_from_devname
(Trying to acquire lock pinctrldev_list_mutex)
CPU #0
pinctrl_unregister
(Holding lock pinctrldev_list_mutex)
-> pinctrl_put ->> pinctrl_free -> pinctrl_dt_free_maps -> pinctrl_unregister_map (Trying to acquire lock pinctrl_maps_mutex)
Simply to say
CPU#1 is holding lock A and trying to acquire lock B, CPU#0 is holding lock B and trying to acquire lock A.
Deadlock 2:
CPU #3
pinctrl_register-> pinctrl_get -> create_pinctrl
(Holding lock pinctrl_maps_mutex)
-> get_pinctrl_dev_from_devname
(Trying to acquire lock pinctrldev_list_mutex)
CPU #2
pinctrl_unregister
(Holding lock pctldev->mutex)
-> pinctrl_put ->> pinctrl_free -> pinctrl_dt_free_maps -> pinctrl_unregister_map (Trying to acquire lock pinctrl_maps_mutex)
CPU #0
tegra_gpio_request
(Holding lock pinctrldev_list_mutex)
-> pinctrl_get_device_gpio_range
(Trying to acquire lock pctldev->mutex)
Simply to say
CPU#3 is holding lock A and trying to acquire lock D, CPU#2 is holding lock B and trying to acquire lock A, CPU#0 is holding lock D and trying to acquire lock B.
--- drivers/pinctrl/core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/pinctrl/core.c +3 -2
@@ -1812,14 +1812,15 @@ void pinctrl_unregister(struct pinctrl_dif (pctldev ==NULL )return ; -mutex_lock (&pinctrldev_list_mutex);mutex_lock (&pctldev->mutex); -pinctrl_remove_device_debugfs (pctldev); +mutex_unlock (&pctldev->mutex);if (!IS_ERR (pctldev->p))pinctrl_put (pctldev->p); +mutex_lock (&pinctrldev_list_mutex); +mutex_lock (&pctldev->mutex);/* TODO: check that no pinmuxes are still active? */ list_del (&pctldev->node);/* Destroy descriptor tree */
Greg Kroah-Hartman
maintainerPATCH 4/77 libata: prevent HSM state change race between ISR and PIO
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Jeffery <[email protected]>
commit ce7514526742c0898b837d4395f515b79dfb5a12 upstream.
It is possible for ata_sff_flush_pio_task() to set ap->hsm_task_state to HSM_ST_IDLE in between the time __ata_sff_port_intr() checks for HSM_ST_IDLE and before it calls ata_sff_hsm_move() causing ata_sff_hsm_move() to BUG().
This problem is hard to reproduce making this patch hard to verify, but this fix will prevent the race.
I have not been able to reproduce the problem, but here is a crash dump from a 2.6.32 kernel.
On examining the ata port's state, its hsm_task_state field has a value of HSM_ST_IDLE:
crash> struct ata_port.hsm_task_state ffff881c1121c000
hsm_task_state = 0
Normally, this should not be possible as ata_sff_hsm_move() was called from ata_sff_host_intr(), which checks hsm_task_state and won't call ata_sff_hsm_move() if it has a HSM_ST_IDLE value.
PID: 11053 TASK: ffff8816e846cae0 CPU: 0 COMMAND: "sshd"
#0 [ffff88008ba03960] machine_kexec at ffffffff81038f3b #1 [ffff88008ba039c0] crash_kexec at ffffffff810c5d92 #2 [ffff88008ba03a90] oops_end at ffffffff8152b510 #3 [ffff88008ba03ac0] die at ffffffff81010e0b #4 [ffff88008ba03af0] do_trap at ffffffff8152ad74 #5 [ffff88008ba03b50] do_invalid_op at ffffffff8100cf95 #6 [ffff88008ba03bf0] invalid_op at ffffffff8100bf9b
[exception RIP: ata_sff_hsm_move+317]
RIP: ffffffff813a77ad RSP: ffff88008ba03ca0 RFLAGS: 00010097
RAX: 0000000000000000 RBX: ffff881c1121dc60 RCX: 0000000000000000
RDX: ffff881c1121dd10 RSI: ffff881c1121dc60 RDI: ffff881c1121c000
RBP: ffff88008ba03d00 R8: 0000000000000000 R9: 000000000000002e
R10: 000000000001003f R11: 000000000000009b R12: ffff881c1121c000
R13: 0000000000000000 R14: 0000000000000050 R15: ffff881c1121dd78
ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
#7 [ffff88008ba03d08] ata_sff_host_intr at ffffffff813a7fbd
#8 [ffff88008ba03d38] ata_sff_interrupt at ffffffff813a821e
#9 [ffff88008ba03d78] handle_IRQ_event at ffffffff810e6ec0
---
drivers/ata/libata-sff.c | 12 ++++++++++++
1 file changed, 12 insertions(+)drivers/ata/libata-sff.c +12 -0
@@ -1333,7 +1333,19 @@ void ata_sff_flush_pio_task(struct ata_pDPRINTK ("ENTER\n" );cancel_delayed_work_sync (&ap->sff_pio_task); + +/* +* We wanna reset the HSM state to IDLE. If we do so without +* grabbing the port lock, critical sections protected by it which +* expect the HSM state to stay stable may get surprised. For +* example, we may set IDLE in between the time +* __ata_sff_port_intr() checks for HSM_ST_IDLE and before it calls +* ata_sff_hsm_move() causing ata_sff_hsm_move() to BUG(). +*/ +spin_lock_irq (ap->lock); ap->hsm_task_state =HSM_ST_IDLE ; +spin_unlock_irq (ap->lock); + ap->sff_pio_task_link =NULL ;if (ata_msg_ctl (ap))
Greg Kroah-Hartman
maintainerPATCH 5/77 ALSA: usb-audio: Add mic volume fix quirk for Logitech Webcam C210
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Lee Cragg <[email protected]>
commit 6455931186bff407493135e74c5f32efd30860e2 upstream.
--- sound/usb/mixer.c | 1 + 1 file changed, 1 insertion(+)
sound/usb/mixer.c +1 -0
@@ -886,6 +886,7 @@ static void volume_control_quirks(structcase USB_ID (0x046d ,0x0807 ):/* Logitech Webcam C500 */ case USB_ID (0x046d ,0x0808 ):case USB_ID (0x046d ,0x0809 ): +case USB_ID (0x046d ,0x0819 ):/* Logitech Webcam C210 */ case USB_ID (0x046d ,0x081b ):/* HD Webcam c310 */ case USB_ID (0x046d ,0x081d ):/* HD Webcam c510 */ case USB_ID (0x046d ,0x0825 ):/* HD Webcam c270 */
Greg Kroah-Hartman
maintainerPATCH 6/77 scripts/recordmcount.pl: There is no -m32 gcc option on Super-H anymore
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Karcher <[email protected]>
commit 1caf6aaaa47471831d77c75f094d4e00ad1ec808 upstream.
Compiling SH with gcc-4.8 fails due to the -m32 option not being supported.
Quoted 1 line
CC init/main.o
gcc-4.8: error: unrecognized command line option '-m32'
ld: cannot find init/.tmp_mc_main.o: No such file or directory
objcopy: 'init/.tmp_mx_main.o': No such file
rm: cannot remove 'init/.tmp_mx_main.o': No such file or directory
rm: cannot remove 'init/.tmp_mc_main.o': No such file or directory
--- scripts/recordmcount.pl | 1 - 1 file changed, 1 deletion(-)
scripts/recordmcount.pl +0 -1
@@ -262,7 +262,6 @@ if ($arch eq "x86_64") { # force flags for this arch $ld .= " -m shlelf_linux"; $objcopy .= " -O elf32-sh-linux"; - $cc .= " -m32"; } elsif ($arch eq "powerpc") { $local_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\.?\\S+)";
Greg Kroah-Hartman
maintainerPATCH 7/77 drm/i915: Fix mutex->owner inspection race under DEBUG_MUTEXES
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Wilson <[email protected]>
commit 226e5ae9e5f9108beb0bde4ac69f68fe6210fed9 upstream.
If CONFIG_DEBUG_MUTEXES is set, the mutex->owner field is only cleared if the mutex debugging is enabled which introduces a race in our mutex_is_locked_by() - i.e. we may inspect the old owner value before it is acquired by the new task.
This is the root cause of this error:
# diff --git a/kernel/locking/mutex-debug.c b/kernel/locking/mutex-debug.c # index 5cf6731..3ef3736 100644 # --- a/kernel/locking/mutex-debug.c # +++ b/kernel/locking/mutex-debug.c # @@ -80,13 +80,13 @@ void debug_mutex_unlock(struct mutex *lock) # DEBUG_LOCKS_WARN_ON(lock->owner != current); # # DEBUG_LOCKS_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next); # - mutex_clear_owner(lock); # } # # /* # * __mutex_slowpath_needs_to_unlock() is explicitly 0 for debug # * mutexes so that we can do it here after we've verified state. # */ # + mutex_clear_owner(lock); # atomic_set(&lock->count, 1); # }
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=87955
--- drivers/gpu/drm/i915/i915_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/i915/i915_gem.c +1 -1
@@ -4978,7 +4978,7 @@ static bool mutex_is_locked_by(struct muif (!mutex_is_locked (mutex))return false; -#if defined(CONFIG_SMP ) || defined(CONFIG_DEBUG_MUTEXES ) +#if defined(CONFIG_SMP ) && !defined(CONFIG_DEBUG_MUTEXES )return mutex->owner == task;#else /* Since UP may be pre-empted, we cannot assume that we own the lock */
Greg Kroah-Hartman
maintainerPATCH 8/77 drm/radeon: add a dpm quirk list
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 4369a69ec6ab86821352bd753c68af5880f87956 upstream.
Disable dpm on certain problematic boards rather than disabling dpm for the entire chip family since most boards work fine.
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1386534
https://bugzilla.kernel.org/show_bug.cgi?id=83731
--- drivers/gpu/drm/radeon/radeon_pm.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+)
drivers/gpu/drm/radeon/radeon_pm.c +33 -0
@@ -1260,8 +1260,39 @@ dpm_failed:return ret; } +struct radeon_dpm_quirk { +u32 chip_vendor; +u32 chip_device; +u32 subsys_vendor; +u32 subsys_device; +}; + +/* cards with dpm stability problems */ +static struct radeon_dpm_quirk radeon_dpm_quirk_list[] = { +/* TURKS - https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1386534 */ + {PCI_VENDOR_ID_ATI ,0x6759 ,0x1682 ,0x3195 }, +/* TURKS - https://bugzilla.kernel.org/show_bug.cgi?id=83731 */ + {PCI_VENDOR_ID_ATI ,0x6840 ,0x1179 ,0xfb81 }, + {0 ,0 ,0 ,0 }, +}; +int radeon_pm_init (struct radeon_device *rdev) { +struct radeon_dpm_quirk *p = radeon_dpm_quirk_list; +bool disable_dpm = false; + +/* Apply dpm quirks */ +while (p && p->chip_device !=0 ) { +if (rdev->pdev->vendor == p->chip_vendor && + rdev->pdev->device == p->chip_device && + rdev->pdev->subsystem_vendor == p->subsys_vendor && + rdev->pdev->subsystem_device == p->subsys_device) { + disable_dpm = true; +break ; + } + ++p; + } +/* enable dpm on rv6xx+ */ switch (rdev->family) {case CHIP_RV610 :
@@ -1316,6 +1347,8 @@ int radeon_pm_init(struct radeon_device (!(rdev->flags &RADEON_IS_IGP )) && (!rdev->smc_fw)) rdev->pm.pm_method = PM_METHOD_PROFILE; + else if (disable_dpm && (radeon_dpm == -1)) + rdev->pm.pm_method = PM_METHOD_PROFILE; else if (radeon_dpm == 0) rdev->pm.pm_method = PM_METHOD_PROFILE; else
Greg Kroah-Hartman
maintainerPATCH 9/77 drm/radeon: add si dpm quirk list
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 5615f890bc6babdc2998dec62f3552326d06eb7b upstream.
This adds a quirks list to fix stability problems with certain SI boards.
bug:
https://bugs.freedesktop.org/show_bug.cgi?id=76490
--- drivers/gpu/drm/radeon/si_dpm.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+)
drivers/gpu/drm/radeon/si_dpm.c +39 -0
@@ -2900,6 +2900,22 @@ static int si_init_smc_spll_table(structreturn ret; } +struct si_dpm_quirk { +u32 chip_vendor; +u32 chip_device; +u32 subsys_vendor; +u32 subsys_device; +u32 max_sclk; +u32 max_mclk; +}; + +/* cards with dpm stability problems */ +static struct si_dpm_quirk si_dpm_quirk_list[] = { +/* PITCAIRN - https://bugs.freedesktop.org/show_bug.cgi?id=76490 */ + {PCI_VENDOR_ID_ATI ,0x6810 ,0x1462 ,0x3036 ,0 ,120000 }, + {0 ,0 ,0 ,0 }, +}; +static void si_apply_state_adjust_rules (struct radeon_device *rdev,struct radeon_ps *rps) {
@@ -2910,7 +2926,22 @@ static void si_apply_state_adjust_rules(u32 mclk, sclk;u16 vddc, vddci;u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc; +u32 max_sclk =0 , max_mclk =0 ;int i; +struct si_dpm_quirk *p = si_dpm_quirk_list; + +/* Apply dpm quirks */ +while (p && p->chip_device !=0 ) { +if (rdev->pdev->vendor == p->chip_vendor && + rdev->pdev->device == p->chip_device && + rdev->pdev->subsystem_vendor == p->subsys_vendor && + rdev->pdev->subsystem_device == p->subsys_device) { + max_sclk = p->max_sclk; + max_mclk = p->max_mclk; +break ; + } + ++p; + }if ((rdev->pm.dpm.new_active_crtc_count >1 ) ||ni_dpm_vblank_too_short (rdev))
@@ -2964,6 +2995,14 @@ static void si_apply_state_adjust_rules(if (ps->performance_levels[i].mclk > max_mclk_vddc) ps->performance_levels[i].mclk = max_mclk_vddc; } +if (max_mclk) { +if (ps->performance_levels[i].mclk > max_mclk) + ps->performance_levels[i].mclk = max_mclk; + } +if (max_sclk) { +if (ps->performance_levels[i].sclk > max_sclk) + ps->performance_levels[i].sclk = max_sclk; + } }/* XXX validate the min clocks required for display */
Greg Kroah-Hartman
maintainerPATCH 10/77 drm/radeon: use rv515_ring_start on r5xx
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit d8a74e186949e1a2c2f1309212478b0659bf9225 upstream.
This was accidently lost in 76a0df859def.
--- drivers/gpu/drm/radeon/radeon_asic.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
drivers/gpu/drm/radeon/radeon_asic.c +16 -2
@@ -335,6 +335,20 @@ static struct radeon_asic_ring r300_gfx_ .set_wptr = &r100_gfx_set_wptr, }; +static struct radeon_asic_ring rv515_gfx_ring = { + .ib_execute = &r100_ring_ib_execute, + .emit_fence = &r300_fence_ring_emit, + .emit_semaphore = &r100_semaphore_ring_emit, + .cs_parse = &r300_cs_parse, + .ring_start = &rv515_ring_start, + .ring_test = &r100_ring_test, + .ib_test = &r100_ib_test, + .is_lockup = &r100_gpu_is_lockup, + .get_rptr = &r100_gfx_get_rptr, + .get_wptr = &r100_gfx_get_wptr, + .set_wptr = &r100_gfx_set_wptr, +}; +static struct radeon_asic r300_asic = { .init = &r300_init, .fini = &r300_fini,
@@ -756,7 +770,7 @@ static struct radeon_asic rv515_asic = { .set_page = &rv370_pcie_gart_set_page, }, .ring = { - [RADEON_RING_TYPE_GFX_INDEX ] = &r300_gfx_ring + [RADEON_RING_TYPE_GFX_INDEX ] = &rv515_gfx_ring }, .irq = { .set = &rs600_irq_set,
@@ -823,7 +837,7 @@ static struct radeon_asic r520_asic = { .set_page = &rv370_pcie_gart_set_page, }, .ring = { - [RADEON_RING_TYPE_GFX_INDEX ] = &r300_gfx_ring + [RADEON_RING_TYPE_GFX_INDEX ] = &rv515_gfx_ring }, .irq = { .set = &rs600_irq_set,
Greg Kroah-Hartman
maintainerPATCH 11/77 PCI: Add flag for devices where we cant use bus reset
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Williamson <[email protected]>
commit f331a859e0ee5a898c1f47596eddad4c4f02d657 upstream.
Enable a mechanism for devices to quirk that they do not behave when doing a PCI bus reset. We require a modest level of spec compliant behavior in order to do a reset, for instance the device should come out of reset without throwing errors and PCI config space should be accessible after reset. This is too much to ask for some devices.
--- drivers/pci/pci.c | 40 ++++++++++++++++++++++++++++++++++++---- include/linux/pci.h | 2 ++ 2 files changed, 38 insertions(+), 4 deletions(-)
drivers/pci/pci.c +36 -4
@@ -3187,7 +3187,8 @@ static int pci_parent_bus_reset(struct p {struct pci_dev *pdev; -if (pci_is_root_bus (dev->bus) || dev->subordinate || !dev->bus->self) +if (pci_is_root_bus (dev->bus) || dev->subordinate || + !dev->bus->self || dev->dev_flags &PCI_DEV_FLAGS_NO_BUS_RESET )return -ENOTTY ;list_for_each_entry (pdev, &dev->bus->devices, bus_list)
@@ -3221,7 +3222,8 @@ static int pci_dev_reset_slot_function(s {struct pci_dev *pdev; -if (dev->subordinate || !dev->slot) +if (dev->subordinate || !dev->slot || + dev->dev_flags &PCI_DEV_FLAGS_NO_BUS_RESET )return -ENOTTY ;list_for_each_entry (pdev, &dev->bus->devices, bus_list)
@@ -3452,6 +3454,20 @@ int pci_try_reset_function(struct pci_de }EXPORT_SYMBOL_GPL (pci_try_reset_function); +/* Do any devices on or below this bus prevent a bus reset? */ +static bool pci_bus_resetable (struct pci_bus *bus) +{ +struct pci_dev *dev; + +list_for_each_entry (dev, &bus->devices, bus_list) { +if (dev->dev_flags &PCI_DEV_FLAGS_NO_BUS_RESET || + (dev->subordinate && !pci_bus_resetable (dev->subordinate))) +return false; + } + +return true; +} +/* Lock devices from the top of the tree down */ static void pci_bus_lock (struct pci_bus *bus) {
@@ -3502,6 +3518,22 @@ unlock:return 0 ; } +/* Do any devices on or below this slot prevent a bus reset? */ +static bool pci_slot_resetable (struct pci_slot *slot) +{ +struct pci_dev *dev; + +list_for_each_entry (dev, &slot->bus->devices, bus_list) { +if (!dev->slot || dev->slot != slot) +continue ; +if (dev->dev_flags &PCI_DEV_FLAGS_NO_BUS_RESET || + (dev->subordinate && !pci_bus_resetable (dev->subordinate))) +return false; + } + +return true; +} +/* Lock devices from the top of the tree down */ static void pci_slot_lock (struct pci_slot *slot) {
@@ -3623,7 +3655,7 @@ static int pci_slot_reset(struct pci_slo {int rc; -if (!slot) +if (!slot || !pci_slot_resetable (slot))return -ENOTTY ;if (!probe)
@@ -3715,7 +3747,7 @@ EXPORT_SYMBOL_GPL(pci_try_reset_slot);static int pci_bus_reset (struct pci_bus *bus,int probe) { -if (!bus->self) +if (!bus->self || !pci_bus_resetable (bus))return -ENOTTY ;if (probe)
include/linux/pci.h +2 -0
@@ -170,6 +170,8 @@ enum pci_dev_flags {PCI_DEV_FLAGS_NO_D3 = (__force pci_dev_flags_t )2 ,/* Provide indication device is assigned by a Virtual Machine Manager */ PCI_DEV_FLAGS_ASSIGNED = (__force pci_dev_flags_t )4 , +/* Do not use bus resets for device */ + PCI_DEV_FLAGS_NO_BUS_RESET = (__force pci_dev_flags_t) (1 << 6), }; enum pci_irq_reroute_variant {
Greg Kroah-Hartman
maintainerPATCH 12/77 PCI: Mark Atheros AR93xx to avoid bus reset
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Williamson <[email protected]>
commit c3e59ee4e76686b0c84ca8faa1011d10cd4ca1b8 upstream.
Reports against the TL-WDN4800 card indicate that PCI bus reset of this Atheros device cause system lock-ups and resets. I've also been able to confirm this behavior on multiple systems. The device never returns from reset and attempts to access config space of the device after reset result in hangs. Blacklist bus reset for the device to avoid this issue.
[bhelgaas: This regression appeared in v3.14. Andreas bisected it to 425c1b223dac ("PCI: Add Virtual Channel to save/restore support"), but we don't understand the mechanism by which that commit affects the reset path.]
--- drivers/pci/quirks.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
drivers/pci/quirks.c +14 -0
@@ -3008,6 +3008,20 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CDECLARE_PCI_FIXUP_HEADER (0x1814 ,0x0601 ,/* Ralink RT2800 802.11n PCI */ quirk_broken_intx_masking); +static void quirk_no_bus_reset (struct pci_dev *dev) +{ + dev->dev_flags |=PCI_DEV_FLAGS_NO_BUS_RESET ; +} + +/* +* Atheros AR93xx chips do not behave after a bus reset. The device will +* throw a Link Down error on AER-capable systems and regardless of AER, +* config space of the device is never accessible again and typically +* causes the system to hang or reset when access is attempted. +* http://www.spinics.net/lists/linux-pci/msg34797.html +*/ +DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_ATHEROS ,0x0030 , quirk_no_bus_reset); +static void pci_do_fixups (struct pci_dev *dev,struct pci_fixup *f,struct pci_fixup *end) {
Greg Kroah-Hartman
maintainerPATCH 13/77 ipr: wait for aborted command responses
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Brian King <[email protected]>
commit 6cdb08172bc89f0a39e1643c5e7eab362692fd1b upstream.
Fixes a race condition in abort handling that was injected when multiple interrupt support was added. When only a single interrupt is present, the adapter guarantees it will send responses for aborted commands prior to the response for the abort command itself. With multiple interrupts, these responses generally come back on different interrupts, so we need to ensure the abort thread waits until the aborted command is complete so we don't perform a double completion. This race condition was being hit frequently in environments which were triggering command timeouts, which was resulting in a double completion causing a kernel oops.
--- drivers/scsi/ipr.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++ drivers/scsi/ipr.h | 1 2 files changed, 93 insertions(+)
drivers/scsi/ipr.c +92 -0
@@ -683,6 +683,7 @@ static void ipr_init_ipr_cmnd(struct ipripr_reinit_ipr_cmnd (ipr_cmd); ipr_cmd->u.scratch =0 ; ipr_cmd->sibling =NULL ; + ipr_cmd->eh_comp =NULL ; ipr_cmd->fast_done = fast_done;init_timer (&ipr_cmd->timer); }
@@ -848,6 +849,8 @@ static void ipr_scsi_eh_done(struct ipr_scsi_dma_unmap (ipr_cmd->scsi_cmd); scsi_cmd->scsi_done (scsi_cmd); +if (ipr_cmd->eh_comp) +complete (ipr_cmd->eh_comp);list_add_tail (&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); }
@@ -4805,6 +4808,84 @@ static int ipr_slave_alloc(struct scsi_dreturn rc; } +/** +* ipr_match_lun - Match function for specified LUN +* @ipr_cmd: ipr command struct +* @device: device to match (sdev) +* +* Returns: +* 1 if command matches sdev / 0 if command does not match sdev +**/ +static int ipr_match_lun (struct ipr_cmnd *ipr_cmd,void *device) +{ +if (ipr_cmd->scsi_cmd && ipr_cmd->scsi_cmd->device == device) +return 1 ; +return 0 ; +} + +/** +* ipr_wait_for_ops - Wait for matching commands to complete +* @ipr_cmd: ipr command struct +* @device: device to match (sdev) +* @match: match function to use +* +* Returns: +* SUCCESS / FAILED +**/ +static int ipr_wait_for_ops (struct ipr_ioa_cfg *ioa_cfg,void *device, +int (*match)(struct ipr_cmnd *,void *)) +{ +struct ipr_cmnd *ipr_cmd; +int wait; +unsigned long flags; +struct ipr_hrr_queue *hrrq; +signed long timeout =IPR_ABORT_TASK_TIMEOUT ; +DECLARE_COMPLETION_ONSTACK (comp); + +ENTER ; +do { + wait =0 ; + +for_each_hrrq (hrrq, ioa_cfg) { +spin_lock_irqsave (hrrq->lock, flags); +list_for_each_entry (ipr_cmd, &hrrq->hrrq_pending_q, queue) { +if (match (ipr_cmd, device)) { + ipr_cmd->eh_comp = ∁ + wait++; + } + } +spin_unlock_irqrestore (hrrq->lock, flags); + } + +if (wait) { + timeout =wait_for_completion_timeout (&comp, timeout); + +if (!timeout) { + wait =0 ; + +for_each_hrrq (hrrq, ioa_cfg) { +spin_lock_irqsave (hrrq->lock, flags); +list_for_each_entry (ipr_cmd, &hrrq->hrrq_pending_q, queue) { +if (match (ipr_cmd, device)) { + ipr_cmd->eh_comp =NULL ; + wait++; + } + } +spin_unlock_irqrestore (hrrq->lock, flags); + } + +if (wait) +dev_err (&ioa_cfg->pdev->dev,"Timed out waiting for aborted commands\n" ); +LEAVE ; +return wait ?FAILED :SUCCESS ; + } + } + }while (wait); + +LEAVE ; +return SUCCESS ; +} +static int ipr_eh_host_reset (struct scsi_cmnd *cmd) {struct ipr_ioa_cfg *ioa_cfg;
@@ -5023,11 +5104,17 @@ static int __ipr_eh_dev_reset(struct scsstatic int ipr_eh_dev_reset (struct scsi_cmnd *cmd) {int rc; +struct ipr_ioa_cfg *ioa_cfg; + + ioa_cfg = (struct ipr_ioa_cfg *) cmd->device->host->hostdata;spin_lock_irq (cmd->device->host->host_lock); rc =__ipr_eh_dev_reset (cmd);spin_unlock_irq (cmd->device->host->host_lock); +if (rc ==SUCCESS ) + rc =ipr_wait_for_ops (ioa_cfg, cmd->device, ipr_match_lun); +return rc; }
@@ -5205,13 +5292,18 @@ static int ipr_eh_abort(struct scsi_cmnd {unsigned long flags;int rc; +struct ipr_ioa_cfg *ioa_cfg;ENTER ; + ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata; +spin_lock_irqsave (scsi_cmd->device->host->host_lock, flags); rc =ipr_cancel_op (scsi_cmd);spin_unlock_irqrestore (scsi_cmd->device->host->host_lock, flags); +if (rc ==SUCCESS ) + rc =ipr_wait_for_ops (ioa_cfg, scsi_cmd->device, ipr_match_lun);LEAVE ;return rc; }
drivers/scsi/ipr.h +1 -0
@@ -1585,6 +1585,7 @@ struct ipr_cmnd {struct scsi_device *sdev; } u; +struct completion *eh_comp;struct ipr_hrr_queue *hrrq;struct ipr_ioa_cfg *ioa_cfg; };
Greg Kroah-Hartman
maintainerPATCH 14/77 dm cache: share cache-metadata object across inactive and active DM tables
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joe Thornber <[email protected]>
commit 9b1cc9f251affdd27f29fe46d0989ba76c33faf6 upstream.
If a DM table is reloaded with an inactive table when the device is not suspended (normal procedure for LVM2), then there will be two dm-bufio objects that can diverge. This can lead to a situation where the inactive table uses bufio to read metadata at the same time the active table writes metadata -- resulting in the inactive table having stale metadata buffers once it is promoted to the active table slot.
Fix this by using reference counting and a global list of cache metadata objects to ensure there is only one metadata object per metadata device.
--- drivers/md/dm-cache-metadata.c | 101 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 95 insertions(+), 6 deletions(-)
drivers/md/dm-cache-metadata.c +95 -6
@@ -94,6 +94,9 @@ struct cache_disk_superblock { } __packed;struct dm_cache_metadata { +atomic_t ref_count; +struct list_head list; +struct block_device *bdev;struct dm_block_manager *bm;struct dm_space_map *metadata_sm;
@@ -669,10 +672,10 @@ static void unpack_value(__le64 value_le/*----------------------------------------------------------------*/ -struct dm_cache_metadata *dm_cache_metadata_open (struct block_device *bdev, -sector_t data_block_size, -bool may_format_device, -size_t policy_hint_size) +static struct dm_cache_metadata *metadata_open (struct block_device *bdev, +sector_t data_block_size, +bool may_format_device, +size_t policy_hint_size) {int r;struct dm_cache_metadata *cmd;
@@ -683,6 +686,7 @@ struct dm_cache_metadata *dm_cache_metadreturn NULL ; } +atomic_set (&cmd->ref_count,1 );init_rwsem (&cmd->root_lock); cmd->bdev = bdev; cmd->data_block_size = data_block_size;
@@ -705,10 +709,95 @@ struct dm_cache_metadata *dm_cache_metadreturn cmd; } +/* +* We keep a little list of ref counted metadata objects to prevent two +* different target instances creating separate bufio instances. This is +* an issue if a table is reloaded before the suspend. +*/ +static DEFINE_MUTEX (table_lock); +static LIST_HEAD (table); + +static struct dm_cache_metadata *lookup (struct block_device *bdev) +{ +struct dm_cache_metadata *cmd; + +list_for_each_entry (cmd, &table, list) +if (cmd->bdev == bdev) { +atomic_inc (&cmd->ref_count); +return cmd; + } + +return NULL ; +} + +static struct dm_cache_metadata *lookup_or_open (struct block_device *bdev, +sector_t data_block_size, +bool may_format_device, +size_t policy_hint_size) +{ +struct dm_cache_metadata *cmd, *cmd2; + +mutex_lock (&table_lock); + cmd =lookup (bdev); +mutex_unlock (&table_lock); + +if (cmd) +return cmd; + + cmd =metadata_open (bdev, data_block_size, may_format_device, policy_hint_size); +if (cmd) { +mutex_lock (&table_lock); + cmd2 =lookup (bdev); +if (cmd2) { +mutex_unlock (&table_lock); +__destroy_persistent_data_objects (cmd); +kfree (cmd); +return cmd2; + } +list_add (&cmd->list, &table); +mutex_unlock (&table_lock); + } + +return cmd; +} + +static bool same_params (struct dm_cache_metadata *cmd,sector_t data_block_size) +{ +if (cmd->data_block_size != data_block_size) { +DMERR ("data_block_size (%llu) different from that in metadata (%llu)\n" , + (unsigned long long ) data_block_size, + (unsigned long long ) cmd->data_block_size); +return false; + } + +return true; +} + +struct dm_cache_metadata *dm_cache_metadata_open (struct block_device *bdev, +sector_t data_block_size, +bool may_format_device, +size_t policy_hint_size) +{ +struct dm_cache_metadata *cmd =lookup_or_open (bdev, data_block_size, + may_format_device, policy_hint_size); +if (cmd && !same_params (cmd, data_block_size)) { +dm_cache_metadata_close (cmd); +return NULL ; + } + +return cmd; +} +void dm_cache_metadata_close (struct dm_cache_metadata *cmd) { -__destroy_persistent_data_objects (cmd); -kfree (cmd); +if (atomic_dec_and_test (&cmd->ref_count)) { +mutex_lock (&table_lock); +list_del (&cmd->list); +mutex_unlock (&table_lock); + +__destroy_persistent_data_objects (cmd); +kfree (cmd); + } }/*
Greg Kroah-Hartman
maintainerPATCH 15/77 dm cache: fix problematic dual use of a single migration count variable
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joe Thornber <[email protected]>
commit a59db67656021fa212e9b95a583f13c34eb67cd9 upstream.
Introduce a new variable to count the number of allocated migration structures. The existing variable cache->nr_migrations became overloaded. It was used to:
i) track of the number of migrations in flight for the purposes of quiescing during suspend.
ii) to estimate the amount of background IO occuring.
Recent discard changes meant that REQ_DISCARD bios are processed with a migration. Discards are not background IO so nr_migrations was not incremented. However this could cause quiescing to complete early.
(i) is now handled with a new variable cache->nr_allocated_migrations. cache->nr_migrations has been renamed cache->nr_io_migrations. cleanup_migration() is now called free_io_migration(), since it decrements that variable.
Also, remove the unused cache->next_migration variable that got replaced with with prealloc_structs a while ago.
--- drivers/md/dm-cache-target.c | 89 ++++++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 39 deletions(-)
drivers/md/dm-cache-target.c +50 -39
@@ -222,7 +222,13 @@ struct cache {struct list_head need_commit_migrations;sector_t migration_threshold;wait_queue_head_t migration_wait; -atomic_t nr_migrations; +atomic_t nr_allocated_migrations; + +/* +* The number of in flight migrations that are performing +* background io. eg, promotion, writeback. +*/ +atomic_t nr_io_migrations;wait_queue_head_t quiescing_wait;atomic_t quiescing;
@@ -259,7 +265,6 @@ struct cache {struct dm_deferred_set *all_io_ds;mempool_t *migration_pool; -struct dm_cache_migration *next_migration;struct dm_cache_policy *policy;unsigned policy_nr_args;
@@ -350,10 +355,31 @@ static void free_prison_cell(struct cachdm_bio_prison_free_cell (cache->prison, cell); } +static struct dm_cache_migration *alloc_migration (struct cache *cache) +{ +struct dm_cache_migration *mg; + + mg =mempool_alloc (cache->migration_pool,GFP_NOWAIT ); +if (mg) { + mg->cache = cache; +atomic_inc (&mg->cache->nr_allocated_migrations); + } + +return mg; +} + +static void free_migration (struct dm_cache_migration *mg) +{ +if (atomic_dec_and_test (&mg->cache->nr_allocated_migrations)) +wake_up (&mg->cache->migration_wait); + +mempool_free (mg, mg->cache->migration_pool); +} +static int prealloc_data_structs (struct cache *cache,struct prealloc *p) {if (!p->mg) { - p->mg =mempool_alloc (cache->migration_pool,GFP_NOWAIT ); + p->mg =alloc_migration (cache);if (!p->mg)return -ENOMEM ; }
@@ -382,7 +408,7 @@ static void prealloc_free_structs(structfree_prison_cell (cache, p->cell1);if (p->mg) -mempool_free (p->mg, cache->migration_pool); +free_migration (p->mg); }static struct dm_cache_migration *prealloc_get_migration (struct prealloc *p)
@@ -812,24 +838,14 @@ static void remap_to_origin_then_cache(s* Migration covers moving data from the origin device to the cache, or * vice versa. *--------------------------------------------------------------*/ -static void free_migration (struct dm_cache_migration *mg) -{ -mempool_free (mg, mg->cache->migration_pool); -} - -static void inc_nr_migrations (struct cache *cache) +static void inc_io_migrations (struct cache *cache) { -atomic_inc (&cache->nr_migrations); +atomic_inc (&cache->nr_io_migrations); } -static void dec_nr_migrations (struct cache *cache) +static void dec_io_migrations (struct cache *cache) { -atomic_dec (&cache->nr_migrations); - -/* -* Wake the worker in case we're suspending the target. -*/ -wake_up (&cache->migration_wait); +atomic_dec (&cache->nr_io_migrations); } static void __cell_defer(struct cache *cache, struct dm_bio_prison_cell *cell,
@@ -852,11 +868,10 @@ static void cell_defer(struct cache *cacwake_worker (cache); } -static void cleanup_migration (struct dm_cache_migration *mg) +static void free_io_migration (struct dm_cache_migration *mg) { -struct cache *cache = mg->cache; +dec_io_migrations (mg->cache);free_migration (mg); -dec_nr_migrations (cache); }static void migration_failure (struct dm_cache_migration *mg)
@@ -881,7 +896,7 @@ static void migration_failure(struct dm_cell_defer (cache, mg->new_ocell, true); } -cleanup_migration (mg); +free_io_migration (mg); }static void migration_success_pre_commit (struct dm_cache_migration *mg)
@@ -892,7 +907,7 @@ static void migration_success_pre_commitif (mg->writeback) {clear_dirty (cache, mg->old_oblock, mg->cblock);cell_defer (cache, mg->old_ocell, false); -cleanup_migration (mg); +free_io_migration (mg);return ; }else if (mg->demote) {
@@ -902,14 +917,14 @@ static void migration_success_pre_commit mg->old_oblock);if (mg->promote)cell_defer (cache, mg->new_ocell, true); -cleanup_migration (mg); +free_io_migration (mg);return ; } }else {if (dm_cache_insert_mapping (cache->cmd, mg->cblock, mg->new_oblock)) {DMWARN_LIMIT ("promotion failed; couldn't update on disk metadata" );policy_remove_mapping (cache->policy, mg->new_oblock); -cleanup_migration (mg); +free_io_migration (mg);return ; } }
@@ -942,7 +957,7 @@ static void migration_success_post_commi }else {if (mg->invalidate)policy_remove_mapping (cache->policy, mg->old_oblock); -cleanup_migration (mg); +free_io_migration (mg); } }else {
@@ -957,7 +972,7 @@ static void migration_success_post_commibio_endio (mg->new_ocell->holder,0 );cell_defer (cache, mg->new_ocell, false); } -cleanup_migration (mg); +free_io_migration (mg); } }
@@ -1169,7 +1184,7 @@ static void promote(struct cache *cache, mg->new_ocell = cell; mg->start_jiffies = jiffies; -inc_nr_migrations (cache); +inc_io_migrations (cache);quiesce_migration (mg); }
@@ -1192,7 +1207,7 @@ static void writeback(struct cache *cach mg->new_ocell =NULL ; mg->start_jiffies = jiffies; -inc_nr_migrations (cache); +inc_io_migrations (cache);quiesce_migration (mg); }
@@ -1218,7 +1233,7 @@ static void demote_then_promote(struct c mg->new_ocell = new_ocell; mg->start_jiffies = jiffies; -inc_nr_migrations (cache); +inc_io_migrations (cache);quiesce_migration (mg); }
@@ -1245,7 +1260,7 @@ static void invalidate(struct cache *cac mg->new_ocell =NULL ; mg->start_jiffies = jiffies; -inc_nr_migrations (cache); +inc_io_migrations (cache);quiesce_migration (mg); }
@@ -1306,7 +1321,7 @@ static void process_discard_bio(struct cstatic bool spare_migration_bandwidth (struct cache *cache) { -sector_t current_volume = (atomic_read (&cache->nr_migrations) +1 ) * +sector_t current_volume = (atomic_read (&cache->nr_io_migrations) +1 ) * cache->sectors_per_block;return current_volume < cache->migration_threshold; }
@@ -1661,7 +1676,7 @@ static void stop_quiescing(struct cachestatic void wait_for_migrations (struct cache *cache) { -wait_event (cache->migration_wait, !atomic_read (&cache->nr_migrations)); +wait_event (cache->migration_wait, !atomic_read (&cache->nr_allocated_migrations)); }static void stop_worker (struct cache *cache)
@@ -1772,9 +1787,6 @@ static void destroy(struct cache *cache) {unsigned i; -if (cache->next_migration) -mempool_free (cache->next_migration, cache->migration_pool); -if (cache->migration_pool)mempool_destroy (cache->migration_pool);
@@ -2282,7 +2294,8 @@ static int cache_create(struct cache_argINIT_LIST_HEAD (&cache->quiesced_migrations);INIT_LIST_HEAD (&cache->completed_migrations);INIT_LIST_HEAD (&cache->need_commit_migrations); -atomic_set (&cache->nr_migrations,0 ); +atomic_set (&cache->nr_allocated_migrations,0 ); +atomic_set (&cache->nr_io_migrations,0 );init_waitqueue_head (&cache->migration_wait);init_waitqueue_head (&cache->quiescing_wait);
@@ -2342,8 +2355,6 @@ static int cache_create(struct cache_arg goto bad; } - cache->next_migration =NULL ; - cache->need_tick_bio = true; cache->sized = false; cache->invalidate = false;
Greg Kroah-Hartman
maintainerPATCH 16/77 time: settimeofday: Validate the values of tv from user
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sasha Levin <[email protected]>
commit 6ada1fc0e1c4775de0e043e1bd3ae9d065491aa5 upstream.
An unvalidated user input is multiplied by a constant, which can result in an undefined behaviour for large values. While this is validated later, we should avoid triggering undefined behaviour.
[jstultz: include trivial milisecond->microsecond correction noticed by Andy]
--- include/linux/time.h | 13 +++++++++++++ kernel/time.c | 4 ++++ 2 files changed, 17 insertions(+)
include/linux/time.h +13 -0
@@ -173,6 +173,19 @@ extern void getboottime(struct timespecextern void monotonic_to_bootbased (struct timespec *ts);extern void get_monotonic_boottime (struct timespec *ts); +static inline bool timeval_valid (const struct timeval *tv) +{ +/* Dates before 1970 are bogus */ +if (tv->tv_sec <0 ) +return false; + +/* Can't have more microseconds then a second */ +if (tv->tv_usec <0 || tv->tv_usec >=USEC_PER_SEC ) +return false; + +return true; +} +extern struct timespec timespec_trunc (struct timespec t,unsigned gran);extern int timekeeping_valid_for_hres (void );extern u64 timekeeping_max_deferment (void );
kernel/time.c +4 -0
@@ -195,6 +195,10 @@ SYSCALL_DEFINE2(settimeofday, struct timif (tv) {if (copy_from_user (&user_tv, tv,sizeof (*tv)))return -EFAULT ; + +if (!timeval_valid (&user_tv)) +return -EINVAL ; + new_ts.tv_sec = user_tv.tv_sec; new_ts.tv_nsec = user_tv.tv_usec *NSEC_PER_USEC ; }
Greg Kroah-Hartman
maintainerPATCH 17/77 time: adjtimex: Validate the ADJ_FREQUENCY values
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sasha Levin <[email protected]>
commit 5e5aeb4367b450a28f447f6d5ab57d8f2ab16a5f upstream.
Verify that the frequency value from userspace is valid and makes sense.
Unverified values can cause overflows later on.
--- kernel/time/ntp.c | 7 +++++++ 1 file changed, 7 insertions(+)
kernel/time/ntp.c +7 -0
@@ -631,6 +631,13 @@ int ntp_validate_timex(struct timex *txcif ((txc->modes &ADJ_SETOFFSET ) && (!capable (CAP_SYS_TIME )))return -EPERM ; +if (txc->modes &ADJ_FREQUENCY ) { +if (LONG_MIN /PPM_SCALE > txc->freq) +return -EINVAL ; +if (LONG_MAX /PPM_SCALE < txc->freq) +return -EINVAL ; + } +return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 18/77 ARM: dts: imx25: Fix PWM "per" clocks
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fabio Estevam <[email protected]>
commit 7ecd0bde5bfea524a843ad8fa8cb66ccbce68779 upstream.
Currently PWM functionality is broken on mx25 due to the wrong assignment of the PWM "per" clock.
According to Documentation/devicetree/bindings/clock/imx25-clock.txt:
pwm_ipg_per 52
,so update the pwm "per" to use 'pwm_ipg_per' instead of 'per10' clock.
With this change PWM can work fine on mx25.
--- arch/arm/boot/dts/imx25.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
arch/arm/boot/dts/imx25.dtsi +4 -4
@@ -352,7 +352,7 @@ compatible = "fsl,imx25-pwm", "fsl,imx27-pwm"; #pwm-cells = <2>; reg = <0x53fa0000 0x4000>; - clocks = <&clks 106>, <&clks 36>; + clocks = <&clks 106>, <&clks 52>; clock-names = "ipg", "per"; interrupts = <36>; };
@@ -371,7 +371,7 @@ compatible = "fsl,imx25-pwm", "fsl,imx27-pwm"; #pwm-cells = <2>; reg = <0x53fa8000 0x4000>; - clocks = <&clks 107>, <&clks 36>; + clocks = <&clks 107>, <&clks 52>; clock-names = "ipg", "per"; interrupts = <41>; };
@@ -412,7 +412,7 @@ pwm4: pwm@53fc8000 { compatible = "fsl,imx25-pwm", "fsl,imx27-pwm"; reg = <0x53fc8000 0x4000>; - clocks = <&clks 108>, <&clks 36>; + clocks = <&clks 108>, <&clks 52>; clock-names = "ipg", "per"; interrupts = <42>; };
@@ -458,7 +458,7 @@ compatible = "fsl,imx25-pwm", "fsl,imx27-pwm"; #pwm-cells = <2>; reg = <0x53fe0000 0x4000>; - clocks = <&clks 105>, <&clks 36>; + clocks = <&clks 105>, <&clks 52>; clock-names = "ipg", "per"; interrupts = <26>; };
Greg Kroah-Hartman
maintainerPATCH 19/77 bus: mvebu-mbus: fix support of MBus window 13
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Lunn <[email protected]>
commit 38bdf45f4aa5cb6186d50a29e6cbbd9d486a1519 upstream.
On Armada XP, 375 and 38x the MBus window 13 has the remap capability, like windows 0 to 7. However, the mvebu-mbus driver isn't currently taking into account this special case, which means that when window 13 is actually used, the remap registers are left to 0, making the device using this MBus window unavailable.
As a minimal fix for stable, don't use window 13. A full fix will follow later.
--- drivers/bus/mvebu-mbus.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
drivers/bus/mvebu-mbus.c +13 -0
@@ -181,12 +181,25 @@ static void mvebu_mbus_disable_window(st }/* Checks whether the given window number is available */ + +/* On Armada XP, 375 and 38x the MBus window 13 has the remap +* capability, like windows 0 to 7. However, the mvebu-mbus driver +* isn't currently taking into account this special case, which means +* that when window 13 is actually used, the remap registers are left +* to 0, making the device using this MBus window unavailable. The +* quick fix for stable is to not use window 13. A follow up patch +* will correctly handle this window. +*/ static int mvebu_mbus_window_is_free (struct mvebu_mbus_state *mbus,const int win) {void __iomem *addr = mbus->mbuswins_base + mbus->soc->win_cfg_offset (win);u32 ctrl =readl (addr +WIN_CTRL_OFF ); + +if (win ==13 ) +return false; +return !(ctrl &WIN_CTRL_ENABLE ); }
Greg Kroah-Hartman
maintainerPATCH 20/77 fix deadlock in cifs_ioctl_clone()
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit 378ff1a53b5724f3ac97b0aba3c9ecac072f6fcd upstream.
It really needs to check that src is non-directory *and* use {un,}lock_two_nodirectories(). As it is, it's trivial to cause double-lock (ioctl(fd, CIFS_IOC_COPYCHUNK_FILE, fd)) and if the last argument is an fd of directory, we are asking for trouble by violating the locking order - all directories go before all non-directories. If the last argument is an fd of parent directory, it has 50% odds of locking child before parent, which will cause AB-BA deadlock if we race with unlink().
--- fs/cifs/ioctl.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-)
fs/cifs/ioctl.c +5 -16
@@ -86,21 +86,16 @@ static long cifs_ioctl_clone(unsigned in } src_inode = src_file.file->f_dentry->d_inode; + rc = -EINVAL ; +if (S_ISDIR (src_inode->i_mode)) + goto out_fput;/* * Note: cifs case is easier than btrfs since server responsible for * checks for proper open modes and file type and if it wants * server could even support copy of range where source = target */ - -/* so we do not deadlock racing two ioctls on same files */ -if (target_inode < src_inode) { -mutex_lock_nested (&target_inode->i_mutex,I_MUTEX_PARENT ); -mutex_lock_nested (&src_inode->i_mutex,I_MUTEX_CHILD ); - }else { -mutex_lock_nested (&src_inode->i_mutex,I_MUTEX_PARENT ); -mutex_lock_nested (&target_inode->i_mutex,I_MUTEX_CHILD ); - } +lock_two_nondirectories (target_inode, src_inode);/* determine range to clone */ rc = -EINVAL ;
@@ -124,13 +119,7 @@ static long cifs_ioctl_clone(unsigned in out_unlock:/* although unlocking in the reverse order from locking is not strictly necessary here it is a little cleaner to be consistent */ -if (target_inode < src_inode) { -mutex_unlock (&src_inode->i_mutex); -mutex_unlock (&target_inode->i_mutex); - }else { -mutex_unlock (&target_inode->i_mutex); -mutex_unlock (&src_inode->i_mutex); - } +unlock_two_nondirectories (src_inode, target_inode); out_fput:fdput (src_file); out_drop_write:
Greg Kroah-Hartman
maintainerPATCH 21/77 can: dev: fix crtlmode_supported check
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp <[email protected]>
commit 9b1087aa5e86448fe6ad40a58964e35f3ba423d5 upstream.
When changing flags in the CAN drivers ctrlmode the provided new content has to be checked whether the bits are allowed to be changed. The bits that are to be changed are given as a bitfield in cm->mask. Therefore checking against cm->flags is wrong as the content can hold any kind of values.
The iproute2 tool sets the bits in cm->mask and cm->flags depending on the detected command line options. To be robust against bogus user space applications additionally sanitize the provided flags with the provided mask.
--- drivers/net/can/dev.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/can/dev.c +6 -2
@@ -664,10 +664,14 @@ static int can_changelink(struct net_devif (dev->flags &IFF_UP )return -EBUSY ; cm =nla_data (data[IFLA_CAN_CTRLMODE ]); -if (cm->flags & ~priv->ctrlmode_supported) + +/* check whether changed bits are allowed to be modified */ +if (cm->mask & ~priv->ctrlmode_supported)return -EOPNOTSUPP ; + +/* clear bits to be modified and copy the flag values */ priv->ctrlmode &= ~cm->mask; - priv->ctrlmode |= cm->flags; + priv->ctrlmode |= (cm->flags & cm->mask); }if (data[IFLA_CAN_RESTART_MS ]) {
Greg Kroah-Hartman
maintainerPATCH 22/77 clocksource: exynos_mct: Fix bitmask regression for exynos4_mct_write
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tobias Jakobi <[email protected]>
commit 8c38d28ba8da98f7102c31d35359b4dbe9d1f329 upstream.
EXYNOS4_MCT_L_MASK is defined as 0xffffff00, so applying this bitmask produces a number outside the range 0x00 to 0xff, which always results in execution of the default switch statement.
Obviously this is wrong and git history shows that the bitmask inversion was incorrectly set during a refactoring of the MCT code.
Fix this by putting the inversion at the correct position again.
--- drivers/clocksource/exynos_mct.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/clocksource/exynos_mct.c +2 -2
@@ -98,8 +98,8 @@ static void exynos4_mct_write(unsigned i__raw_writel (value, reg_base + offset);if (likely (offset >=EXYNOS4_MCT_L_BASE (0 ))) { - stat_addr = (offset & ~EXYNOS4_MCT_L_MASK ) +MCT_L_WSTAT_OFFSET ; -switch (offset &EXYNOS4_MCT_L_MASK ) { + stat_addr = (offset &EXYNOS4_MCT_L_MASK ) +MCT_L_WSTAT_OFFSET ; +switch (offset & ~EXYNOS4_MCT_L_MASK ) {case MCT_L_TCON_OFFSET : mask =1 <<3 ;/* L_TCON write status */ break ;
Greg Kroah-Hartman
maintainerPATCH 23/77 x86, hyperv: Mark the Hyper-V clocksource as being continuous
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: "K. Y. Srinivasan" <[email protected]>
commit 32c6590d126836a062b3140ed52d898507987017 upstream.
The Hyper-V clocksource is continuous; mark it accordingly.
--- arch/x86/kernel/cpu/mshyperv.c | 1 + 1 file changed, 1 insertion(+)
arch/x86/kernel/cpu/mshyperv.c +1 -0
@@ -67,6 +67,7 @@ static struct clocksource hyperv_cs = { .rating = 400, /* use this when running on Hyperv*/ .read = read_hv_clock, .mask = CLOCKSOURCE_MASK(64), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, };static void __init ms_hyperv_init_platform (void )
Greg Kroah-Hartman
maintainerPATCH 24/77 x86/tsc: Change Fast TSC calibration failed from error to info
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexandre Demers <[email protected]>
commit 520452172e6b318f3a8bd9d4fe1e25066393de25 upstream.
Many users see this message when booting without knowning that it is of no importance and that TSC calibration may have succeeded by another way.
As explained by Paul Bolle in
http://lkml.kernel.org/r/[email protected]
"Fast TSC calibration failed" should not be considered as an error since other calibration methods are being tried afterward. At most, those send a warning if they fail (not an error). So let's change the message from error to warning.
[ tglx: Make if pr_info. It's really not important at all ]
--- arch/x86/kernel/tsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/tsc.c +1 -1
@@ -618,7 +618,7 @@ static unsigned long quick_pit_calibrate goto success; } } -pr_err ("Fast TSC calibration failed\n" ); +pr_info ("Fast TSC calibration failed\n" );return 0 ; success:
Greg Kroah-Hartman
maintainerPATCH 25/77 x86, boot: Skip relocs when load address unchanged
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kees Cook <[email protected]>
commit f285f4a21c3253887caceed493089ece17579d59 upstream.
On 64-bit, relocation is not required unless the load address gets changed. Without this, relocations do unexpected things when the kernel is above 4G.
--- arch/x86/boot/compressed/misc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
arch/x86/boot/compressed/misc.c +8 -1
@@ -396,6 +396,8 @@ asmlinkage void *decompress_kernel(void unsigned long output_len, unsigned long run_size) { +unsigned char *output_orig = output; + real_mode = rmode;sanitize_boot_params (real_mode);
@@ -444,7 +446,12 @@ asmlinkage void *decompress_kernel(voiddebug_putstr ("\nDecompressing Linux... " );decompress (input_data, input_len,NULL ,NULL , output,NULL , error);parse_elf (output); -handle_relocations (output, output_len); +/* +* 32-bit always performs relocations. 64-bit relocations are only +* needed if kASLR has chosen a different load address. +*/ +if (!IS_ENABLED (CONFIG_X86_64 ) || output != output_orig) +handle_relocations (output, output_len);debug_putstr ("done.\nBooting the kernel.\n" );return output; }
Greg Kroah-Hartman
maintainerPATCH 26/77 KVM: x86: Fix of previously incomplete fix for CVE-2014-8480
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nadav Amit <[email protected]>
commit 63ea0a49ae0b145b91ff2b070c01b66fc75854b9 upstream.
STR and SLDT with rip-relative operand can cause a host kernel oops. Mark them as DstMem as well.
--- arch/x86/kvm/emulate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/kvm/emulate.c +2 -2
@@ -3668,8 +3668,8 @@ static const struct opcode group5[] = { };static const struct opcode group6[] = { -DI (Prot, sldt), -DI (Prot, str), +DI (Prot | DstMem, sldt), +DI (Prot | DstMem, str),II (Prot | Priv | SrcMem16, em_lldt, lldt),II (Prot | Priv | SrcMem16, em_ltr, ltr),N ,N ,N ,N ,
Greg Kroah-Hartman
maintainerPATCH 27/77 x86, tls, ldt: Stop checking lm in LDT_empty
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Lutomirski <[email protected]>
commit e30ab185c490e9a9381385529e0fd32f0a399495 upstream.
32-bit programs don't have an lm bit in their ABI, so they can't reliably cause LDT_empty to return true without resorting to memset. They shouldn't need to do this.
This should fix a longstanding, if minor, issue in all 64-bit kernels as well as a potential regression in the TLS hardening code.
--- arch/x86/include/asm/desc.h | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
arch/x86/include/asm/desc.h +2 -7
@@ -251,7 +251,8 @@ static inline void native_load_tls(struc gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; } -#define _LDT_empty (info) \ +/* This intentionally ignores lm, since 32-bit apps don't have that field. */ +#define LDT_empty (info) \ ((info)->base_addr == 0 && \ (info)->limit == 0 && \ (info)->contents == 0 && \
@@ -261,12 +262,6 @@ static inline void native_load_tls(struc (info)->seg_not_present == 1 && \ (info)->useable == 0) -#ifdef CONFIG_X86_64 -#define LDT_empty (info) (_LDT_empty(info) && ((info)->lm == 0)) -#else -#define LDT_empty (info) (_LDT_empty(info)) -#endif -static inline void clear_LDT (void ) {set_ldt (NULL ,0 );
Greg Kroah-Hartman
maintainerPATCH 28/77 x86, tls: Interpret an all-zero struct user_desc as "no segment"
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Lutomirski <[email protected]>
commit 3669ef9fa7d35f573ec9c0e0341b29251c2734a7 upstream.
The Witcher 2 did something like this to allocate a TLS segment index:
struct user_desc u_info;
bzero(&u_info, sizeof(u_info));
u_info.entry_number = (uint32_t)-1;
syscall(SYS_set_thread_area, &u_info);Strictly speaking, this code was never correct. It should have set read_exec_only and seg_not_present to 1 to indicate that it wanted to find a free slot without putting anything there, or it should have put something sensible in the TLS slot if it wanted to allocate a TLS entry for real. The actual effect of this code was to allocate a bogus segment that could be used to exploit espfix.
The set_thread_area hardening patches changed the behavior, causing set_thread_area to return -EINVAL and crashing the game.
This changes set_thread_area to interpret this as a request to find a free slot and to leave it empty, which isn't *quite* what the game expects but should be close enough to keep it working. In particular, using the code above to allocate two segments will allocate the same segment both times.
According to FrostbittenKing on Github, this fixes The Witcher 2.
If this somehow still causes problems, we could instead allocate a limit==0 32-bit data segment, but that seems rather ugly to me.
--- arch/x86/include/asm/desc.h | 13 +++++++++++++ arch/x86/kernel/tls.c | 25 +++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-)
arch/x86/include/asm/desc.h +13 -0
@@ -262,6 +262,19 @@ static inline void native_load_tls(struc (info)->seg_not_present == 1 && \ (info)->useable == 0) +/* Lots of programs expect an all-zero user_desc to mean "no segment at all". */ +static inline bool LDT_zero (const struct user_desc *info) +{ +return (info->base_addr ==0 && + info->limit ==0 && + info->contents ==0 && + info->read_exec_only ==0 && + info->seg_32bit ==0 && + info->limit_in_pages ==0 && + info->seg_not_present ==0 && + info->useable ==0 ); +} +static inline void clear_LDT (void ) {set_ldt (NULL ,0 );
arch/x86/kernel/tls.c +23 -2
@@ -29,7 +29,28 @@ static int get_free_idx(void)static bool tls_desc_okay (const struct user_desc *info) { -if (LDT_empty (info)) +/* +* For historical reasons (i.e. no one ever documented how any +* of the segmentation APIs work), user programs can and do +* assume that a struct user_desc that's all zeros except for +* entry_number means "no segment at all". This never actually +* worked. In fact, up to Linux 3.19, a struct user_desc like +* this would create a 16-bit read-write segment with base and +* limit both equal to zero. +* +* That was close enough to "no segment at all" until we +* hardened this function to disallow 16-bit TLS segments. Fix +* it up by interpreting these zeroed segments the way that they +* were almost certainly intended to be interpreted. +* +* The correct way to ask for "no segment at all" is to specify +* a user_desc that satisfies LDT_empty. To keep everything +* working, we accept both. +* +* Note that there's a similar kludge in modify_ldt -- look at +* the distinction between modes 1 and 0x11. +*/ +if (LDT_empty (info) ||LDT_zero (info))return true;/*
@@ -71,7 +92,7 @@ static void set_tls_desc(struct task_str cpu =get_cpu ();while (n-- >0 ) { -if (LDT_empty (info)) +if (LDT_empty (info) ||LDT_zero (info)) desc->a = desc->b =0 ;else fill_ldt (desc, info);
Greg Kroah-Hartman
maintainerPATCH 29/77 x86/apic: Re-enable PCI_MSI support for non-SMP X86_32
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bryan O'Donoghue <[email protected]>
commit 38a1dfda8e77d7ba74c94d06d8bc41ba98a4bc8c upstream.
Commit 0dbc6078c06bc0 ('x86, build, pci: Fix PCI_MSI build on !SMP') introduced the dependency that X86_UP_APIC is only available when PCI_MSI is false. This effectively prevents PCI_MSI support on 32bit UP systems because it disables both APIC and IO-APIC. But APIC support is architecturally required for PCI_MSI.
The intention of the patch was to enforce APIC support when PCI_MSI is enabled, but failed to do so.
Remove the !PCI_MSI dependency from X86_UP_APIC and enforce X86_UP_APIC when PCI_MSI support is enabled on 32bit UP systems.
[ tglx: Massaged changelog ]
Fixes 0dbc6078c06bc0 'x86, build, pci: Fix PCI_MSI build on !SMP'
--- arch/x86/Kconfig | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
arch/x86/Kconfig +5 -1
@@ -854,7 +854,7 @@ source "kernel/Kconfig.preempt" config X86_UP_APIC bool "Local APIC support on uniprocessors" - depends on X86_32 && !SMP && !X86_32_NON_STANDARD && !PCI_MSI + depends on X86_32 && !SMP && !X86_32_NON_STANDARD ---help--- A local APIC (Advanced Programmable Interrupt Controller) is an integrated interrupt controller in the CPU. If you have a single-CPU
@@ -865,6 +865,10 @@ config X86_UP_APIC performance counters), and the NMI watchdog which detects hard lockups. +config X86_UP_APIC_MSI + def_bool y + select X86_UP_APIC if X86_32 && !SMP && !X86_32_NON_STANDARD && PCI_MSI + config X86_UP_IOAPIC bool "IO-APIC support on uniprocessors" depends on X86_UP_APIC
Greg Kroah-Hartman
maintainerPATCH 30/77 x86/asm/traps: Disable tracing and kprobes in fixup_bad_iret and sync_regs
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Lutomirski <[email protected]>
commit 7ddc6a2199f1da405a2fb68c40db8899b1a8cd87 upstream.
These functions can be executed on the int3 stack, so kprobes are dangerous. Tracing is probably a bad idea, too.
[bwh: Backported to 3.10:
- Use __kprobes instead of NOKPROBE_SYMBOL()
- Adjust context]
--- arch/x86/kernel/traps.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/kernel/traps.c +2 -2
@@ -365,7 +365,7 @@ exit:* for scheduling or signal handling. The actual stack switch is done in * entry.S */ -asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) +asmlinkage notrace __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) {struct pt_regs *regs = eregs;/* Did already sync */
@@ -390,7 +390,7 @@ struct bad_iret_stack {struct pt_regs regs; }; -asmlinkage __visible +asmlinkage __visible notrace __kprobesstruct bad_iret_stack *fixup_bad_iret (struct bad_iret_stack *s) {/*
Greg Kroah-Hartman
maintainerPATCH 31/77 sata_dwc_460ex: fix resource leak on error path
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
commit 4aaa71873ddb9faf4b0c4826579e2f6d18ff9ab4 upstream.
DMA mapped IO should be unmapped on the error path in probe() and unconditionally on remove().
--- drivers/ata/sata_dwc_460ex.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-)
drivers/ata/sata_dwc_460ex.c +12 -14
@@ -799,7 +799,7 @@ static int dma_dwc_init(struct sata_dwc_if (err) {dev_err (host_pvt.dwc_dev,"%s: dma_request_interrupts returns" " %d\n" , __func__, err); - goto error_out; +return err; }/* Enabe DMA */
@@ -810,11 +810,6 @@ static int dma_dwc_init(struct sata_dwc_ sata_dma_regs);return 0 ; - -error_out: -dma_dwc_exit (hsdev); - -return err; }static int sata_dwc_scr_read (struct ata_link *link,unsigned int scr,u32 *val)
@@ -1664,7 +1659,7 @@ static int sata_dwc_probe(struct platforchar *ver = (char *)&versionr;u8 *base =NULL ;int err =0 ; -int irq, rc; +int irq;struct ata_host *host;struct ata_port_info pi = sata_dwc_port_info[0 ];const struct ata_port_info *ppi[] = { &pi,NULL };
@@ -1727,7 +1722,7 @@ static int sata_dwc_probe(struct platforif (irq ==NO_IRQ ) {dev_err (&ofdev->dev,"no SATA DMA irq\n" ); err = -ENODEV ; - goto error_out; + goto error_iomap; }/* Get physical SATA DMA register base address */
@@ -1736,14 +1731,16 @@ static int sata_dwc_probe(struct platfordev_err (&ofdev->dev,"ioremap failed for AHBDMA register" " address\n" ); err = -ENODEV ; - goto error_out; + goto error_iomap; }/* Save dev for later use in dev_xxx() routines */ host_pvt.dwc_dev = &ofdev->dev;/* Initialize AHB DMAC */ -dma_dwc_init (hsdev, irq); + err =dma_dwc_init (hsdev, irq); +if (err) + goto error_dma_iomap;/* Enable SATA Interrupts */ sata_dwc_enable_interrupts (hsdev);
@@ -1761,9 +1758,8 @@ static int sata_dwc_probe(struct platfor* device discovery process, invoking our port_start() handler & * error_handler() to execute a dummy Softreset EH session */ - rc =ata_host_activate (host, irq, sata_dwc_isr,0 , &sata_dwc_sht); - -if (rc !=0 ) + err =ata_host_activate (host, irq, sata_dwc_isr,0 , &sata_dwc_sht); +if (err)dev_err (&ofdev->dev,"failed to activate host" );dev_set_drvdata (&ofdev->dev, host);
@@ -1772,7 +1768,8 @@ static int sata_dwc_probe(struct platfor error_out:/* Free SATA DMA resources */ dma_dwc_exit (hsdev); - +error_dma_iomap: +iounmap ((void __iomem *)host_pvt.sata_dma_regs); error_iomap:iounmap (base); error_kmalloc:
@@ -1793,6 +1790,7 @@ static int sata_dwc_remove(struct platfo/* Free SATA DMA resources */ dma_dwc_exit (hsdev); +iounmap ((void __iomem *)host_pvt.sata_dma_regs);iounmap (hsdev->reg_base);kfree (hsdev);kfree (host);
Greg Kroah-Hartman
maintainerPATCH 32/77 KEYS: close race between key lookup and freeing
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sasha Levin <[email protected]>
commit a3a8784454692dd72e5d5d34dcdab17b4420e74c upstream.
When a key is being garbage collected, it's key->user would get put before the ->destroy() callback is called, where the key is removed from it's respective tracking structures.
This leaves a key hanging in a semi-invalid state which leaves a window open for a different task to try an access key->user. An example is find_keyring_by_name() which would dereference key->user for a key that is in the process of being garbage collected (where key->user was freed but ->destroy() wasn't called yet - so it's still present in the linked list).
This would cause either a panic, or corrupt memory.
Fixes CVE-2014-9529.
--- security/keys/gc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
security/keys/gc.c +2 -2
@@ -157,12 +157,12 @@ static noinline void key_gc_unused_keys(if (test_bit (KEY_FLAG_INSTANTIATED , &key->flags))atomic_dec (&key->user->nikeys); -key_user_put (key->user); -/* now throw away the key memory */ if (key->type->destroy) key->type->destroy (key); +key_user_put (key->user); +kfree (key->description);#ifdef KEY_DEBUGGING
Greg Kroah-Hartman
maintainerPATCH 33/77 netfilter: nfnetlink: validate nfnetlink header from batch
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pablo Neira Ayuso <[email protected]>
commit 9ea2aa8b7dba9e99544c4187cc298face254569f upstream.
Make sure there is enough room for the nfnetlink header in the netlink messages that are part of the batch. There is a similar check in netlink_rcv_skb().
--- net/netfilter/nfnetlink.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/netfilter/nfnetlink.c +2 -1
@@ -265,7 +265,8 @@ replay: nlh =nlmsg_hdr (skb); err =0 ; -if (nlh->nlmsg_len <NLMSG_HDRLEN ) { +if (nlmsg_len (nlh) <sizeof (struct nfgenmsg ) || + skb->len < nlh->nlmsg_len) { err = -EINVAL ; goto ack; }
Greg Kroah-Hartman
maintainerPATCH 34/77 ipvs: uninitialized data with IP_VS_IPV6
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
commit 3b05ac3824ed9648c0d9c02d51d9b54e4e7e874f upstream.
The app_tcp_pkt_out() function expects "*diff" to be set and ends up using uninitialized data if CONFIG_IP_VS_IPV6 is turned on.
The same issue is there in app_tcp_pkt_in(). Thanks to Julian Anastasov for noticing that.
--- net/netfilter/ipvs/ip_vs_ftp.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
net/netfilter/ipvs/ip_vs_ftp.c +5 -5
@@ -183,6 +183,8 @@ static int ip_vs_ftp_out(struct ip_vs_apstruct nf_conn *ct;struct net *net; + *diff =0 ; +#ifdef CONFIG_IP_VS_IPV6 /* This application helper doesn't work with IPv6 yet, * so turn this into a no-op for IPv6 packets
@@ -191,8 +193,6 @@ static int ip_vs_ftp_out(struct ip_vs_apreturn 1 ;#endif - *diff =0 ; -/* Only useful for established sessions */ if (cp->state !=IP_VS_TCP_S_ESTABLISHED )return 1 ;
@@ -321,6 +321,9 @@ static int ip_vs_ftp_in(struct ip_vs_appstruct ip_vs_conn *n_cp;struct net *net; +/* no diff required for incoming packets */ + *diff =0 ; +#ifdef CONFIG_IP_VS_IPV6 /* This application helper doesn't work with IPv6 yet, * so turn this into a no-op for IPv6 packets
@@ -329,9 +332,6 @@ static int ip_vs_ftp_in(struct ip_vs_appreturn 1 ;#endif -/* no diff required for incoming packets */ - *diff =0 ; -/* Only useful for established sessions */ if (cp->state !=IP_VS_TCP_S_ESTABLISHED )return 1 ;
Greg Kroah-Hartman
maintainerPATCH 35/77 Revert "swiotlb-xen: pass dev_addr to swiotlb_tbl_unmap_single"
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Vrabel <[email protected]>
commit dbdd74763f1faf799fbb9ed30423182e92919378 upstream.
This reverts commit 2c3fc8d26dd09b9d7069687eead849ee81c78e46.
This commit broke on x86 PV because entries in the generic SWIOTLB are indexed using (pseudo-)physical address not DMA address and these are not the same in a x86 PV guest.
--- drivers/xen/swiotlb-xen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/xen/swiotlb-xen.c +1 -1
@@ -449,7 +449,7 @@ static void xen_unmap_single(struct devi/* NOTE: We use dev_addr here, not paddr! */ if (is_xen_swiotlb_buffer (dev_addr)) { -swiotlb_tbl_unmap_single (hwdev, dev_addr, size, dir); +swiotlb_tbl_unmap_single (hwdev, paddr, size, dir);return ; }
Greg Kroah-Hartman
maintainerPATCH 36/77 drbd: merge_bvec_fn: properly remap bvm->bi_bdev
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lars Ellenberg <[email protected]>
commit 3b9d35d744bb5139f9fed57f38c019bb8c7d351c upstream.
This was not noticed for many years. Affects operation if md raid is used a backing device for DRBD.
--- drivers/block/drbd/drbd_req.c | 1 + 1 file changed, 1 insertion(+)
drivers/block/drbd/drbd_req.c +1 -0
@@ -1310,6 +1310,7 @@ int drbd_merge_bvec(struct request_queuestruct request_queue *const b = mdev->ldev->backing_bdev->bd_disk->queue;if (b->merge_bvec_fn) { + bvm->bi_bdev = mdev->ldev->backing_bdev; backing_limit = b->merge_bvec_fn (b, bvm, bvec); limit =min (limit, backing_limit); }
Greg Kroah-Hartman
maintainerPATCH 37/77 crypto: prefix module autoloading with "crypto-"
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kees Cook <[email protected]>
commit 5d26a105b5a73e5635eae0629b42fa0a90e07b7b upstream.
This prefixes all crypto module loading with "crypto-" so we never run the risk of exposing module auto-loading to userspace via a crypto API, as demonstrated by Mathias Krause:
https://lkml.org/lkml/2013/3/4/70
--- arch/arm/crypto/aes_glue.c | 4 ++-- arch/arm/crypto/sha1_glue.c | 2 +- arch/powerpc/crypto/sha1.c | 2 +- arch/s390/crypto/aes_s390.c | 2 +- arch/s390/crypto/des_s390.c | 4 ++-- arch/s390/crypto/ghash_s390.c | 2 +- arch/s390/crypto/sha1_s390.c | 2 +- arch/s390/crypto/sha256_s390.c | 4 ++-- arch/s390/crypto/sha512_s390.c | 4 ++-- arch/sparc/crypto/aes_glue.c | 2 +- arch/sparc/crypto/camellia_glue.c | 2 +- arch/sparc/crypto/crc32c_glue.c | 2 +- arch/sparc/crypto/des_glue.c | 2 +- arch/sparc/crypto/md5_glue.c | 2 +- arch/sparc/crypto/sha1_glue.c | 2 +- arch/sparc/crypto/sha256_glue.c | 4 ++-- arch/sparc/crypto/sha512_glue.c | 4 ++-- arch/x86/crypto/aes_glue.c | 4 ++-- arch/x86/crypto/aesni-intel_glue.c | 2 +- arch/x86/crypto/blowfish_glue.c | 4 ++-- arch/x86/crypto/camellia_aesni_avx2_glue.c | 4 ++-- arch/x86/crypto/camellia_aesni_avx_glue.c | 4 ++-- arch/x86/crypto/camellia_glue.c | 4 ++-- arch/x86/crypto/cast5_avx_glue.c | 2 +- arch/x86/crypto/cast6_avx_glue.c | 2 +- arch/x86/crypto/crc32-pclmul_glue.c | 4 ++-- arch/x86/crypto/crc32c-intel_glue.c | 4 ++-- arch/x86/crypto/crct10dif-pclmul_glue.c | 4 ++-- arch/x86/crypto/ghash-clmulni-intel_glue.c | 2 +- arch/x86/crypto/salsa20_glue.c | 4 ++-- arch/x86/crypto/serpent_avx2_glue.c | 4 ++-- arch/x86/crypto/serpent_avx_glue.c | 2 +- arch/x86/crypto/serpent_sse2_glue.c | 2 +- arch/x86/crypto/sha1_ssse3_glue.c | 2 +- arch/x86/crypto/sha256_ssse3_glue.c | 4 ++-- arch/x86/crypto/sha512_ssse3_glue.c | 4 ++-- arch/x86/crypto/twofish_avx_glue.c | 2 +- arch/x86/crypto/twofish_glue.c | 4 ++-- arch/x86/crypto/twofish_glue_3way.c | 4 ++-- crypto/842.c | 1 + crypto/aes_generic.c | 2 +- crypto/ansi_cprng.c | 2 +- crypto/anubis.c | 1 + crypto/api.c | 4 ++-- crypto/arc4.c | 1 + crypto/blowfish_generic.c | 2 +- crypto/camellia_generic.c | 2 +- crypto/cast5_generic.c | 2 +- crypto/cast6_generic.c | 2 +- crypto/ccm.c | 4 ++-- crypto/crc32.c | 1 + crypto/crct10dif_generic.c | 2 +- crypto/crypto_null.c | 6 +++--- crypto/ctr.c | 2 +- crypto/deflate.c | 2 +- crypto/des_generic.c | 4 ++-- crypto/fcrypt.c | 1 + crypto/gcm.c | 6 +++--- crypto/ghash-generic.c | 2 +- crypto/khazad.c | 1 + crypto/krng.c | 2 +- crypto/lz4.c | 1 + crypto/lz4hc.c | 1 + crypto/lzo.c | 1 + crypto/md4.c | 2 +- crypto/md5.c | 1 + crypto/michael_mic.c | 1 + crypto/rmd128.c | 1 + crypto/rmd160.c | 1 + crypto/rmd256.c | 1 + crypto/rmd320.c | 1 + crypto/salsa20_generic.c | 2 +- crypto/seed.c | 1 + crypto/serpent_generic.c | 4 ++-- crypto/sha1_generic.c | 2 +- crypto/sha256_generic.c | 4 ++-- crypto/sha512_generic.c | 4 ++-- crypto/tea.c | 4 ++-- crypto/tgr192.c | 4 ++-- crypto/twofish_generic.c | 2 +- crypto/wp512.c | 4 ++-- crypto/zlib.c | 1 + drivers/crypto/padlock-aes.c | 2 +- drivers/crypto/padlock-sha.c | 8 ++++---- drivers/crypto/ux500/cryp/cryp_core.c | 4 ++-- drivers/crypto/ux500/hash/hash_core.c | 8 ++++---- drivers/s390/crypto/ap_bus.c | 3 ++- include/linux/crypto.h | 13 +++++++++++++ 88 files changed, 141 insertions(+), 110 deletions(-)
arch/arm/crypto/aes_glue.c +2 -2
@@ -93,6 +93,6 @@ module_exit(aes_fini);MODULE_DESCRIPTION ("Rijndael (AES) Cipher Algorithm (ASM)" );MODULE_LICENSE ("GPL" ); -MODULE_ALIAS ("aes" ); -MODULE_ALIAS ("aes-asm" ); +MODULE_ALIAS_CRYPTO ("aes" ); +MODULE_ALIAS_CRYPTO ("aes-asm" );MODULE_AUTHOR ("David McCullough <[email protected]>" );
arch/arm/crypto/sha1_glue.c +1 -1
@@ -175,5 +175,5 @@ module_exit(sha1_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("SHA1 Secure Hash Algorithm (ARM)" ); -MODULE_ALIAS ("sha1" ); +MODULE_ALIAS_CRYPTO ("sha1" );MODULE_AUTHOR ("David McCullough <[email protected]>" );
arch/powerpc/crypto/sha1.c +1 -1
@@ -154,4 +154,4 @@ module_exit(sha1_powerpc_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("SHA1 Secure Hash Algorithm" ); -MODULE_ALIAS ("sha1-powerpc" ); +MODULE_ALIAS_CRYPTO ("sha1-powerpc" );
arch/s390/crypto/aes_s390.c +1 -1
@@ -979,7 +979,7 @@ static void __exit aes_s390_fini(void)module_init (aes_s390_init);module_exit (aes_s390_fini); -MODULE_ALIAS ("aes-all" ); +MODULE_ALIAS_CRYPTO ("aes-all" );MODULE_DESCRIPTION ("Rijndael (AES) Cipher Algorithm" );MODULE_LICENSE ("GPL" );
arch/s390/crypto/des_s390.c +2 -2
@@ -619,8 +619,8 @@ static void __exit des_s390_exit(void)module_init (des_s390_init);module_exit (des_s390_exit); -MODULE_ALIAS ("des" ); -MODULE_ALIAS ("des3_ede" ); +MODULE_ALIAS_CRYPTO ("des" ); +MODULE_ALIAS_CRYPTO ("des3_ede" );MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("DES & Triple DES EDE Cipher Algorithms" );
arch/s390/crypto/ghash_s390.c +1 -1
@@ -160,7 +160,7 @@ static void __exit ghash_mod_exit(void)module_init (ghash_mod_init);module_exit (ghash_mod_exit); -MODULE_ALIAS ("ghash" ); +MODULE_ALIAS_CRYPTO ("ghash" );MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("GHASH Message Digest Algorithm, s390 implementation" );
arch/s390/crypto/sha1_s390.c +1 -1
@@ -103,6 +103,6 @@ static void __exit sha1_s390_fini(void)module_init (sha1_s390_init);module_exit (sha1_s390_fini); -MODULE_ALIAS ("sha1" ); +MODULE_ALIAS_CRYPTO ("sha1" );MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("SHA1 Secure Hash Algorithm" );
arch/s390/crypto/sha256_s390.c +2 -2
@@ -143,7 +143,7 @@ static void __exit sha256_s390_fini(voidmodule_init (sha256_s390_init);module_exit (sha256_s390_fini); -MODULE_ALIAS ("sha256" ); -MODULE_ALIAS ("sha224" ); +MODULE_ALIAS_CRYPTO ("sha256" ); +MODULE_ALIAS_CRYPTO ("sha224" );MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("SHA256 and SHA224 Secure Hash Algorithm" );
arch/s390/crypto/sha512_s390.c +2 -2
@@ -86,7 +86,7 @@ static struct shash_alg sha512_alg = { } }; -MODULE_ALIAS ("sha512" ); +MODULE_ALIAS_CRYPTO ("sha512" );static int sha384_init (struct shash_desc *desc) {
@@ -126,7 +126,7 @@ static struct shash_alg sha384_alg = { } }; -MODULE_ALIAS ("sha384" ); +MODULE_ALIAS_CRYPTO ("sha384" );static int __init init (void ) {
arch/sparc/crypto/aes_glue.c +1 -1
@@ -499,6 +499,6 @@ module_exit(aes_sparc64_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("AES Secure Hash Algorithm, sparc64 aes opcode accelerated" ); -MODULE_ALIAS ("aes" ); +MODULE_ALIAS_CRYPTO ("aes" );#include "crop_devid.c"
arch/sparc/crypto/camellia_glue.c +1 -1
@@ -322,6 +322,6 @@ module_exit(camellia_sparc64_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Camellia Cipher Algorithm, sparc64 camellia opcode accelerated" ); -MODULE_ALIAS ("aes" ); +MODULE_ALIAS_CRYPTO ("aes" );#include "crop_devid.c"
arch/sparc/crypto/crc32c_glue.c +1 -1
@@ -176,6 +176,6 @@ module_exit(crc32c_sparc64_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("CRC32c (Castagnoli), sparc64 crc32c opcode accelerated" ); -MODULE_ALIAS ("crc32c" ); +MODULE_ALIAS_CRYPTO ("crc32c" );#include "crop_devid.c"
arch/sparc/crypto/des_glue.c +1 -1
@@ -532,6 +532,6 @@ module_exit(des_sparc64_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("DES & Triple DES EDE Cipher Algorithms, sparc64 des opcode accelerated" ); -MODULE_ALIAS ("des" ); +MODULE_ALIAS_CRYPTO ("des" );#include "crop_devid.c"
arch/sparc/crypto/md5_glue.c +1 -1
@@ -185,6 +185,6 @@ module_exit(md5_sparc64_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("MD5 Secure Hash Algorithm, sparc64 md5 opcode accelerated" ); -MODULE_ALIAS ("md5" ); +MODULE_ALIAS_CRYPTO ("md5" );#include "crop_devid.c"
arch/sparc/crypto/sha1_glue.c +1 -1
@@ -180,6 +180,6 @@ module_exit(sha1_sparc64_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("SHA1 Secure Hash Algorithm, sparc64 sha1 opcode accelerated" ); -MODULE_ALIAS ("sha1" ); +MODULE_ALIAS_CRYPTO ("sha1" );#include "crop_devid.c"
arch/sparc/crypto/sha256_glue.c +2 -2
@@ -237,7 +237,7 @@ module_exit(sha256_sparc64_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("SHA-224 and SHA-256 Secure Hash Algorithm, sparc64 sha256 opcode accelerated" ); -MODULE_ALIAS ("sha224" ); -MODULE_ALIAS ("sha256" ); +MODULE_ALIAS_CRYPTO ("sha224" ); +MODULE_ALIAS_CRYPTO ("sha256" );#include "crop_devid.c"
arch/sparc/crypto/sha512_glue.c +2 -2
@@ -222,7 +222,7 @@ module_exit(sha512_sparc64_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("SHA-384 and SHA-512 Secure Hash Algorithm, sparc64 sha512 opcode accelerated" ); -MODULE_ALIAS ("sha384" ); -MODULE_ALIAS ("sha512" ); +MODULE_ALIAS_CRYPTO ("sha384" ); +MODULE_ALIAS_CRYPTO ("sha512" );#include "crop_devid.c"
arch/x86/crypto/aes_glue.c +2 -2
@@ -66,5 +66,5 @@ module_exit(aes_fini);MODULE_DESCRIPTION ("Rijndael (AES) Cipher Algorithm, asm optimized" );MODULE_LICENSE ("GPL" ); -MODULE_ALIAS ("aes" ); -MODULE_ALIAS ("aes-asm" ); +MODULE_ALIAS_CRYPTO ("aes" ); +MODULE_ALIAS_CRYPTO ("aes-asm" );
arch/x86/crypto/aesni-intel_glue.c +1 -1
@@ -1514,4 +1514,4 @@ module_exit(aesni_exit);MODULE_DESCRIPTION ("Rijndael (AES) Cipher Algorithm, Intel AES-NI instructions optimized" );MODULE_LICENSE ("GPL" ); -MODULE_ALIAS ("aes" ); +MODULE_ALIAS_CRYPTO ("aes" );
arch/x86/crypto/blowfish_glue.c +2 -2
@@ -481,5 +481,5 @@ module_exit(fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Blowfish Cipher Algorithm, asm optimized" ); -MODULE_ALIAS ("blowfish" ); -MODULE_ALIAS ("blowfish-asm" ); +MODULE_ALIAS_CRYPTO ("blowfish" ); +MODULE_ALIAS_CRYPTO ("blowfish-asm" );
arch/x86/crypto/camellia_aesni_avx2_glue.c +2 -2
@@ -582,5 +582,5 @@ module_exit(camellia_aesni_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Camellia Cipher Algorithm, AES-NI/AVX2 optimized" ); -MODULE_ALIAS ("camellia" ); -MODULE_ALIAS ("camellia-asm" ); +MODULE_ALIAS_CRYPTO ("camellia" ); +MODULE_ALIAS_CRYPTO ("camellia-asm" );
arch/x86/crypto/camellia_aesni_avx_glue.c +2 -2
@@ -574,5 +574,5 @@ module_exit(camellia_aesni_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Camellia Cipher Algorithm, AES-NI/AVX optimized" ); -MODULE_ALIAS ("camellia" ); -MODULE_ALIAS ("camellia-asm" ); +MODULE_ALIAS_CRYPTO ("camellia" ); +MODULE_ALIAS_CRYPTO ("camellia-asm" );
arch/x86/crypto/camellia_glue.c +2 -2
@@ -1725,5 +1725,5 @@ module_exit(fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Camellia Cipher Algorithm, asm optimized" ); -MODULE_ALIAS ("camellia" ); -MODULE_ALIAS ("camellia-asm" ); +MODULE_ALIAS_CRYPTO ("camellia" ); +MODULE_ALIAS_CRYPTO ("camellia-asm" );
arch/x86/crypto/cast5_avx_glue.c +1 -1
@@ -494,4 +494,4 @@ module_exit(cast5_exit);MODULE_DESCRIPTION ("Cast5 Cipher Algorithm, AVX optimized" );MODULE_LICENSE ("GPL" ); -MODULE_ALIAS ("cast5" ); +MODULE_ALIAS_CRYPTO ("cast5" );
arch/x86/crypto/cast6_avx_glue.c +1 -1
@@ -611,4 +611,4 @@ module_exit(cast6_exit);MODULE_DESCRIPTION ("Cast6 Cipher Algorithm, AVX optimized" );MODULE_LICENSE ("GPL" ); -MODULE_ALIAS ("cast6" ); +MODULE_ALIAS_CRYPTO ("cast6" );
arch/x86/crypto/crc32-pclmul_glue.c +2 -2
@@ -197,5 +197,5 @@ module_exit(crc32_pclmul_mod_fini);MODULE_AUTHOR ("Alexander Boyko <[email protected]>" );MODULE_LICENSE ("GPL" ); -MODULE_ALIAS ("crc32" ); -MODULE_ALIAS ("crc32-pclmul" ); +MODULE_ALIAS_CRYPTO ("crc32" ); +MODULE_ALIAS_CRYPTO ("crc32-pclmul" );
arch/x86/crypto/crc32c-intel_glue.c +2 -2
@@ -280,5 +280,5 @@ MODULE_AUTHOR("Austin Zhang <austin.zhanMODULE_DESCRIPTION ("CRC32c (Castagnoli) optimization using Intel Hardware." );MODULE_LICENSE ("GPL" ); -MODULE_ALIAS ("crc32c" ); -MODULE_ALIAS ("crc32c-intel" ); +MODULE_ALIAS_CRYPTO ("crc32c" ); +MODULE_ALIAS_CRYPTO ("crc32c-intel" );
arch/x86/crypto/crct10dif-pclmul_glue.c +2 -2
@@ -147,5 +147,5 @@ MODULE_AUTHOR("Tim Chen <tim.c.chen@linuMODULE_DESCRIPTION ("T10 DIF CRC calculation accelerated with PCLMULQDQ." );MODULE_LICENSE ("GPL" ); -MODULE_ALIAS ("crct10dif" ); -MODULE_ALIAS ("crct10dif-pclmul" ); +MODULE_ALIAS_CRYPTO ("crct10dif" ); +MODULE_ALIAS_CRYPTO ("crct10dif-pclmul" );
arch/x86/crypto/ghash-clmulni-intel_glue.c +1 -1
@@ -341,4 +341,4 @@ module_exit(ghash_pclmulqdqni_mod_exit);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("GHASH Message Digest Algorithm, " "acclerated by PCLMULQDQ-NI" ); -MODULE_ALIAS ("ghash" ); +MODULE_ALIAS_CRYPTO ("ghash" );
arch/x86/crypto/salsa20_glue.c +2 -2
@@ -119,5 +119,5 @@ module_exit(fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Salsa20 stream cipher algorithm (optimized assembly version)" ); -MODULE_ALIAS ("salsa20" ); -MODULE_ALIAS ("salsa20-asm" ); +MODULE_ALIAS_CRYPTO ("salsa20" ); +MODULE_ALIAS_CRYPTO ("salsa20-asm" );
arch/x86/crypto/serpent_avx2_glue.c +2 -2
@@ -558,5 +558,5 @@ module_exit(fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Serpent Cipher Algorithm, AVX2 optimized" ); -MODULE_ALIAS ("serpent" ); -MODULE_ALIAS ("serpent-asm" ); +MODULE_ALIAS_CRYPTO ("serpent" ); +MODULE_ALIAS_CRYPTO ("serpent-asm" );
arch/x86/crypto/serpent_avx_glue.c +1 -1
@@ -617,4 +617,4 @@ module_exit(serpent_exit);MODULE_DESCRIPTION ("Serpent Cipher Algorithm, AVX optimized" );MODULE_LICENSE ("GPL" ); -MODULE_ALIAS ("serpent" ); +MODULE_ALIAS_CRYPTO ("serpent" );
arch/x86/crypto/serpent_sse2_glue.c +1 -1
@@ -618,4 +618,4 @@ module_exit(serpent_sse2_exit);MODULE_DESCRIPTION ("Serpent Cipher Algorithm, SSE2 optimized" );MODULE_LICENSE ("GPL" ); -MODULE_ALIAS ("serpent" ); +MODULE_ALIAS_CRYPTO ("serpent" );
arch/x86/crypto/sha1_ssse3_glue.c +1 -1
@@ -237,4 +237,4 @@ module_exit(sha1_ssse3_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("SHA1 Secure Hash Algorithm, Supplemental SSE3 accelerated" ); -MODULE_ALIAS ("sha1" ); +MODULE_ALIAS_CRYPTO ("sha1" );
arch/x86/crypto/sha256_ssse3_glue.c +2 -2
@@ -318,5 +318,5 @@ module_exit(sha256_ssse3_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("SHA256 Secure Hash Algorithm, Supplemental SSE3 accelerated" ); -MODULE_ALIAS ("sha256" ); -MODULE_ALIAS ("sha224" ); +MODULE_ALIAS_CRYPTO ("sha256" ); +MODULE_ALIAS_CRYPTO ("sha224" );
arch/x86/crypto/sha512_ssse3_glue.c +2 -2
@@ -326,5 +326,5 @@ module_exit(sha512_ssse3_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("SHA512 Secure Hash Algorithm, Supplemental SSE3 accelerated" ); -MODULE_ALIAS ("sha512" ); -MODULE_ALIAS ("sha384" ); +MODULE_ALIAS_CRYPTO ("sha512" ); +MODULE_ALIAS_CRYPTO ("sha384" );
arch/x86/crypto/twofish_avx_glue.c +1 -1
@@ -579,4 +579,4 @@ module_exit(twofish_exit);MODULE_DESCRIPTION ("Twofish Cipher Algorithm, AVX optimized" );MODULE_LICENSE ("GPL" ); -MODULE_ALIAS ("twofish" ); +MODULE_ALIAS_CRYPTO ("twofish" );
arch/x86/crypto/twofish_glue.c +2 -2
@@ -96,5 +96,5 @@ module_exit(fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Twofish Cipher Algorithm, asm optimized" ); -MODULE_ALIAS ("twofish" ); -MODULE_ALIAS ("twofish-asm" ); +MODULE_ALIAS_CRYPTO ("twofish" ); +MODULE_ALIAS_CRYPTO ("twofish-asm" );
arch/x86/crypto/twofish_glue_3way.c +2 -2
@@ -495,5 +495,5 @@ module_exit(fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Twofish Cipher Algorithm, 3-way parallel asm optimized" ); -MODULE_ALIAS ("twofish" ); -MODULE_ALIAS ("twofish-asm" ); +MODULE_ALIAS_CRYPTO ("twofish" ); +MODULE_ALIAS_CRYPTO ("twofish-asm" );
crypto/842.c +1 -0
@@ -180,3 +180,4 @@ module_exit(nx842_mod_exit);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("842 Compression Algorithm" ); +MODULE_ALIAS_CRYPTO ("842" );
crypto/aes_generic.c +1 -1
@@ -1474,4 +1474,4 @@ module_exit(aes_fini);MODULE_DESCRIPTION ("Rijndael (AES) Cipher Algorithm" );MODULE_LICENSE ("Dual BSD/GPL" ); -MODULE_ALIAS ("aes" ); +MODULE_ALIAS_CRYPTO ("aes" );
crypto/ansi_cprng.c +1 -1
@@ -476,4 +476,4 @@ module_param(dbg, int, 0);MODULE_PARM_DESC (dbg,"Boolean to enable debugging (0/1 == off/on)" );module_init (prng_mod_init);module_exit (prng_mod_fini); -MODULE_ALIAS ("stdrng" ); +MODULE_ALIAS_CRYPTO ("stdrng" );
crypto/anubis.c +1 -0
@@ -704,3 +704,4 @@ module_exit(anubis_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Anubis Cryptographic Algorithm" ); +MODULE_ALIAS_CRYPTO ("anubis" );
crypto/api.c +2 -2
@@ -216,11 +216,11 @@ struct crypto_alg *crypto_larval_lookup( alg =crypto_alg_lookup (name, type, mask);if (!alg) { -request_module ("%s" , name); +request_module ("crypto-%s" , name);if (!((type ^CRYPTO_ALG_NEED_FALLBACK ) & mask &CRYPTO_ALG_NEED_FALLBACK )) -request_module ("%s-all" , name); +request_module ("crypto-%s-all" , name); alg =crypto_alg_lookup (name, type, mask); }
crypto/arc4.c +1 -0
@@ -166,3 +166,4 @@ module_exit(arc4_exit);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("ARC4 Cipher Algorithm" );MODULE_AUTHOR ("Jon Oberheide <[email protected]>" ); +MODULE_ALIAS_CRYPTO ("arc4" );
crypto/blowfish_generic.c +1 -1
@@ -138,4 +138,4 @@ module_exit(blowfish_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Blowfish Cipher Algorithm" ); -MODULE_ALIAS ("blowfish" ); +MODULE_ALIAS_CRYPTO ("blowfish" );
crypto/camellia_generic.c +1 -1
@@ -1098,4 +1098,4 @@ module_exit(camellia_fini);MODULE_DESCRIPTION ("Camellia Cipher Algorithm" );MODULE_LICENSE ("GPL" ); -MODULE_ALIAS ("camellia" ); +MODULE_ALIAS_CRYPTO ("camellia" );
crypto/cast5_generic.c +1 -1
@@ -549,4 +549,4 @@ module_exit(cast5_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Cast5 Cipher Algorithm" ); -MODULE_ALIAS ("cast5" ); +MODULE_ALIAS_CRYPTO ("cast5" );
crypto/cast6_generic.c +1 -1
@@ -291,4 +291,4 @@ module_exit(cast6_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Cast6 Cipher Algorithm" ); -MODULE_ALIAS ("cast6" ); +MODULE_ALIAS_CRYPTO ("cast6" );
crypto/ccm.c +2 -2
@@ -879,5 +879,5 @@ module_exit(crypto_ccm_module_exit);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Counter with CBC MAC" ); -MODULE_ALIAS ("ccm_base" ); -MODULE_ALIAS ("rfc4309" ); +MODULE_ALIAS_CRYPTO ("ccm_base" ); +MODULE_ALIAS_CRYPTO ("rfc4309" );
crypto/crc32.c +1 -0
@@ -156,3 +156,4 @@ module_exit(crc32_mod_fini);MODULE_AUTHOR ("Alexander Boyko <[email protected]>" );MODULE_DESCRIPTION ("CRC32 calculations wrapper for lib/crc32" );MODULE_LICENSE ("GPL" ); +MODULE_ALIAS_CRYPTO ("crc32" );
crypto/crct10dif_generic.c +1 -1
@@ -124,4 +124,4 @@ module_exit(crct10dif_mod_fini);MODULE_AUTHOR ("Tim Chen <[email protected]>" );MODULE_DESCRIPTION ("T10 DIF CRC calculation." );MODULE_LICENSE ("GPL" ); -MODULE_ALIAS ("crct10dif" ); +MODULE_ALIAS_CRYPTO ("crct10dif" );
crypto/crypto_null.c +3 -3
@@ -149,9 +149,9 @@ static struct crypto_alg null_algs[3] = .coa_decompress = null_compress } } } }; -MODULE_ALIAS ("compress_null" ); -MODULE_ALIAS ("digest_null" ); -MODULE_ALIAS ("cipher_null" ); +MODULE_ALIAS_CRYPTO ("compress_null" ); +MODULE_ALIAS_CRYPTO ("digest_null" ); +MODULE_ALIAS_CRYPTO ("cipher_null" );static int __init crypto_null_mod_init (void ) {
crypto/ctr.c +1 -1
@@ -466,4 +466,4 @@ module_exit(crypto_ctr_module_exit);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("CTR Counter block mode" ); -MODULE_ALIAS ("rfc3686" ); +MODULE_ALIAS_CRYPTO ("rfc3686" );
crypto/deflate.c +1 -1
@@ -222,4 +222,4 @@ module_exit(deflate_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Deflate Compression Algorithm for IPCOMP" );MODULE_AUTHOR ("James Morris <[email protected]>" ); - +MODULE_ALIAS_CRYPTO ("deflate" );
crypto/des_generic.c +2 -2
@@ -971,7 +971,7 @@ static struct crypto_alg des_algs[2] = { .cia_decrypt = des3_ede_decrypt } } } }; -MODULE_ALIAS ("des3_ede" ); +MODULE_ALIAS_CRYPTO ("des3_ede" );static int __init des_generic_mod_init (void ) {
@@ -989,4 +989,4 @@ module_exit(des_generic_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("DES & Triple DES EDE Cipher Algorithms" );MODULE_AUTHOR ("Dag Arne Osvik <[email protected]>" ); -MODULE_ALIAS ("des" ); +MODULE_ALIAS_CRYPTO ("des" );
crypto/fcrypt.c +1 -0
@@ -420,3 +420,4 @@ module_exit(fcrypt_mod_fini);MODULE_LICENSE ("Dual BSD/GPL" );MODULE_DESCRIPTION ("FCrypt Cipher Algorithm" );MODULE_AUTHOR ("David Howells <[email protected]>" ); +MODULE_ALIAS_CRYPTO ("fcrypt" );
crypto/gcm.c +3 -3
@@ -1441,6 +1441,6 @@ module_exit(crypto_gcm_module_exit);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Galois/Counter Mode" );MODULE_AUTHOR ("Mikko Herranen <[email protected]>" ); -MODULE_ALIAS ("gcm_base" ); -MODULE_ALIAS ("rfc4106" ); -MODULE_ALIAS ("rfc4543" ); +MODULE_ALIAS_CRYPTO ("gcm_base" ); +MODULE_ALIAS_CRYPTO ("rfc4106" ); +MODULE_ALIAS_CRYPTO ("rfc4543" );
crypto/ghash-generic.c +1 -1
@@ -172,4 +172,4 @@ module_exit(ghash_mod_exit);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("GHASH Message Digest Algorithm" ); -MODULE_ALIAS ("ghash" ); +MODULE_ALIAS_CRYPTO ("ghash" );
crypto/khazad.c +1 -0
@@ -880,3 +880,4 @@ module_exit(khazad_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Khazad Cryptographic Algorithm" ); +MODULE_ALIAS_CRYPTO ("khazad" );
crypto/krng.c +1 -1
@@ -62,4 +62,4 @@ module_exit(krng_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Kernel Random Number Generator" ); -MODULE_ALIAS ("stdrng" ); +MODULE_ALIAS_CRYPTO ("stdrng" );
crypto/lz4.c +1 -0
@@ -104,3 +104,4 @@ module_exit(lz4_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("LZ4 Compression Algorithm" ); +MODULE_ALIAS_CRYPTO ("lz4" );
crypto/lz4hc.c +1 -0
@@ -104,3 +104,4 @@ module_exit(lz4hc_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("LZ4HC Compression Algorithm" ); +MODULE_ALIAS_CRYPTO ("lz4hc" );
crypto/lzo.c +1 -0
@@ -103,3 +103,4 @@ module_exit(lzo_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("LZO Compression Algorithm" ); +MODULE_ALIAS_CRYPTO ("lzo" );
crypto/md4.c +1 -1
@@ -255,4 +255,4 @@ module_exit(md4_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("MD4 Message Digest Algorithm" ); - +MODULE_ALIAS_CRYPTO ("md4" );
crypto/md5.c +1 -0
@@ -168,3 +168,4 @@ module_exit(md5_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("MD5 Message Digest Algorithm" ); +MODULE_ALIAS_CRYPTO ("md5" );
crypto/michael_mic.c +1 -0
@@ -184,3 +184,4 @@ module_exit(michael_mic_exit);MODULE_LICENSE ("GPL v2" );MODULE_DESCRIPTION ("Michael MIC" );MODULE_AUTHOR ("Jouni Malinen <[email protected]>" ); +MODULE_ALIAS_CRYPTO ("michael_mic" );
crypto/rmd128.c +1 -0
@@ -327,3 +327,4 @@ module_exit(rmd128_mod_fini);MODULE_LICENSE ("GPL" );MODULE_AUTHOR ("Adrian-Ken Rueegsegger <[email protected]>" );MODULE_DESCRIPTION ("RIPEMD-128 Message Digest" ); +MODULE_ALIAS_CRYPTO ("rmd128" );
crypto/rmd160.c +1 -0
@@ -371,3 +371,4 @@ module_exit(rmd160_mod_fini);MODULE_LICENSE ("GPL" );MODULE_AUTHOR ("Adrian-Ken Rueegsegger <[email protected]>" );MODULE_DESCRIPTION ("RIPEMD-160 Message Digest" ); +MODULE_ALIAS_CRYPTO ("rmd160" );
crypto/rmd256.c +1 -0
@@ -346,3 +346,4 @@ module_exit(rmd256_mod_fini);MODULE_LICENSE ("GPL" );MODULE_AUTHOR ("Adrian-Ken Rueegsegger <[email protected]>" );MODULE_DESCRIPTION ("RIPEMD-256 Message Digest" ); +MODULE_ALIAS_CRYPTO ("rmd256" );
crypto/rmd320.c +1 -0
@@ -395,3 +395,4 @@ module_exit(rmd320_mod_fini);MODULE_LICENSE ("GPL" );MODULE_AUTHOR ("Adrian-Ken Rueegsegger <[email protected]>" );MODULE_DESCRIPTION ("RIPEMD-320 Message Digest" ); +MODULE_ALIAS_CRYPTO ("rmd320" );
crypto/salsa20_generic.c +1 -1
@@ -248,4 +248,4 @@ module_exit(salsa20_generic_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Salsa20 stream cipher algorithm" ); -MODULE_ALIAS ("salsa20" ); +MODULE_ALIAS_CRYPTO ("salsa20" );
crypto/seed.c +1 -0
@@ -476,3 +476,4 @@ module_exit(seed_fini);MODULE_DESCRIPTION ("SEED Cipher Algorithm" );MODULE_LICENSE ("GPL" );MODULE_AUTHOR ("Hye-Shik Chang <[email protected]>, Kim Hyun <[email protected]>" ); +MODULE_ALIAS_CRYPTO ("seed" );
crypto/serpent_generic.c +2 -2
@@ -665,5 +665,5 @@ module_exit(serpent_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Serpent and tnepres (kerneli compatible serpent reversed) Cipher Algorithm" );MODULE_AUTHOR ("Dag Arne Osvik <[email protected]>" ); -MODULE_ALIAS ("tnepres" ); -MODULE_ALIAS ("serpent" ); +MODULE_ALIAS_CRYPTO ("tnepres" ); +MODULE_ALIAS_CRYPTO ("serpent" );
crypto/sha1_generic.c +1 -1
@@ -153,4 +153,4 @@ module_exit(sha1_generic_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("SHA1 Secure Hash Algorithm" ); -MODULE_ALIAS ("sha1" ); +MODULE_ALIAS_CRYPTO ("sha1" );
crypto/sha256_generic.c +2 -2
@@ -384,5 +384,5 @@ module_exit(sha256_generic_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("SHA-224 and SHA-256 Secure Hash Algorithm" ); -MODULE_ALIAS ("sha224" ); -MODULE_ALIAS ("sha256" ); +MODULE_ALIAS_CRYPTO ("sha224" ); +MODULE_ALIAS_CRYPTO ("sha256" );
crypto/sha512_generic.c +2 -2
@@ -287,5 +287,5 @@ module_exit(sha512_generic_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("SHA-512 and SHA-384 Secure Hash Algorithms" ); -MODULE_ALIAS ("sha384" ); -MODULE_ALIAS ("sha512" ); +MODULE_ALIAS_CRYPTO ("sha384" ); +MODULE_ALIAS_CRYPTO ("sha512" );
crypto/tea.c +2 -2
@@ -270,8 +270,8 @@ static void __exit tea_mod_fini(void)crypto_unregister_algs (tea_algs,ARRAY_SIZE (tea_algs)); } -MODULE_ALIAS ("xtea" ); -MODULE_ALIAS ("xeta" ); +MODULE_ALIAS_CRYPTO ("xtea" ); +MODULE_ALIAS_CRYPTO ("xeta" );module_init (tea_mod_init);module_exit (tea_mod_fini);
crypto/tgr192.c +2 -2
@@ -676,8 +676,8 @@ static void __exit tgr192_mod_fini(void)crypto_unregister_shashes (tgr_algs,ARRAY_SIZE (tgr_algs)); } -MODULE_ALIAS ("tgr160" ); -MODULE_ALIAS ("tgr128" ); +MODULE_ALIAS_CRYPTO ("tgr160" ); +MODULE_ALIAS_CRYPTO ("tgr128" );module_init (tgr192_mod_init);module_exit (tgr192_mod_fini);
crypto/twofish_generic.c +1 -1
@@ -211,4 +211,4 @@ module_exit(twofish_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Twofish Cipher Algorithm" ); -MODULE_ALIAS ("twofish" ); +MODULE_ALIAS_CRYPTO ("twofish" );
crypto/wp512.c +2 -2
@@ -1167,8 +1167,8 @@ static void __exit wp512_mod_fini(void)crypto_unregister_shashes (wp_algs,ARRAY_SIZE (wp_algs)); } -MODULE_ALIAS ("wp384" ); -MODULE_ALIAS ("wp256" ); +MODULE_ALIAS_CRYPTO ("wp384" ); +MODULE_ALIAS_CRYPTO ("wp256" );module_init (wp512_mod_init);module_exit (wp512_mod_fini);
crypto/zlib.c +1 -0
@@ -378,3 +378,4 @@ module_exit(zlib_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Zlib Compression Algorithm" );MODULE_AUTHOR ("Sony Corporation" ); +MODULE_ALIAS_CRYPTO ("zlib" );
drivers/crypto/padlock-aes.c +1 -1
@@ -563,4 +563,4 @@ MODULE_DESCRIPTION("VIA PadLock AES algoMODULE_LICENSE ("GPL" );MODULE_AUTHOR ("Michal Ludvig" ); -MODULE_ALIAS ("aes" ); +MODULE_ALIAS_CRYPTO ("aes" );
drivers/crypto/padlock-sha.c +4 -4
@@ -593,7 +593,7 @@ MODULE_DESCRIPTION("VIA PadLock SHA1/SHAMODULE_LICENSE ("GPL" );MODULE_AUTHOR ("Michal Ludvig" ); -MODULE_ALIAS ("sha1-all" ); -MODULE_ALIAS ("sha256-all" ); -MODULE_ALIAS ("sha1-padlock" ); -MODULE_ALIAS ("sha256-padlock" ); +MODULE_ALIAS_CRYPTO ("sha1-all" ); +MODULE_ALIAS_CRYPTO ("sha256-all" ); +MODULE_ALIAS_CRYPTO ("sha1-padlock" ); +MODULE_ALIAS_CRYPTO ("sha256-padlock" );
drivers/crypto/ux500/cryp/cryp_core.c +2 -2
@@ -1810,7 +1810,7 @@ module_exit(ux500_cryp_mod_fini);module_param (cryp_mode, int,0 );MODULE_DESCRIPTION ("Driver for ST-Ericsson UX500 CRYP crypto engine." ); -MODULE_ALIAS ("aes-all" ); -MODULE_ALIAS ("des-all" ); +MODULE_ALIAS_CRYPTO ("aes-all" ); +MODULE_ALIAS_CRYPTO ("des-all" );MODULE_LICENSE ("GPL" );
drivers/crypto/ux500/hash/hash_core.c +4 -4
@@ -1995,7 +1995,7 @@ module_exit(ux500_hash_mod_fini);MODULE_DESCRIPTION ("Driver for ST-Ericsson UX500 HASH engine." );MODULE_LICENSE ("GPL" ); -MODULE_ALIAS ("sha1-all" ); -MODULE_ALIAS ("sha256-all" ); -MODULE_ALIAS ("hmac-sha1-all" ); -MODULE_ALIAS ("hmac-sha256-all" ); +MODULE_ALIAS_CRYPTO ("sha1-all" ); +MODULE_ALIAS_CRYPTO ("sha256-all" ); +MODULE_ALIAS_CRYPTO ("hmac-sha1-all" ); +MODULE_ALIAS_CRYPTO ("hmac-sha256-all" );
drivers/s390/crypto/ap_bus.c +2 -1
@@ -44,6 +44,7 @@#include <linux/hrtimer.h> #include <linux/ktime.h> #include <asm/facility.h> +#include <linux/crypto.h> #include "ap_bus.h"
@@ -71,7 +72,7 @@ MODULE_AUTHOR("IBM Corporation");MODULE_DESCRIPTION ("Adjunct Processor Bus driver, " \"Copyright IBM Corp. 2006, 2012" );MODULE_LICENSE ("GPL" ); -MODULE_ALIAS ("z90crypt" ); +MODULE_ALIAS_CRYPTO ("z90crypt" );/* * Module parameter
include/linux/crypto.h +13 -0
@@ -26,6 +26,19 @@#include <linux/uaccess.h> /* +* Autoloaded crypto modules should only use a prefixed name to avoid allowing +* arbitrary modules to be loaded. Loading from userspace may still need the +* unprefixed names, so retains those aliases as well. +* This uses __MODULE_INFO directly instead of MODULE_ALIAS because pre-4.3 +* gcc (e.g. avr32 toolchain) uses __LINE__ for uniqueness, and this macro +* expands twice on the same line. Instead, use a separate base name for the +* alias. +*/ +#define MODULE_ALIAS_CRYPTO (name) \ + __MODULE_INFO(alias, alias_userspace, name); \ + __MODULE_INFO(alias, alias_crypto, "crypto-" name) + +/* * Algorithm masks and types. */ #define CRYPTO_ALG_TYPE_MASK 0x0000000f
Greg Kroah-Hartman
maintainerPATCH 38/77 crypto: include crypto- module prefix in template
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kees Cook <[email protected]>
commit 4943ba16bbc2db05115707b3ff7b4874e9e3c560 upstream.
This adds the module loading prefix "crypto-" to the template lookup as well.
For example, attempting to load 'vfat(blowfish)' via AF_ALG now correctly includes the "crypto-" prefix at every level, correctly rejecting "vfat":
net-pf-38 algif-hash crypto-vfat(blowfish) crypto-vfat(blowfish)-all crypto-vfat
--- arch/x86/crypto/fpu.c | 3 +++ crypto/algapi.c | 4 ++-- crypto/authenc.c | 1 + crypto/authencesn.c | 1 + crypto/cbc.c | 1 + crypto/ccm.c | 1 + crypto/chainiv.c | 1 + crypto/cmac.c | 1 + crypto/cryptd.c | 1 + crypto/ctr.c | 1 + crypto/cts.c | 1 + crypto/ecb.c | 1 + crypto/eseqiv.c | 1 + crypto/gcm.c | 1 + crypto/hmac.c | 1 + crypto/lrw.c | 1 + crypto/pcbc.c | 1 + crypto/pcrypt.c | 1 + crypto/seqiv.c | 1 + crypto/vmac.c | 1 + crypto/xcbc.c | 1 + crypto/xts.c | 1 + 22 files changed, 25 insertions(+), 2 deletions(-)
arch/x86/crypto/fpu.c +3 -0
@@ -17,6 +17,7 @@#include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> +#include <linux/crypto.h> #include <asm/i387.h> struct crypto_fpu_ctx {
@@ -159,3 +160,5 @@ void __exit crypto_fpu_exit(void) {crypto_unregister_template (&crypto_fpu_tmpl); } + +MODULE_ALIAS_CRYPTO ("fpu" );
crypto/algapi.c +2 -2
@@ -495,8 +495,8 @@ static struct crypto_template *__crypto_struct crypto_template *crypto_lookup_template (const char *name) { -return try_then_request_module (__crypto_lookup_template (name),"%s" , - name); +return try_then_request_module (__crypto_lookup_template (name), +"crypto-%s" , name); }EXPORT_SYMBOL_GPL (crypto_lookup_template);
crypto/authenc.c +1 -0
@@ -721,3 +721,4 @@ module_exit(crypto_authenc_module_exit);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Simple AEAD wrapper for IPsec" ); +MODULE_ALIAS_CRYPTO ("authenc" );
crypto/authencesn.c +1 -0
@@ -814,3 +814,4 @@ module_exit(crypto_authenc_esn_module_exMODULE_LICENSE ("GPL" );MODULE_AUTHOR ("Steffen Klassert <[email protected]>" );MODULE_DESCRIPTION ("AEAD wrapper for IPsec with extended sequence numbers" ); +MODULE_ALIAS_CRYPTO ("authencesn" );
crypto/cbc.c +1 -0
@@ -289,3 +289,4 @@ module_exit(crypto_cbc_module_exit);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("CBC block cipher algorithm" ); +MODULE_ALIAS_CRYPTO ("cbc" );
crypto/ccm.c +1 -0
@@ -881,3 +881,4 @@ MODULE_LICENSE("GPL");MODULE_DESCRIPTION ("Counter with CBC MAC" );MODULE_ALIAS_CRYPTO ("ccm_base" );MODULE_ALIAS_CRYPTO ("rfc4309" ); +MODULE_ALIAS_CRYPTO ("ccm" );
crypto/chainiv.c +1 -0
@@ -359,3 +359,4 @@ module_exit(chainiv_module_exit);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Chain IV Generator" ); +MODULE_ALIAS_CRYPTO ("chainiv" );
crypto/cmac.c +1 -0
@@ -313,3 +313,4 @@ module_exit(crypto_cmac_module_exit);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("CMAC keyed hash algorithm" ); +MODULE_ALIAS_CRYPTO ("cmac" );
crypto/cryptd.c +1 -0
@@ -955,3 +955,4 @@ module_exit(cryptd_exit);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Software async crypto daemon" ); +MODULE_ALIAS_CRYPTO ("cryptd" );
crypto/ctr.c +1 -0
@@ -467,3 +467,4 @@ module_exit(crypto_ctr_module_exit);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("CTR Counter block mode" );MODULE_ALIAS_CRYPTO ("rfc3686" ); +MODULE_ALIAS_CRYPTO ("ctr" );
crypto/cts.c +1 -0
@@ -350,3 +350,4 @@ module_exit(crypto_cts_module_exit);MODULE_LICENSE ("Dual BSD/GPL" );MODULE_DESCRIPTION ("CTS-CBC CipherText Stealing for CBC" ); +MODULE_ALIAS_CRYPTO ("cts" );
crypto/ecb.c +1 -0
@@ -185,3 +185,4 @@ module_exit(crypto_ecb_module_exit);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("ECB block cipher algorithm" ); +MODULE_ALIAS_CRYPTO ("ecb" );
crypto/eseqiv.c +1 -0
@@ -267,3 +267,4 @@ module_exit(eseqiv_module_exit);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Encrypted Sequence Number IV Generator" ); +MODULE_ALIAS_CRYPTO ("eseqiv" );
crypto/gcm.c +1 -0
@@ -1444,3 +1444,4 @@ MODULE_AUTHOR("Mikko Herranen <[email protected]MODULE_ALIAS_CRYPTO ("gcm_base" );MODULE_ALIAS_CRYPTO ("rfc4106" );MODULE_ALIAS_CRYPTO ("rfc4543" ); +MODULE_ALIAS_CRYPTO ("gcm" );
crypto/hmac.c +1 -0
@@ -271,3 +271,4 @@ module_exit(hmac_module_exit);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("HMAC hash algorithm" ); +MODULE_ALIAS_CRYPTO ("hmac" );
crypto/lrw.c +1 -0
@@ -400,3 +400,4 @@ module_exit(crypto_module_exit);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("LRW block cipher mode" ); +MODULE_ALIAS_CRYPTO ("lrw" );
crypto/pcbc.c +1 -0
@@ -295,3 +295,4 @@ module_exit(crypto_pcbc_module_exit);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("PCBC block cipher algorithm" ); +MODULE_ALIAS_CRYPTO ("pcbc" );
crypto/pcrypt.c +1 -0
@@ -565,3 +565,4 @@ module_exit(pcrypt_exit);MODULE_LICENSE ("GPL" );MODULE_AUTHOR ("Steffen Klassert <[email protected]>" );MODULE_DESCRIPTION ("Parallel crypto wrapper" ); +MODULE_ALIAS_CRYPTO ("pcrypt" );
crypto/seqiv.c +1 -0
@@ -362,3 +362,4 @@ module_exit(seqiv_module_exit);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Sequence Number IV Generator" ); +MODULE_ALIAS_CRYPTO ("seqiv" );
crypto/vmac.c +1 -0
@@ -713,3 +713,4 @@ module_exit(vmac_module_exit);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("VMAC hash algorithm" ); +MODULE_ALIAS_CRYPTO ("vmac" );
crypto/xcbc.c +1 -0
@@ -286,3 +286,4 @@ module_exit(crypto_xcbc_module_exit);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("XCBC keyed hash algorithm" ); +MODULE_ALIAS_CRYPTO ("xcbc" );
crypto/xts.c +1 -0
@@ -362,3 +362,4 @@ module_exit(crypto_module_exit);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("XTS block cipher mode" ); +MODULE_ALIAS_CRYPTO ("xts" );
Greg Kroah-Hartman
maintainerPATCH 39/77 crypto: add missing crypto module aliases
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mathias Krause <[email protected]>
commit 3e14dcf7cb80b34a1f38b55bc96f02d23fdaaaaf upstream.
Commit 5d26a105b5a7 ("crypto: prefix module autoloading with "crypto-"") changed the automatic module loading when requesting crypto algorithms to prefix all module requests with "crypto-". This requires all crypto modules to have a crypto specific module alias even if their file name would otherwise match the requested crypto algorithm.
Even though commit 5d26a105b5a7 added those aliases for a vast amount of modules, it was missing a few. Add the required MODULE_ALIAS_CRYPTO annotations to those files to make them get loaded automatically, again. This fixes, e.g., requesting 'ecb(blowfish-generic)', which used to work with kernels v3.18 and below.
Also change MODULE_ALIAS() lines to MODULE_ALIAS_CRYPTO(). The former won't work for crypto modules any more.
--- arch/powerpc/crypto/sha1.c | 1 + crypto/aes_generic.c | 1 + crypto/ansi_cprng.c | 1 + crypto/blowfish_generic.c | 1 + crypto/camellia_generic.c | 1 + crypto/cast5_generic.c | 1 + crypto/cast6_generic.c | 1 + crypto/crct10dif_generic.c | 1 + crypto/des_generic.c | 5 +++-- crypto/ghash-generic.c | 1 + crypto/krng.c | 1 + crypto/salsa20_generic.c | 1 + crypto/serpent_generic.c | 1 + crypto/sha1_generic.c | 1 + crypto/sha256_generic.c | 2 ++ crypto/sha512_generic.c | 2 ++ crypto/tea.c | 1 + crypto/tgr192.c | 1 + crypto/twofish_generic.c | 1 + crypto/wp512.c | 1 + 20 files changed, 24 insertions(+), 2 deletions(-)
arch/powerpc/crypto/sha1.c +1 -0
@@ -154,4 +154,5 @@ module_exit(sha1_powerpc_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("SHA1 Secure Hash Algorithm" ); +MODULE_ALIAS_CRYPTO ("sha1" );MODULE_ALIAS_CRYPTO ("sha1-powerpc" );
crypto/aes_generic.c +1 -0
@@ -1475,3 +1475,4 @@ module_exit(aes_fini);MODULE_DESCRIPTION ("Rijndael (AES) Cipher Algorithm" );MODULE_LICENSE ("Dual BSD/GPL" );MODULE_ALIAS_CRYPTO ("aes" ); +MODULE_ALIAS_CRYPTO ("aes-generic" );
crypto/ansi_cprng.c +1 -0
@@ -477,3 +477,4 @@ MODULE_PARM_DESC(dbg, "Boolean to enablemodule_init (prng_mod_init);module_exit (prng_mod_fini);MODULE_ALIAS_CRYPTO ("stdrng" ); +MODULE_ALIAS_CRYPTO ("ansi_cprng" );
crypto/blowfish_generic.c +1 -0
@@ -139,3 +139,4 @@ module_exit(blowfish_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Blowfish Cipher Algorithm" );MODULE_ALIAS_CRYPTO ("blowfish" ); +MODULE_ALIAS_CRYPTO ("blowfish-generic" );
crypto/camellia_generic.c +1 -0
@@ -1099,3 +1099,4 @@ module_exit(camellia_fini);MODULE_DESCRIPTION ("Camellia Cipher Algorithm" );MODULE_LICENSE ("GPL" );MODULE_ALIAS_CRYPTO ("camellia" ); +MODULE_ALIAS_CRYPTO ("camellia-generic" );
crypto/cast5_generic.c +1 -0
@@ -550,3 +550,4 @@ module_exit(cast5_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Cast5 Cipher Algorithm" );MODULE_ALIAS_CRYPTO ("cast5" ); +MODULE_ALIAS_CRYPTO ("cast5-generic" );
crypto/cast6_generic.c +1 -0
@@ -292,3 +292,4 @@ module_exit(cast6_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Cast6 Cipher Algorithm" );MODULE_ALIAS_CRYPTO ("cast6" ); +MODULE_ALIAS_CRYPTO ("cast6-generic" );
crypto/crct10dif_generic.c +1 -0
@@ -125,3 +125,4 @@ MODULE_AUTHOR("Tim Chen <tim.c.chen@linuMODULE_DESCRIPTION ("T10 DIF CRC calculation." );MODULE_LICENSE ("GPL" );MODULE_ALIAS_CRYPTO ("crct10dif" ); +MODULE_ALIAS_CRYPTO ("crct10dif-generic" );
crypto/des_generic.c +3 -2
@@ -971,8 +971,6 @@ static struct crypto_alg des_algs[2] = { .cia_decrypt = des3_ede_decrypt } } } }; -MODULE_ALIAS_CRYPTO ("des3_ede" ); -static int __init des_generic_mod_init (void ) {return crypto_register_algs (des_algs,ARRAY_SIZE (des_algs));
@@ -990,3 +988,6 @@ MODULE_LICENSE("GPL");MODULE_DESCRIPTION ("DES & Triple DES EDE Cipher Algorithms" );MODULE_AUTHOR ("Dag Arne Osvik <[email protected]>" );MODULE_ALIAS_CRYPTO ("des" ); +MODULE_ALIAS_CRYPTO ("des-generic" ); +MODULE_ALIAS_CRYPTO ("des3_ede" ); +MODULE_ALIAS_CRYPTO ("des3_ede-generic" );
crypto/ghash-generic.c +1 -0
@@ -173,3 +173,4 @@ module_exit(ghash_mod_exit);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("GHASH Message Digest Algorithm" );MODULE_ALIAS_CRYPTO ("ghash" ); +MODULE_ALIAS_CRYPTO ("ghash-generic" );
crypto/krng.c +1 -0
@@ -63,3 +63,4 @@ module_exit(krng_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Kernel Random Number Generator" );MODULE_ALIAS_CRYPTO ("stdrng" ); +MODULE_ALIAS_CRYPTO ("krng" );
crypto/salsa20_generic.c +1 -0
@@ -249,3 +249,4 @@ module_exit(salsa20_generic_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Salsa20 stream cipher algorithm" );MODULE_ALIAS_CRYPTO ("salsa20" ); +MODULE_ALIAS_CRYPTO ("salsa20-generic" );
crypto/serpent_generic.c +1 -0
@@ -667,3 +667,4 @@ MODULE_DESCRIPTION("Serpent and tnepresMODULE_AUTHOR ("Dag Arne Osvik <[email protected]>" );MODULE_ALIAS_CRYPTO ("tnepres" );MODULE_ALIAS_CRYPTO ("serpent" ); +MODULE_ALIAS_CRYPTO ("serpent-generic" );
crypto/sha1_generic.c +1 -0
@@ -154,3 +154,4 @@ MODULE_LICENSE("GPL");MODULE_DESCRIPTION ("SHA1 Secure Hash Algorithm" );MODULE_ALIAS_CRYPTO ("sha1" ); +MODULE_ALIAS_CRYPTO ("sha1-generic" );
crypto/sha256_generic.c +2 -0
@@ -385,4 +385,6 @@ MODULE_LICENSE("GPL");MODULE_DESCRIPTION ("SHA-224 and SHA-256 Secure Hash Algorithm" );MODULE_ALIAS_CRYPTO ("sha224" ); +MODULE_ALIAS_CRYPTO ("sha224-generic" );MODULE_ALIAS_CRYPTO ("sha256" ); +MODULE_ALIAS_CRYPTO ("sha256-generic" );
crypto/sha512_generic.c +2 -0
@@ -288,4 +288,6 @@ MODULE_LICENSE("GPL");MODULE_DESCRIPTION ("SHA-512 and SHA-384 Secure Hash Algorithms" );MODULE_ALIAS_CRYPTO ("sha384" ); +MODULE_ALIAS_CRYPTO ("sha384-generic" );MODULE_ALIAS_CRYPTO ("sha512" ); +MODULE_ALIAS_CRYPTO ("sha512-generic" );
crypto/tea.c +1 -0
@@ -270,6 +270,7 @@ static void __exit tea_mod_fini(void)crypto_unregister_algs (tea_algs,ARRAY_SIZE (tea_algs)); } +MODULE_ALIAS_CRYPTO ("tea" );MODULE_ALIAS_CRYPTO ("xtea" );MODULE_ALIAS_CRYPTO ("xeta" );
crypto/tgr192.c +1 -0
@@ -676,6 +676,7 @@ static void __exit tgr192_mod_fini(void)crypto_unregister_shashes (tgr_algs,ARRAY_SIZE (tgr_algs)); } +MODULE_ALIAS_CRYPTO ("tgr192" );MODULE_ALIAS_CRYPTO ("tgr160" );MODULE_ALIAS_CRYPTO ("tgr128" );
crypto/twofish_generic.c +1 -0
@@ -212,3 +212,4 @@ module_exit(twofish_mod_fini);MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Twofish Cipher Algorithm" );MODULE_ALIAS_CRYPTO ("twofish" ); +MODULE_ALIAS_CRYPTO ("twofish-generic" );
crypto/wp512.c +1 -0
@@ -1167,6 +1167,7 @@ static void __exit wp512_mod_fini(void)crypto_unregister_shashes (wp_algs,ARRAY_SIZE (wp_algs)); } +MODULE_ALIAS_CRYPTO ("wp512" );MODULE_ALIAS_CRYPTO ("wp384" );MODULE_ALIAS_CRYPTO ("wp256" );
Greg Kroah-Hartman
maintainerPATCH 40/77 ARC: Delete stale barrier.h
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vineet Gupta <[email protected]>
commit 64ee9f32c33cbd53545284742e73c17fedf9d429 upstream.
Commit 93ea02bb8435 ("arch: Clean up asm/barrier.h implementations") wired generic barrier.h for ARC, but failed to delete the existing file.
In 3.15, due to rcupdate.h updates, this causes a build breakage on ARC:
CC arch/arc/kernel/asm-offsets.s
In file included from include/linux/sched.h:45:0,
from arch/arc/kernel/asm-offsets.c:9:
include/linux/rculist.h: In function __list_add_rcu:
include/linux/rculist.h:54:2: error: implicit declaration of function smp_store_release [-Werror=implicit-function-declaration]
rcu_assign_pointer(list_next_rcu(prev), new);
^
--- arch/arc/include/asm/barrier.h | 37 ------------------------------------- 1 file changed, 37 deletions(-)
arch/arc/include/asm/barrier.h deleted +0 -37
@@ -1,37 +0,0 @@ -/* -* Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License version 2 as -* published by the Free Software Foundation. -*/ - -#ifndef __ASM_BARRIER_H -#define __ASM_BARRIER_H - -#ifndef __ASSEMBLY__ - -/* TODO-vineetg: Need to see what this does, don't we need sync anywhere */ -#define mb () __asm__ __volatile__ ("" : : : "memory") -#define rmb () mb() -#define wmb () mb() -#define set_mb (var, value) do { var = value; mb(); } while (0) -#define set_wmb (var, value) do { var = value; wmb(); } while (0) -#define read_barrier_depends () mb() - -/* TODO-vineetg verify the correctness of macros here */ -#ifdef CONFIG_SMP -#define smp_mb () mb() -#define smp_rmb () rmb() -#define smp_wmb () wmb() -#else -#define smp_mb () barrier() -#define smp_rmb () barrier() -#define smp_wmb () barrier() -#endif - -#define smp_read_barrier_depends () do { } while (0) - -#endif - -#endif
Greg Kroah-Hartman
maintainerPATCH 41/77 ARC: Fix build breakage for !CONFIG_ARC_DW2_UNWIND
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vineet Gupta <[email protected]>
commit ba25915fb2cd18152cb14b144dbe8bf2f2bd8e45 upstream.
--- arch/arc/kernel/ctx_sw_asm.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arc/kernel/ctx_sw_asm.S +1 -1
@@ -10,9 +10,9 @@ * -This is the more "natural" hand written assembler */ +#include <linux/linkage.h> #include <asm/entry.h> /* For the SAVE_* macros */ #include <asm/asm-offsets.h> -#include <asm/linkage.h> #define KSP_WORD_OFF ((TASK_THREAD + THREAD_KSP) / 4)
Greg Kroah-Hartman
maintainerPATCH 42/77 Input: evdev - fix EVIOCG{type} ioctl
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Torokhov <[email protected]>
commit 7c4f56070fde2367766fa1fb04852599b5e1ad35 upstream.
The 'max' size passed into the function is measured in number of bits (KEY_MAX, LED_MAX, etc) so we need to convert it accordingly before trying to copy the data out, otherwise we will try copying too much and end up with up with a page fault.
--- drivers/input/evdev.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/input/evdev.c +8 -5
@@ -757,20 +757,23 @@ static int evdev_handle_set_keycode_v2(s*/ static int evdev_handle_get_val (struct evdev_client *client,struct input_dev *dev,unsigned int type, -unsigned long *bits,unsigned int max, -unsigned int size,void __user *p,int compat) +unsigned long *bits,unsigned int maxbit, +unsigned int maxlen,void __user *p, +int compat) {int ret;unsigned long *mem; +size_t len; - mem =kmalloc (sizeof (unsigned long ) * max,GFP_KERNEL ); + len =BITS_TO_LONGS (maxbit) *sizeof (unsigned long ); + mem =kmalloc (len,GFP_KERNEL );if (!mem)return -ENOMEM ;spin_lock_irq (&dev->event_lock);spin_lock (&client->buffer_lock); -memcpy (mem, bits,sizeof (unsigned long ) * max); +memcpy (mem, bits, len);spin_unlock (&dev->event_lock);
@@ -778,7 +781,7 @@ static int evdev_handle_get_val(struct espin_unlock_irq (&client->buffer_lock); - ret =bits_to_user (mem, max, size, p, compat); + ret =bits_to_user (mem, maxbit, maxlen, p, compat);if (ret <0 )evdev_queue_syn_dropped (client);
Greg Kroah-Hartman
maintainerPATCH 43/77 tty: Fix pty master poll() after slave closes v2
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Francesco Ruggeri <[email protected]>
commit c4dc304677e8d566572c4738d95c48be150c6606 upstream.
Commit f95499c3030f ("n_tty: Don't wait for buffer work in read() loop") introduces a race window where a pty master can be signalled that the pty slave was closed before all the data that the slave wrote is delivered. Commit f8747d4a466a ("tty: Fix pty master read() after slave closes") fixed the problem in case of n_tty_read, but the problem still exists for n_tty_poll. This can be seen by running 'for ((i=0; i<100;i++));do ./test.py ;done' where test.py is:
import os, select, pty
(pid, pty_fd) = pty.fork()
if pid == 0:
os.write(1, 'This string should be received by parent')
else:
poller = select.epoll()
poller.register( pty_fd, select.EPOLLIN ) ready = poller.poll( 1 * 1000 )
for fd, events in ready:
if not events & select.EPOLLIN:
print 'missed POLLIN event'
else:
print os.read(fd, 100)
poller.close()
The string from the slave is missed several times.
This patch takes the same approach as the fix for read and special cases this condition for poll.
Tested on 3.16.
--- drivers/tty/n_tty.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/tty/n_tty.c +7 -2
@@ -2417,12 +2417,17 @@ static unsigned int n_tty_poll(struct ttpoll_wait (file, &tty->read_wait, wait);poll_wait (file, &tty->write_wait, wait); +if (test_bit (TTY_OTHER_CLOSED , &tty->flags)) + mask |=POLLHUP ;if (input_available_p (tty,1 )) mask |=POLLIN |POLLRDNORM ; +else if (mask &POLLHUP ) { +tty_flush_to_ldisc (tty); +if (input_available_p (tty,1 )) + mask |=POLLIN |POLLRDNORM ; + }if (tty->packet && tty->link->ctrl_status) mask |=POLLPRI |POLLIN |POLLRDNORM ; -if (test_bit (TTY_OTHER_CLOSED , &tty->flags)) - mask |=POLLHUP ;if (tty_hung_up_p (file)) mask |=POLLHUP ;if (!(mask & (POLLHUP |POLLIN |POLLRDNORM ))) {
Greg Kroah-Hartman
maintainerPATCH 44/77 mmc: sdhci: Dont signal the sdio irq if its not setup
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sjoerd Simons <[email protected]>
[Not needed in newer kernels due to refactoring fixing this issue.]
With 3.14.29 (and older kernels) some of my I.mx6 Sabrelite boards were crashing with the following oops:
sdhci: Secure Digital Host Controller Interface driver
sdhci: Copyright(c) Pierre Ossman
sdhci-pltfm: SDHCI platform and OF driver helper
sdhci-esdhc-imx 2198000.usdhc: could not get ultra high speed state, work on normal mode
mmc0: no vqmmc regulator found
mmc0: SDHCI controller on 2198000.usdhc [2198000.usdhc] using ADMA
Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = c0004000 [00000000] *pgd=00000000 Internal error: Oops: 5 [#1] SMP ARM Modules linked in: CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.14.29 #1 task: c08a7120 ti: c089c000 task.ti: c089c000 PC is at wake_up_process+0x8/0x40 LR is at sdhci_irq+0x748/0x9c4
Full boot log can be found at:
http://storage.kernelci.org/stable/v3.14.29/arm-multi_v7_defconfig/lab-collabora/boot-imx6q-sabrelite.html
This happens if the sdhci interrupt status contains SDHCI_INT_CARD_INT, while the sdio irq was never setup. This patch fixes that in a minimal way by checking if the sdio irq was setup.
In more recent kernels this bug went away due to refactoring done by Russel King. So an alternative (potentially better?) fix for this patch is to cherrypick the following patches from a recent kernel:
18258f7239a6 - genirq: Provide synchronize_hardirq() bf3b5ec66bd0 - mmc: sdio_irq: rework sdio irq handling 41005003bcaf - mmc: sdhci: clean up interrupt handling 781e989cf593 - mmc: sdhci: convert to new SDIO IRQ handling
--- drivers/mmc/host/sdhci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mmc/host/sdhci.c +1 -1
@@ -2537,7 +2537,7 @@ out:/* * We have to delay this as it calls back into the driver. */ -if (cardint) +if (cardint && host->mmc->sdio_irqs)mmc_signal_sdio_irq (host->mmc);return result;
Greg Kroah-Hartman
maintainerPATCH 45/77 mm/swap.c: clean up *lru_cache_add* functions
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jianyu Zhan <[email protected]>
commit 2329d3751b082b4fd354f334a88662d72abac52d upstream.
In mm/swap.c, __lru_cache_add() is exported, but actually there are no users outside this file.
This patch unexports __lru_cache_add(), and makes it static. It also exports lru_cache_add_file(), as it is use by cifs and fuse, which can loaded as modules.
--- include/linux/swap.h | 19 ++----------------- mm/swap.c | 31 +++++++++++++++++++++++-------- 2 files changed, 25 insertions(+), 25 deletions(-)
include/linux/swap.h +2 -17
@@ -268,8 +268,9 @@ extern unsigned long nr_free_pagecache_p/* linux/mm/swap.c */ -extern void __lru_cache_add (struct page *);extern void lru_cache_add (struct page *); +extern void lru_cache_add_anon (struct page *page); +extern void lru_cache_add_file (struct page *page);extern void lru_add_page_tail (struct page *page,struct page *page_tail,struct lruvec *lruvec,struct list_head *head);extern void activate_page (struct page *);
@@ -283,22 +284,6 @@ extern void swap_setup(void);extern void add_page_to_unevictable_list (struct page *page); -/** -* lru_cache_add: add a page to the page lists -* @page: the page to add -*/ -static inline void lru_cache_add_anon (struct page *page) -{ -ClearPageActive (page); -__lru_cache_add (page); -} - -static inline void lru_cache_add_file (struct page *page) -{ -ClearPageActive (page); -__lru_cache_add (page); -} -/* linux/mm/vmscan.c */ extern unsigned long try_to_free_pages (struct zonelist *zonelist,int order,gfp_t gfp_mask,nodemask_t *mask);
mm/swap.c +23 -8
@@ -580,13 +580,7 @@ void mark_page_accessed(struct page *pag }EXPORT_SYMBOL (mark_page_accessed); -/* -* Queue the page for addition to the LRU via pagevec. The decision on whether -* to add the page to the [in]active [file|anon] list is deferred until the -* pagevec is drained. This gives a chance for the caller of __lru_cache_add() -* have the page added to the active list using mark_page_accessed(). -*/ -void __lru_cache_add (struct page *page) +static void __lru_cache_add (struct page *page) {struct pagevec *pvec = &get_cpu_var (lru_add_pvec);
@@ -596,11 +590,32 @@ void __lru_cache_add(struct page *page)pagevec_add (pvec, page);put_cpu_var (lru_add_pvec); } -EXPORT_SYMBOL (__lru_cache_add); + +/** +* lru_cache_add: add a page to the page lists +* @page: the page to add +*/ +void lru_cache_add_anon (struct page *page) +{ +ClearPageActive (page); +__lru_cache_add (page); +} + +void lru_cache_add_file (struct page *page) +{ +ClearPageActive (page); +__lru_cache_add (page); +} +EXPORT_SYMBOL (lru_cache_add_file);/** * lru_cache_add - add a page to a page list * @page: the page to be added to the LRU. +* +* Queue the page for addition to the LRU via pagevec. The decision on whether +* to add the page to the [in]active [file|anon] list is deferred until the +* pagevec is drained. This gives a chance for the caller of lru_cache_add() +* have the page added to the active list using mark_page_accessed(). */ void lru_cache_add (struct page *page) {
Greg Kroah-Hartman
maintainerPATCH 46/77 mm: page_alloc: do not update zlc unless the zlc is active
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mel Gorman <[email protected]>
commit 65bb371984d6a2c909244eb749e482bb40b72e36 upstream.
The zlc is used on NUMA machines to quickly skip over zones that are full.
However it is always updated, even for the first zone scanned when the
zlc might not even be active. As it's a write to a bitmap that potentially bounces cache line it's deceptively expensive and most machines will not care. Only update the zlc if it was active.
--- mm/page_alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/page_alloc.c +1 -1
@@ -2059,7 +2059,7 @@ try_this_zone:if (page)break ; this_zone_full: -if (IS_ENABLED (CONFIG_NUMA )) +if (IS_ENABLED (CONFIG_NUMA ) && zlc_active)zlc_mark_zone_full (zonelist, z); }
Greg Kroah-Hartman
maintainerPATCH 47/77 mm: page_alloc: do not treat a zone that cannot be used for dirty pages as "full"
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mel Gorman <[email protected]>
commit 800a1e750c7b04c2aa2459afca77e936e01c0029 upstream.
If a zone cannot be used for a dirty page then it gets marked "full" which is cached in the zlc and later potentially skipped by allocation requests that have nothing to do with dirty zones.
--- mm/page_alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/page_alloc.c +1 -1
@@ -1991,7 +1991,7 @@ zonelist_scan:*/ if ((alloc_flags &ALLOC_WMARK_LOW ) && (gfp_mask & __GFP_WRITE) && !zone_dirty_ok (zone)) - goto this_zone_full; +continue ; mark = zone->watermark[alloc_flags &ALLOC_WMARK_MASK ]; if (!zone_watermark_ok(zone, order, mark,
Greg Kroah-Hartman
maintainerPATCH 48/77 include/linux/jump_label.h: expose the reference count
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mel Gorman <[email protected]>
commit ea5e9539abf1258f23e725cb9cb25aa74efa29eb upstream.
This patch exposes the jump_label reference count in preparation for the next patch. cpusets cares about both the jump_label being enabled and how many users of the cpusets there currently are.
--- include/linux/jump_label.h | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-)
include/linux/jump_label.h +13 -7
@@ -69,6 +69,10 @@ struct static_key {# include <asm/jump_label.h> # define HAVE_JUMP_LABEL +#else +struct static_key { +atomic_t enabled; +};#endif /* CC_HAVE_ASM_GOTO && CONFIG_JUMP_LABEL */ enum jump_label_type {
@@ -79,6 +83,12 @@ enum jump_label_type {struct module ;#include <linux/atomic.h> + +static inline int static_key_count (struct static_key *key) +{ +return atomic_read (&key->enabled); +} +#ifdef HAVE_JUMP_LABEL #define JUMP_LABEL_TYPE_FALSE_BRANCH 0UL
@@ -134,10 +144,6 @@ extern void jump_label_apply_nops(struct#else /* !HAVE_JUMP_LABEL */ -struct static_key { -atomic_t enabled; -}; - static __always_inline void jump_label_init(void) { static_key_initialized = true;
@@ -145,14 +151,14 @@ static __always_inline void jump_label_i static __always_inline bool static_key_false(struct static_key *key) { -if (unlikely (atomic_read (&key->enabled) >0 )) +if (unlikely (static_key_count (key) >0 ))return true;return false; } static __always_inline bool static_key_true(struct static_key *key) { -if (likely (atomic_read (&key->enabled) >0 )) +if (likely (static_key_count (key) >0 ))return true;return false; }
@@ -194,7 +200,7 @@ static inline int jump_label_apply_nops(static inline bool static_key_enabled (struct static_key *key) { -return (atomic_read (&key->enabled) >0 ); +return static_key_count (key) >0 ; }#endif /* _LINUX_JUMP_LABEL_H */
Greg Kroah-Hartman
maintainerPATCH 49/77 mm: page_alloc: use jump labels to avoid checking number_of_cpusets
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mel Gorman <[email protected]>
commit 664eeddeef6539247691197c1ac124d4aa872ab6 upstream.
If cpusets are not in use then we still check a global variable on every page allocation. Use jump labels to avoid the overhead.
--- include/linux/cpuset.h | 29 ++++++++++++++++++++++++++--- kernel/cpuset.c | 14 ++++---------- mm/page_alloc.c | 3 ++- 3 files changed, 32 insertions(+), 14 deletions(-)
include/linux/cpuset.h +26 -3
@@ -12,10 +12,31 @@#include <linux/cpumask.h> #include <linux/nodemask.h> #include <linux/mm.h> +#include <linux/jump_label.h> #ifdef CONFIG_CPUSETS -extern int number_of_cpusets;/* How many cpusets are defined in system? */ +extern struct static_key cpusets_enabled_key; +static inline bool cpusets_enabled (void ) +{ +return static_key_false (&cpusets_enabled_key); +} + +static inline int nr_cpusets (void ) +{ +/* jump label reference count + the top-level cpuset */ +return static_key_count (&cpusets_enabled_key) +1 ; +} + +static inline void cpuset_inc (void ) +{ +static_key_slow_inc (&cpusets_enabled_key); +} + +static inline void cpuset_dec (void ) +{ +static_key_slow_dec (&cpusets_enabled_key); +}extern int cpuset_init (void );extern void cpuset_init_smp (void );
@@ -32,13 +53,13 @@ extern int __cpuset_node_allowed_hardwalstatic inline int cpuset_node_allowed_softwall (int node,gfp_t gfp_mask) { -return number_of_cpusets <=1 || +return nr_cpusets () <=1 ||__cpuset_node_allowed_softwall (node, gfp_mask); }static inline int cpuset_node_allowed_hardwall (int node,gfp_t gfp_mask) { -return number_of_cpusets <=1 || +return nr_cpusets () <=1 ||__cpuset_node_allowed_hardwall (node, gfp_mask); }
@@ -124,6 +145,8 @@ static inline void set_mems_allowed(node#else /* !CONFIG_CPUSETS */ +static inline bool cpusets_enabled (void ) {return false; } +static inline int cpuset_init (void ) {return 0 ; }static inline void cpuset_init_smp (void ) {}
kernel/cpuset.c +4 -10
@@ -61,12 +61,7 @@#include <linux/cgroup.h> #include <linux/wait.h> -/* -* Tracks how many cpusets are currently defined in system. -* When there is only one cpuset (the root cpuset) we can -* short circuit some hooks. -*/ -int number_of_cpusets__read_mostly ; +struct static_key cpusets_enabled_key__read_mostly =STATIC_KEY_INIT_FALSE ;/* See "Frequency meter" comments, below. */
@@ -611,7 +606,7 @@ static int generate_sched_domains(cpumas goto done; } - csa =kmalloc (number_of_cpusets *sizeof (cp),GFP_KERNEL ); + csa =kmalloc (nr_cpusets () *sizeof (cp),GFP_KERNEL );if (!csa) goto done; csn =0 ;
@@ -1961,7 +1956,7 @@ static int cpuset_css_online(struct cgroif (is_spread_slab (parent))set_bit (CS_SPREAD_SLAB , &cs->flags); - number_of_cpusets++; +cpuset_inc ();if (!test_bit (CGRP_CPUSET_CLONE_CHILDREN , &css->cgroup->flags)) goto out_unlock;
@@ -2012,7 +2007,7 @@ static void cpuset_css_offline(struct cgif (is_sched_load_balance (cs))update_flag (CS_SCHED_LOAD_BALANCE , cs,0 ); - number_of_cpusets--; +cpuset_dec ();clear_bit (CS_ONLINE , &cs->flags);mutex_unlock (&cpuset_mutex);
@@ -2067,7 +2062,6 @@ int __init cpuset_init(void)if (!alloc_cpumask_var (&cpus_attach,GFP_KERNEL ))BUG (); - number_of_cpusets =1 ;return 0 ; }
mm/page_alloc.c +2 -1
@@ -1945,7 +1945,8 @@ zonelist_scan:if (IS_ENABLED (CONFIG_NUMA ) && zlc_active && !zlc_zone_worth_trying (zonelist, z, allowednodes))continue ; -if ((alloc_flags &ALLOC_CPUSET ) && +if (cpusets_enabled () && + (alloc_flags &ALLOC_CPUSET ) && !cpuset_zone_allowed_softwall (zone, gfp_mask))continue ;BUILD_BUG_ON (ALLOC_NO_WATERMARKS <NR_WMARK );
Greg Kroah-Hartman
maintainerPATCH 50/77 mm: page_alloc: calculate classzone_idx once from the zonelist ref
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mel Gorman <[email protected]>
commit d8846374a85f4290a473a4e2a64c1ba046c4a0e1 upstream.
There is no need to calculate zone_idx(preferred_zone) multiple times or use the pgdat to figure it out.
--- mm/page_alloc.c | 60 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 25 deletions(-)
mm/page_alloc.c +35 -25
@@ -1922,17 +1922,15 @@ static inline void init_zone_allows_reclstatic struct page *get_page_from_freelist (gfp_t gfp_mask,nodemask_t *nodemask,unsigned int order,struct zonelist *zonelist,int high_zoneidx,int alloc_flags, -struct zone *preferred_zone,int migratetype) +struct zone *preferred_zone,int classzone_idx,int migratetype) {struct zoneref *z;struct page *page =NULL ; -int classzone_idx;struct zone *zone;nodemask_t *allowednodes =NULL ;/* zonelist_cache approximation */ int zlc_active =0 ;/* set if using zonelist_cache */ int did_zlc_setup =0 ;/* just call zlc_setup() one time */ - classzone_idx =zone_idx (preferred_zone); zonelist_scan:/* * Scan zonelist, looking for a zone with enough free.
@@ -2189,7 +2187,7 @@ static inline struct page * __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order, struct zonelist *zonelist, enum zone_type high_zoneidx, nodemask_t *nodemask, struct zone *preferred_zone, - int migratetype) + int classzone_idx, int migratetype) { struct page *page;
@@ -2215,7 +2213,7 @@ __alloc_pages_may_oom(gfp_t gfp_mask, un page =get_page_from_freelist (gfp_mask|__GFP_HARDWALL, nodemask, order, zonelist, high_zoneidx,ALLOC_WMARK_HIGH |ALLOC_CPUSET , - preferred_zone, migratetype); + preferred_zone, classzone_idx, migratetype);if (page) goto out;
@@ -2250,7 +2248,7 @@ static struct page * __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, struct zonelist *zonelist, enum zone_type high_zoneidx, nodemask_t *nodemask, int alloc_flags, struct zone *preferred_zone, - int migratetype, enum migrate_mode mode, + int classzone_idx, int migratetype, enum migrate_mode mode, bool *contended_compaction, bool *deferred_compaction, unsigned long *did_some_progress) {
@@ -2278,7 +2276,7 @@ __alloc_pages_direct_compact(gfp_t gfp_m page =get_page_from_freelist (gfp_mask, nodemask, order, zonelist, high_zoneidx, alloc_flags & ~ALLOC_NO_WATERMARKS , - preferred_zone, migratetype); + preferred_zone, classzone_idx, migratetype);if (page) { preferred_zone->compact_blockskip_flush = false;compaction_defer_reset (preferred_zone, order, true);
@@ -2310,7 +2308,8 @@ static inline struct page * __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, struct zonelist *zonelist, enum zone_type high_zoneidx, nodemask_t *nodemask, int alloc_flags, struct zone *preferred_zone, - int migratetype, enum migrate_mode mode, bool *contended_compaction, + int classzone_idx, int migratetype, + enum migrate_mode mode, bool *contended_compaction, bool *deferred_compaction, unsigned long *did_some_progress) { return NULL;
@@ -2350,7 +2349,7 @@ static inline struct page * __alloc_pages_direct_reclaim(gfp_t gfp_mask, unsigned int order, struct zonelist *zonelist, enum zone_type high_zoneidx, nodemask_t *nodemask, int alloc_flags, struct zone *preferred_zone, - int migratetype, unsigned long *did_some_progress) + int classzone_idx, int migratetype, unsigned long *did_some_progress) { struct page *page = NULL;bool drained = false;
@@ -2368,7 +2367,8 @@ retry: page =get_page_from_freelist (gfp_mask, nodemask, order, zonelist, high_zoneidx, alloc_flags & ~ALLOC_NO_WATERMARKS , - preferred_zone, migratetype); + preferred_zone, classzone_idx, + migratetype);/* * If an allocation failed after direct reclaim, it could be because
@@ -2391,14 +2391,14 @@ static inline struct page * __alloc_pages_high_priority(gfp_t gfp_mask, unsigned int order, struct zonelist *zonelist, enum zone_type high_zoneidx, nodemask_t *nodemask, struct zone *preferred_zone, - int migratetype) + int classzone_idx, int migratetype) { struct page *page; do { page = get_page_from_freelist(gfp_mask, nodemask, order, zonelist, high_zoneidx, ALLOC_NO_WATERMARKS, - preferred_zone, migratetype); + preferred_zone, classzone_idx, migratetype); if (!page && gfp_mask & __GFP_NOFAIL) wait_iff_congested(preferred_zone, BLK_RW_ASYNC, HZ/50);
@@ -2499,7 +2499,7 @@ static inline struct page * __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, struct zonelist *zonelist, enum zone_type high_zoneidx, nodemask_t *nodemask, struct zone *preferred_zone, - int migratetype) + int classzone_idx, int migratetype) { const gfp_t wait = gfp_mask & __GFP_WAIT;struct page *page =NULL ;
@@ -2548,15 +2548,19 @@ restart:* Find the true preferred zone if the allocation is unconstrained by * cpusets. */ -if (!(alloc_flags &ALLOC_CPUSET ) && !nodemask) -first_zones_zonelist (zonelist, high_zoneidx,NULL , - &preferred_zone); +if (!(alloc_flags &ALLOC_CPUSET ) && !nodemask) { +struct zoneref *preferred_zoneref; + preferred_zoneref =first_zones_zonelist (zonelist, high_zoneidx, +NULL , + &preferred_zone); + classzone_idx =zonelist_zone_idx (preferred_zoneref); + } rebalance:/* This is the last chance, in general, before the goto nopage. */ page =get_page_from_freelist (gfp_mask, nodemask, order, zonelist, high_zoneidx, alloc_flags & ~ALLOC_NO_WATERMARKS , - preferred_zone, migratetype); + preferred_zone, classzone_idx, migratetype);if (page) goto got_pg;
@@ -2571,7 +2575,7 @@ rebalance: page =__alloc_pages_high_priority (gfp_mask, order, zonelist, high_zoneidx, nodemask, - preferred_zone, migratetype); + preferred_zone, classzone_idx, migratetype);if (page) { goto got_pg; }
@@ -2602,7 +2606,8 @@ rebalance:*/ page =__alloc_pages_direct_compact (gfp_mask, order, zonelist, high_zoneidx, nodemask, alloc_flags, - preferred_zone, migratetype, + preferred_zone, + classzone_idx, migratetype, migration_mode, &contended_compaction, &deferred_compaction, &did_some_progress);
@@ -2625,7 +2630,8 @@ rebalance: zonelist, high_zoneidx, nodemask, alloc_flags, preferred_zone, - migratetype, &did_some_progress); + classzone_idx, migratetype, + &did_some_progress);if (page) goto got_pg;
@@ -2644,7 +2650,7 @@ rebalance: page =__alloc_pages_may_oom (gfp_mask, order, zonelist, high_zoneidx, nodemask, preferred_zone, - migratetype); + classzone_idx, migratetype);if (page) goto got_pg;
@@ -2685,7 +2691,8 @@ rebalance:*/ page =__alloc_pages_direct_compact (gfp_mask, order, zonelist, high_zoneidx, nodemask, alloc_flags, - preferred_zone, migratetype, + preferred_zone, + classzone_idx, migratetype, migration_mode, &contended_compaction, &deferred_compaction, &did_some_progress);
@@ -2712,11 +2719,13 @@ __alloc_pages_nodemask(gfp_t gfp_mask, u {enum zone_type high_zoneidx =gfp_zone (gfp_mask);struct zone *preferred_zone; +struct zoneref *preferred_zoneref;struct page *page =NULL ;int migratetype =allocflags_to_migratetype (gfp_mask);unsigned int cpuset_mems_cookie;int alloc_flags =ALLOC_WMARK_LOW |ALLOC_CPUSET |ALLOC_FAIR ;struct mem_cgroup *memcg =NULL ; +int classzone_idx; gfp_mask &= gfp_allowed_mask;
@@ -2746,11 +2755,12 @@ retry_cpuset: cpuset_mems_cookie =read_mems_allowed_begin ();/* The preferred zone is used for statistics later */ -first_zones_zonelist (zonelist, high_zoneidx, + preferred_zoneref =first_zones_zonelist (zonelist, high_zoneidx, nodemask ? : &cpuset_current_mems_allowed, &preferred_zone);if (!preferred_zone) goto out; + classzone_idx =zonelist_zone_idx (preferred_zoneref);#ifdef CONFIG_CMA if (allocflags_to_migratetype (gfp_mask) ==MIGRATE_MOVABLE )
@@ -2760,7 +2770,7 @@ retry:/* First allocation attempt */ page =get_page_from_freelist (gfp_mask|__GFP_HARDWALL, nodemask, order, zonelist, high_zoneidx, alloc_flags, - preferred_zone, migratetype); + preferred_zone, classzone_idx, migratetype);if (unlikely (!page)) {/* * The first pass makes sure allocations are spread
@@ -2786,7 +2796,7 @@ retry: gfp_mask =memalloc_noio_flags (gfp_mask); page =__alloc_pages_slowpath (gfp_mask, order, zonelist, high_zoneidx, nodemask, - preferred_zone, migratetype); + preferred_zone, classzone_idx, migratetype); }trace_mm_page_alloc (page, order, gfp_mask, migratetype);
Greg Kroah-Hartman
maintainerPATCH 51/77 mm: page_alloc: only check the zone id check if pages are buddies
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mel Gorman <[email protected]>
commit d34c5fa06fade08a689fc171bf756fba2858ae73 upstream.
A node/zone index is used to check if pages are compatible for merging but this happens unconditionally even if the buddy page is not free. Defer the calculation as long as possible. Ideally we would check the zone boundary but nodes can overlap.
--- mm/page_alloc.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
mm/page_alloc.c +13 -3
@@ -508,16 +508,26 @@ static inline int page_is_buddy(struct pif (!pfn_valid_within (page_to_pfn (buddy)))return 0 ; -if (page_zone_id (page) !=page_zone_id (buddy)) -return 0 ; -if (page_is_guard (buddy) &&page_order (buddy) == order) {VM_BUG_ON_PAGE (page_count (buddy) !=0 , buddy); + +if (page_zone_id (page) !=page_zone_id (buddy)) +return 0 ; +return 1 ; }if (PageBuddy (buddy) &&page_order (buddy) == order) {VM_BUG_ON_PAGE (page_count (buddy) !=0 , buddy); + +/* +* zone check is done late to avoid uselessly +* calculating zone/node ids for pages that could +* never merge. +*/ +if (page_zone_id (page) !=page_zone_id (buddy)) +return 0 ; +return 1 ; }return 0 ;
Greg Kroah-Hartman
maintainerPATCH 52/77 mm: page_alloc: only check the alloc flags and gfp_mask for dirty once
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mel Gorman <[email protected]>
commit a6e21b14f22041382e832d30deda6f26f37b1097 upstream.
Currently it's calculated once per zone in the zonelist.
--- mm/page_alloc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
mm/page_alloc.c +3 -2
@@ -1940,6 +1940,8 @@ get_page_from_freelist(gfp_t gfp_mask, nnodemask_t *allowednodes =NULL ;/* zonelist_cache approximation */ int zlc_active =0 ;/* set if using zonelist_cache */ int did_zlc_setup =0 ;/* just call zlc_setup() one time */ +bool consider_zone_dirty = (alloc_flags &ALLOC_WMARK_LOW ) && + (gfp_mask & __GFP_WRITE); zonelist_scan:/*
@@ -1998,8 +2000,7 @@ zonelist_scan:* will require awareness of zones in the * dirty-throttling and the flusher threads. */ -if ((alloc_flags &ALLOC_WMARK_LOW ) && - (gfp_mask & __GFP_WRITE) && !zone_dirty_ok (zone)) +if (consider_zone_dirty && !zone_dirty_ok (zone))continue ; mark = zone->watermark[alloc_flags &ALLOC_WMARK_MASK ];
Greg Kroah-Hartman
maintainerPATCH 53/77 mm: page_alloc: take the ALLOC_NO_WATERMARK check out of the fast path
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mel Gorman <[email protected]>
commit 5dab29113ca56335c78be3f98bf5ddf2ef8eb6a6 upstream.
ALLOC_NO_WATERMARK is set in a few cases. Always by kswapd, always for __GFP_MEMALLOC, sometimes for swap-over-nfs, tasks etc. Each of these cases are relatively rare events but the ALLOC_NO_WATERMARK check is an unlikely branch in the fast path. This patch moves the check out of the fast path and after it has been determined that the watermarks have not been met. This helps the common fast path at the cost of making the slow path slower and hitting kswapd with a performance cost. It's a reasonable tradeoff.
--- mm/page_alloc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
mm/page_alloc.c +5 -3
@@ -1959,9 +1959,6 @@ zonelist_scan: (alloc_flags &ALLOC_CPUSET ) && !cpuset_zone_allowed_softwall(zone, gfp_mask)) continue; -BUILD_BUG_ON (ALLOC_NO_WATERMARKS <NR_WMARK ); -if (unlikely (alloc_flags &ALLOC_NO_WATERMARKS )) - goto try_this_zone;/* * Distribute pages in proportion to the individual * zone size to ensure fair page aging. The zone a
@@ -2008,6 +2005,11 @@ zonelist_scan: classzone_idx, alloc_flags)) {int ret; +/* Checked here to keep the fast path fast */ +BUILD_BUG_ON (ALLOC_NO_WATERMARKS <NR_WMARK ); +if (alloc_flags &ALLOC_NO_WATERMARKS ) + goto try_this_zone; +if (IS_ENABLED (CONFIG_NUMA ) && !did_zlc_setup && nr_online_nodes >1 ) {/*
Greg Kroah-Hartman
maintainerPATCH 54/77 mm: page_alloc: use unsigned int for order in more places
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mel Gorman <[email protected]>
commit 7aeb09f9104b760fc53c98cb7d20d06640baf9e6 upstream.
X86 prefers the use of unsigned types for iterators and there is a tendency to mix whether a signed or unsigned type if used for page order. This converts a number of sites in mm/page_alloc.c to use unsigned int for order where possible.
--- include/linux/mmzone.h | 8 ++++---- mm/page_alloc.c | 43 +++++++++++++++++++++++-------------------- 2 files changed, 27 insertions(+), 24 deletions(-)
include/linux/mmzone.h +4 -4
@@ -807,10 +807,10 @@ static inline bool pgdat_is_empty(pg_datextern struct mutex zonelists_mutex;void build_all_zonelists (pg_data_t *pgdat,struct zone *zone);void wakeup_kswapd (struct zone *zone,int order,enum zone_type classzone_idx); -bool zone_watermark_ok (struct zone *z,int order,unsigned long mark, -int classzone_idx,int alloc_flags); -bool zone_watermark_ok_safe (struct zone *z,int order,unsigned long mark, -int classzone_idx,int alloc_flags); +bool zone_watermark_ok (struct zone *z,unsigned int order, +unsigned long mark,int classzone_idx,int alloc_flags); +bool zone_watermark_ok_safe (struct zone *z,unsigned int order, +unsigned long mark,int classzone_idx,int alloc_flags);enum memmap_context {MEMMAP_EARLY ,MEMMAP_HOTPLUG ,
mm/page_alloc.c +23 -20
133 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 55/77 mm: page_alloc: reduce number of times page_to_pfn is called
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mel Gorman <[email protected]>
commit dc4b0caff24d9b2918e9f27bc65499ee63187eba upstream.
In the free path we calculate page_to_pfn multiple times. Reduce that.
--- include/linux/mmzone.h | 9 +++++++-- include/linux/pageblock-flags.h | 33 +++++++++++++-------------------- mm/page_alloc.c | 34 +++++++++++++++++++--------------- 3 files changed, 39 insertions(+), 37 deletions(-)
include/linux/mmzone.h +7 -2
@@ -78,10 +78,15 @@ extern int page_group_by_mobility_disabl#define NR_MIGRATETYPE_BITS (PB_migrate_end - PB_migrate + 1)#define MIGRATETYPE_MASK ((1UL << NR_MIGRATETYPE_BITS) - 1) -static inline int get_pageblock_migratetype (struct page *page) +#define get_pageblock_migratetype (page) \ + get_pfnblock_flags_mask(page, page_to_pfn(page), \ + PB_migrate_end, MIGRATETYPE_MASK) + +static inline int get_pfnblock_migratetype (struct page *page,unsigned long pfn) {BUILD_BUG_ON (PB_migrate_end - PB_migrate !=2 ); -return get_pageblock_flags_mask (page, PB_migrate_end,MIGRATETYPE_MASK ); +return get_pfnblock_flags_mask (page, pfn, PB_migrate_end, +MIGRATETYPE_MASK ); }struct free_area {
include/linux/pageblock-flags.h +13 -20
@@ -65,33 +65,26 @@ extern int pageblock_order;/* Forward declaration */ struct page ; -unsigned long get_pageblock_flags_mask (struct page *page, +unsigned long get_pfnblock_flags_mask (struct page *page, +unsigned long pfn,unsigned long end_bitidx,unsigned long mask); -void set_pageblock_flags_mask (struct page *page, + +void set_pfnblock_flags_mask (struct page *page,unsigned long flags, +unsigned long pfn,unsigned long end_bitidx,unsigned long mask);/* Declarations for getting and setting flags. See mm/page_alloc.c */ -static inline unsigned long get_pageblock_flags_group (struct page *page, -int start_bitidx,int end_bitidx) -{ -unsigned long nr_flag_bits = end_bitidx - start_bitidx +1 ; -unsigned long mask = (1 << nr_flag_bits) -1 ; - -return get_pageblock_flags_mask (page, end_bitidx, mask); -} - -static inline void set_pageblock_flags_group (struct page *page, -unsigned long flags, -int start_bitidx,int end_bitidx) -{ -unsigned long nr_flag_bits = end_bitidx - start_bitidx +1 ; -unsigned long mask = (1 << nr_flag_bits) -1 ; - -set_pageblock_flags_mask (page, flags, end_bitidx, mask); -} +#define get_pageblock_flags_group (page, start_bitidx, end_bitidx) \ + get_pfnblock_flags_mask(page, page_to_pfn(page), \ + end_bitidx, \ + (1 << (end_bitidx - start_bitidx + 1)) - 1) +#define set_pageblock_flags_group (page, flags, start_bitidx, end_bitidx) \ + set_pfnblock_flags_mask(page, flags, page_to_pfn(page), \ + end_bitidx, \ + (1 << (end_bitidx - start_bitidx + 1)) - 1)#ifdef CONFIG_COMPACTION #define get_pageblock_skip (page) \
mm/page_alloc.c +19 -15
@@ -560,6 +560,7 @@ static inline int page_is_buddy(struct p*/ static inline void __free_one_page (struct page *page, +unsigned long pfn,struct zone *zone,unsigned int order,int migratetype) {
@@ -576,7 +577,7 @@ static inline void __free_one_page(strucVM_BUG_ON (migratetype ==-1 ); - page_idx =page_to_pfn (page) & ((1 <<MAX_ORDER ) -1 ); + page_idx = pfn & ((1 <<MAX_ORDER ) -1 );VM_BUG_ON_PAGE (page_idx & ((1 << order) -1 ), page);VM_BUG_ON_PAGE (bad_range (zone, page), page);
@@ -711,7 +712,7 @@ static void free_pcppages_bulk(struct zolist_del (&page->lru); mt =get_freepage_migratetype (page);/* MIGRATE_MOVABLE list may include MIGRATE_RESERVEs */ -__free_one_page (page, zone,0 , mt); +__free_one_page (page,page_to_pfn (page), zone,0 , mt);trace_mm_page_pcpu_drain (page,0 , mt);if (likely (!is_migrate_isolate_page (page))) {__mod_zone_page_state (zone,NR_FREE_PAGES ,1 );
@@ -723,13 +724,15 @@ static void free_pcppages_bulk(struct zospin_unlock (&zone->lock); } -static void free_one_page (struct zone *zone,struct page *page,unsigned int order, +static void free_one_page (struct zone *zone, +struct page *page,unsigned long pfn, +unsigned int order,int migratetype) {spin_lock (&zone->lock); zone->pages_scanned =0 ; -__free_one_page (page, zone, order, migratetype); +__free_one_page (page, pfn, zone, order, migratetype);if (unlikely (!is_migrate_isolate (migratetype)))__mod_zone_freepage_state (zone,1 << order, migratetype);spin_unlock (&zone->lock);
@@ -766,15 +769,16 @@ static void __free_pages_ok(struct page {unsigned long flags;int migratetype; +unsigned long pfn =page_to_pfn (page);if (!free_pages_prepare (page, order))return ;local_irq_save (flags);__count_vm_events (PGFREE ,1 << order); - migratetype =get_pageblock_migratetype (page); + migratetype =get_pfnblock_migratetype (page, pfn);set_freepage_migratetype (page, migratetype); -free_one_page (page_zone (page), page, order, migratetype); +free_one_page (page_zone (page), page, pfn, order, migratetype);local_irq_restore (flags); }
@@ -1393,12 +1397,13 @@ void free_hot_cold_page(struct page *pagstruct zone *zone =page_zone (page);struct per_cpu_pages *pcp;unsigned long flags; +unsigned long pfn =page_to_pfn (page);int migratetype;if (!free_pages_prepare (page,0 ))return ; - migratetype =get_pageblock_migratetype (page); + migratetype =get_pfnblock_migratetype (page, pfn);set_freepage_migratetype (page, migratetype);local_irq_save (flags);__count_vm_event (PGFREE );
@@ -1412,7 +1417,7 @@ void free_hot_cold_page(struct page *pag*/ if (migratetype >=MIGRATE_PCPTYPES ) {if (unlikely (is_migrate_isolate (migratetype))) { -free_one_page (zone, page,0 , migratetype); +free_one_page (zone, page, pfn,0 , migratetype); goto out; } migratetype =MIGRATE_MOVABLE ;
@@ -6068,17 +6073,16 @@ static inline int pfn_to_bitidx(struct z* @end_bitidx: The last bit of interest * returns pageblock_bits flags */ -unsigned long get_pageblock_flags_mask (struct page *page, +unsigned long get_pfnblock_flags_mask (struct page *page,unsigned long pfn,unsigned long end_bitidx,unsigned long mask) {struct zone *zone;unsigned long *bitmap; -unsigned long pfn, bitidx, word_bitidx; +unsigned long bitidx, word_bitidx;unsigned long word; zone =page_zone (page); - pfn =page_to_pfn (page); bitmap =get_pageblock_bitmap (zone, pfn); bitidx =pfn_to_bitidx (zone, pfn); word_bitidx = bitidx /BITS_PER_LONG ;
@@ -6090,25 +6094,25 @@ unsigned long get_pageblock_flags_mask(s }/** -* set_pageblock_flags_mask - Set the requested group of flags for a pageblock_nr_pages block of pages +* set_pfnblock_flags_mask - Set the requested group of flags for a pageblock_nr_pages block of pages * @page: The page within the block of interest * @start_bitidx: The first bit of interest * @end_bitidx: The last bit of interest * @flags: The flags to set */ -void set_pageblock_flags_mask (struct page *page,unsigned long flags, +void set_pfnblock_flags_mask (struct page *page,unsigned long flags, +unsigned long pfn,unsigned long end_bitidx,unsigned long mask) {struct zone *zone;unsigned long *bitmap; -unsigned long pfn, bitidx, word_bitidx; +unsigned long bitidx, word_bitidx;unsigned long old_word, word;BUILD_BUG_ON (NR_PAGEBLOCK_BITS !=4 ); zone =page_zone (page); - pfn =page_to_pfn (page); bitmap =get_pageblock_bitmap (zone, pfn); bitidx =pfn_to_bitidx (zone, pfn); word_bitidx = bitidx /BITS_PER_LONG ;
Greg Kroah-Hartman
maintainerPATCH 56/77 mm: page_alloc: convert hot/cold parameter and immediate callers to bool
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mel Gorman <[email protected]>
commit b745bc85f21ea707e4ea1a91948055fa3e72c77b upstream.
cold is a bool, make it one. Make the likely case the "if" part of the block instead of the else as according to the optimisation manual this is preferred.
--- arch/tile/mm/homecache.c | 2 +- fs/fuse/dev.c | 2 +- include/linux/gfp.h | 4 ++-- include/linux/pagemap.h | 2 +- include/linux/swap.h | 2 +- mm/page_alloc.c | 20 ++++++++++---------- mm/swap.c | 4 ++-- mm/swap_state.c | 2 +- mm/vmscan.c | 6 +++--- 9 files changed, 22 insertions(+), 22 deletions(-)
arch/tile/mm/homecache.c +1 -1
@@ -417,7 +417,7 @@ void __homecache_free_pages(struct pageif (put_page_testzero (page)) {homecache_change_page_home (page, order,PAGE_HOME_HASH );if (order ==0 ) { -free_hot_cold_page (page,0 ); +free_hot_cold_page (page, false); }else {init_page_count (page);__free_pages (page, order);
fs/fuse/dev.c +1 -1
@@ -1614,7 +1614,7 @@ out_finish:static void fuse_retrieve_end (struct fuse_conn *fc,struct fuse_req *req) { -release_pages (req->pages, req->num_pages,0 ); +release_pages (req->pages, req->num_pages, false); } static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode,
include/linux/gfp.h +2 -2
@@ -369,8 +369,8 @@ void *alloc_pages_exact_nid(int nid, sizextern void __free_pages (struct page *page,unsigned int order);extern void free_pages (unsigned long addr,unsigned int order); -extern void free_hot_cold_page (struct page *page,int cold); -extern void free_hot_cold_page_list (struct list_head *list,int cold); +extern void free_hot_cold_page (struct page *page,bool cold); +extern void free_hot_cold_page_list (struct list_head *list,bool cold);extern void __free_memcg_kmem_pages (struct page *page,unsigned int order);extern void free_memcg_kmem_pages (unsigned long addr,unsigned int order);
include/linux/pagemap.h +1 -1
@@ -99,7 +99,7 @@ static inline void mapping_set_gfp_mask(#define page_cache_get (page) get_page(page)#define page_cache_release (page) put_page(page) -void release_pages (struct page **pages,int nr,int cold); +void release_pages (struct page **pages,int nr,bool cold);/* * speculatively take a reference to a page.
include/linux/swap.h +1 -1
@@ -441,7 +441,7 @@ mem_cgroup_uncharge_swapcache(struct pag#define free_page_and_swap_cache (page) \ page_cache_release(page)#define free_pages_and_swap_cache (pages, nr) \ - release_pages((pages), (nr), 0); + release_pages((pages), (nr), false);static inline void show_swap_cache_info (void ) {
mm/page_alloc.c +10 -10
@@ -1210,7 +1210,7 @@ retry_reserve:*/ static int rmqueue_bulk (struct zone *zone,unsigned int order,unsigned long count,struct list_head *list, -int migratetype,int cold) +int migratetype,bool cold) {int i;
@@ -1229,7 +1229,7 @@ static int rmqueue_bulk(struct zone *zon* merge IO requests if the physical pages are ordered * properly. */ -if (likely (cold ==0 )) +if (likely (!cold))list_add (&page->lru, list);else list_add_tail (&page->lru, list);
@@ -1390,9 +1390,9 @@ void mark_free_pages(struct zone *zone)/* * Free a 0-order page -* cold == 1 ? free a cold page : free a hot page +* cold == true ? free a cold page : free a hot page */ -void free_hot_cold_page (struct page *page,int cold) +void free_hot_cold_page (struct page *page,bool cold) {struct zone *zone =page_zone (page);struct per_cpu_pages *pcp;
@@ -1424,10 +1424,10 @@ void free_hot_cold_page(struct page *pag } pcp = &this_cpu_ptr (zone->pageset)->pcp; -if (cold) -list_add_tail (&page->lru, &pcp->lists[migratetype]); -else +if (!cold)list_add (&page->lru, &pcp->lists[migratetype]); +else +list_add_tail (&page->lru, &pcp->lists[migratetype]); pcp->count++;if (pcp->count >= pcp->high) {unsigned long batch =ACCESS_ONCE (pcp->batch);
@@ -1442,7 +1442,7 @@ out:/* * Free a list of 0-order pages */ -void free_hot_cold_page_list (struct list_head *list,int cold) +void free_hot_cold_page_list (struct list_head *list,bool cold) {struct page *page, *next;
@@ -1559,7 +1559,7 @@ struct page *buffered_rmqueue(struct zon {unsigned long flags;struct page *page; -int cold = !!(gfp_flags & __GFP_COLD); +bool cold = ((gfp_flags & __GFP_COLD) !=0 ); again:if (likely (order ==0 )) {
@@ -2868,7 +2868,7 @@ void __free_pages(struct page *page, uns {if (put_page_testzero (page)) {if (order ==0 ) -free_hot_cold_page (page,0 ); +free_hot_cold_page (page, false);else __free_pages_ok (page, order); }
mm/swap.c +2 -2
@@ -67,7 +67,7 @@ static void __page_cache_release(structstatic void __put_single_page (struct page *page) {__page_cache_release (page); -free_hot_cold_page (page,0 ); +free_hot_cold_page (page, false); }static void __put_compound_page (struct page *page)
@@ -826,7 +826,7 @@ void lru_add_drain_all(void)* grabbed the page via the LRU. If it did, give up: shrink_inactive_list() * will free it. */ -void release_pages (struct page **pages,int nr,int cold) +void release_pages (struct page **pages,int nr,bool cold) {int i;LIST_HEAD (pages_to_free);
mm/swap_state.c +1 -1
@@ -270,7 +270,7 @@ void free_pages_and_swap_cache(struct pafor (i =0 ; i < todo; i++)free_swap_cache (pagep[i]); -release_pages (pagep, todo,0 ); +release_pages (pagep, todo, false); pagep += todo; nr -= todo; }
mm/vmscan.c +3 -3
@@ -1107,7 +1107,7 @@ keep:VM_BUG_ON_PAGE (PageLRU (page) ||PageUnevictable (page), page); } -free_hot_cold_page_list (&free_pages,1 ); +free_hot_cold_page_list (&free_pages, true);list_splice (&ret_pages, page_list);count_vm_events (PGACTIVATE , pgactivate);
@@ -1505,7 +1505,7 @@ shrink_inactive_list(unsigned long nr_tospin_unlock_irq (&zone->lru_lock); -free_hot_cold_page_list (&page_list,1 ); +free_hot_cold_page_list (&page_list, true);/* * If reclaim is isolating dirty pages under writeback, it implies
@@ -1725,7 +1725,7 @@ static void shrink_active_list(unsigned__mod_zone_page_state (zone,NR_ISOLATED_ANON + file, -nr_taken);spin_unlock_irq (&zone->lru_lock); -free_hot_cold_page_list (&l_hold,1 ); +free_hot_cold_page_list (&l_hold, true); }#ifdef CONFIG_SWAP
Greg Kroah-Hartman
maintainerPATCH 57/77 mm: page_alloc: lookup pageblock migratetype with IRQs enabled during free
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mel Gorman <[email protected]>
commit cfc47a2803db42140167b92d991ef04018e162c7 upstream.
get_pageblock_migratetype() is called during free with IRQs disabled. This is unnecessary and disables IRQs for longer than necessary.
--- mm/page_alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/page_alloc.c +1 -1
@@ -774,9 +774,9 @@ static void __free_pages_ok(struct pageif (!free_pages_prepare (page, order))return ; + migratetype =get_pfnblock_migratetype (page, pfn);local_irq_save (flags);__count_vm_events (PGFREE ,1 << order); - migratetype =get_pfnblock_migratetype (page, pfn);set_freepage_migratetype (page, migratetype);free_one_page (page_zone (page), page, pfn, order, migratetype);local_irq_restore (flags);
Greg Kroah-Hartman
maintainerPATCH 58/77 mm: shmem: avoid atomic operation during shmem_getpage_gfp
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mel Gorman <[email protected]>
commit 07a427884348d38a6fd56fa4d78249c407196650 upstream.
shmem_getpage_gfp uses an atomic operation to set the SwapBacked field before it's even added to the LRU or visible. This is unnecessary as what could it possible race against? Use an unlocked variant.
--- include/linux/page-flags.h | 1 + mm/shmem.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)
include/linux/page-flags.h +1 -0
@@ -208,6 +208,7 @@ PAGEFLAG(Pinned, pinned) TESTSCFLAG(PinnPAGEFLAG (SavePinned, savepinned);/* Xen */ PAGEFLAG(Reserved, reserved) __CLEARPAGEFLAG(Reserved, reserved) PAGEFLAG(SwapBacked, swapbacked) __CLEARPAGEFLAG(SwapBacked, swapbacked) + __SETPAGEFLAG(SwapBacked, swapbacked)__PAGEFLAG (SlobFree, slob_free)
mm/shmem.c +1 -1
@@ -1140,7 +1140,7 @@ repeat: goto decused; } -SetPageSwapBacked (page); +__SetPageSwapBacked (page);__set_page_locked (page); error =mem_cgroup_cache_charge (page, current->mm, gfp &GFP_RECLAIM_MASK );
Greg Kroah-Hartman
maintainerPATCH 59/77 mm: do not use atomic operations when releasing pages
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mel Gorman <[email protected]>
commit e3741b506c5088fa8c911bb5884c430f770fb49d upstream.
There should be no references to it any more and a parallel mark should not be reordered against us. Use non-locked varient to clear page active.
--- mm/swap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/swap.c +1 -1
@@ -867,7 +867,7 @@ void release_pages(struct page **pages, }/* Clear Active bit in case of parallel mark_page_accessed */ -ClearPageActive (page); +__ClearPageActive (page);list_add (&page->lru, &pages_to_free); }
Greg Kroah-Hartman
maintainerPATCH 60/77 mm: do not use unnecessary atomic operations when adding pages to the LRU
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mel Gorman <[email protected]>
commit 6fb81a17d21f2a138b8f424af4cf379f2b694060 upstream.
When adding pages to the LRU we clear the active bit unconditionally. As the page could be reachable from other paths we cannot use unlocked operations without risk of corruption such as a parallel mark_page_accessed. This patch tests if is necessary to clear the active flag before using an atomic operation. This potentially opens a tiny race when PageActive is checked as mark_page_accessed could be called after PageActive was checked. The race already exists but this patch changes it slightly. The consequence is that that the page may be promoted to the active list that might have been left on the inactive list before the patch. It's too tiny a race and too marginal a consequence to always use atomic operations for.
--- mm/swap.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
mm/swap.c +4 -2
@@ -597,13 +597,15 @@ static void __lru_cache_add(struct page*/ void lru_cache_add_anon (struct page *page) { -ClearPageActive (page); +if (PageActive (page)) +ClearPageActive (page);__lru_cache_add (page); }void lru_cache_add_file (struct page *page) { -ClearPageActive (page); +if (PageActive (page)) +ClearPageActive (page);__lru_cache_add (page); }EXPORT_SYMBOL (lru_cache_add_file);
Greg Kroah-Hartman
maintainerPATCH 61/77 fs: buffer: do not use unnecessary atomic operations when discarding buffers
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mel Gorman <[email protected]>
commit e7470ee89f003634a88e7b5e5a7b65b3025987de upstream.
Discarding buffers uses a bunch of atomic operations when discarding buffers because ...... I can't think of a reason. Use a cmpxchg loop to clear all the necessary flags. In most (all?) cases this will be a single atomic operations.
--- fs/buffer.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-)
fs/buffer.c +16 -5
@@ -1485,16 +1485,27 @@ EXPORT_SYMBOL(set_bh_page);/* * Called when truncating a buffer on a page completely. */ + +/* Bits that are cleared during an invalidate */ +#define BUFFER_FLAGS_DISCARD \ + (1 << BH_Mapped | 1 << BH_New | 1 << BH_Req | \ + 1 << BH_Delay | 1 << BH_Unwritten) +static void discard_buffer (struct buffer_head * bh) { +unsigned long b_state, b_state_old; +lock_buffer (bh);clear_buffer_dirty (bh); bh->b_bdev =NULL ; -clear_buffer_mapped (bh); -clear_buffer_req (bh); -clear_buffer_new (bh); -clear_buffer_delay (bh); -clear_buffer_unwritten (bh); + b_state = bh->b_state; +for (;;) { + b_state_old =cmpxchg (&bh->b_state, b_state, + (b_state & ~BUFFER_FLAGS_DISCARD )); +if (b_state_old == b_state) +break ; + b_state = b_state_old; + }unlock_buffer (bh); }
Greg Kroah-Hartman
maintainerPATCH 62/77 mm: non-atomically mark page accessed during page cache allocation where possible
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mel Gorman <[email protected]>
commit 2457aec63745e235bcafb7ef312b182d8682f0fc upstream.
aops->write_begin may allocate a new page and make it visible only to have mark_page_accessed called almost immediately after. Once the page is visible the atomic operations are necessary which is noticable overhead when writing to an in-memory filesystem like tmpfs but should also be noticable with fast storage. The objective of the patch is to initialse the accessed information with non-atomic operations before the page is visible.
The bulk of filesystems directly or indirectly use grab_cache_page_write_begin or find_or_create_page for the initial allocation of a page cache page. This patch adds an init_page_accessed() helper which behaves like the first call to mark_page_accessed() but may called before the page is visible and can be done non-atomically.
The primary APIs of concern in this care are the following and are used by most filesystems.
find_get_page
find_lock_page
find_or_create_page
grab_cache_page_nowait
grab_cache_page_write_begin
All of them are very similar in detail to the patch creates a core helper pagecache_get_page() which takes a flags parameter that affects its behavior such as whether the page should be marked accessed or not. Then old API is preserved but is basically a thin wrapper around this core function.
Each of the filesystems are then updated to avoid calling mark_page_accessed when it is known that the VM interfaces have already done the job. There is a slight snag in that the timing of the mark_page_accessed() has now changed so in rare cases it's possible a page gets to the end of the LRU as PageReferenced where as previously it might have been repromoted. This is expected to be rare but it's worth the filesystem people thinking about it in case they see a problem with the timing change. It is also the case that some filesystems may be marking pages accessed that previously did not but it makes sense that filesystems have consistent behaviour in this regard.
The test case used to evaulate this is a simple dd of a large file done multiple times with the file deleted on each iterations. The size of the file is 1/10th physical memory to avoid dirty page balancing. In the async case it will be possible that the workload completes without even hitting the disk and will have variable results but highlight the impact of mark_page_accessed for async IO. The sync results are expected to be more stable. The exception is tmpfs where the normal case is for the "IO" to not hit the disk.
The test machine was single socket and UMA to avoid any scheduling or NUMA artifacts. Throughput and wall times are presented for sync IO, only wall times are shown for async as the granularity reported by dd and the variability is unsuitable for comparison. As async results were variable do to writback timings, I'm only reporting the maximum figures. The sync results were stable enough to make the mean and stddev uninteresting.
The performance results are reported based on a run with no profiling. Profile data is based on a separate run with oprofile running.
async dd
3.15.0-rc3 3.15.0-rc3
vanilla accessed-v2ext3 Max elapsed 13.9900 ( 0.00%) 11.5900 ( 17.16%)
tmpfs Max elapsed 0.5100 ( 0.00%) 0.4900 ( 3.92%)
btrfs Max elapsed 12.8100 ( 0.00%) 12.7800 ( 0.23%)
ext4 Max elapsed 18.6000 ( 0.00%) 13.3400 ( 28.28%)
xfs Max elapsed 12.5600 ( 0.00%) 2.0900 ( 83.36%)
The XFS figure is a bit strange as it managed to avoid a worst case by sheer luck but the average figures looked reasonable.
samples percentage
ext3 86107 0.9783 vmlinux-3.15.0-rc4-vanilla mark_page_accessed ext3 23833 0.2710 vmlinux-3.15.0-rc4-accessed-v3r25 mark_page_accessed ext3 5036 0.0573 vmlinux-3.15.0-rc4-accessed-v3r25 init_page_accessed ext4 64566 0.8961 vmlinux-3.15.0-rc4-vanilla mark_page_accessed ext4 5322 0.0713 vmlinux-3.15.0-rc4-accessed-v3r25 mark_page_accessed ext4 2869 0.0384 vmlinux-3.15.0-rc4-accessed-v3r25 init_page_accessed xfs 62126 1.7675 vmlinux-3.15.0-rc4-vanilla mark_page_accessed xfs 1904 0.0554 vmlinux-3.15.0-rc4-accessed-v3r25 init_page_accessed xfs 103 0.0030 vmlinux-3.15.0-rc4-accessed-v3r25 mark_page_accessed btrfs 10655 0.1338 vmlinux-3.15.0-rc4-vanilla mark_page_accessed btrfs 2020 0.0273 vmlinux-3.15.0-rc4-accessed-v3r25 init_page_accessed btrfs 587 0.0079 vmlinux-3.15.0-rc4-accessed-v3r25 mark_page_accessed tmpfs 59562 3.2628 vmlinux-3.15.0-rc4-vanilla mark_page_accessed tmpfs 1210 0.0696 vmlinux-3.15.0-rc4-accessed-v3r25 init_page_accessed tmpfs 94 0.0054 vmlinux-3.15.0-rc4-accessed-v3r25 mark_page_accessed
--- fs/btrfs/extent_io.c | 11 +- fs/btrfs/file.c | 5 - fs/buffer.c | 7 - fs/ext4/mballoc.c | 14 +-- fs/f2fs/checkpoint.c | 1 fs/f2fs/node.c | 2 fs/fuse/file.c | 2 fs/gfs2/aops.c | 1 fs/gfs2/meta_io.c | 4 fs/ntfs/attrib.c | 1 fs/ntfs/file.c | 1 include/linux/page-flags.h | 1 include/linux/pagemap.h | 107 ++++++++++++++++++++++- include/linux/swap.h | 1 mm/filemap.c | 202 ++++++++++++++++----------------------------- mm/shmem.c | 6 + mm/swap.c | 11 ++ 17 files changed, 217 insertions(+), 160 deletions(-)
fs/btrfs/extent_io.c +6 -5
@@ -4507,7 +4507,8 @@ static void check_buffer_tree_ref(structspin_unlock (&eb->refs_lock); } -static void mark_extent_buffer_accessed (struct extent_buffer *eb) +static void mark_extent_buffer_accessed (struct extent_buffer *eb, +struct page *accessed) {unsigned long num_pages, i;
@@ -4516,7 +4517,8 @@ static void mark_extent_buffer_accessed( num_pages =num_extent_pages (eb->start, eb->len);for (i =0 ; i < num_pages; i++) {struct page *p =extent_buffer_page (eb, i); -mark_page_accessed (p); +if (p != accessed) +mark_page_accessed (p); } }
@@ -4530,7 +4532,7 @@ struct extent_buffer *find_extent_buffer start >> PAGE_CACHE_SHIFT);if (eb &&atomic_inc_not_zero (&eb->refs)) {rcu_read_unlock (); -mark_extent_buffer_accessed (eb); +mark_extent_buffer_accessed (eb,NULL );return eb; }rcu_read_unlock ();
@@ -4578,7 +4580,7 @@ struct extent_buffer *alloc_extent_buffespin_unlock (&mapping->private_lock);unlock_page (p);page_cache_release (p); -mark_extent_buffer_accessed (exists); +mark_extent_buffer_accessed (exists, p); goto free_eb; }
@@ -4593,7 +4595,6 @@ struct extent_buffer *alloc_extent_buffeattach_extent_buffer_page (eb, p);spin_unlock (&mapping->private_lock);WARN_ON (PageDirty (p)); -mark_page_accessed (p); eb->pages[i] = p;if (!PageUptodate (p)) uptodate =0 ;
fs/btrfs/file.c +3 -2
@@ -470,11 +470,12 @@ static void btrfs_drop_pages(struct pagefor (i =0 ; i < num_pages; i++) {/* page checked is some magic around finding pages that * have been modified without going through btrfs_set_page_dirty -* clear it here +* clear it here. There should be no need to mark the pages +* accessed as prepare_pages should have marked them accessed +* in prepare_pages via find_or_create_page() */ ClearPageChecked (pages[i]);unlock_page (pages[i]); -mark_page_accessed (pages[i]);page_cache_release (pages[i]); } }
fs/buffer.c +4 -3
@@ -227,7 +227,7 @@ __find_get_block_slow(struct block_devicint all_mapped =1 ; index = block >> (PAGE_CACHE_SHIFT - bd_inode->i_blkbits); - page =find_get_page (bd_mapping, index); + page =find_get_page_flags (bd_mapping, index,FGP_ACCESSED );if (!page) goto out;
@@ -1368,12 +1368,13 @@ __find_get_block(struct block_device *bdstruct buffer_head *bh =lookup_bh_lru (bdev, block, size);if (bh ==NULL ) { +/* __find_get_block_slow will mark the page accessed */ bh =__find_get_block_slow (bdev, block);if (bh)bh_lru_install (bh); - } -if (bh) + }else touch_buffer (bh); +return bh; }EXPORT_SYMBOL (__find_get_block);
fs/ext4/mballoc.c +8 -6
@@ -1044,6 +1044,8 @@ int ext4_mb_init_group(struct super_bloc* allocating. If we are looking at the buddy cache we would * have taken a reference using ext4_mb_load_buddy and that * would have pinned buddy page to page cache. +* The call to ext4_mb_get_buddy_page_lock will mark the +* page accessed. */ ret =ext4_mb_get_buddy_page_lock (sb, group, &e4b);if (ret || !EXT4_MB_GRP_NEED_INIT (this_grp)) {
@@ -1062,7 +1064,6 @@ int ext4_mb_init_group(struct super_bloc ret = -EIO ; goto err; } -mark_page_accessed (page);if (e4b.bd_buddy_page ==NULL ) {/*
@@ -1082,7 +1083,6 @@ int ext4_mb_init_group(struct super_bloc ret = -EIO ; goto err; } -mark_page_accessed (page); err:ext4_mb_put_buddy_page_lock (&e4b);return ret;
@@ -1141,7 +1141,7 @@ ext4_mb_load_buddy(struct super_block *s/* we could use find_or_create_page(), but it locks page * what we'd like to avoid in fast path ... */ - page =find_get_page (inode->i_mapping, pnum); + page =find_get_page_flags (inode->i_mapping, pnum,FGP_ACCESSED );if (page ==NULL || !PageUptodate (page)) {if (page)/*
@@ -1172,15 +1172,16 @@ ext4_mb_load_buddy(struct super_block *s ret = -EIO ; goto err; } + +/* Pages marked accessed already */ e4b->bd_bitmap_page = page; e4b->bd_bitmap =page_address (page) + (poff * sb->s_blocksize); -mark_page_accessed (page); block++; pnum = block / blocks_per_page; poff = block % blocks_per_page; - page =find_get_page (inode->i_mapping, pnum); + page =find_get_page_flags (inode->i_mapping, pnum,FGP_ACCESSED );if (page ==NULL || !PageUptodate (page)) {if (page)page_cache_release (page);
@@ -1201,9 +1202,10 @@ ext4_mb_load_buddy(struct super_block *s ret = -EIO ; goto err; } + +/* Pages marked accessed already */ e4b->bd_buddy_page = page; e4b->bd_buddy =page_address (page) + (poff * sb->s_blocksize); -mark_page_accessed (page);BUG_ON (e4b->bd_bitmap_page ==NULL );BUG_ON (e4b->bd_buddy_page ==NULL );
fs/f2fs/checkpoint.c +0 -1
@@ -71,7 +71,6 @@ repeat: goto repeat; } out: -mark_page_accessed (page);return page; }
fs/f2fs/node.c +0 -2
@@ -969,7 +969,6 @@ repeat: } got_it:f2fs_bug_on (nid !=nid_of_node (page)); -mark_page_accessed (page);return page; }
@@ -1024,7 +1023,6 @@ page_hit:f2fs_put_page (page,1 );return ERR_PTR (-EIO ); } -mark_page_accessed (page);return page; }
fs/fuse/file.c +0 -2
@@ -1006,8 +1006,6 @@ static ssize_t fuse_fill_write_pages(str tmp =iov_iter_copy_from_user_atomic (page, ii, offset, bytes);flush_dcache_page (page); -mark_page_accessed (page); -if (!tmp) {unlock_page (page);page_cache_release (page);
fs/gfs2/aops.c +0 -1
@@ -517,7 +517,6 @@ int gfs2_internal_read(struct gfs2_inode p =kmap_atomic (page);memcpy (buf + copied, p + offset, amt);kunmap_atomic (p); -mark_page_accessed (page);page_cache_release (page); copied += amt; index++;
fs/gfs2/meta_io.c +2 -2
@@ -136,7 +136,8 @@ struct buffer_head *gfs2_getbuf(struct gyield (); } }else { - page =find_lock_page (mapping, index); + page =find_get_page_flags (mapping, index, +FGP_LOCK |FGP_ACCESSED );if (!page)return NULL ; }
@@ -153,7 +154,6 @@ struct buffer_head *gfs2_getbuf(struct gmap_bh (bh, sdp->sd_vfs, blkno);unlock_page (page); -mark_page_accessed (page);page_cache_release (page);return bh;
fs/ntfs/attrib.c +0 -1
@@ -1748,7 +1748,6 @@ int ntfs_attr_make_non_resident(ntfs_inoif (page) {set_page_dirty (page);unlock_page (page); -mark_page_accessed (page);page_cache_release (page); }ntfs_debug ("Done." );
fs/ntfs/file.c +0 -1
@@ -2060,7 +2060,6 @@ static ssize_t ntfs_file_buffered_write( }do {unlock_page (pages[--do_pages]); -mark_page_accessed (pages[do_pages]);page_cache_release (pages[do_pages]); }while (do_pages);if (unlikely (status))
include/linux/page-flags.h +1 -0
@@ -198,6 +198,7 @@ struct page; /* forward declaration */ TESTPAGEFLAG(Locked, locked) PAGEFLAG(Error, error) TESTCLEARFLAG(Error, error) PAGEFLAG(Referenced, referenced) TESTCLEARFLAG(Referenced, referenced) + __SETPAGEFLAG(Referenced, referenced) PAGEFLAG(Dirty, dirty) TESTSCFLAG(Dirty, dirty) __CLEARPAGEFLAG(Dirty, dirty) PAGEFLAG(LRU, lru) __CLEARPAGEFLAG(LRU, lru) PAGEFLAG(Active, active) __CLEARPAGEFLAG(Active, active)
include/linux/pagemap.h +101 -6
121 lines not on this page · raw message
include/linux/swap.h +1 -0
@@ -275,6 +275,7 @@ extern void lru_add_page_tail(struct pag struct lruvec *lruvec, struct list_head *head);extern void activate_page (struct page *);extern void mark_page_accessed (struct page *); +extern void init_page_accessed (struct page *page);extern void lru_add_drain (void );extern void lru_add_drain_cpu (int cpu);extern void lru_add_drain_all (void );
mm/filemap.c +75 -127
270 lines not on this page · raw message
mm/shmem.c +5 -1
@@ -1438,9 +1438,13 @@ shmem_write_begin(struct file *file, str loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata) { + int ret;struct inode *inode = mapping->host;pgoff_t index = pos >>PAGE_CACHE_SHIFT ; -return shmem_getpage (inode, index, pagep,SGP_WRITE ,NULL ); + ret =shmem_getpage (inode, index, pagep,SGP_WRITE ,NULL ); +if (ret ==0 && *pagep) +init_page_accessed (*pagep); +return ret; } static int
mm/swap.c +11 -0
@@ -580,6 +580,17 @@ void mark_page_accessed(struct page *pag }EXPORT_SYMBOL (mark_page_accessed); +/* +* Used to mark_page_accessed(page) that is not visible yet and when it is +* still safe to use non-atomic ops +*/ +void init_page_accessed (struct page *page) +{ +if (!PageReferenced (page)) +__SetPageReferenced (page); +} +EXPORT_SYMBOL (init_page_accessed); +static void __lru_cache_add (struct page *page) {struct pagevec *pvec = &get_cpu_var (lru_add_pvec);
Greg Kroah-Hartman
maintainerPATCH 63/77 mm: avoid unnecessary atomic operations during end_page_writeback()
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mel Gorman <[email protected]>
commit 888cf2db475a256fb0cda042140f73d7881f81fe upstream.
If a page is marked for immediate reclaim then it is moved to the tail of the LRU list. This occurs when the system is under enough memory pressure for pages under writeback to reach the end of the LRU but we test for this using atomic operations on every writeback. This patch uses an optimistic non-atomic test first. It'll miss some pages in rare cases but the consequences are not severe enough to warrant such a penalty.
While the function does not dominate profiles during a simple dd test the cost of it is reduced.
73048 0.7428 vmlinux-3.15.0-rc5-mmotm-20140513 end_page_writeback 23740 0.2409 vmlinux-3.15.0-rc5-lessatomic end_page_writeback
--- mm/filemap.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
mm/filemap.c +10 -1
@@ -644,8 +644,17 @@ EXPORT_SYMBOL(unlock_page);*/ void end_page_writeback (struct page *page) { -if (TestClearPageReclaim (page)) +/* +* TestClearPageReclaim could be used here but it is an atomic +* operation and overkill in this particular case. Failing to +* shuffle a page marked for immediate reclaim is too mild to +* justify taking an atomic operation penalty at the end of +* ever page writeback. +*/ +if (PageReclaim (page)) { +ClearPageReclaim (page);rotate_reclaimable_page (page); + }if (!test_clear_page_writeback (page))BUG ();
Greg Kroah-Hartman
maintainerPATCH 64/77 shmem: fix init_page_accessed use to stop !PageLRU bug
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hugh Dickins <[email protected]>
commit 66d2f4d28cd030220e7ea2a628993fcabcb956d1 upstream.
Under shmem swapping load, I sometimes hit the VM_BUG_ON_PAGE(!PageLRU) in isolate_lru_pages() at mm/vmscan.c:1281!
Commit 2457aec63745 ("mm: non-atomically mark page accessed during page cache allocation where possible") looks like interrupted work-in-progress.
mm/filemap.c's call to init_page_accessed() is fine, but not mm/shmem.c's
- shmem_write_begin() is clearly wrong to use it after shmem_getpage(), when the page is always visible in radix_tree, and often already on LRU.
Revert change to shmem_write_begin(), and use init_page_accessed() or mark_page_accessed() appropriately for SGP_WRITE in shmem_getpage_gfp().
SGP_WRITE also covers shmem_symlink(), which did not mark_page_accessed() before; but since many other filesystems use [__]page_symlink(), which did and does mark the page accessed, consider this as rectifying an oversight.
--- mm/shmem.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
mm/shmem.c +10 -5
@@ -1035,6 +1035,9 @@ repeat: goto failed; } +if (page && sgp ==SGP_WRITE ) +mark_page_accessed (page); +/* fallocated page? */ if (page && !PageUptodate (page)) {if (sgp !=SGP_READ )
@@ -1116,6 +1119,9 @@ repeat:shmem_recalc_inode (inode);spin_unlock (&info->lock); +if (sgp ==SGP_WRITE ) +mark_page_accessed (page); +delete_from_swap_cache (page);set_page_dirty (page);swap_free (swap);
@@ -1142,6 +1148,9 @@ repeat:__SetPageSwapBacked (page);__set_page_locked (page); +if (sgp ==SGP_WRITE ) +init_page_accessed (page); + error =mem_cgroup_cache_charge (page, current->mm, gfp &GFP_RECLAIM_MASK );if (error)
@@ -1438,13 +1447,9 @@ shmem_write_begin(struct file *file, str loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata) { - int ret; struct inode *inode = mapping->host;pgoff_t index = pos >>PAGE_CACHE_SHIFT ; - ret =shmem_getpage (inode, index, pagep,SGP_WRITE ,NULL ); -if (ret ==0 && *pagep) -init_page_accessed (*pagep); -return ret; +return shmem_getpage (inode, index, pagep,SGP_WRITE ,NULL ); } static int
Greg Kroah-Hartman
maintainerPATCH 65/77 mm/memory.c: use entry = ACCESS_ONCE(*pte) in handle_pte_fault()
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hugh Dickins <[email protected]>
commit c0d73261f5c1355a35b8b40e871d31578ce0c044 upstream.
Use ACCESS_ONCE() in handle_pte_fault() when getting the entry or orig_pte upon which all subsequent decisions and pte_same() tests will be made.
I have no evidence that its lack is responsible for the mm/filemap.c:202 BUG_ON(page_mapped(page)) in __delete_from_page_cache() found by trinity, and I am not optimistic that it will fix it. But I have found no other explanation, and ACCESS_ONCE() here will surely not hurt.
If gcc does re-access the pte before passing it down, then that would be disastrous for correct page fault handling, and certainly could explain the page_mapped() BUGs seen (concurrent fault causing page to be mapped in a second time on top of itself: mapcount 2 for a single pte).
--- mm/memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/memory.c +1 -1
@@ -3646,7 +3646,7 @@ static int handle_pte_fault(struct mm_stpte_t entry;spinlock_t *ptl; - entry = *pte; + entry =ACCESS_ONCE (*pte);if (!pte_present (entry)) {if (pte_none (entry)) {if (vma->vm_ops) {
Greg Kroah-Hartman
maintainerPATCH 66/77 mm, thp: only collapse hugepages to nodes with affinity for zone_reclaim_mode
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Rientjes <[email protected]>
commit 14a4e2141e24304fff2c697be6382ffb83888185 upstream.
Commit 9f1b868a13ac ("mm: thp: khugepaged: add policy for finding target node") improved the previous khugepaged logic which allocated a transparent hugepages from the node of the first page being collapsed.
However, it is still possible to collapse pages to remote memory which may suffer from additional access latency. With the current policy, it is possible that 255 pages (with PAGE_SHIFT == 12) will be collapsed remotely if the majority are allocated from that node.
When zone_reclaim_mode is enabled, it means the VM should make every attempt to allocate locally to prevent NUMA performance degradation. In this case, we do not want to collapse hugepages to remote nodes that would suffer from increased access latency. Thus, when zone_reclaim_mode is enabled, only allow collapsing to nodes with RECLAIM_DISTANCE or less.
There is no functional change for systems that disable zone_reclaim_mode.
--- mm/huge_memory.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
mm/huge_memory.c +26 -0
@@ -2273,6 +2273,30 @@ static void khugepaged_alloc_sleep(void)static int khugepaged_node_load[MAX_NUMNODES ]; +static bool khugepaged_scan_abort (int nid) +{ +int i; + +/* +* If zone_reclaim_mode is disabled, then no extra effort is made to +* allocate memory locally. +*/ +if (!zone_reclaim_mode) +return false; + +/* If there is a count for this node already, it must be acceptable */ +if (khugepaged_node_load[nid]) +return false; + +for (i =0 ; i <MAX_NUMNODES ; i++) { +if (!khugepaged_node_load[i]) +continue ; +if (node_distance (nid, i) >RECLAIM_DISTANCE ) +return true; + } +return false; +} +#ifdef CONFIG_NUMA static int khugepaged_find_target_node (void ) {
@@ -2589,6 +2613,8 @@ static int khugepaged_scan_pmd(struct mm* hit record. */ node =page_to_nid (page); +if (khugepaged_scan_abort (node)) + goto out_unmap; khugepaged_node_load[node]++;VM_BUG_ON_PAGE (PageCompound (page), page);if (!PageLRU (page) ||PageLocked (page) || !PageAnon (page))
Greg Kroah-Hartman
maintainerPATCH 67/77 mm: make copy_pte_range static again
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jerome Marchand <[email protected]>
commit 21bda264f4243f61dfcc485174055f12ad0530b4 upstream.
Commit 71e3aac0724f ("thp: transparent hugepage core") adds copy_pte_range prototype to huge_mm.h. I'm not sure why (or if) this function have been used outside of memory.c, but it currently isn't. This patch makes copy_pte_range() static again.
--- include/linux/huge_mm.h | 4 ---- mm/memory.c | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-)
include/linux/huge_mm.h +0 -4
@@ -93,10 +93,6 @@ extern bool is_vma_temporary_stack(struc#endif /* CONFIG_DEBUG_VM */ extern unsigned long transparent_hugepage_flags; -extern int copy_pte_range (struct mm_struct *dst_mm,struct mm_struct *src_mm, -pmd_t *dst_pmd,pmd_t *src_pmd, -struct vm_area_struct *vma, -unsigned long addr,unsigned long end);extern int split_huge_page_to_list (struct page *page,struct list_head *list);static inline int split_huge_page (struct page *page) {
mm/memory.c +1 -1
@@ -878,7 +878,7 @@ out_set_pte:return 0 ; } -int copy_pte_range (struct mm_struct *dst_mm,struct mm_struct *src_mm, +static int copy_pte_range (struct mm_struct *dst_mm,struct mm_struct *src_mm,pmd_t *dst_pmd,pmd_t *src_pmd,struct vm_area_struct *vma,unsigned long addr,unsigned long end) {
Greg Kroah-Hartman
maintainerPATCH 68/77 vmalloc: use rcu list iterator to reduce vmap_area_lock contention
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joonsoo Kim <[email protected]>
commit 474750aba88817c53f39424e5567b8e4acc4b39b upstream.
Richard Yao reported a month ago that his system have a trouble with vmap_area_lock contention during performance analysis by /proc/meminfo. Andrew asked why his analysis checks /proc/meminfo stressfully, but he didn't answer it.
https://lkml.org/lkml/2014/4/10/416
Although I'm not sure that this is right usage or not, there is a solution reducing vmap_area_lock contention with no side-effect. That is just to use rcu list iterator in get_vmalloc_info().
rcu can be used in this function because all RCU protocol is already respected by writers, since Nick Piggin commit db64fe02258f1 ("mm:
rewrite vmap layer") back in linux-2.6.28
Specifically :
insertions use list_add_rcu(),
deletions use list_del_rcu() and kfree_rcu().
Note the rb tree is not used from rcu reader (it would not be safe), only the vmap_area_list has full RCU protection.
Note that __purge_vmap_area_lazy() already uses this rcu protection.
rcu_read_lock();
list_for_each_entry_rcu(va, &vmap_area_list, list) {
if (va->flags & VM_LAZY_FREE) {
if (va->va_start < *start)
*start = va->va_start;
if (va->va_end > *end)
*end = va->va_end;
nr += (va->va_end - va->va_start) >> PAGE_SHIFT;
list_add_tail(&va->purge_list, &valist);
va->flags |= VM_LAZY_FREEING;
va->flags &= ~VM_LAZY_FREE;
}
}
rcu_read_unlock();Peter:
: While rcu list traversal over the vmap_area_list is safe, this may : arrive at different results than the spinlocked version. The rcu list : traversal version will not be a 'snapshot' of a single, valid instant : of the entire vmap_area_list, but rather a potential amalgam of : different list states.
Joonsoo:
: Yes, you are right, but I don't think that we should be strict here. : Meminfo is already not a 'snapshot' at specific time. While we try to get : certain stats, the other stats can change. And, although we may arrive at : different results than the spinlocked version, the difference would not be : large and would not make serious side-effect.
--- mm/vmalloc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
mm/vmalloc.c +3 -3
@@ -2681,14 +2681,14 @@ void get_vmalloc_info(struct vmalloc_inf prev_end =VMALLOC_START ; -spin_lock (&vmap_area_lock); +rcu_read_lock ();if (list_empty (&vmap_area_list)) { vmi->largest_chunk =VMALLOC_TOTAL ; goto out; } -list_for_each_entry (va, &vmap_area_list, list) { +list_for_each_entry_rcu (va, &vmap_area_list, list) {unsigned long addr = va->va_start;/*
@@ -2715,7 +2715,7 @@ void get_vmalloc_info(struct vmalloc_inf vmi->largest_chunk =VMALLOC_END - prev_end; out: - spin_unlock(&vmap_area_lock); + rcu_read_unlock(); }#endif
Greg Kroah-Hartman
maintainerPATCH 69/77 memcg, vmscan: Fix forced scan of anonymous pages
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jerome Marchand <[email protected]>
commit 2ab051e11bfa3cbb7b24177f3d6aaed10a0d743e upstream.
When memory cgoups are enabled, the code that decides to force to scan anonymous pages in get_scan_count() compares global values (free, high_watermark) to a value that is restricted to a memory cgroup (file). It make the code over-eager to force anon scan.
For instance, it will force anon scan when scanning a memcg that is mainly populated by anonymous page, even when there is plenty of file pages to get rid of in others memcgs, even when swappiness == 0. It breaks user's expectation about swappiness and hurts performance.
This patch makes sure that forced anon scan only happens when there not enough file pages for the all zone, not just in one random memcg.
--- mm/vmscan.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-)
mm/vmscan.c +15 -8
@@ -1847,7 +1847,7 @@ static void get_scan_count(struct lruvecstruct zone *zone =lruvec_zone (lruvec);unsigned long anon_prio, file_prio;enum scan_balance scan_balance; -unsigned long anon, file, free; +unsigned long anon, file;bool force_scan = false;unsigned long ap, fp;enum lru_list lru;
@@ -1895,11 +1895,6 @@ static void get_scan_count(struct lruvec goto out; } - anon =get_lru_size (lruvec,LRU_ACTIVE_ANON ) + -get_lru_size (lruvec,LRU_INACTIVE_ANON ); - file =get_lru_size (lruvec,LRU_ACTIVE_FILE ) + -get_lru_size (lruvec,LRU_INACTIVE_FILE ); -/* * If it's foreseeable that reclaiming the file cache won't be * enough to get the zone back into a desirable shape, we have
@@ -1907,8 +1902,14 @@ static void get_scan_count(struct lruvec* thrashing - remaining file pages alone. */ if (global_reclaim (sc)) { - free =zone_page_state (zone,NR_FREE_PAGES ); -if (unlikely (file + free <=high_wmark_pages (zone))) { +unsigned long zonefile; +unsigned long zonefree; + + zonefree =zone_page_state (zone,NR_FREE_PAGES ); + zonefile =zone_page_state (zone,NR_ACTIVE_FILE ) + +zone_page_state (zone,NR_INACTIVE_FILE ); + +if (unlikely (zonefile + zonefree <=high_wmark_pages (zone))) { scan_balance =SCAN_ANON ; goto out; }
@@ -1943,6 +1944,12 @@ static void get_scan_count(struct lruvec* * anon in [0], file in [1] */ + + anon =get_lru_size (lruvec,LRU_ACTIVE_ANON ) + +get_lru_size (lruvec,LRU_INACTIVE_ANON ); + file =get_lru_size (lruvec,LRU_ACTIVE_FILE ) + +get_lru_size (lruvec,LRU_INACTIVE_FILE ); +spin_lock_irq (&zone->lru_lock);if (unlikely (reclaim_stat->recent_scanned[0 ] > anon /4 )) { reclaim_stat->recent_scanned[0 ] /=2 ;
Greg Kroah-Hartman
maintainerPATCH 70/77 mm: pagemap: avoid unnecessary overhead when tracepoints are deactivated
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mel Gorman <[email protected]>
commit 24b7e5819ad5cbef2b7c7376510862aa8319d240 upstream.
This was formerly the series "Improve sequential read throughput" which noted some major differences in performance of tiobench since 3.0. While there are a number of factors, two that dominated were the introduction of the fair zone allocation policy and changes to CFQ.
The behaviour of fair zone allocation policy makes more sense than tiobench as a benchmark and CFQ defaults were not changed due to insufficient benchmarking.
This series is what's left. It's one functional fix to the fair zone allocation policy when used on NUMA machines and a reduction of overhead in general. tiobench was used for the comparison despite its flaws as an IO benchmark as in this case we are primarily interested in the overhead of page allocator and page reclaim activity.
On UMA, it makes little difference to overhead
3.16.0-rc3 3.16.0-rc3
vanilla lowercost-v5
User 383.61 386.77
System 403.83 401.74Elapsed 5411.50 5413.11
On a 4-socket NUMA machine it's a bit more noticable
3.16.0-rc3 3.16.0-rc3
vanilla lowercost-v5
User 746.94 802.00
System 65336.22 40852.33
Elapsed 27553.52 27368.46This patch (of 6):
The LRU insertion and activate tracepoints take PFN as a parameter forcing the overhead to the caller. Move the overhead to the tracepoint fast-assign method to ensure the cost is only incurred when the tracepoint is active.
--- include/trace/events/pagemap.h | 16 +++++++--------- mm/swap.c | 4 ++-- 2 files changed, 9 insertions(+), 11 deletions(-)
include/trace/events/pagemap.h +7 -9
@@ -28,12 +28,10 @@ TRACE_EVENT(mm_lru_insertion,TP_PROTO ( struct page *page, - unsigned long pfn, - int lru, - unsigned long flags + int lru ), -TP_ARGS (page, pfn, lru, flags), +TP_ARGS (page, lru),TP_STRUCT__entry ( __field(struct page *, page )
@@ -44,9 +42,9 @@ TRACE_EVENT(mm_lru_insertion,TP_fast_assign ( __entry->page = page; - __entry->pfn = pfn; + __entry->pfn =page_to_pfn (page); __entry->lru = lru; - __entry->flags = flags; + __entry->flags =trace_pagemap_flags (page); ),/* Flag format is based on page-types.c formatting for pagemap */
@@ -64,9 +62,9 @@ TRACE_EVENT(mm_lru_insertion, TRACE_EVENT(mm_lru_activate, - TP_PROTO(struct page *page, unsigned long pfn), + TP_PROTO(struct page *page), - TP_ARGS(page, pfn), + TP_ARGS(page), TP_STRUCT__entry( __field(struct page *, page )
@@ -75,7 +73,7 @@ TRACE_EVENT(mm_lru_activate,TP_fast_assign ( __entry->page = page; - __entry->pfn = pfn; + __entry->pfn =page_to_pfn (page); ),/* Flag format is based on page-types.c formatting for pagemap */
mm/swap.c +2 -2
@@ -469,7 +469,7 @@ static void __activate_page(struct pageSetPageActive (page); lru +=LRU_ACTIVE ;add_page_to_lru_list (page, lruvec, lru); -trace_mm_lru_activate (page,page_to_pfn (page)); +trace_mm_lru_activate (page);__count_vm_event (PGACTIVATE );update_page_reclaim_stat (lruvec, file,1 );
@@ -962,7 +962,7 @@ static void __pagevec_lru_add_fn(structSetPageLRU (page);add_page_to_lru_list (page, lruvec, lru);update_page_reclaim_stat (lruvec, file, active); -trace_mm_lru_insertion (page,page_to_pfn (page), lru,trace_pagemap_flags (page)); +trace_mm_lru_insertion (page, lru); }/*
Greg Kroah-Hartman
maintainerPATCH 71/77 mm: rearrange zone fields into read-only, page alloc, statistics and page reclaim lines
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mel Gorman <[email protected]>
commit 3484b2de9499df23c4604a513b36f96326ae81ad upstream.
The arrangement of struct zone has changed over time and now it has reached the point where there is some inappropriate sharing going on. On x86-64 for example
o The zone->node field is shared with the zone lock and zone->node is accessed frequently from the page allocator due to the fair zone allocation policy.
o span_seqlock is almost never used by shares a line with free_area
o Some zone statistics share a cache line with the LRU lock so reclaim-intensive and allocator-intensive workloads can bounce the cache line on a stat update
This patch rearranges struct zone to put read-only and read-mostly fields together and then splits the page allocator intensive fields, the zone statistics and the page reclaim intensive fields into their own cache lines. Note that the type of lowmem_reserve changes due to the watermark calculations being signed and avoiding a signed/unsigned conversion there.
On the test configuration I used the overall size of struct zone shrunk by one cache line. On smaller machines, this is not likely to be noticable. However, on a 4-node NUMA machine running tiobench the system CPU overhead is reduced by this patch.
3.16.0-rc3 3.16.0-rc3
vanillarearrange-v5r9
User 746.94 759.78
System 65336.22 58350.98
Elapsed 27553.52 27282.02--- include/linux/mmzone.h | 205 +++++++++++++++++++++++++------------------------ mm/page_alloc.c | 7 - mm/vmstat.c | 4 3 files changed, 110 insertions(+), 106 deletions(-)
include/linux/mmzone.h +105 -100
@@ -321,19 +321,12 @@ enum zone_type { #ifndef __GENERATING_BOUNDS_H struct zone { - /* Fields commonly accessed by the page allocator */ + /* Read-mostly fields */ /* zone watermarks, access with *_wmark_pages(zone) macros */ unsigned long watermark[NR_WMARK]; /* - * When free pages are below this point, additional steps are taken - * when reading the number of free pages to avoid per-cpu counter - * drift allowing watermarks to be breached - */ - unsigned long percpu_drift_mark; - - /* * We don't know if the memory that we're going to allocate will be freeable * or/and it will be released eventually, so to avoid totally wasting several * GB of ram we must reserve some of the lower zone memory (otherwise we risk
@@ -341,41 +334,26 @@ struct zone {* on the higher zones). This array is recalculated at runtime if the * sysctl_lowmem_reserve_ratio sysctl changes. */ -unsigned long lowmem_reserve[MAX_NR_ZONES ]; - -/* -* This is a per-zone reserve of pages that should not be -* considered dirtyable memory. -*/ -unsigned long dirty_balance_reserve; +long lowmem_reserve[MAX_NR_ZONES ];#ifdef CONFIG_NUMA int node; +#endif +/* -* zone reclaim becomes active if more unmapped pages exist. +* The target ratio of ACTIVE_ANON to INACTIVE_ANON pages on +* this zone's LRU. Maintained by the pageout code. */ -unsigned long min_unmapped_pages; -unsigned long min_slab_pages; -#endif +unsigned int inactive_ratio; + +struct pglist_data *zone_pgdat;struct per_cpu_pageset __percpu *pageset; +/* -* free areas of different sizes +* This is a per-zone reserve of pages that should not be +* considered dirtyable memory. */ -spinlock_t lock; -#if definedCONFIG_COMPACTION || definedCONFIG_CMA -/* Set to true when the PG_migrate_skip bits should be cleared */ -bool compact_blockskip_flush; - -/* pfn where compaction free scanner should start */ -unsigned long compact_cached_free_pfn; -/* pfn where async and sync compaction migration scanner should start */ -unsigned long compact_cached_migrate_pfn[2 ]; -#endif -#ifdef CONFIG_MEMORY_HOTPLUG -/* see spanned/present_pages for more description */ -seqlock_t span_seqlock; -#endif -struct free_area free_area[MAX_ORDER ]; +unsigned long dirty_balance_reserve;#ifndef CONFIG_SPARSEMEM /*
@@ -385,71 +363,14 @@ struct zone {unsigned long *pageblock_flags;#endif /* CONFIG_SPARSEMEM */ -#ifdef CONFIG_COMPACTION -/* -* On compaction failure, 1<<compact_defer_shift compactions -* are skipped before trying again. The number attempted since -* last failure is tracked with compact_considered. -*/ -unsigned int compact_considered; -unsigned int compact_defer_shift; -int compact_order_failed; -#endif - -ZONE_PADDING (_pad1_) - -/* Fields commonly accessed by the page reclaim scanner */ - spinlock_t lru_lock; -struct lruvec lruvec; - -unsigned long pages_scanned;/* since last reclaim */ -unsigned long flags;/* zone flags, see below */ - -/* Zone statistics */ -atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS ]; - -/* -* The target ratio of ACTIVE_ANON to INACTIVE_ANON pages on -* this zone's LRU. Maintained by the pageout code. -*/ -unsigned int inactive_ratio; - - -ZONE_PADDING (_pad2_) -/* Rarely used or read-mostly fields */ - +#ifdef CONFIG_NUMA /* -* wait_table -- the array holding the hash table -* wait_table_hash_nr_entries -- the size of the hash table array -* wait_table_bits -- wait_table_size == (1 << wait_table_bits) -* -* The purpose of all these is to keep track of the people -* waiting for a page to become available and make them -* runnable again when possible. The trouble is that this -* consumes a lot of space, especially when so few things -* wait on pages at a given time. So instead of using -* per-page waitqueues, we use a waitqueue hash table. -* -* The bucket discipline is to sleep on the same queue when -* colliding and wake all in that wait queue when removing. -* When something wakes, it must check to be sure its page is -* truly available, a la thundering herd. The cost of a -* collision is great, but given the expected load of the -* table, they should be so rare as to be outweighed by the -* benefits from the saved space. -* -* __wait_on_page_locked() and unlock_page() in mm/filemap.c, are the -* primary users of these fields, and in mm/page_alloc.c -* free_area_init_core() performs the initialization of them. +* zone reclaim becomes active if more unmapped pages exist. */ - wait_queue_head_t * wait_table; -unsigned long wait_table_hash_nr_entries; -unsigned long wait_table_bits; +unsigned long min_unmapped_pages; +unsigned long min_slab_pages; +#endif /* CONFIG_NUMA */ -/* -* Discontig memory support fields. -*/ -struct pglist_data *zone_pgdat;/* zone_start_pfn == zone_start_paddr >> PAGE_SHIFT */ unsigned long zone_start_pfn;
@@ -495,9 +416,11 @@ struct zone {* adjust_managed_page_count() should be used instead of directly * touching zone->managed_pages and totalram_pages. */ +unsigned long managed_pages;unsigned long spanned_pages;unsigned long present_pages; -unsigned long managed_pages; + +const char *name;/* * Number of MIGRATE_RESEVE page block. To maintain for just
@@ -505,10 +428,92 @@ struct zone {*/ int nr_migrate_reserve_block; +#ifdef CONFIG_MEMORY_HOTPLUG +/* see spanned/present_pages for more description */ +seqlock_t span_seqlock; +#endif +/* -* rarely used fields: +* wait_table -- the array holding the hash table +* wait_table_hash_nr_entries -- the size of the hash table array +* wait_table_bits -- wait_table_size == (1 << wait_table_bits) +* +* The purpose of all these is to keep track of the people +* waiting for a page to become available and make them +* runnable again when possible. The trouble is that this +* consumes a lot of space, especially when so few things +* wait on pages at a given time. So instead of using +* per-page waitqueues, we use a waitqueue hash table. +* +* The bucket discipline is to sleep on the same queue when +* colliding and wake all in that wait queue when removing. +* When something wakes, it must check to be sure its page is +* truly available, a la thundering herd. The cost of a +* collision is great, but given the expected load of the +* table, they should be so rare as to be outweighed by the +* benefits from the saved space. +* +* __wait_on_page_locked() and unlock_page() in mm/filemap.c, are the +* primary users of these fields, and in mm/page_alloc.c +* free_area_init_core() performs the initialization of them. */ -const char *name; +wait_queue_head_t *wait_table; +unsigned long wait_table_hash_nr_entries; +unsigned long wait_table_bits; + +ZONE_PADDING (_pad1_) + +/* Write-intensive fields used from the page allocator */ + spinlock_t lock; + +/* free areas of different sizes */ +struct free_area free_area[MAX_ORDER ]; + +/* zone flags, see below */ +unsigned long flags; + +ZONE_PADDING (_pad2_) + +/* Write-intensive fields used by page reclaim */ + +/* Fields commonly accessed by the page reclaim scanner */ + spinlock_t lru_lock; +unsigned long pages_scanned;/* since last reclaim */ +struct lruvec lruvec; + +/* +* When free pages are below this point, additional steps are taken +* when reading the number of free pages to avoid per-cpu counter +* drift allowing watermarks to be breached +*/ +unsigned long percpu_drift_mark; + +#if definedCONFIG_COMPACTION || definedCONFIG_CMA +/* pfn where compaction free scanner should start */ +unsigned long compact_cached_free_pfn; +/* pfn where async and sync compaction migration scanner should start */ +unsigned long compact_cached_migrate_pfn[2 ]; +#endif + +#ifdef CONFIG_COMPACTION +/* +* On compaction failure, 1<<compact_defer_shift compactions +* are skipped before trying again. The number attempted since +* last failure is tracked with compact_considered. +*/ +unsigned int compact_considered; +unsigned int compact_defer_shift; +int compact_order_failed; +#endif + +#if definedCONFIG_COMPACTION || definedCONFIG_CMA +/* Set to true when the PG_migrate_skip bits should be cleared */ +bool compact_blockskip_flush; +#endif + +ZONE_PADDING (_pad3_) +/* Zone statistics */ + atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS]; }____cacheline_internodealigned_in_smp ; typedef enum {
mm/page_alloc.c +3 -4
@@ -1710,7 +1710,6 @@ static bool __zone_watermark_ok(struct z {/* free_pages my go negative - that's OK */ long min = mark; -long lowmem_reserve = z->lowmem_reserve[classzone_idx];int o;long free_cma =0 ;
@@ -1725,7 +1724,7 @@ static bool __zone_watermark_ok(struct z free_cma =zone_page_state (z,NR_FREE_CMA_PAGES );#endif -if (free_pages - free_cma <= min + lowmem_reserve) +if (free_pages - free_cma <= min + z->lowmem_reserve[classzone_idx])return false;for (o =0 ; o < order; o++) {/* At the next order, this order's pages become unavailable */
@@ -3257,7 +3256,7 @@ void show_free_areas(unsigned int filter );printk ("lowmem_reserve[]:" );for (i =0 ; i <MAX_NR_ZONES ; i++) -printk (" %lu" , zone->lowmem_reserve[i]); +printk (" %ld" , zone->lowmem_reserve[i]);printk ("\n" ); }
@@ -5585,7 +5584,7 @@ static void calculate_totalreserve_pagesfor_each_online_pgdat (pgdat) {for (i =0 ; i <MAX_NR_ZONES ; i++) {struct zone *zone = pgdat->node_zones + i; -unsigned long max =0 ; +long max =0 ;/* Find valid and maximum lowmem_reserve in the zone */ for (j = i; j <MAX_NR_ZONES ; j++) {
mm/vmstat.c +2 -2
@@ -1065,10 +1065,10 @@ static void zoneinfo_show_print(struct s zone_page_state(zone, i));seq_printf (m, -"\n protection: (%lu" , +"\n protection: (%ld" , zone->lowmem_reserve[0 ]);for (i =1 ; i <ARRAY_SIZE (zone->lowmem_reserve); i++) -seq_printf (m,", %lu" , zone->lowmem_reserve[i]); +seq_printf (m,", %ld" , zone->lowmem_reserve[i]);seq_printf (m,")" "\n pagesets" );
Greg Kroah-Hartman
maintainerPATCH 72/77 mm: move zone->pages_scanned into a vmstat counter
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mel Gorman <[email protected]>
commit 0d5d823ab4e608ec7b52ac4410de4cb74bbe0edd upstream.
zone->pages_scanned is a write-intensive cache line during page reclaim and it's also updated during page free. Move the counter into vmstat to take advantage of the per-cpu updates and do not update it in the free paths unless necessary.
On a small UMA machine running tiobench the difference is marginal. On a 4-node machine the overhead is more noticable. Note that automatic NUMA balancing was disabled for this test as otherwise the system CPU overhead is unpredictable.
3.16.0-rc3 3.16.0-rc3 3.16.0-rc3
vanillarearrange-v5 vmstat-v5
User 746.94 759.78 774.56
System 65336.22 58350.98 32847.27
Elapsed 27553.52 27282.02 27415.04Note that the overhead reduction will vary depending on where exactly pages are allocated and freed.
--- include/linux/mmzone.h | 2 +- mm/page_alloc.c | 12 +++++++++--- mm/vmscan.c | 7 ++++--- mm/vmstat.c | 3 ++- 4 files changed, 16 insertions(+), 8 deletions(-)
include/linux/mmzone.h +1 -1
@@ -143,6 +143,7 @@ enum zone_stat_item {NR_SHMEM ,/* shmem pages (included tmpfs/GEM pages) */ NR_DIRTIED ,/* page dirtyings since bootup */ NR_WRITTEN ,/* page writings since bootup */ +NR_PAGES_SCANNED ,/* pages scanned since last reclaim */ #ifdef CONFIG_NUMANUMA_HIT ,/* allocated in intended node */ NUMA_MISS, /* allocated in non intended node */
@@ -478,7 +479,6 @@ struct zone {/* Fields commonly accessed by the page reclaim scanner */ spinlock_t lru_lock; -unsigned long pages_scanned;/* since last reclaim */ struct lruvec lruvec;/*
mm/page_alloc.c +9 -3
@@ -678,9 +678,12 @@ static void free_pcppages_bulk(struct zoint migratetype =0 ;int batch_free =0 ;int to_free = count; +unsigned long nr_scanned;spin_lock (&zone->lock); - zone->pages_scanned =0 ; + nr_scanned =zone_page_state (zone,NR_PAGES_SCANNED ); +if (nr_scanned) +__mod_zone_page_state (zone,NR_PAGES_SCANNED , -nr_scanned);while (to_free) {struct page *page;
@@ -729,8 +732,11 @@ static void free_one_page(struct zone *z unsigned int order, int migratetype) { +unsigned long nr_scanned;spin_lock (&zone->lock); - zone->pages_scanned =0 ; + nr_scanned =zone_page_state (zone,NR_PAGES_SCANNED ); +if (nr_scanned) +__mod_zone_page_state (zone,NR_PAGES_SCANNED , -nr_scanned);__free_one_page (page, pfn, zone, order, migratetype);if (unlikely (!is_migrate_isolate (migratetype)))
@@ -3251,7 +3257,7 @@ void show_free_areas(unsigned int filterK (zone_page_state (zone,NR_BOUNCE )),K (zone_page_state (zone,NR_FREE_CMA_PAGES )),K (zone_page_state (zone,NR_WRITEBACK_TEMP )), - zone->pages_scanned, +K (zone_page_state (zone,NR_PAGES_SCANNED )), (!zone_reclaimable (zone) ?"yes" :"no" ) );printk ("lowmem_reserve[]:" );
mm/vmscan.c +4 -3
@@ -163,7 +163,8 @@ static unsigned long zone_reclaimable_pabool zone_reclaimable (struct zone *zone) { -return zone->pages_scanned <zone_reclaimable_pages (zone) *6 ; +return zone_page_state (zone,NR_PAGES_SCANNED ) < +zone_reclaimable_pages (zone) *6 ; }static unsigned long get_lru_size (struct lruvec *lruvec,enum lru_list lru)
@@ -1470,7 +1471,7 @@ shrink_inactive_list(unsigned long nr_to__mod_zone_page_state (zone,NR_ISOLATED_ANON + file, nr_taken);if (global_reclaim (sc)) { - zone->pages_scanned += nr_scanned; +__mod_zone_page_state (zone,NR_PAGES_SCANNED , nr_scanned);if (current_is_kswapd ())__count_zone_vm_events (PGSCAN_KSWAPD , zone, nr_scanned);else
@@ -1659,7 +1660,7 @@ static void shrink_active_list(unsigned nr_taken =isolate_lru_pages (nr_to_scan, lruvec, &l_hold, &nr_scanned, sc, isolate_mode, lru);if (global_reclaim (sc)) - zone->pages_scanned += nr_scanned; +__mod_zone_page_state (zone,NR_PAGES_SCANNED , nr_scanned); reclaim_stat->recent_scanned[file] += nr_taken;
mm/vmstat.c +2 -1
@@ -761,6 +761,7 @@ const char * const vmstat_text[] = {"nr_shmem" ,"nr_dirtied" ,"nr_written" , +"nr_pages_scanned" , #ifdef CONFIG_NUMA "numa_hit",
@@ -1055,7 +1056,7 @@ static void zoneinfo_show_print(struct smin_wmark_pages (zone),low_wmark_pages (zone),high_wmark_pages (zone), - zone->pages_scanned, +zone_page_state (zone,NR_PAGES_SCANNED ), zone->spanned_pages, zone->present_pages, zone->managed_pages);
Greg Kroah-Hartman
maintainerPATCH 73/77 mm: vmscan: only update per-cpu thresholds for online CPU
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mel Gorman <[email protected]>
commit bb0b6dffa2ccfbd9747ad0cc87c7459622896e60 upstream.
When kswapd is awake reclaiming, the per-cpu stat thresholds are lowered to get more accurate counts to avoid breaching watermarks. This threshold update iterates over all possible CPUs which is unnecessary. Only online CPUs need to be updated. If a new CPU is onlined, refresh_zone_stat_thresholds() will set the thresholds correctly.
--- mm/vmstat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/vmstat.c +1 -1
@@ -200,7 +200,7 @@ void set_pgdat_percpu_threshold(pg_data_continue ; threshold = (*calculate_pressure)(zone); -for_each_possible_cpu (cpu) +for_each_online_cpu (cpu)per_cpu_ptr (zone->pageset, cpu)->stat_threshold = threshold; }
Greg Kroah-Hartman
maintainerPATCH 74/77 mm: page_alloc: abort fair zone allocation policy when remotes nodes are encountered
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mel Gorman <[email protected]>
commit f7b5d647946aae1647bf5cd26c16b3a793c1ac49 upstream.
The purpose of numa_zonelist_order=zone is to preserve lower zones for use with 32-bit devices. If locality is preferred then the numa_zonelist_order=node policy should be used.
Unfortunately, the fair zone allocation policy overrides this by skipping zones on remote nodes until the lower one is found. While this makes sense from a page aging and performance perspective, it breaks the expected zonelist policy. This patch restores the expected behaviour for zone-list ordering.
--- mm/page_alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/page_alloc.c +1 -1
@@ -1980,7 +1980,7 @@ zonelist_scan:*/ if (alloc_flags &ALLOC_FAIR ) {if (!zone_local (preferred_zone, zone)) -continue ; +break ;if (atomic_long_read (&zone->vm_stat[NR_ALLOC_BATCH ]) <=0 )continue ; }
Greg Kroah-Hartman
maintainerPATCH 75/77 mm: page_alloc: reduce cost of the fair zone allocation policy
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mel Gorman <[email protected]>
commit 4ffeaf3560a52b4a69cc7909873d08c0ef5909d4 upstream.
The fair zone allocation policy round-robins allocations between zones within a node to avoid age inversion problems during reclaim. If the first allocation fails, the batch counts are reset and a second attempt made before entering the slow path.
One assumption made with this scheme is that batches expire at roughly the same time and the resets each time are justified. This assumption does not hold when zones reach their low watermark as the batches will be consumed at uneven rates. Allocation failure due to watermark depletion result in additional zonelist scans for the reset and another watermark check before hitting the slowpath.
On UMA, the benefit is negligible -- around 0.25%. On 4-socket NUMA machine it's variable due to the variability of measuring overhead with the vmstat changes. The system CPU overhead comparison looks like
3.16.0-rc3 3.16.0-rc3 3.16.0-rc3
vanilla vmstat-v5 lowercost-v5
User 746.94 774.56 802.00
System 65336.22 32847.27 40852.33 Elapsed 27553.52 27415.04 27368.46
However it is worth noting that the overall benchmark still completed faster and intuitively it makes sense to take as few passes as possible through the zonelists.
--- include/linux/mmzone.h | 6 ++ mm/page_alloc.c | 101 +++++++++++++++++++++++++------------------------ 2 files changed, 59 insertions(+), 48 deletions(-)
include/linux/mmzone.h +6 -0
@@ -529,6 +529,7 @@ typedef enum {ZONE_WRITEBACK ,/* reclaim scanning has recently found * many pages under writeback */ +ZONE_FAIR_DEPLETED ,/* fair zone policy batch depleted */ } zone_flags_t;static inline void zone_set_flag (struct zone *zone,zone_flags_t flag)
@@ -566,6 +567,11 @@ static inline int zone_is_reclaim_lockedreturn test_bit (ZONE_RECLAIM_LOCKED , &zone->flags); } +static inline int zone_is_fair_depleted (const struct zone *zone) +{ +return test_bit (ZONE_FAIR_DEPLETED , &zone->flags); +} +static inline int zone_is_oom_locked (const struct zone *zone) {return test_bit (ZONE_OOM_LOCKED , &zone->flags);
mm/page_alloc.c +53 -48
159 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 76/77 mm: get rid of radix tree gfp mask for pagecache_get_page
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Hocko <[email protected]>
commit 45f87de57f8fad59302fd263dd81ffa4843b5b24 upstream.
Commit 2457aec63745 ("mm: non-atomically mark page accessed during page cache allocation where possible") has added a separate parameter for specifying gfp mask for radix tree allocations.
Not only this is less than optimal from the API point of view because it is error prone, it is also buggy currently because grab_cache_page_write_begin is using GFP_KERNEL for radix tree and if fgp_flags doesn't contain FGP_NOFS (mostly controlled by fs by AOP_FLAG_NOFS flag) but the mapping_gfp_mask has __GFP_FS cleared then the radix tree allocation wouldn't obey the restriction and might recurse into filesystem and cause deadlocks. This is the case for most filesystems unfortunately because only ext4 and gfs2 are using AOP_FLAG_NOFS.
Let's simply remove radix_gfp_mask parameter because the allocation context is same for both page cache and for the radix tree. Just make sure that the radix tree gets only the sane subset of the mask (e.g. do not pass __GFP_WRITE).
Long term it is more preferable to convert remaining users of AOP_FLAG_NOFS to use mapping_gfp_mask instead and simplify this interface even further.
--- include/linux/pagemap.h | 13 ++++++------- mm/filemap.c | 20 +++++++++----------- 2 files changed, 15 insertions(+), 18 deletions(-)
include/linux/pagemap.h +6 -7
@@ -256,7 +256,7 @@ pgoff_t page_cache_prev_hole(struct addr#define FGP_NOWAIT 0x00000020struct page *pagecache_get_page (struct address_space *mapping,pgoff_t offset, -int fgp_flags,gfp_t cache_gfp_mask,gfp_t radix_gfp_mask); +int fgp_flags,gfp_t cache_gfp_mask);/** * find_get_page - find and get a page reference
@@ -271,13 +271,13 @@ struct page *pagecache_get_page(struct astatic inline struct page *find_get_page (struct address_space *mapping,pgoff_t offset) { -return pagecache_get_page (mapping, offset,0 ,0 ,0 ); +return pagecache_get_page (mapping, offset,0 ,0 ); }static inline struct page *find_get_page_flags (struct address_space *mapping,pgoff_t offset,int fgp_flags) { -return pagecache_get_page (mapping, offset, fgp_flags,0 ,0 ); +return pagecache_get_page (mapping, offset, fgp_flags,0 ); }/**
@@ -297,7 +297,7 @@ static inline struct page *find_get_pagestatic inline struct page *find_lock_page (struct address_space *mapping,pgoff_t offset) { -return pagecache_get_page (mapping, offset,FGP_LOCK ,0 ,0 ); +return pagecache_get_page (mapping, offset,FGP_LOCK ,0 ); }/**
@@ -324,7 +324,7 @@ static inline struct page *find_or_creat {return pagecache_get_page (mapping, offset,FGP_LOCK |FGP_ACCESSED |FGP_CREAT , - gfp_mask, gfp_mask &GFP_RECLAIM_MASK ); + gfp_mask); }/**
@@ -345,8 +345,7 @@ static inline struct page *grab_cache_pa {return pagecache_get_page (mapping, index,FGP_LOCK |FGP_CREAT |FGP_NOFS |FGP_NOWAIT , -mapping_gfp_mask (mapping), -GFP_NOFS ); +mapping_gfp_mask (mapping)); }struct page *find_get_entry (struct address_space *mapping,pgoff_t offset);
mm/filemap.c +9 -11
@@ -897,7 +897,7 @@ EXPORT_SYMBOL(find_lock_entry);* @mapping: the address_space to search * @offset: the page index * @fgp_flags: PCG flags -* @gfp_mask: gfp mask to use if a page is to be allocated +* @gfp_mask: gfp mask to use for the page cache data page allocation * * Looks up the page cache slot at @mapping & @offset. *
@@ -916,7 +916,7 @@ EXPORT_SYMBOL(find_lock_entry);* If there is a page cache page, it is returned with an increased refcount. */ struct page *pagecache_get_page (struct address_space *mapping,pgoff_t offset, -int fgp_flags,gfp_t cache_gfp_mask,gfp_t radix_gfp_mask) +int fgp_flags,gfp_t gfp_mask) {struct page *page;
@@ -953,13 +953,11 @@ no_page:if (!page && (fgp_flags &FGP_CREAT )) {int err;if ((fgp_flags &FGP_WRITE ) &&mapping_cap_account_dirty (mapping)) - cache_gfp_mask |= __GFP_WRITE; -if (fgp_flags &FGP_NOFS ) { - cache_gfp_mask &= ~__GFP_FS; - radix_gfp_mask &= ~__GFP_FS; - } + gfp_mask |= __GFP_WRITE; +if (fgp_flags &FGP_NOFS ) + gfp_mask &= ~__GFP_FS; - page =__page_cache_alloc (cache_gfp_mask); + page =__page_cache_alloc (gfp_mask);if (!page)return NULL ;
@@ -970,7 +968,8 @@ no_page:if (fgp_flags &FGP_ACCESSED )init_page_accessed (page); - err =add_to_page_cache_lru (page, mapping, offset, radix_gfp_mask); + err =add_to_page_cache_lru (page, mapping, offset, + gfp_mask &GFP_RECLAIM_MASK );if (unlikely (err)) {page_cache_release (page); page =NULL ;
@@ -2460,8 +2459,7 @@ struct page *grab_cache_page_write_begin fgp_flags |=FGP_NOFS ; page =pagecache_get_page (mapping, index, fgp_flags, -mapping_gfp_mask (mapping), -GFP_KERNEL ); +mapping_gfp_mask (mapping));if (page)wait_for_stable_page (page);
Greg Kroah-Hartman
maintainerPATCH 77/77 md/raid5: fetch_block must fetch all the blocks handle_stripe_dirtying wants.
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: NeilBrown <[email protected]>
commit 108cef3aa41669610e1836fe638812dd067d72de upstream.
It is critical that fetch_block() and handle_stripe_dirtying() are consistent in their analysis of what needs to be loaded. Otherwise raid5 can wait forever for a block that won't be loaded.
Currently when writing to a RAID5 that is resyncing, to a location beyond the resync offset, handle_stripe_dirtying chooses a reconstruct-write cycle, but fetch_block() assumes a read-modify-write, and a lockup can happen.
So treat that case just like RAID6, just as we do in handle_stripe_dirtying. RAID6 always does reconstruct-write.
This bug was introduced when the behaviour of handle_stripe_dirtying was changed in 3.7, so the patch is suitable for any kernel since, though it will need careful merging for some versions.
--- drivers/md/raid5.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/md/raid5.c +2 -1
@@ -2896,7 +2896,8 @@ static int fetch_block(struct stripe_hea (s->failed >=2 && fdev[1 ]->toread) || (sh->raid_conf->level <=5 && s->failed && fdev[0 ]->towrite && !test_bit (R5_OVERWRITE , &fdev[0 ]->flags)) || - (sh->raid_conf->level == 6 && s->failed && s->to_write))) { + ((sh->raid_conf->level ==6 || sh->sector >= sh->raid_conf->mddev->recovery_cp) + && s->failed && s->to_write))) {/* we would like to get this block, possibly by computing it, * otherwise read it if the backing disk is insync */
Re: [PATCH 3.14 26/77] KVM: x86: Fix of previously incomplete fix for CVE-2014-8480
In reply to Greg Kroah-HartmanThis CVE only affect 3.17 and 3.18. It shouldn’t hurt, but you can omit this patch from 3.14.
Regards,
Nadav
Quoted 32 lines · Greg Kroah-Hartman
3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nadav Amit <[email protected]>
commit
63ea0a49ae0b145b91ff2b070c01b66fc75854b9upstream.STR and SLDT with rip-relative operand can cause a host kernel oops. Mark them as DstMem as well.
Signed-off-by Nadav Amit <[email protected]>Signed-off-by Paolo Bonzini <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>---
arch/x86/kvm/emulate.c| 4 ++--1 file changed, 2 insertions(+), 2 deletions(-)arch/x86/kvm/emulate.c +2
-2@@ -3668,8 +3668,8 @@ static const struct opcode group5[] = { };static const struct opcode group6[] = { -DI (Prot, sldt), -DI (Prot, str), +DI (Prot | DstMem, sldt), +DI (Prot | DstMem, str),II (Prot | Priv | SrcMem16, em_lldt, lldt),II (Prot | Priv | SrcMem16, em_ltr, ltr),N ,N ,N ,N ,
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 3.14.31 release. There are 77 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 Jan 30 01:27:34 UTC 2015. Anything received after that time might be too late.
Build results:
total: 137 pass: 137 fail: 0 Qemu tests: total: 30 pass: 30 fail: 0
Details are available at http://server.roeck-us.net:8010/builders.
Guenter
Re: [PATCH 3.14 02/77] gpio: sysfs: fix gpio device-attribute leak
In reply to Greg Kroah-HartmanQuoted 102 lines · Greg Kroah-Hartman
3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit
0915e6feb38de8d3601819992a5bd050201a56faupstream.The gpio device attributes were never destroyed when the gpio was unexported (or on export failures).
Use
device_create_with_groups()to create the default device attributes of the gpio class device. Note that this also fixes the attribute-creation race with userspace for these attributes.Remove contingent attributes in export error path and on unexport.
Fixes d8f388d8dc8d ("gpio: sysfs interface")Signed-off-by Johan Hovold <[email protected]>Signed-off-by Linus Walleij <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- drivers/gpio/gpiolib.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-)drivers/gpio/gpiolib.c +11
-14@@ -408,7 +408,7 @@ static ssize_t gpio_value_store(struct dreturn status; } -static const DEVICE_ATTR(value, 0644, +static DEVICE_ATTR(value, 0644, gpio_value_show, gpio_value_store);static irqreturn_t gpio_sysfs_irq (int irq,void *priv)@@ -633,18 +633,16 @@ static ssize_t gpio_active_low_store(strreturn status ? : size; } -static const DEVICE_ATTR(active_low, 0644, +static DEVICE_ATTR(active_low, 0644, gpio_active_low_show, gpio_active_low_store); -static const struct attribute *gpio_attrs[] = { +static struct attribute *gpio_attrs[] = { &dev_attr_value.attr, &dev_attr_active_low.attr,NULL , }; -static const struct attribute_group gpio_attr_group = { - .attrs = (struct attribute **) gpio_attrs, -}; +ATTRIBUTE_GROUPS (gpio);/* * /sys/class/gpio/gpiochipN/ @@ -841,18 +839,15 @@ int gpiod_export(struct gpio_desc *desc,if (desc->chip->names && desc->chip->names[offset]) ioname = desc->chip->names[offset]; - dev =device_create (&gpio_class, desc->chip->dev,MKDEV (0 ,0 ), - desc, ioname ? ioname :"gpio%u" , -desc_to_gpio (desc)); + dev =device_create_with_groups (&gpio_class, desc->chip->dev, +MKDEV (0 ,0 ), desc, gpio_groups, + ioname ? ioname :"gpio%u" , +desc_to_gpio (desc));if (IS_ERR (dev)) { status =PTR_ERR (dev); goto fail_unlock; } - status =sysfs_create_group (&dev->kobj, &gpio_attr_group); -if (status) - goto fail_unregister_device; -if (direction_may_change) { status =device_create_file (dev, &dev_attr_direction);if (status)@@ -863,13 +858,15 @@ int gpiod_export(struct gpio_desc *desc, !test_bit(FLAG_IS_OUT, &desc->flags))) { status =device_create_file (dev, &dev_attr_edge);if (status) - goto fail_unregister_device; + goto fail_remove_attr_direction; }set_bit (FLAG_EXPORT , &desc->flags);mutex_unlock (&sysfs_lock);return 0 ; +fail_remove_attr_direction: +device_remove_file (dev, &dev_attr_direction); fail_unregister_device:device_unregister (dev); fail_unlock:
drivers/gpio/gpiolib.c void gpiod_unexport(struct gpio_desc *de · line 998
Quoted 8 lines
drivers/gpio/gpiolib.c +2
-0@@ -994,6 +991,8 @@ void gpiod_unexport(struct gpio_desc *de dev =class_find_device (&gpio_class,NULL , desc, match_export);if (dev) { +device_remove_file (dev, &dev_attr_edge); +device_remove_file (dev, &dev_attr_direction);gpio_setup_irq (desc, dev,0 );clear_bit (FLAG_EXPORT , &desc->flags); }else
I believe there's a mistake in this backport: the changes to the gpiod_unexport() function are being applied to the wrong code block; they should be in:
if (dev) {
device_unregister(dev);
put_device(dev);
}The backport to the 3.10 kernel have the same problem.
Cheers,
--
Lu�s
Quoted 5 lines
--
To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3.14 02/77] gpio: sysfs: fix gpio device-attribute leak
Quoted 17 lines · Luis Henriques
drivers/gpio/gpiolib.c void gpiod_unexport(struct gpio_desc *de · line 998
Quoted 10 lines · Greg Kroah-Hartman
drivers/gpio/gpiolib.c +2
-0@@ -994,6 +991,8 @@ void gpiod_unexport(struct gpio_desc *de dev =class_find_device (&gpio_class,NULL , desc, match_export);if (dev) { +device_remove_file (dev, &dev_attr_edge); +device_remove_file (dev, &dev_attr_direction);gpio_setup_irq (desc, dev,0 );clear_bit (FLAG_EXPORT , &desc->flags); }else I believe there's a mistake in this backport: the changes to the
gpiod_unexport()function are being applied to the wrong code block; they should be in:
Quoted 6 lines
if (dev) { device_unregister(dev); put_device(dev); }The backport to the 3.10 kernel have the same problem.
You're right, thanks for catching this.
I'll send a v2.
Johan
PATCH v2 1/1 gpio: sysfs: fix gpio device-attribute leak
commit 0915e6feb38de8d3601819992a5bd050201a56fa upstream.
The gpio device attributes were never destroyed when the gpio was unexported (or on export failures).
Use device_create_with_groups() to create the default device attributes of the gpio class device. Note that this also fixes the attribute-creation race with userspace for these attributes.
Remove contingent attributes in export error path and on unexport.
---
Backport to v3.12 (and 3.14).
Changes since v1
- fix mistake in backport, which removed the attributes while holding the mutex in gpiod_unexport (reported by Luis Henriques)
drivers/gpio/gpiolib.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-)
drivers/gpio/gpiolib.c +13 -14
@@ -362,7 +362,7 @@ static ssize_t gpio_value_store(struct device *dev,return status; } -static const DEVICE_ATTR(value, 0644, +static DEVICE_ATTR(value, 0644, gpio_value_show, gpio_value_store);static irqreturn_t gpio_sysfs_irq (int irq,void *priv)
@@ -580,18 +580,16 @@ static ssize_t gpio_active_low_store(struct device *dev,return status ? : size; } -static const DEVICE_ATTR(active_low, 0644, +static DEVICE_ATTR(active_low, 0644, gpio_active_low_show, gpio_active_low_store); -static const struct attribute *gpio_attrs[] = { +static struct attribute *gpio_attrs[] = { &dev_attr_value.attr, &dev_attr_active_low.attr,NULL , }; -static const struct attribute_group gpio_attr_group = { - .attrs = (struct attribute **) gpio_attrs, -}; +ATTRIBUTE_GROUPS (gpio);/* * /sys/class/gpio/gpiochipN/
@@ -788,18 +786,15 @@ static int gpiod_export(struct gpio_desc *desc, bool direction_may_change)if (desc->chip->names && desc->chip->names[offset]) ioname = desc->chip->names[offset]; - dev =device_create (&gpio_class, desc->chip->dev,MKDEV (0 ,0 ), - desc, ioname ? ioname :"gpio%u" , -desc_to_gpio (desc)); + dev =device_create_with_groups (&gpio_class, desc->chip->dev, +MKDEV (0 ,0 ), desc, gpio_groups, + ioname ? ioname :"gpio%u" , +desc_to_gpio (desc));if (IS_ERR (dev)) { status =PTR_ERR (dev); goto fail_unlock; } - status =sysfs_create_group (&dev->kobj, &gpio_attr_group); -if (status) - goto fail_unregister_device; -if (direction_may_change) { status =device_create_file (dev, &dev_attr_direction);if (status)
@@ -810,13 +805,15 @@ static int gpiod_export(struct gpio_desc *desc, bool direction_may_change) !test_bit(FLAG_IS_OUT, &desc->flags))) { status =device_create_file (dev, &dev_attr_edge);if (status) - goto fail_unregister_device; + goto fail_remove_attr_direction; }set_bit (FLAG_EXPORT , &desc->flags);mutex_unlock (&sysfs_lock);return 0 ; +fail_remove_attr_direction: +device_remove_file (dev, &dev_attr_direction); fail_unregister_device:device_unregister (dev); fail_unlock:
@@ -968,6 +965,8 @@ static void gpiod_unexport(struct gpio_desc *desc)mutex_unlock (&sysfs_lock);if (dev) { +device_remove_file (dev, &dev_attr_edge); +device_remove_file (dev, &dev_attr_direction);device_unregister (dev);put_device (dev); }
Signature · 1 line
2.0.5
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 3.14.31 release. There are 77 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 Jan 30 01:27:34 UTC 2015. Anything received after that time might be too late.
Quoted 8 lines
The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v3.0/stable-review/patch-3.14.31-rc1.gzand the diffstat can be found below.
thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Signature · 5 lines
Shuah Khan Sr. Linux Kernel Developer Open Source Innovation Group Samsung Research America (Silicon Valley) [email protected] | (970) 217-8978
Greg Kroah-Hartman
maintainerRe: [PATCH v2] gpio: sysfs: fix gpio device-attribute leak
In reply to Johan HovoldQuoted 15 lines · Johan Hovold
commit
0915e6feb38de8d3601819992a5bd050201a56faupstream.The gpio device attributes were never destroyed when the gpio was unexported (or on export failures).
Use
device_create_with_groups()to create the default device attributes of the gpio class device. Note that this also fixes the attribute-creation race with userspace for these attributes.Remove contingent attributes in export error path and on unexport.
Fixes d8f388d8dc8d ("gpio: sysfs interface")Cc stable <[email protected]> # v2.6.27+Signed-off-by Johan Hovold <[email protected]>Signed-off-by Linus Walleij <[email protected]>
Quoted 7 lines
---
Backport to v3.12 (and 3.14).
Changes since v1
- fix mistake in backport, which removed the attributes while holding the mutex ingpiod_unexport(reported by Luis Henriques)
Thanks, now applied.
greg k-h