diff options
author | Mike Pagano <mpagano@gentoo.org> | 2015-10-27 09:38:22 -0400 |
---|---|---|
committer | Mike Pagano <mpagano@gentoo.org> | 2015-10-27 09:38:22 -0400 |
commit | 9cd6b37a67e6a9299fd28e066e9c675aceb16110 (patch) | |
tree | 984ad1bb6d90ec85a4c7bae6d713fc90e1e74d79 | |
parent | Linux patch 3.14.55 (diff) | |
download | linux-patches-9cd6b37a67e6a9299fd28e066e9c675aceb16110.tar.gz linux-patches-9cd6b37a67e6a9299fd28e066e9c675aceb16110.tar.bz2 linux-patches-9cd6b37a67e6a9299fd28e066e9c675aceb16110.zip |
Linux patch 3.14.563.14-62
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1055_linux-3.14.56.patch | 782 |
2 files changed, 786 insertions, 0 deletions
diff --git a/0000_README b/0000_README index a1429953..1326707f 100644 --- a/0000_README +++ b/0000_README @@ -262,6 +262,10 @@ Patch: 1054_linux-3.14.55.patch From: http://www.kernel.org Desc: Linux 3.14.55 +Patch: 1055_linux-3.14.56.patch +From: http://www.kernel.org +Desc: Linux 3.14.56 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1055_linux-3.14.56.patch b/1055_linux-3.14.56.patch new file mode 100644 index 00000000..83b202c4 --- /dev/null +++ b/1055_linux-3.14.56.patch @@ -0,0 +1,782 @@ +diff --git a/Makefile b/Makefile +index 97d18c1d27f2..2a13d9d63880 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 14 +-SUBLEVEL = 55 ++SUBLEVEL = 56 + EXTRAVERSION = + NAME = Remembering Coco + +diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile +index 0ab1a34dab58..dcc26850727d 100644 +--- a/arch/arm64/Makefile ++++ b/arch/arm64/Makefile +@@ -35,7 +35,7 @@ comma = , + CHECKFLAGS += -D__aarch64__ + + ifeq ($(CONFIG_ARM64_ERRATUM_843419), y) +-CFLAGS_MODULE += -mcmodel=large ++KBUILD_CFLAGS_MODULE += -mcmodel=large + endif + + # Default value +diff --git a/arch/sparc/crypto/aes_glue.c b/arch/sparc/crypto/aes_glue.c +index ded4cee35318..dc78cdd43e0a 100644 +--- a/arch/sparc/crypto/aes_glue.c ++++ b/arch/sparc/crypto/aes_glue.c +@@ -433,6 +433,7 @@ static struct crypto_alg algs[] = { { + .blkcipher = { + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, ++ .ivsize = AES_BLOCK_SIZE, + .setkey = aes_set_key, + .encrypt = cbc_encrypt, + .decrypt = cbc_decrypt, +@@ -452,6 +453,7 @@ static struct crypto_alg algs[] = { { + .blkcipher = { + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, ++ .ivsize = AES_BLOCK_SIZE, + .setkey = aes_set_key, + .encrypt = ctr_crypt, + .decrypt = ctr_crypt, +diff --git a/arch/sparc/crypto/camellia_glue.c b/arch/sparc/crypto/camellia_glue.c +index 641f55cb61c3..eb87d6dd86b1 100644 +--- a/arch/sparc/crypto/camellia_glue.c ++++ b/arch/sparc/crypto/camellia_glue.c +@@ -274,6 +274,7 @@ static struct crypto_alg algs[] = { { + .blkcipher = { + .min_keysize = CAMELLIA_MIN_KEY_SIZE, + .max_keysize = CAMELLIA_MAX_KEY_SIZE, ++ .ivsize = CAMELLIA_BLOCK_SIZE, + .setkey = camellia_set_key, + .encrypt = cbc_encrypt, + .decrypt = cbc_decrypt, +diff --git a/arch/sparc/crypto/des_glue.c b/arch/sparc/crypto/des_glue.c +index d11500972994..1359bfc544e4 100644 +--- a/arch/sparc/crypto/des_glue.c ++++ b/arch/sparc/crypto/des_glue.c +@@ -429,6 +429,7 @@ static struct crypto_alg algs[] = { { + .blkcipher = { + .min_keysize = DES_KEY_SIZE, + .max_keysize = DES_KEY_SIZE, ++ .ivsize = DES_BLOCK_SIZE, + .setkey = des_set_key, + .encrypt = cbc_encrypt, + .decrypt = cbc_decrypt, +@@ -485,6 +486,7 @@ static struct crypto_alg algs[] = { { + .blkcipher = { + .min_keysize = DES3_EDE_KEY_SIZE, + .max_keysize = DES3_EDE_KEY_SIZE, ++ .ivsize = DES3_EDE_BLOCK_SIZE, + .setkey = des3_ede_set_key, + .encrypt = cbc3_encrypt, + .decrypt = cbc3_decrypt, +diff --git a/arch/x86/include/asm/preempt.h b/arch/x86/include/asm/preempt.h +index b39e194f6c8d..999b4a3e65f5 100644 +--- a/arch/x86/include/asm/preempt.h ++++ b/arch/x86/include/asm/preempt.h +@@ -105,9 +105,9 @@ static __always_inline bool __preempt_count_dec_and_test(void) + /* + * Returns true when we need to resched and can (barring IRQ state). + */ +-static __always_inline bool should_resched(void) ++static __always_inline bool should_resched(int preempt_offset) + { +- return unlikely(!__this_cpu_read_4(__preempt_count)); ++ return unlikely(__this_cpu_read_4(__preempt_count) == preempt_offset); + } + + #ifdef CONFIG_PREEMPT +diff --git a/crypto/ahash.c b/crypto/ahash.c +index a92dc382f781..865ef923eda6 100644 +--- a/crypto/ahash.c ++++ b/crypto/ahash.c +@@ -465,7 +465,8 @@ static int ahash_prepare_alg(struct ahash_alg *alg) + struct crypto_alg *base = &alg->halg.base; + + if (alg->halg.digestsize > PAGE_SIZE / 8 || +- alg->halg.statesize > PAGE_SIZE / 8) ++ alg->halg.statesize > PAGE_SIZE / 8 || ++ alg->halg.statesize == 0) + return -EINVAL; + + base->cra_type = &crypto_ahash_type; +diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c +index b583773e4ecb..2ea515509ca6 100644 +--- a/drivers/block/rbd.c ++++ b/drivers/block/rbd.c +@@ -4851,7 +4851,6 @@ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev) + out_err: + if (parent) { + rbd_dev_unparent(rbd_dev); +- kfree(rbd_dev->header_name); + rbd_dev_destroy(parent); + } else { + rbd_put_client(rbdc); +diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c +index 7903e0ed3c75..a5846b34fdd9 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c ++++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c +@@ -183,8 +183,30 @@ nouveau_fbcon_sync(struct fb_info *info) + return 0; + } + ++static int ++nouveau_fbcon_open(struct fb_info *info, int user) ++{ ++ struct nouveau_fbdev *fbcon = info->par; ++ struct nouveau_drm *drm = nouveau_drm(fbcon->dev); ++ int ret = pm_runtime_get_sync(drm->dev->dev); ++ if (ret < 0 && ret != -EACCES) ++ return ret; ++ return 0; ++} ++ ++static int ++nouveau_fbcon_release(struct fb_info *info, int user) ++{ ++ struct nouveau_fbdev *fbcon = info->par; ++ struct nouveau_drm *drm = nouveau_drm(fbcon->dev); ++ pm_runtime_put(drm->dev->dev); ++ return 0; ++} ++ + static struct fb_ops nouveau_fbcon_ops = { + .owner = THIS_MODULE, ++ .fb_open = nouveau_fbcon_open, ++ .fb_release = nouveau_fbcon_release, + .fb_check_var = drm_fb_helper_check_var, + .fb_set_par = drm_fb_helper_set_par, + .fb_fillrect = nouveau_fbcon_fillrect, +@@ -200,6 +222,8 @@ static struct fb_ops nouveau_fbcon_ops = { + + static struct fb_ops nouveau_fbcon_sw_ops = { + .owner = THIS_MODULE, ++ .fb_open = nouveau_fbcon_open, ++ .fb_release = nouveau_fbcon_release, + .fb_check_var = drm_fb_helper_check_var, + .fb_set_par = drm_fb_helper_set_par, + .fb_fillrect = cfb_fillrect, +diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c +index 11d06c7b5afa..1af604a4512a 100644 +--- a/drivers/gpu/drm/radeon/radeon_display.c ++++ b/drivers/gpu/drm/radeon/radeon_display.c +@@ -1479,18 +1479,8 @@ int radeon_modeset_init(struct radeon_device *rdev) + radeon_fbdev_init(rdev); + drm_kms_helper_poll_init(rdev->ddev); + +- if (rdev->pm.dpm_enabled) { +- /* do dpm late init */ +- ret = radeon_pm_late_init(rdev); +- if (ret) { +- rdev->pm.dpm_enabled = false; +- DRM_ERROR("radeon_pm_late_init failed, disabling dpm\n"); +- } +- /* set the dpm state for PX since there won't be +- * a modeset to call this. +- */ +- radeon_pm_compute_clocks(rdev); +- } ++ /* do pm late init */ ++ ret = radeon_pm_late_init(rdev); + + return 0; + } +diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c +index 0095ee7fce34..214adc6d2a68 100644 +--- a/drivers/gpu/drm/radeon/radeon_pm.c ++++ b/drivers/gpu/drm/radeon/radeon_pm.c +@@ -1153,14 +1153,6 @@ static int radeon_pm_init_old(struct radeon_device *rdev) + INIT_DELAYED_WORK(&rdev->pm.dynpm_idle_work, radeon_dynpm_idle_work_handler); + + if (rdev->pm.num_power_states > 1) { +- /* where's the best place to put these? */ +- ret = device_create_file(rdev->dev, &dev_attr_power_profile); +- if (ret) +- DRM_ERROR("failed to create device file for power profile\n"); +- ret = device_create_file(rdev->dev, &dev_attr_power_method); +- if (ret) +- DRM_ERROR("failed to create device file for power method\n"); +- + if (radeon_debugfs_pm_init(rdev)) { + DRM_ERROR("Failed to register debugfs file for PM!\n"); + } +@@ -1218,20 +1210,6 @@ static int radeon_pm_init_dpm(struct radeon_device *rdev) + goto dpm_failed; + rdev->pm.dpm_enabled = true; + +- ret = device_create_file(rdev->dev, &dev_attr_power_dpm_state); +- if (ret) +- DRM_ERROR("failed to create device file for dpm state\n"); +- ret = device_create_file(rdev->dev, &dev_attr_power_dpm_force_performance_level); +- if (ret) +- DRM_ERROR("failed to create device file for dpm state\n"); +- /* XXX: these are noops for dpm but are here for backwards compat */ +- ret = device_create_file(rdev->dev, &dev_attr_power_profile); +- if (ret) +- DRM_ERROR("failed to create device file for power profile\n"); +- ret = device_create_file(rdev->dev, &dev_attr_power_method); +- if (ret) +- DRM_ERROR("failed to create device file for power method\n"); +- + if (radeon_debugfs_pm_init(rdev)) { + DRM_ERROR("Failed to register debugfs file for dpm!\n"); + } +@@ -1371,9 +1349,44 @@ int radeon_pm_late_init(struct radeon_device *rdev) + int ret = 0; + + if (rdev->pm.pm_method == PM_METHOD_DPM) { +- mutex_lock(&rdev->pm.mutex); +- ret = radeon_dpm_late_enable(rdev); +- mutex_unlock(&rdev->pm.mutex); ++ if (rdev->pm.dpm_enabled) { ++ ret = device_create_file(rdev->dev, &dev_attr_power_dpm_state); ++ if (ret) ++ DRM_ERROR("failed to create device file for dpm state\n"); ++ ret = device_create_file(rdev->dev, &dev_attr_power_dpm_force_performance_level); ++ if (ret) ++ DRM_ERROR("failed to create device file for dpm state\n"); ++ /* XXX: these are noops for dpm but are here for backwards compat */ ++ ret = device_create_file(rdev->dev, &dev_attr_power_profile); ++ if (ret) ++ DRM_ERROR("failed to create device file for power profile\n"); ++ ret = device_create_file(rdev->dev, &dev_attr_power_method); ++ if (ret) ++ DRM_ERROR("failed to create device file for power method\n"); ++ ++ mutex_lock(&rdev->pm.mutex); ++ ret = radeon_dpm_late_enable(rdev); ++ mutex_unlock(&rdev->pm.mutex); ++ if (ret) { ++ rdev->pm.dpm_enabled = false; ++ DRM_ERROR("radeon_pm_late_init failed, disabling dpm\n"); ++ } else { ++ /* set the dpm state for PX since there won't be ++ * a modeset to call this. ++ */ ++ radeon_pm_compute_clocks(rdev); ++ } ++ } ++ } else { ++ if (rdev->pm.num_power_states > 1) { ++ /* where's the best place to put these? */ ++ ret = device_create_file(rdev->dev, &dev_attr_power_profile); ++ if (ret) ++ DRM_ERROR("failed to create device file for power profile\n"); ++ ret = device_create_file(rdev->dev, &dev_attr_power_method); ++ if (ret) ++ DRM_ERROR("failed to create device file for power method\n"); ++ } + } + return ret; + } +diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c +index d0bdac0498ce..f7439c556413 100644 +--- a/drivers/i2c/busses/i2c-designware-platdrv.c ++++ b/drivers/i2c/busses/i2c-designware-platdrv.c +@@ -28,6 +28,7 @@ + #include <linux/kernel.h> + #include <linux/module.h> + #include <linux/delay.h> ++#include <linux/dmi.h> + #include <linux/i2c.h> + #include <linux/clk.h> + #include <linux/errno.h> +@@ -53,6 +54,22 @@ static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev) + } + + #ifdef CONFIG_ACPI ++/* ++ * The HCNT/LCNT information coming from ACPI should be the most accurate ++ * for given platform. However, some systems get it wrong. On such systems ++ * we get better results by calculating those based on the input clock. ++ */ ++static const struct dmi_system_id dw_i2c_no_acpi_params[] = { ++ { ++ .ident = "Dell Inspiron 7348", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7348"), ++ }, ++ }, ++ { } ++}; ++ + static void dw_i2c_acpi_params(struct platform_device *pdev, char method[], + u16 *hcnt, u16 *lcnt, u32 *sda_hold) + { +@@ -60,6 +77,9 @@ static void dw_i2c_acpi_params(struct platform_device *pdev, char method[], + acpi_handle handle = ACPI_HANDLE(&pdev->dev); + union acpi_object *obj; + ++ if (dmi_check_system(dw_i2c_no_acpi_params)) ++ return; ++ + if (ACPI_FAILURE(acpi_evaluate_object(handle, method, NULL, &buf))) + return; + +diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c +index d3c5d6216575..32812d3e5411 100644 +--- a/drivers/i2c/busses/i2c-rcar.c ++++ b/drivers/i2c/busses/i2c-rcar.c +@@ -712,15 +712,16 @@ static int rcar_i2c_probe(struct platform_device *pdev) + return ret; + } + ++ pm_runtime_enable(dev); ++ platform_set_drvdata(pdev, priv); ++ + ret = i2c_add_numbered_adapter(adap); + if (ret < 0) { + dev_err(dev, "reg adap failed: %d\n", ret); ++ pm_runtime_disable(dev); + return ret; + } + +- pm_runtime_enable(dev); +- platform_set_drvdata(pdev, priv); +- + dev_info(dev, "probed\n"); + + return 0; +diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c +index 79a211782766..a272988f8f10 100644 +--- a/drivers/i2c/busses/i2c-s3c2410.c ++++ b/drivers/i2c/busses/i2c-s3c2410.c +@@ -1198,17 +1198,19 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) + i2c->adap.nr = i2c->pdata->bus_num; + i2c->adap.dev.of_node = pdev->dev.of_node; + ++ platform_set_drvdata(pdev, i2c); ++ ++ pm_runtime_enable(&pdev->dev); ++ + ret = i2c_add_numbered_adapter(&i2c->adap); + if (ret < 0) { + dev_err(&pdev->dev, "failed to add bus to i2c core\n"); ++ pm_runtime_disable(&pdev->dev); + s3c24xx_i2c_deregister_cpufreq(i2c); + clk_unprepare(i2c->clk); + return ret; + } + +- platform_set_drvdata(pdev, i2c); +- +- pm_runtime_enable(&pdev->dev); + pm_runtime_enable(&i2c->adap.dev); + + dev_info(&pdev->dev, "%s: S3C I2C adapter\n", dev_name(&i2c->adap.dev)); +diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c +index c1120eb96d86..b94e4648c199 100644 +--- a/drivers/md/dm-thin.c ++++ b/drivers/md/dm-thin.c +@@ -2373,7 +2373,7 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv) + metadata_low_callback, + pool); + if (r) +- goto out_free_pt; ++ goto out_flags_changed; + + pt->callbacks.congested_fn = pool_is_congested; + dm_table_add_target_callbacks(ti->table, &pt->callbacks); +diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c +index 6c9c16d76935..f606b5ba611f 100644 +--- a/drivers/net/ppp/pppoe.c ++++ b/drivers/net/ppp/pppoe.c +@@ -313,7 +313,6 @@ static void pppoe_flush_dev(struct net_device *dev) + if (po->pppoe_dev == dev && + sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND | PPPOX_ZOMBIE)) { + pppox_unbind_sock(sk); +- sk->sk_state = PPPOX_ZOMBIE; + sk->sk_state_change(sk); + po->pppoe_dev = NULL; + dev_put(dev); +diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c +index 5d194093f3e1..816d511e34d3 100644 +--- a/drivers/net/usb/asix_devices.c ++++ b/drivers/net/usb/asix_devices.c +@@ -465,19 +465,7 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) + return ret; + } + +- ret = asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL); +- if (ret < 0) +- return ret; +- +- msleep(150); +- +- ret = asix_sw_reset(dev, AX_SWRESET_CLEAR); +- if (ret < 0) +- return ret; +- +- msleep(150); +- +- ret = asix_sw_reset(dev, embd_phy ? AX_SWRESET_IPRL : AX_SWRESET_PRTE); ++ ax88772_reset(dev); + + /* Read PHYID register *AFTER* the PHY was reset properly */ + phyid = asix_get_phyid(dev); +@@ -890,7 +878,7 @@ static const struct driver_info ax88772_info = { + .unbind = ax88772_unbind, + .status = asix_status, + .link_reset = ax88772_link_reset, +- .reset = ax88772_reset, ++ .reset = ax88772_link_reset, + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | FLAG_MULTI_PACKET, + .rx_fixup = asix_rx_fixup_common, + .tx_fixup = asix_tx_fixup, +diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c +index 6244f9cf8ae3..0529defbdf73 100644 +--- a/fs/btrfs/backref.c ++++ b/fs/btrfs/backref.c +@@ -1692,7 +1692,6 @@ static int iterate_inode_extrefs(u64 inum, struct btrfs_root *fs_root, + int found = 0; + struct extent_buffer *eb; + struct btrfs_inode_extref *extref; +- struct extent_buffer *leaf; + u32 item_size; + u32 cur_offset; + unsigned long ptr; +@@ -1720,9 +1719,8 @@ static int iterate_inode_extrefs(u64 inum, struct btrfs_root *fs_root, + btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); + btrfs_release_path(path); + +- leaf = path->nodes[0]; +- item_size = btrfs_item_size_nr(leaf, slot); +- ptr = btrfs_item_ptr_offset(leaf, slot); ++ item_size = btrfs_item_size_nr(eb, slot); ++ ptr = btrfs_item_ptr_offset(eb, slot); + cur_offset = 0; + + while (cur_offset < item_size) { +@@ -1736,7 +1734,7 @@ static int iterate_inode_extrefs(u64 inum, struct btrfs_root *fs_root, + if (ret) + break; + +- cur_offset += btrfs_inode_extref_name_len(leaf, extref); ++ cur_offset += btrfs_inode_extref_name_len(eb, extref); + cur_offset += sizeof(*extref); + } + btrfs_tree_read_unlock_blocking(eb); +diff --git a/include/asm-generic/preempt.h b/include/asm-generic/preempt.h +index 1cd3f5d767a8..54352f4dde1a 100644 +--- a/include/asm-generic/preempt.h ++++ b/include/asm-generic/preempt.h +@@ -74,9 +74,10 @@ static __always_inline bool __preempt_count_dec_and_test(void) + /* + * Returns true when we need to resched and can (barring IRQ state). + */ +-static __always_inline bool should_resched(void) ++static __always_inline bool should_resched(int preempt_offset) + { +- return unlikely(!preempt_count() && tif_need_resched()); ++ return unlikely(preempt_count() == preempt_offset && ++ tif_need_resched()); + } + + #ifdef CONFIG_PREEMPT +diff --git a/include/linux/preempt.h b/include/linux/preempt.h +index 1841b58cf173..411a5c6371da 100644 +--- a/include/linux/preempt.h ++++ b/include/linux/preempt.h +@@ -22,7 +22,8 @@ + #if defined(CONFIG_DEBUG_PREEMPT) || defined(CONFIG_PREEMPT_TRACER) + extern void preempt_count_add(int val); + extern void preempt_count_sub(int val); +-#define preempt_count_dec_and_test() ({ preempt_count_sub(1); should_resched(); }) ++#define preempt_count_dec_and_test() \ ++ ({ preempt_count_sub(1); should_resched(0); }) + #else + #define preempt_count_add(val) __preempt_count_add(val) + #define preempt_count_sub(val) __preempt_count_sub(val) +@@ -61,7 +62,7 @@ do { \ + + #define preempt_check_resched() \ + do { \ +- if (should_resched()) \ ++ if (should_resched(0)) \ + __preempt_schedule(); \ + } while (0) + +diff --git a/include/linux/preempt_mask.h b/include/linux/preempt_mask.h +index dbeec4d4a3be..5cb25f17331a 100644 +--- a/include/linux/preempt_mask.h ++++ b/include/linux/preempt_mask.h +@@ -71,13 +71,21 @@ + */ + #define in_nmi() (preempt_count() & NMI_MASK) + ++/* ++ * The preempt_count offset after preempt_disable(); ++ */ + #if defined(CONFIG_PREEMPT_COUNT) +-# define PREEMPT_CHECK_OFFSET 1 ++# define PREEMPT_DISABLE_OFFSET PREEMPT_OFFSET + #else +-# define PREEMPT_CHECK_OFFSET 0 ++# define PREEMPT_DISABLE_OFFSET 0 + #endif + + /* ++ * The preempt_count offset after spin_lock() ++ */ ++#define PREEMPT_LOCK_OFFSET PREEMPT_DISABLE_OFFSET ++ ++/* + * The preempt_count offset needed for things like: + * + * spin_lock_bh() +@@ -90,7 +98,7 @@ + * + * Work as expected. + */ +-#define SOFTIRQ_LOCK_OFFSET (SOFTIRQ_DISABLE_OFFSET + PREEMPT_CHECK_OFFSET) ++#define SOFTIRQ_LOCK_OFFSET (SOFTIRQ_DISABLE_OFFSET + PREEMPT_LOCK_OFFSET) + + /* + * Are we running in atomic context? WARNING: this macro cannot +@@ -106,7 +114,7 @@ + * (used by the scheduler, *after* releasing the kernel lock) + */ + #define in_atomic_preempt_off() \ +- ((preempt_count() & ~PREEMPT_ACTIVE) != PREEMPT_CHECK_OFFSET) ++ ((preempt_count() & ~PREEMPT_ACTIVE) != PREEMPT_DISABLE_OFFSET) + + #ifdef CONFIG_PREEMPT_COUNT + # define preemptible() (preempt_count() == 0 && !irqs_disabled()) +diff --git a/include/linux/sched.h b/include/linux/sched.h +index 91fe6a38b307..ec6000f66e75 100644 +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -2647,12 +2647,6 @@ extern int _cond_resched(void); + + extern int __cond_resched_lock(spinlock_t *lock); + +-#ifdef CONFIG_PREEMPT_COUNT +-#define PREEMPT_LOCK_OFFSET PREEMPT_OFFSET +-#else +-#define PREEMPT_LOCK_OFFSET 0 +-#endif +- + #define cond_resched_lock(lock) ({ \ + __might_sleep(__FILE__, __LINE__, PREEMPT_LOCK_OFFSET); \ + __cond_resched_lock(lock); \ +diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h +index ab3133797ff7..d8bec47b6edd 100644 +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -2347,6 +2347,9 @@ static inline void skb_postpull_rcsum(struct sk_buff *skb, + { + if (skb->ip_summed == CHECKSUM_COMPLETE) + skb->csum = csum_sub(skb->csum, csum_partial(start, len, 0)); ++ else if (skb->ip_summed == CHECKSUM_PARTIAL && ++ skb_checksum_start_offset(skb) < 0) ++ skb->ip_summed = CHECKSUM_NONE; + } + + unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len); +diff --git a/include/net/af_unix.h b/include/net/af_unix.h +index a175ba4a7adb..dfe4ddfbb43c 100644 +--- a/include/net/af_unix.h ++++ b/include/net/af_unix.h +@@ -64,7 +64,11 @@ struct unix_sock { + #define UNIX_GC_MAYBE_CYCLE 1 + struct socket_wq peer_wq; + }; +-#define unix_sk(__sk) ((struct unix_sock *)__sk) ++ ++static inline struct unix_sock *unix_sk(struct sock *sk) ++{ ++ return (struct unix_sock *)sk; ++} + + #define peer_wait peer_wq.wait + +diff --git a/include/net/sock.h b/include/net/sock.h +index 0c79a740e97d..ff4f825647a5 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -805,6 +805,14 @@ static inline __must_check int sk_add_backlog(struct sock *sk, struct sk_buff *s + if (sk_rcvqueues_full(sk, skb, limit)) + return -ENOBUFS; + ++ /* ++ * If the skb was allocated from pfmemalloc reserves, only ++ * allow SOCK_MEMALLOC sockets to use it as this socket is ++ * helping free memory ++ */ ++ if (skb_pfmemalloc(skb) && !sock_flag(sk, SOCK_MEMALLOC)) ++ return -ENOMEM; ++ + __sk_add_backlog(sk, skb); + sk->sk_backlog.len += skb->truesize; + return 0; +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index a19262a7d70b..bbe957762ace 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -4113,7 +4113,7 @@ static void __cond_resched(void) + + int __sched _cond_resched(void) + { +- if (should_resched()) { ++ if (should_resched(0)) { + __cond_resched(); + return 1; + } +@@ -4131,7 +4131,7 @@ EXPORT_SYMBOL(_cond_resched); + */ + int __cond_resched_lock(spinlock_t *lock) + { +- int resched = should_resched(); ++ int resched = should_resched(PREEMPT_LOCK_OFFSET); + int ret = 0; + + lockdep_assert_held(lock); +@@ -4153,7 +4153,7 @@ int __sched __cond_resched_softirq(void) + { + BUG_ON(!in_softirq()); + +- if (should_resched()) { ++ if (should_resched(SOFTIRQ_DISABLE_OFFSET)) { + local_bh_enable(); + __cond_resched(); + local_bh_disable(); +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index 423c9e37a9e7..646a8b81bee1 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -1475,13 +1475,13 @@ static void __queue_delayed_work(int cpu, struct workqueue_struct *wq, + timer_stats_timer_set_start_info(&dwork->timer); + + dwork->wq = wq; ++ /* timer isn't guaranteed to run in this cpu, record earlier */ ++ if (cpu == WORK_CPU_UNBOUND) ++ cpu = raw_smp_processor_id(); + dwork->cpu = cpu; + timer->expires = jiffies + delay; + +- if (unlikely(cpu != WORK_CPU_UNBOUND)) +- add_timer_on(timer, cpu); +- else +- add_timer(timer); ++ add_timer_on(timer, cpu); + } + + /** +diff --git a/net/core/ethtool.c b/net/core/ethtool.c +index 30071dec287a..0b39ab6f7675 100644 +--- a/net/core/ethtool.c ++++ b/net/core/ethtool.c +@@ -1080,7 +1080,7 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr) + + gstrings.len = ret; + +- data = kmalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER); ++ data = kcalloc(gstrings.len, ETH_GSTRING_LEN, GFP_USER); + if (!data) + return -ENOMEM; + +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index 8207f8d7f665..366f7ff741b7 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -2862,11 +2862,12 @@ EXPORT_SYMBOL(skb_append_datato_frags); + */ + unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len) + { ++ unsigned char *data = skb->data; ++ + BUG_ON(len > skb->len); +- skb->len -= len; +- BUG_ON(skb->len < skb->data_len); +- skb_postpull_rcsum(skb, skb->data, len); +- return skb->data += len; ++ __skb_pull(skb, len); ++ skb_postpull_rcsum(skb, data, len); ++ return skb->data; + } + EXPORT_SYMBOL_GPL(skb_pull_rcsum); + +diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c +index 85d9d94c0a3c..3679bd6000d7 100644 +--- a/net/l2tp/l2tp_core.c ++++ b/net/l2tp/l2tp_core.c +@@ -1435,7 +1435,7 @@ static void l2tp_tunnel_del_work(struct work_struct *work) + tunnel = container_of(work, struct l2tp_tunnel, del_work); + sk = l2tp_tunnel_sock_lookup(tunnel); + if (!sk) +- return; ++ goto out; + + sock = sk->sk_socket; + +@@ -1456,6 +1456,8 @@ static void l2tp_tunnel_del_work(struct work_struct *work) + } + + l2tp_tunnel_sock_put(sk); ++out: ++ l2tp_tunnel_dec_refcount(tunnel); + } + + /* Create a socket for the tunnel, if one isn't set up by +@@ -1785,8 +1787,13 @@ EXPORT_SYMBOL_GPL(l2tp_tunnel_create); + */ + int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel) + { ++ l2tp_tunnel_inc_refcount(tunnel); + l2tp_tunnel_closeall(tunnel); +- return (false == queue_work(l2tp_wq, &tunnel->del_work)); ++ if (false == queue_work(l2tp_wq, &tunnel->del_work)) { ++ l2tp_tunnel_dec_refcount(tunnel); ++ return 1; ++ } ++ return 0; + } + EXPORT_SYMBOL_GPL(l2tp_tunnel_delete); + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 4757f1cf6237..4affedbe0206 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -1956,6 +1956,11 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, + goto out; + } + ++ if (flags & MSG_PEEK) ++ skip = sk_peek_offset(sk, flags); ++ else ++ skip = 0; ++ + do { + int chunk; + struct sk_buff *skb, *last; +@@ -2002,7 +2007,6 @@ again: + break; + } + +- skip = sk_peek_offset(sk, flags); + while (skip >= unix_skb_len(skb)) { + skip -= unix_skb_len(skb); + last = skb; +@@ -2066,6 +2070,16 @@ again: + + sk_peek_offset_fwd(sk, chunk); + ++ if (UNIXCB(skb).fp) ++ break; ++ ++ skip = 0; ++ last = skb; ++ unix_state_lock(sk); ++ skb = skb_peek_next(skb, &sk->sk_receive_queue); ++ if (skb) ++ goto again; ++ unix_state_unlock(sk); + break; + } + } while (size); |