diff --git a/Makefile b/Makefile
index 0e546913f1c4..60506b154d53 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 VERSION = 4
 PATCHLEVEL = 14
-SUBLEVEL = 226
+SUBLEVEL = 227
 EXTRAVERSION =
 NAME = Petit Gorille
 
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index 550b7814ef92..49dd12997a21 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -1515,7 +1515,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs 
*iregs)
                 */
                if (!pebs_status && cpuc->pebs_enabled &&
                        !(cpuc->pebs_enabled & (cpuc->pebs_enabled-1)))
-                       pebs_status = cpuc->pebs_enabled;
+                       pebs_status = p->status = cpuc->pebs_enabled;
 
                bit = find_first_bit((unsigned long *)&pebs_status,
                                        x86_pmu.max_pebs_events);
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 56a89519dc14..be441d520d63 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -511,15 +511,6 @@ struct thread_struct {
         */
 };
 
-/*
- * Thread-synchronous status.
- *
- * This is different from the flags in that nobody else
- * ever touches our thread-synchronous status, so we don't
- * have to worry about atomic accesses.
- */
-#define TS_COMPAT              0x0002  /* 32bit syscall active (64BIT)*/
-
 /*
  * Set IOPL bits in EFLAGS from given mask
  */
diff --git a/arch/x86/include/asm/thread_info.h 
b/arch/x86/include/asm/thread_info.h
index bf9175d87844..a77f0ad96d94 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -229,10 +229,31 @@ static inline int arch_within_stack_frames(const void * 
const stack,
 
 #endif
 
+/*
+ * Thread-synchronous status.
+ *
+ * This is different from the flags in that nobody else
+ * ever touches our thread-synchronous status, so we don't
+ * have to worry about atomic accesses.
+ */
+#define TS_COMPAT              0x0002  /* 32bit syscall active (64BIT)*/
+
+#ifndef __ASSEMBLY__
 #ifdef CONFIG_COMPAT
 #define TS_I386_REGS_POKED     0x0004  /* regs poked by 32-bit ptracer */
+#define TS_COMPAT_RESTART      0x0008
+
+#define arch_set_restart_data  arch_set_restart_data
+
+static inline void arch_set_restart_data(struct restart_block *restart)
+{
+       struct thread_info *ti = current_thread_info();
+       if (ti->status & TS_COMPAT)
+               ti->status |= TS_COMPAT_RESTART;
+       else
+               ti->status &= ~TS_COMPAT_RESTART;
+}
 #endif
-#ifndef __ASSEMBLY__
 
 #ifdef CONFIG_X86_32
 #define in_ia32_syscall() true
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index be226cdd08d3..de74bca6a8ff 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1042,6 +1042,16 @@ static int mp_map_pin_to_irq(u32 gsi, int idx, int 
ioapic, int pin,
        if (idx >= 0 && test_bit(mp_irqs[idx].srcbus, mp_bus_not_pci)) {
                irq = mp_irqs[idx].srcbusirq;
                legacy = mp_is_legacy_irq(irq);
+               /*
+                * IRQ2 is unusable for historical reasons on systems which
+                * have a legacy PIC. See the comment vs. IRQ2 further down.
+                *
+                * If this gets removed at some point then the related code
+                * in lapic_assign_system_vectors() needs to be adjusted as
+                * well.
+                */
+               if (legacy && irq == PIC_CASCADE_IR)
+                       return -EINVAL;
        }
 
        mutex_lock(&ioapic_mutex);
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index 01741834fd6a..a18632b4da83 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -769,30 +769,8 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 
 static inline unsigned long get_nr_restart_syscall(const struct pt_regs *regs)
 {
-       /*
-        * This function is fundamentally broken as currently
-        * implemented.
-        *
-        * The idea is that we want to trigger a call to the
-        * restart_block() syscall and that we want in_ia32_syscall(),
-        * in_x32_syscall(), etc. to match whatever they were in the
-        * syscall being restarted.  We assume that the syscall
-        * instruction at (regs->ip - 2) matches whatever syscall
-        * instruction we used to enter in the first place.
-        *
-        * The problem is that we can get here when ptrace pokes
-        * syscall-like values into regs even if we're not in a syscall
-        * at all.
-        *
-        * For now, we maintain historical behavior and guess based on
-        * stored state.  We could do better by saving the actual
-        * syscall arch in restart_block or (with caveats on x32) by
-        * checking if regs->ip points to 'int $0x80'.  The current
-        * behavior is incorrect if a tracer has a different bitness
-        * than the tracee.
-        */
 #ifdef CONFIG_IA32_EMULATION
-       if (current_thread_info()->status & (TS_COMPAT|TS_I386_REGS_POKED))
+       if (current_thread_info()->status & TS_COMPAT_RESTART)
                return __NR_ia32_restart_syscall;
 #endif
 #ifdef CONFIG_X86_X32_ABI
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 1547f8209e78..b2b1eece0db1 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -306,22 +306,22 @@ static void rpm_put_suppliers(struct device *dev)
 static int __rpm_callback(int (*cb)(struct device *), struct device *dev)
        __releases(&dev->power.lock) __acquires(&dev->power.lock)
 {
-       bool use_links = dev->power.links_count > 0;
-       bool get = false;
        int retval, idx;
-       bool put;
+       bool use_links = dev->power.links_count > 0;
 
        if (dev->power.irq_safe) {
                spin_unlock(&dev->power.lock);
-       } else if (!use_links) {
-               spin_unlock_irq(&dev->power.lock);
        } else {
-               get = dev->power.runtime_status == RPM_RESUMING;
-
                spin_unlock_irq(&dev->power.lock);
 
-               /* Resume suppliers if necessary. */
-               if (get) {
+               /*
+                * Resume suppliers if necessary.
+                *
+                * The device's runtime PM status cannot change until this
+                * routine returns, so it is safe to read the status outside of
+                * the lock.
+                */
+               if (use_links && dev->power.runtime_status == RPM_RESUMING) {
                        idx = device_links_read_lock();
 
                        retval = rpm_get_suppliers(dev);
@@ -336,36 +336,24 @@ static int __rpm_callback(int (*cb)(struct device *), 
struct device *dev)
 
        if (dev->power.irq_safe) {
                spin_lock(&dev->power.lock);
-               return retval;
-       }
-
-       spin_lock_irq(&dev->power.lock);
-
-       if (!use_links)
-               return retval;
-
-       /*
-        * If the device is suspending and the callback has returned success,
-        * drop the usage counters of the suppliers that have been reference
-        * counted on its resume.
-        *
-        * Do that if the resume fails too.
-        */
-       put = dev->power.runtime_status == RPM_SUSPENDING && !retval;
-       if (put)
-               __update_runtime_status(dev, RPM_SUSPENDED);
-       else
-               put = get && retval;
-
-       if (put) {
-               spin_unlock_irq(&dev->power.lock);
-
-               idx = device_links_read_lock();
+       } else {
+               /*
+                * If the device is suspending and the callback has returned
+                * success, drop the usage counters of the suppliers that have
+                * been reference counted on its resume.
+                *
+                * Do that if resume fails too.
+                */
+               if (use_links
+                   && ((dev->power.runtime_status == RPM_SUSPENDING && !retval)
+                   || (dev->power.runtime_status == RPM_RESUMING && retval))) {
+                       idx = device_links_read_lock();
 
-fail:
-               rpm_put_suppliers(dev);
+ fail:
+                       rpm_put_suppliers(dev);
 
-               device_links_read_unlock(idx);
+                       device_links_read_unlock(idx);
+               }
 
                spin_lock_irq(&dev->power.lock);
        }
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 369a2c632e46..3a3aed47414f 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -635,6 +635,7 @@ config STM32_ADC_CORE
        depends on HAS_DMA
        depends on OF
        depends on REGULATOR
+       depends on HAS_IOMEM
        select IIO_BUFFER
        select MFD_STM32_TIMERS
        select IIO_STM32_TIMER_TRIGGER
diff --git a/drivers/iio/adc/qcom-spmi-vadc.c b/drivers/iio/adc/qcom-spmi-vadc.c
index 9e600bfd1765..1a7d4c7cfde4 100644
--- a/drivers/iio/adc/qcom-spmi-vadc.c
+++ b/drivers/iio/adc/qcom-spmi-vadc.c
@@ -607,7 +607,7 @@ static const struct vadc_channels vadc_chans[] = {
        VADC_CHAN_NO_SCALE(P_MUX16_1_3, 1)
 
        VADC_CHAN_NO_SCALE(LR_MUX1_BAT_THERM, 0)
-       VADC_CHAN_NO_SCALE(LR_MUX2_BAT_ID, 0)
+       VADC_CHAN_VOLT(LR_MUX2_BAT_ID, 0, SCALE_DEFAULT)
        VADC_CHAN_NO_SCALE(LR_MUX3_XO_THERM, 0)
        VADC_CHAN_NO_SCALE(LR_MUX4_AMUX_THM1, 0)
        VADC_CHAN_NO_SCALE(LR_MUX5_AMUX_THM2, 0)
diff --git a/drivers/iio/gyro/mpu3050-core.c b/drivers/iio/gyro/mpu3050-core.c
index a7be4670bf8f..3db843206db3 100644
--- a/drivers/iio/gyro/mpu3050-core.c
+++ b/drivers/iio/gyro/mpu3050-core.c
@@ -549,6 +549,8 @@ static irqreturn_t mpu3050_trigger_handler(int irq, void *p)
                                               MPU3050_FIFO_R,
                                               &fifo_values[offset],
                                               toread);
+                       if (ret)
+                               goto out_trigger_unlock;
 
                        dev_dbg(mpu3050->dev,
                                "%04x %04x %04x %04x %04x\n",
diff --git a/drivers/iio/humidity/hid-sensor-humidity.c 
b/drivers/iio/humidity/hid-sensor-humidity.c
index e53914d51ec3..3ef742951dbd 100644
--- a/drivers/iio/humidity/hid-sensor-humidity.c
+++ b/drivers/iio/humidity/hid-sensor-humidity.c
@@ -28,7 +28,10 @@
 struct hid_humidity_state {
        struct hid_sensor_common common_attributes;
        struct hid_sensor_hub_attribute_info humidity_attr;
-       s32 humidity_data;
+       struct {
+               s32 humidity_data;
+               u64 timestamp __aligned(8);
+       } scan;
        int scale_pre_decml;
        int scale_post_decml;
        int scale_precision;
@@ -139,9 +142,8 @@ static int humidity_proc_event(struct hid_sensor_hub_device 
*hsdev,
        struct hid_humidity_state *humid_st = iio_priv(indio_dev);
 
        if (atomic_read(&humid_st->common_attributes.data_ready))
-               iio_push_to_buffers_with_timestamp(indio_dev,
-                                       &humid_st->humidity_data,
-                                       iio_get_time_ns(indio_dev));
+               iio_push_to_buffers_with_timestamp(indio_dev, &humid_st->scan,
+                                                  iio_get_time_ns(indio_dev));
 
        return 0;
 }
@@ -156,7 +158,7 @@ static int humidity_capture_sample(struct 
hid_sensor_hub_device *hsdev,
 
        switch (usage_id) {
        case HID_USAGE_SENSOR_ATMOSPHERIC_HUMIDITY:
-               humid_st->humidity_data = *(s32 *)raw_data;
+               humid_st->scan.humidity_data = *(s32 *)raw_data;
 
                return 0;
        default:
diff --git a/drivers/iio/imu/adis16400_core.c b/drivers/iio/imu/adis16400_core.c
index 9b697d35dbef..af0904c42bd1 100644
--- a/drivers/iio/imu/adis16400_core.c
+++ b/drivers/iio/imu/adis16400_core.c
@@ -288,8 +288,7 @@ static int adis16400_initial_setup(struct iio_dev 
*indio_dev)
                if (ret)
                        goto err_ret;
 
-               ret = sscanf(indio_dev->name, "adis%u\n", &device_id);
-               if (ret != 1) {
+               if (sscanf(indio_dev->name, "adis%u\n", &device_id) != 1) {
                        ret = -EINVAL;
                        goto err_ret;
                }
diff --git a/drivers/iio/light/hid-sensor-prox.c 
b/drivers/iio/light/hid-sensor-prox.c
index 8c017abc4ee2..29ebcd0c252c 100644
--- a/drivers/iio/light/hid-sensor-prox.c
+++ b/drivers/iio/light/hid-sensor-prox.c
@@ -37,6 +37,9 @@ struct prox_state {
        struct hid_sensor_common common_attributes;
        struct hid_sensor_hub_attribute_info prox_attr;
        u32 human_presence;
+       int scale_pre_decml;
+       int scale_post_decml;
+       int scale_precision;
 };
 
 /* Channel definitions */
@@ -107,8 +110,9 @@ static int prox_read_raw(struct iio_dev *indio_dev,
                ret_type = IIO_VAL_INT;
                break;
        case IIO_CHAN_INFO_SCALE:
-               *val = prox_state->prox_attr.units;
-               ret_type = IIO_VAL_INT;
+               *val = prox_state->scale_pre_decml;
+               *val2 = prox_state->scale_post_decml;
+               ret_type = prox_state->scale_precision;
                break;
        case IIO_CHAN_INFO_OFFSET:
                *val = hid_sensor_convert_exponent(
@@ -249,6 +253,11 @@ static int prox_parse_report(struct platform_device *pdev,
                        HID_USAGE_SENSOR_HUMAN_PRESENCE,
                        &st->common_attributes.sensitivity);
 
+       st->scale_precision = hid_sensor_format_scale(
+                               hsdev->usage,
+                               &st->prox_attr,
+                               &st->scale_pre_decml, &st->scale_post_decml);
+
        return ret;
 }
 
diff --git a/drivers/iio/temperature/hid-sensor-temperature.c 
b/drivers/iio/temperature/hid-sensor-temperature.c
index 6ed5cd5742f1..36f4e270dddb 100644
--- a/drivers/iio/temperature/hid-sensor-temperature.c
+++ b/drivers/iio/temperature/hid-sensor-temperature.c
@@ -28,7 +28,10 @@
 struct temperature_state {
        struct hid_sensor_common common_attributes;
        struct hid_sensor_hub_attribute_info temperature_attr;
-       s32 temperature_data;
+       struct {
+               s32 temperature_data;
+               u64 timestamp __aligned(8);
+       } scan;
        int scale_pre_decml;
        int scale_post_decml;
        int scale_precision;
@@ -45,7 +48,7 @@ static const struct iio_chan_spec temperature_channels[] = {
                        BIT(IIO_CHAN_INFO_SAMP_FREQ) |
                        BIT(IIO_CHAN_INFO_HYSTERESIS),
        },
-       IIO_CHAN_SOFT_TIMESTAMP(3),
+       IIO_CHAN_SOFT_TIMESTAMP(1),
 };
 
 /* Adjust channel real bits based on report descriptor */
@@ -137,9 +140,8 @@ static int temperature_proc_event(struct 
hid_sensor_hub_device *hsdev,
        struct temperature_state *temp_st = iio_priv(indio_dev);
 
        if (atomic_read(&temp_st->common_attributes.data_ready))
-               iio_push_to_buffers_with_timestamp(indio_dev,
-                               &temp_st->temperature_data,
-                               iio_get_time_ns(indio_dev));
+               iio_push_to_buffers_with_timestamp(indio_dev, &temp_st->scan,
+                                                  iio_get_time_ns(indio_dev));
 
        return 0;
 }
@@ -154,7 +156,7 @@ static int temperature_capture_sample(struct 
hid_sensor_hub_device *hsdev,
 
        switch (usage_id) {
        case HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE:
-               temp_st->temperature_data = *(s32 *)raw_data;
+               temp_st->scan.temperature_data = *(s32 *)raw_data;
                return 0;
        default:
                return -EINVAL;
diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index c17cdbd0bb6a..820aed3e2352 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -501,6 +501,19 @@ static void b53_imp_vlan_setup(struct dsa_switch *ds, int 
cpu_port)
        }
 }
 
+static void b53_port_set_learning(struct b53_device *dev, int port,
+                                 bool learning)
+{
+       u16 reg;
+
+       b53_read16(dev, B53_CTRL_PAGE, B53_DIS_LEARNING, &reg);
+       if (learning)
+               reg &= ~BIT(port);
+       else
+               reg |= BIT(port);
+       b53_write16(dev, B53_CTRL_PAGE, B53_DIS_LEARNING, reg);
+}
+
 static int b53_enable_port(struct dsa_switch *ds, int port,
                           struct phy_device *phy)
 {
@@ -508,6 +521,8 @@ static int b53_enable_port(struct dsa_switch *ds, int port,
        unsigned int cpu_port = dev->cpu_port;
        u16 pvlan;
 
+       b53_port_set_learning(dev, port, false);
+
        /* Clear the Rx and Tx disable bits and set to no spanning tree */
        b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), 0);
 
@@ -551,6 +566,8 @@ static void b53_enable_cpu_port(struct b53_device *dev)
                    PORT_CTRL_RX_MCST_EN |
                    PORT_CTRL_RX_UCST_EN;
        b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(cpu_port), port_ctrl);
+
+       b53_port_set_learning(dev, cpu_port, false);
 }
 
 static void b53_enable_mib(struct b53_device *dev)
@@ -1342,6 +1359,8 @@ int b53_br_join(struct dsa_switch *ds, int port, struct 
net_device *br)
        b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), pvlan);
        dev->ports[port].vlan_ctl_mask = pvlan;
 
+       b53_port_set_learning(dev, port, true);
+
        return 0;
 }
 EXPORT_SYMBOL(b53_br_join);
@@ -1392,6 +1411,7 @@ void b53_br_leave(struct dsa_switch *ds, int port, struct 
net_device *br)
                vl->untag |= BIT(port) | BIT(dev->cpu_port);
                b53_set_vlan_entry(dev, pvid, vl);
        }
+       b53_port_set_learning(dev, port, false);
 }
 EXPORT_SYMBOL(b53_br_leave);
 
diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h
index 247aef92b759..2b892b8d0374 100644
--- a/drivers/net/dsa/b53/b53_regs.h
+++ b/drivers/net/dsa/b53/b53_regs.h
@@ -112,6 +112,7 @@
 #define B53_UC_FLOOD_MASK              0x32
 #define B53_MC_FLOOD_MASK              0x34
 #define B53_IPMC_FLOOD_MASK            0x36
+#define B53_DIS_LEARNING               0x3c
 
 /*
  * Override Ports 0-7 State on devices with xMII interfaces (8 bit)
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
index 91c8405e515f..7fc84ae562a2 100644
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -252,6 +252,11 @@ static int bcm_sf2_port_setup(struct dsa_switch *ds, int 
port,
        reg &= ~P_TXQ_PSM_VDD(port);
        core_writel(priv, reg, CORE_MEM_PSM_VDD_CTRL);
 
+       /* Disable learning */
+       reg = core_readl(priv, CORE_DIS_LEARN);
+       reg |= BIT(port);
+       core_writel(priv, reg, CORE_DIS_LEARN);
+
        /* Enable Broadcom tags for that port if requested */
        if (priv->brcm_tag_mask & BIT(port))
                bcm_sf2_brcm_hdr_setup(priv, port);
diff --git a/drivers/net/dsa/bcm_sf2_regs.h b/drivers/net/dsa/bcm_sf2_regs.h
index 49695fcc2ea8..da1336ddd52d 100644
--- a/drivers/net/dsa/bcm_sf2_regs.h
+++ b/drivers/net/dsa/bcm_sf2_regs.h
@@ -150,6 +150,8 @@ enum bcm_sf2_reg_offs {
 #define CORE_SWITCH_CTRL               0x00088
 #define  MII_DUMB_FWDG_EN              (1 << 6)
 
+#define CORE_DIS_LEARN                 0x000f0
+
 #define CORE_SFT_LRN_CTRL              0x000f8
 #define  SW_LEARN_CNTL(x)              (1 << (x))
 
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index 564e457f1345..57e1c0dd63c4 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -655,8 +655,11 @@ static int nvme_rdma_alloc_io_queues(struct nvme_rdma_ctrl 
*ctrl)
                return ret;
 
        ctrl->ctrl.queue_count = nr_io_queues + 1;
-       if (ctrl->ctrl.queue_count < 2)
-               return 0;
+       if (ctrl->ctrl.queue_count < 2) {
+               dev_err(ctrl->ctrl.device,
+                       "unable to set any I/O queues\n");
+               return -ENOMEM;
+       }
 
        dev_info(ctrl->ctrl.device,
                "creating %d I/O queues.\n", nr_io_queues);
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index 7d6d30a2d771..e02423d7b3b9 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -594,9 +594,20 @@ static void nvmet_start_ctrl(struct nvmet_ctrl *ctrl)
 {
        lockdep_assert_held(&ctrl->lock);
 
-       if (nvmet_cc_iosqes(ctrl->cc) != NVME_NVM_IOSQES ||
-           nvmet_cc_iocqes(ctrl->cc) != NVME_NVM_IOCQES ||
-           nvmet_cc_mps(ctrl->cc) != 0 ||
+       /*
+        * Only I/O controllers should verify iosqes,iocqes.
+        * Strictly speaking, the spec says a discovery controller
+        * should verify iosqes,iocqes are zeroed, however that
+        * would break backwards compatibility, so don't enforce it.
+        */
+       if (ctrl->subsys->type != NVME_NQN_DISC &&
+           (nvmet_cc_iosqes(ctrl->cc) != NVME_NVM_IOSQES ||
+            nvmet_cc_iocqes(ctrl->cc) != NVME_NVM_IOCQES)) {
+               ctrl->csts = NVME_CSTS_CFS;
+               return;
+       }
+
+       if (nvmet_cc_mps(ctrl->cc) != 0 ||
            nvmet_cc_ams(ctrl->cc) != 0 ||
            nvmet_cc_css(ctrl->cc) != 0) {
                ctrl->csts = NVME_CSTS_CFS;
diff --git a/drivers/pci/hotplug/rpadlpar_sysfs.c 
b/drivers/pci/hotplug/rpadlpar_sysfs.c
index edb5d8a53020..5b2228402f9b 100644
--- a/drivers/pci/hotplug/rpadlpar_sysfs.c
+++ b/drivers/pci/hotplug/rpadlpar_sysfs.c
@@ -39,12 +39,11 @@ static ssize_t add_slot_store(struct kobject *kobj, struct 
kobj_attribute *attr,
        if (nbytes >= MAX_DRC_NAME_LEN)
                return 0;
 
-       memcpy(drc_name, buf, nbytes);
+       strscpy(drc_name, buf, nbytes + 1);
 
        end = strchr(drc_name, '\n');
-       if (!end)
-               end = &drc_name[nbytes];
-       *end = '\0';
+       if (end)
+               *end = '\0';
 
        rc = dlpar_add_slot(drc_name);
        if (rc)
@@ -70,12 +69,11 @@ static ssize_t remove_slot_store(struct kobject *kobj,
        if (nbytes >= MAX_DRC_NAME_LEN)
                return 0;
 
-       memcpy(drc_name, buf, nbytes);
+       strscpy(drc_name, buf, nbytes + 1);
 
        end = strchr(drc_name, '\n');
-       if (!end)
-               end = &drc_name[nbytes];
-       *end = '\0';
+       if (end)
+               *end = '\0';
 
        rc = dlpar_remove_slot(drc_name);
        if (rc)
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index d50c481ec41c..c77ad2b78ce4 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -1753,7 +1753,7 @@ lpfc_debugfs_dif_err_write(struct file *file, const char 
__user *buf,
        memset(dstbuf, 0, 33);
        size = (nbytes < 32) ? nbytes : 32;
        if (copy_from_user(dstbuf, buf, size))
-               return 0;
+               return -EFAULT;
 
        if (dent == phba->debug_InjErrLBA) {
                if ((buf[0] == 'o') && (buf[1] == 'f') && (buf[2] == 'f'))
@@ -1761,7 +1761,7 @@ lpfc_debugfs_dif_err_write(struct file *file, const char 
__user *buf,
        }
 
        if ((tmp == 0) && (kstrtoull(dstbuf, 0, &tmp)))
-               return 0;
+               return -EINVAL;
 
        if (dent == phba->debug_writeGuard)
                phba->lpfc_injerr_wgrd_cnt = (uint32_t)tmp;
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index c98c80ca3bbc..6696fdd97530 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1080,7 +1080,7 @@ static void collect_langs(struct usb_gadget_strings **sp, 
__le16 *buf)
        while (*sp) {
                s = *sp;
                language = cpu_to_le16(s->language);
-               for (tmp = buf; *tmp && tmp < &buf[126]; tmp++) {
+               for (tmp = buf; *tmp && tmp < &buf[USB_MAX_STRING_LEN]; tmp++) {
                        if (*tmp == language)
                                goto repeat;
                }
@@ -1155,7 +1155,7 @@ static int get_string(struct usb_composite_dev *cdev,
                        collect_langs(sp, s->wData);
                }
 
-               for (len = 0; len <= 126 && s->wData[len]; len++)
+               for (len = 0; len <= USB_MAX_STRING_LEN && s->wData[len]; len++)
                        continue;
                if (!len)
                        return -EINVAL;
diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
index 2c70b0bcea6a..8209e035e52f 100644
--- a/drivers/usb/gadget/configfs.c
+++ b/drivers/usb/gadget/configfs.c
@@ -108,21 +108,27 @@ struct gadget_config_name {
        struct list_head list;
 };
 
+#define USB_MAX_STRING_WITH_NULL_LEN   (USB_MAX_STRING_LEN+1)
+
 static int usb_string_copy(const char *s, char **s_copy)
 {
        int ret;
        char *str;
        char *copy = *s_copy;
        ret = strlen(s);
-       if (ret > 126)
+       if (ret > USB_MAX_STRING_LEN)
                return -EOVERFLOW;
 
-       str = kstrdup(s, GFP_KERNEL);
-       if (!str)
-               return -ENOMEM;
+       if (copy) {
+               str = copy;
+       } else {
+               str = kmalloc(USB_MAX_STRING_WITH_NULL_LEN, GFP_KERNEL);
+               if (!str)
+                       return -ENOMEM;
+       }
+       strcpy(str, s);
        if (str[ret - 1] == '\n')
                str[ret - 1] = '\0';
-       kfree(copy);
        *s_copy = str;
        return 0;
 }
diff --git a/drivers/usb/gadget/usbstring.c b/drivers/usb/gadget/usbstring.c
index 73a4dfba0edb..0173a9969b9a 100644
--- a/drivers/usb/gadget/usbstring.c
+++ b/drivers/usb/gadget/usbstring.c
@@ -59,9 +59,9 @@ usb_gadget_get_string (struct usb_gadget_strings *table, int 
id, u8 *buf)
                return -EINVAL;
 
        /* string descriptors have length, tag, then UTF16-LE text */
-       len = min ((size_t) 126, strlen (s->s));
+       len = min((size_t)USB_MAX_STRING_LEN, strlen(s->s));
        len = utf8s_to_utf16s(s->s, len, UTF16_LITTLE_ENDIAN,
-                       (wchar_t *) &buf[2], 126);
+                       (wchar_t *) &buf[2], USB_MAX_STRING_LEN);
        if (len < 0)
                return -EINVAL;
        buf [0] = (len + 1) * 2;
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index a3ccb899df60..86b9254ba5ed 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -667,6 +667,13 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, 
struct us_data *us)
                need_auto_sense = 1;
        }
 
+       /* Some devices (Kindle) require another command after SYNC CACHE */
+       if ((us->fflags & US_FL_SENSE_AFTER_SYNC) &&
+                       srb->cmnd[0] == SYNCHRONIZE_CACHE) {
+               usb_stor_dbg(us, "-- sense after SYNC CACHE\n");
+               need_auto_sense = 1;
+       }
+
        /*
         * If we have a failure, we're going to do a REQUEST_SENSE 
         * automatically.  Note that we differentiate between a command
diff --git a/drivers/usb/storage/unusual_devs.h 
b/drivers/usb/storage/unusual_devs.h
index e77140a5b672..a34818357caa 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -2230,6 +2230,18 @@ UNUSUAL_DEV( 0x1908, 0x3335, 0x0200, 0x0200,
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
                US_FL_NO_READ_DISC_INFO ),
 
+/*
+ * Reported by Matthias Schwarzott <[email protected]>
+ * The Amazon Kindle treats SYNCHRONIZE CACHE as an indication that
+ * the host may be finished with it, and automatically ejects its
+ * emulated media unless it receives another command within one second.
+ */
+UNUSUAL_DEV( 0x1949, 0x0004, 0x0000, 0x9999,
+               "Amazon",
+               "Kindle",
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_SENSE_AFTER_SYNC ),
+
 /*
  * Reported by Oliver Neukum <[email protected]>
  * This device morphes spontaneously into another device if the access
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 5178065e39f3..f1033448b667 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -1431,7 +1431,9 @@ get_old_root(struct btrfs_root *root, u64 time_seq)
                                   "failed to read tree block %llu from 
get_old_root",
                                   logical);
                } else {
+                       btrfs_tree_read_lock(old);
                        eb = btrfs_clone_extent_buffer(old);
+                       btrfs_tree_read_unlock(old);
                        free_extent_buffer(old);
                }
        } else if (old_root) {
diff --git a/fs/ext4/block_validity.c b/fs/ext4/block_validity.c
index 3cbee832e796..080410433110 100644
--- a/fs/ext4/block_validity.c
+++ b/fs/ext4/block_validity.c
@@ -24,6 +24,7 @@ struct ext4_system_zone {
        struct rb_node  node;
        ext4_fsblk_t    start_blk;
        unsigned int    count;
+       u32             ino;
 };
 
 static struct kmem_cache *ext4_system_zone_cachep;
@@ -44,7 +45,8 @@ void ext4_exit_system_zone(void)
 static inline int can_merge(struct ext4_system_zone *entry1,
                     struct ext4_system_zone *entry2)
 {
-       if ((entry1->start_blk + entry1->count) == entry2->start_blk)
+       if ((entry1->start_blk + entry1->count) == entry2->start_blk &&
+           entry1->ino == entry2->ino)
                return 1;
        return 0;
 }
@@ -56,9 +58,9 @@ static inline int can_merge(struct ext4_system_zone *entry1,
  */
 static int add_system_zone(struct ext4_sb_info *sbi,
                           ext4_fsblk_t start_blk,
-                          unsigned int count)
+                          unsigned int count, u32 ino)
 {
-       struct ext4_system_zone *new_entry = NULL, *entry;
+       struct ext4_system_zone *new_entry, *entry;
        struct rb_node **n = &sbi->system_blks.rb_node, *node;
        struct rb_node *parent = NULL, *new_node = NULL;
 
@@ -69,30 +71,21 @@ static int add_system_zone(struct ext4_sb_info *sbi,
                        n = &(*n)->rb_left;
                else if (start_blk >= (entry->start_blk + entry->count))
                        n = &(*n)->rb_right;
-               else {
-                       if (start_blk + count > (entry->start_blk +
-                                                entry->count))
-                               entry->count = (start_blk + count -
-                                               entry->start_blk);
-                       new_node = *n;
-                       new_entry = rb_entry(new_node, struct ext4_system_zone,
-                                            node);
-                       break;
-               }
+               else    /* Unexpected overlap of system zones. */
+                       return -EFSCORRUPTED;
        }
 
-       if (!new_entry) {
-               new_entry = kmem_cache_alloc(ext4_system_zone_cachep,
-                                            GFP_KERNEL);
-               if (!new_entry)
-                       return -ENOMEM;
-               new_entry->start_blk = start_blk;
-               new_entry->count = count;
-               new_node = &new_entry->node;
+       new_entry = kmem_cache_alloc(ext4_system_zone_cachep,
+                                    GFP_KERNEL);
+       if (!new_entry)
+               return -ENOMEM;
+       new_entry->start_blk = start_blk;
+       new_entry->count = count;
+       new_entry->ino = ino;
+       new_node = &new_entry->node;
 
-               rb_link_node(new_node, parent, n);
-               rb_insert_color(new_node, &sbi->system_blks);
-       }
+       rb_link_node(new_node, parent, n);
+       rb_insert_color(new_node, &sbi->system_blks);
 
        /* Can we merge to the left? */
        node = rb_prev(new_node);
@@ -164,16 +157,16 @@ static int ext4_protect_reserved_inode(struct super_block 
*sb, u32 ino)
                if (n == 0) {
                        i++;
                } else {
-                       if (!ext4_data_block_valid(sbi, map.m_pblk, n)) {
-                               ext4_error(sb, "blocks %llu-%llu from inode %u "
+                       err = add_system_zone(sbi, map.m_pblk, n, ino);
+                       if (err < 0) {
+                               if (err == -EFSCORRUPTED) {
+                                       ext4_error(sb,
+                                          "blocks %llu-%llu from inode %u "
                                           "overlap system zone", map.m_pblk,
                                           map.m_pblk + map.m_len - 1, ino);
-                               err = -EFSCORRUPTED;
+                               }
                                break;
                        }
-                       err = add_system_zone(sbi, map.m_pblk, n);
-                       if (err < 0)
-                               break;
                        i += n;
                }
        }
@@ -202,16 +195,16 @@ int ext4_setup_system_zone(struct super_block *sb)
                if (ext4_bg_has_super(sb, i) &&
                    ((i < 5) || ((i % flex_size) == 0)))
                        add_system_zone(sbi, ext4_group_first_block_no(sb, i),
-                                       ext4_bg_num_gdb(sb, i) + 1);
+                                       ext4_bg_num_gdb(sb, i) + 1, 0);
                gdp = ext4_get_group_desc(sb, i, NULL);
-               ret = add_system_zone(sbi, ext4_block_bitmap(sb, gdp), 1);
+               ret = add_system_zone(sbi, ext4_block_bitmap(sb, gdp), 1, 0);
                if (ret)
                        return ret;
-               ret = add_system_zone(sbi, ext4_inode_bitmap(sb, gdp), 1);
+               ret = add_system_zone(sbi, ext4_inode_bitmap(sb, gdp), 1, 0);
                if (ret)
                        return ret;
                ret = add_system_zone(sbi, ext4_inode_table(sb, gdp),
-                               sbi->s_itb_per_group);
+                               sbi->s_itb_per_group, 0);
                if (ret)
                        return ret;
        }
@@ -244,10 +237,11 @@ void ext4_release_system_zone(struct super_block *sb)
  * start_blk+count) is valid; 0 if some part of the block region
  * overlaps with filesystem metadata blocks.
  */
-int ext4_data_block_valid(struct ext4_sb_info *sbi, ext4_fsblk_t start_blk,
-                         unsigned int count)
+int ext4_inode_block_valid(struct inode *inode, ext4_fsblk_t start_blk,
+                          unsigned int count)
 {
        struct ext4_system_zone *entry;
+       struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
        struct rb_node *n = sbi->system_blks.rb_node;
 
        if ((start_blk <= le32_to_cpu(sbi->s_es->s_first_data_block)) ||
@@ -263,6 +257,8 @@ int ext4_data_block_valid(struct ext4_sb_info *sbi, 
ext4_fsblk_t start_blk,
                else if (start_blk >= (entry->start_blk + entry->count))
                        n = n->rb_right;
                else {
+                       if (entry->ino == inode->i_ino)
+                               return 1;
                        sbi->s_es->s_last_error_block = cpu_to_le64(start_blk);
                        return 0;
                }
@@ -285,8 +281,7 @@ int ext4_check_blockref(const char *function, unsigned int 
line,
        while (bref < p+max) {
                blk = le32_to_cpu(*bref++);
                if (blk &&
-                   unlikely(!ext4_data_block_valid(EXT4_SB(inode->i_sb),
-                                                   blk, 1))) {
+                   unlikely(!ext4_inode_block_valid(inode, blk, 1))) {
                        es->s_last_error_block = cpu_to_le64(blk);
                        ext4_error_inode(inode, function, line, blk,
                                         "invalid block");
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index c5908f5eb075..5e9ff118977e 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -3151,9 +3151,9 @@ extern void ext4_release_system_zone(struct super_block 
*sb);
 extern int ext4_setup_system_zone(struct super_block *sb);
 extern int __init ext4_init_system_zone(void);
 extern void ext4_exit_system_zone(void);
-extern int ext4_data_block_valid(struct ext4_sb_info *sbi,
-                                ext4_fsblk_t start_blk,
-                                unsigned int count);
+extern int ext4_inode_block_valid(struct inode *inode,
+                                 ext4_fsblk_t start_blk,
+                                 unsigned int count);
 extern int ext4_check_blockref(const char *, unsigned int,
                               struct inode *, __le32 *, unsigned int);
 
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index fc6bc261f7ac..264332fb0e77 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -389,7 +389,7 @@ static int ext4_valid_extent(struct inode *inode, struct 
ext4_extent *ext)
         */
        if (lblock + len <= lblock)
                return 0;
-       return ext4_data_block_valid(EXT4_SB(inode->i_sb), block, len);
+       return ext4_inode_block_valid(inode, block, len);
 }
 
 static int ext4_valid_extent_idx(struct inode *inode,
@@ -397,7 +397,7 @@ static int ext4_valid_extent_idx(struct inode *inode,
 {
        ext4_fsblk_t block = ext4_idx_pblock(ext_idx);
 
-       return ext4_data_block_valid(EXT4_SB(inode->i_sb), block, 1);
+       return ext4_inode_block_valid(inode, block, 1);
 }
 
 static int ext4_valid_extent_entries(struct inode *inode,
@@ -554,14 +554,10 @@ __read_extent_tree_block(const char *function, unsigned 
int line,
        }
        if (buffer_verified(bh) && !(flags & EXT4_EX_FORCE_CACHE))
                return bh;
-       if (!ext4_has_feature_journal(inode->i_sb) ||
-           (inode->i_ino !=
-            le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_journal_inum))) {
-               err = __ext4_ext_check(function, line, inode,
-                                      ext_block_hdr(bh), depth, pblk);
-               if (err)
-                       goto errout;
-       }
+       err = __ext4_ext_check(function, line, inode,
+                              ext_block_hdr(bh), depth, pblk);
+       if (err)
+               goto errout;
        set_buffer_verified(bh);
        /*
         * If this is a leaf block, cache all of its entries
diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c
index e1801b288847..a5442528a60d 100644
--- a/fs/ext4/indirect.c
+++ b/fs/ext4/indirect.c
@@ -842,8 +842,7 @@ static int ext4_clear_blocks(handle_t *handle, struct inode 
*inode,
        else if (ext4_should_journal_data(inode))
                flags |= EXT4_FREE_BLOCKS_FORGET;
 
-       if (!ext4_data_block_valid(EXT4_SB(inode->i_sb), block_to_free,
-                                  count)) {
+       if (!ext4_inode_block_valid(inode, block_to_free, count)) {
                EXT4_ERROR_INODE(inode, "attempt to clear invalid "
                                 "blocks %llu len %lu",
                                 (unsigned long long) block_to_free, count);
@@ -1005,8 +1004,7 @@ static void ext4_free_branches(handle_t *handle, struct 
inode *inode,
                        if (!nr)
                                continue;               /* A hole */
 
-                       if (!ext4_data_block_valid(EXT4_SB(inode->i_sb),
-                                                  nr, 1)) {
+                       if (!ext4_inode_block_valid(inode, nr, 1)) {
                                EXT4_ERROR_INODE(inode,
                                                 "invalid indirect mapped "
                                                 "block %lu (level %d)",
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index eb635eab304e..ad6a1282a5cd 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -420,8 +420,7 @@ static int __check_block_validity(struct inode *inode, 
const char *func,
            (inode->i_ino ==
             le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_journal_inum)))
                return 0;
-       if (!ext4_data_block_valid(EXT4_SB(inode->i_sb), map->m_pblk,
-                                  map->m_len)) {
+       if (!ext4_inode_block_valid(inode, map->m_pblk, map->m_len)) {
                ext4_error_inode(inode, func, line, map->m_pblk,
                                 "lblock %lu mapped to illegal pblock %llu "
                                 "(length %d)", (unsigned long) map->m_lblk,
@@ -4940,7 +4939,7 @@ struct inode *__ext4_iget(struct super_block *sb, 
unsigned long ino,
 
        ret = 0;
        if (ei->i_file_acl &&
-           !ext4_data_block_valid(EXT4_SB(sb), ei->i_file_acl, 1)) {
+           !ext4_inode_block_valid(inode, ei->i_file_acl, 1)) {
                ext4_error_inode(inode, function, line, 0,
                                 "iget: bad extended attribute block %llu",
                                 ei->i_file_acl);
@@ -5131,7 +5130,7 @@ static int ext4_do_update_inode(handle_t *handle,
        struct ext4_inode_info *ei = EXT4_I(inode);
        struct buffer_head *bh = iloc->bh;
        struct super_block *sb = inode->i_sb;
-       int err = 0, rc, block;
+       int err = 0, block;
        int need_datasync = 0, set_large_file = 0;
        uid_t i_uid;
        gid_t i_gid;
@@ -5241,9 +5240,9 @@ static int ext4_do_update_inode(handle_t *handle,
                                              bh->b_data);
 
        BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
-       rc = ext4_handle_dirty_metadata(handle, NULL, bh);
-       if (!err)
-               err = rc;
+       err = ext4_handle_dirty_metadata(handle, NULL, bh);
+       if (err)
+               goto out_brelse;
        ext4_clear_inode_state(inode, EXT4_STATE_NEW);
        if (set_large_file) {
                BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get write access");
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 4cafe41ab524..b4da63f24093 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -3017,7 +3017,7 @@ ext4_mb_mark_diskspace_used(struct 
ext4_allocation_context *ac,
        block = ext4_grp_offs_to_block(sb, &ac->ac_b_ex);
 
        len = EXT4_C2B(sbi, ac->ac_b_ex.fe_len);
-       if (!ext4_data_block_valid(sbi, block, len)) {
+       if (!ext4_inode_block_valid(ac->ac_inode, block, len)) {
                ext4_error(sb, "Allocating blocks %llu-%llu which overlap "
                           "fs metadata", block, block+len);
                /* File system mounted not to panic on error
@@ -4783,7 +4783,7 @@ void ext4_free_blocks(handle_t *handle, struct inode 
*inode,
 
        sbi = EXT4_SB(sb);
        if (!(flags & EXT4_FREE_BLOCKS_VALIDATED) &&
-           !ext4_data_block_valid(sbi, block, count)) {
+           !ext4_inode_block_valid(inode, block, count)) {
                ext4_error(sb, "Freeing blocks not in datazone - "
                           "block = %llu, count = %lu", block, count);
                goto error_return;
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index eff27e9de775..647d4a8d6b68 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -3445,6 +3445,31 @@ static int ext4_setent(handle_t *handle, struct 
ext4_renament *ent,
        return 0;
 }
 
+static void ext4_resetent(handle_t *handle, struct ext4_renament *ent,
+                         unsigned ino, unsigned file_type)
+{
+       struct ext4_renament old = *ent;
+       int retval = 0;
+
+       /*
+        * old->de could have moved from under us during make indexed dir,
+        * so the old->de may no longer valid and need to find it again
+        * before reset old inode info.
+        */
+       old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de, NULL);
+       if (IS_ERR(old.bh))
+               retval = PTR_ERR(old.bh);
+       if (!old.bh)
+               retval = -ENOENT;
+       if (retval) {
+               ext4_std_error(old.dir->i_sb, retval);
+               return;
+       }
+
+       ext4_setent(handle, &old, ino, file_type);
+       brelse(old.bh);
+}
+
 static int ext4_find_delete_entry(handle_t *handle, struct inode *dir,
                                  const struct qstr *d_name)
 {
@@ -3754,8 +3779,8 @@ static int ext4_rename(struct inode *old_dir, struct 
dentry *old_dentry,
 end_rename:
        if (whiteout) {
                if (retval) {
-                       ext4_setent(handle, &old,
-                               old.inode->i_ino, old_file_type);
+                       ext4_resetent(handle, &old,
+                                     old.inode->i_ino, old_file_type);
                        drop_nlink(whiteout);
                }
                unlock_new_inode(whiteout);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index eaa8bcd59b6a..8e6178dc0e6e 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -5364,7 +5364,10 @@ static int ext4_remount(struct super_block *sb, int 
*flags, char *data)
                ext4_register_li_request(sb, first_not_zeroed);
        }
 
-       ext4_setup_system_zone(sb);
+       err = ext4_setup_system_zone(sb);
+       if (err)
+               goto restore_opts;
+
        if (sbi->s_journal == NULL && !(old_sb_flags & MS_RDONLY))
                ext4_commit_super(sb, 1);
 
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index 823b01f6b0f0..1e73feb5970b 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -2418,7 +2418,7 @@ ext4_xattr_set_handle(handle_t *handle, struct inode 
*inode, int name_index,
                                 * external inode if possible.
                                 */
                                if (ext4_has_feature_ea_inode(inode->i_sb) &&
-                                   !i.in_inode) {
+                                   i.value_len && !i.in_inode) {
                                        i.in_inode = 1;
                                        goto retry_inode;
                                }
diff --git a/fs/select.c b/fs/select.c
index 063067e606ca..b752dabb3131 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -1006,10 +1006,9 @@ static long do_restart_poll(struct restart_block 
*restart_block)
 
        ret = do_sys_poll(ufds, nfds, to);
 
-       if (ret == -EINTR) {
-               restart_block->fn = do_restart_poll;
-               ret = -ERESTART_RESTARTBLOCK;
-       }
+       if (ret == -EINTR)
+               ret = set_restart_fn(restart_block, do_restart_poll);
+
        return ret;
 }
 
@@ -1031,7 +1030,6 @@ SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, 
unsigned int, nfds,
                struct restart_block *restart_block;
 
                restart_block = &current->restart_block;
-               restart_block->fn = do_restart_poll;
                restart_block->poll.ufds = ufds;
                restart_block->poll.nfds = nfds;
 
@@ -1042,7 +1040,7 @@ SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, 
unsigned int, nfds,
                } else
                        restart_block->poll.has_timeout = 0;
 
-               ret = -ERESTART_RESTARTBLOCK;
+               ret = set_restart_fn(restart_block, do_restart_poll);
        }
        return ret;
 }
diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h
index cf2862bd134a..de250d50cd37 100644
--- a/include/linux/thread_info.h
+++ b/include/linux/thread_info.h
@@ -11,6 +11,7 @@
 #include <linux/types.h>
 #include <linux/bug.h>
 #include <linux/restart_block.h>
+#include <linux/errno.h>
 
 #ifdef CONFIG_THREAD_INFO_IN_TASK
 /*
@@ -39,6 +40,18 @@ enum {
 
 #ifdef __KERNEL__
 
+#ifndef arch_set_restart_data
+#define arch_set_restart_data(restart) do { } while (0)
+#endif
+
+static inline long set_restart_fn(struct restart_block *restart,
+                                       long (*fn)(struct restart_block *))
+{
+       restart->fn = fn;
+       arch_set_restart_data(restart);
+       return -ERESTART_RESTARTBLOCK;
+}
+
 #ifndef THREAD_ALIGN
 #define THREAD_ALIGN   THREAD_SIZE
 #endif
diff --git a/include/linux/usb_usual.h b/include/linux/usb_usual.h
index a7f7ebdd3069..0a958c794832 100644
--- a/include/linux/usb_usual.h
+++ b/include/linux/usb_usual.h
@@ -86,6 +86,8 @@
                /* lies about caching, so always sync */        \
        US_FLAG(NO_SAME, 0x40000000)                            \
                /* Cannot handle WRITE_SAME */                  \
+       US_FLAG(SENSE_AFTER_SYNC, 0x80000000)                   \
+               /* Do REQUEST_SENSE after SYNCHRONIZE_CACHE */  \
 
 #define US_FLAG(name, value)   US_FL_##name = value ,
 enum { US_DO_ALL_FLAGS };
diff --git a/include/uapi/linux/usb/ch9.h b/include/uapi/linux/usb/ch9.h
index 8512777889b0..4c02fa757af7 100644
--- a/include/uapi/linux/usb/ch9.h
+++ b/include/uapi/linux/usb/ch9.h
@@ -360,6 +360,9 @@ struct usb_config_descriptor {
 
 /*-------------------------------------------------------------------------*/
 
+/* USB String descriptors can contain at most 126 characters. */
+#define USB_MAX_STRING_LEN     126
+
 /* USB_DT_STRING: String descriptor */
 struct usb_string_descriptor {
        __u8  bLength;
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 615a2e44d2a0..0c3a9302be93 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -2029,24 +2029,29 @@ static int retrieve_ptr_limit(const struct 
bpf_reg_state *ptr_reg,
 {
        bool mask_to_left = (opcode == BPF_ADD &&  off_is_neg) ||
                            (opcode == BPF_SUB && !off_is_neg);
-       u32 off;
+       u32 off, max;
 
        switch (ptr_reg->type) {
        case PTR_TO_STACK:
+               /* Offset 0 is out-of-bounds, but acceptable start for the
+                * left direction, see BPF_REG_FP.
+                */
+               max = MAX_BPF_STACK + mask_to_left;
                off = ptr_reg->off + ptr_reg->var_off.value;
                if (mask_to_left)
                        *ptr_limit = MAX_BPF_STACK + off;
                else
-                       *ptr_limit = -off;
-               return 0;
+                       *ptr_limit = -off - 1;
+               return *ptr_limit >= max ? -ERANGE : 0;
        case PTR_TO_MAP_VALUE:
+               max = ptr_reg->map_ptr->value_size;
                if (mask_to_left) {
                        *ptr_limit = ptr_reg->umax_value + ptr_reg->off;
                } else {
                        off = ptr_reg->smin_value + ptr_reg->off;
-                       *ptr_limit = ptr_reg->map_ptr->value_size - off;
+                       *ptr_limit = ptr_reg->map_ptr->value_size - off - 1;
                }
-               return 0;
+               return *ptr_limit >= max ? -ERANGE : 0;
        default:
                return -EINVAL;
        }
@@ -2099,6 +2104,7 @@ static int sanitize_ptr_alu(struct bpf_verifier_env *env,
        u32 alu_state, alu_limit;
        struct bpf_reg_state tmp;
        bool ret;
+       int err;
 
        if (can_skip_alu_sanitation(env, insn))
                return 0;
@@ -2114,10 +2120,13 @@ static int sanitize_ptr_alu(struct bpf_verifier_env 
*env,
        alu_state |= ptr_is_dst_reg ?
                     BPF_ALU_SANITIZE_SRC : BPF_ALU_SANITIZE_DST;
 
-       if (retrieve_ptr_limit(ptr_reg, &alu_limit, opcode, off_is_neg))
-               return 0;
-       if (update_alu_sanitation_state(aux, alu_state, alu_limit))
-               return -EACCES;
+       err = retrieve_ptr_limit(ptr_reg, &alu_limit, opcode, off_is_neg);
+       if (err < 0)
+               return err;
+
+       err = update_alu_sanitation_state(aux, alu_state, alu_limit);
+       if (err < 0)
+               return err;
 do_sim:
        /* Simulate and find potential out-of-bounds access under
         * speculative execution from truncation as a result of
@@ -2210,7 +2219,7 @@ static int adjust_ptr_min_max_vals(struct 
bpf_verifier_env *env,
        case BPF_ADD:
                ret = sanitize_ptr_alu(env, insn, ptr_reg, dst_reg, smin_val < 
0);
                if (ret < 0) {
-                       verbose("R%d tried to add from different maps or 
paths\n", dst);
+                       verbose("R%d tried to add from different maps, paths, 
or prohibited types\n", dst);
                        return ret;
                }
                /* We can take a fixed offset as long as it doesn't overflow
@@ -2265,7 +2274,7 @@ static int adjust_ptr_min_max_vals(struct 
bpf_verifier_env *env,
        case BPF_SUB:
                ret = sanitize_ptr_alu(env, insn, ptr_reg, dst_reg, smin_val < 
0);
                if (ret < 0) {
-                       verbose("R%d tried to sub from different maps or 
paths\n", dst);
+                       verbose("R%d tried to sub from different maps, paths, 
or prohibited types\n", dst);
                        return ret;
                }
                if (dst_reg == off_reg) {
@@ -4802,7 +4811,7 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
                        off_reg = issrc ? insn->src_reg : insn->dst_reg;
                        if (isneg)
                                *patch++ = BPF_ALU64_IMM(BPF_MUL, off_reg, -1);
-                       *patch++ = BPF_MOV32_IMM(BPF_REG_AX, aux->alu_limit - 
1);
+                       *patch++ = BPF_MOV32_IMM(BPF_REG_AX, aux->alu_limit);
                        *patch++ = BPF_ALU64_REG(BPF_SUB, BPF_REG_AX, off_reg);
                        *patch++ = BPF_ALU64_REG(BPF_OR, BPF_REG_AX, off_reg);
                        *patch++ = BPF_ALU64_IMM(BPF_NEG, BPF_REG_AX, 0);
diff --git a/kernel/futex.c b/kernel/futex.c
index 39d2c20f500d..283bebc08ecd 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -2875,14 +2875,13 @@ static int futex_wait(u32 __user *uaddr, unsigned int 
flags, u32 val,
                goto out;
 
        restart = &current->restart_block;
-       restart->fn = futex_wait_restart;
        restart->futex.uaddr = uaddr;
        restart->futex.val = val;
        restart->futex.time = *abs_time;
        restart->futex.bitset = bitset;
        restart->futex.flags = flags | FLAGS_HAS_TIMEOUT;
 
-       ret = -ERESTART_RESTARTBLOCK;
+       ret = set_restart_fn(restart, futex_wait_restart);
 
 out:
        if (to) {
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 3193be58805c..914b43f2255b 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -916,11 +916,15 @@ irq_forced_thread_fn(struct irq_desc *desc, struct 
irqaction *action)
        irqreturn_t ret;
 
        local_bh_disable();
+       if (!IS_ENABLED(CONFIG_PREEMPT_RT_BASE))
+               local_irq_disable();
        ret = action->thread_fn(action->irq, action->dev_id);
        if (ret == IRQ_HANDLED)
                atomic_inc(&desc->threads_handled);
 
        irq_finalize_oneshot(desc, action);
+       if (!IS_ENABLED(CONFIG_PREEMPT_RT_BASE))
+               local_irq_enable();
        local_bh_enable();
        return ret;
 }
diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index 9eece67f29f3..6a2ba39889bd 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -822,9 +822,9 @@ static int alarm_timer_nsleep(const clockid_t which_clock, 
int flags,
        if (flags == TIMER_ABSTIME)
                return -ERESTARTNOHAND;
 
-       restart->fn = alarm_timer_nsleep_restart;
        restart->nanosleep.clockid = type;
        restart->nanosleep.expires = exp;
+       set_restart_fn(restart, alarm_timer_nsleep_restart);
        return ret;
 }
 
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index ecce9122343b..94dd37e8890d 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -1545,9 +1545,9 @@ long hrtimer_nanosleep(const struct timespec64 *rqtp,
        }
 
        restart = &current->restart_block;
-       restart->fn = hrtimer_nanosleep_restart;
        restart->nanosleep.clockid = t.timer.base->clockid;
        restart->nanosleep.expires = hrtimer_get_expires_tv64(&t.timer);
+       set_restart_fn(restart, hrtimer_nanosleep_restart);
 out:
        destroy_hrtimer_on_stack(&t.timer);
        return ret;
diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c
index 6e8c230ca877..fb5a57ffb98c 100644
--- a/kernel/time/posix-cpu-timers.c
+++ b/kernel/time/posix-cpu-timers.c
@@ -1348,8 +1348,8 @@ static int posix_cpu_nsleep(const clockid_t which_clock, 
int flags,
                if (flags & TIMER_ABSTIME)
                        return -ERESTARTNOHAND;
 
-               restart_block->fn = posix_cpu_nsleep_restart;
                restart_block->nanosleep.clockid = which_clock;
+               set_restart_fn(restart_block, posix_cpu_nsleep_restart);
        }
        return error;
 }
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index b9b6235a4cf2..11f79c3b01a9 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -235,7 +235,7 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void 
*data, size_t len)
        if (dst != QRTR_PORT_CTRL && type != QRTR_TYPE_DATA)
                return -EINVAL;
 
-       skb = netdev_alloc_skb(NULL, len);
+       skb = __netdev_alloc_skb(NULL, len, GFP_ATOMIC | __GFP_NOWARN);
        if (!skb)
                return -ENOMEM;
 
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 3a9a03717212..582b85182933 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -1329,7 +1329,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec 
*argv, struct kvec *resv)
 
  sendit:
        if (svc_authorise(rqstp))
-               goto close;
+               goto close_xprt;
        return 1;               /* Caller can now send it */
 
  dropit:
@@ -1338,6 +1338,8 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec 
*argv, struct kvec *resv)
        return 0;
 
  close:
+       svc_authorise(rqstp);
+close_xprt:
        if (rqstp->rq_xprt && test_bit(XPT_TEMP, &rqstp->rq_xprt->xpt_flags))
                svc_close_xprt(rqstp->rq_xprt);
        dprintk("svc: svc_process close\n");
@@ -1346,7 +1348,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec 
*argv, struct kvec *resv)
 err_short_len:
        svc_printk(rqstp, "short len %zd, dropping request\n",
                        argv->iov_len);
-       goto close;
+       goto close_xprt;
 
 err_bad_rpc:
        serv->sv_stats->rpcbadfmt++;
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index b293827b2a58..795cc679491d 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -1106,7 +1106,7 @@ static int svc_close_list(struct svc_serv *serv, struct 
list_head *xprt_list, st
        struct svc_xprt *xprt;
        int ret = 0;
 
-       spin_lock(&serv->sv_lock);
+       spin_lock_bh(&serv->sv_lock);
        list_for_each_entry(xprt, xprt_list, xpt_list) {
                if (xprt->xpt_net != net)
                        continue;
@@ -1114,7 +1114,7 @@ static int svc_close_list(struct svc_serv *serv, struct 
list_head *xprt_list, st
                set_bit(XPT_CLOSE, &xprt->xpt_flags);
                svc_xprt_enqueue(xprt);
        }
-       spin_unlock(&serv->sv_lock);
+       spin_unlock_bh(&serv->sv_lock);
        return ret;
 }
 
diff --git a/net/sunrpc/xprtrdma/svc_rdma_backchannel.c 
b/net/sunrpc/xprtrdma/svc_rdma_backchannel.c
index 4b9aaf487327..4ea3eb7e0d30 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_backchannel.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_backchannel.c
@@ -321,9 +321,9 @@ xprt_setup_rdma_bc(struct xprt_create *args)
        xprt->timeout = &xprt_rdma_bc_timeout;
        xprt_set_bound(xprt);
        xprt_set_connected(xprt);
-       xprt->bind_timeout = RPCRDMA_BIND_TO;
-       xprt->reestablish_timeout = RPCRDMA_INIT_REEST_TO;
-       xprt->idle_timeout = RPCRDMA_IDLE_DISC_TO;
+       xprt->bind_timeout = 0;
+       xprt->reestablish_timeout = 0;
+       xprt->idle_timeout = 0;
 
        xprt->prot = XPRT_TRANSPORT_BC_RDMA;
        xprt->tsh_size = RPCRDMA_HDRLEN_MIN / sizeof(__be32);
diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
index 79427b09590c..037daca06b9c 100644
--- a/tools/build/Makefile.feature
+++ b/tools/build/Makefile.feature
@@ -31,8 +31,11 @@ FEATURE_TESTS_BASIC :=                  \
         backtrace                       \
         dwarf                           \
         dwarf_getlocations              \
+        eventfd                         \
         fortify-source                  \
         sync-compare-and-swap           \
+        get_current_dir_name            \
+        gettid                         \
         glibc                           \
         gtk2                            \
         gtk2-infobar                    \
@@ -56,6 +59,7 @@ FEATURE_TESTS_BASIC :=                  \
         libunwind-arm                   \
         libunwind-aarch64               \
         pthread-attr-setaffinity-np     \
+        pthread-barrier                \
         stackprotector-all              \
         timerfd                         \
         libdw-dwarf-unwind              \
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index 26316749e594..a1a3eb8fe52e 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -5,8 +5,10 @@ FILES=                                          \
          test-bionic.bin                        \
          test-dwarf.bin                         \
          test-dwarf_getlocations.bin            \
+         test-eventfd.bin                       \
          test-fortify-source.bin                \
          test-sync-compare-and-swap.bin         \
+         test-get_current_dir_name.bin          \
          test-glibc.bin                         \
          test-gtk2.bin                          \
          test-gtk2-infobar.bin                  \
@@ -37,6 +39,7 @@ FILES=                                          \
          test-libunwind-debug-frame-arm.bin     \
          test-libunwind-debug-frame-aarch64.bin \
          test-pthread-attr-setaffinity-np.bin   \
+         test-pthread-barrier.bin              \
          test-stackprotector-all.bin            \
          test-timerfd.bin                       \
          test-libdw-dwarf-unwind.bin            \
@@ -49,6 +52,7 @@ FILES=                                          \
          test-get_cpuid.bin                     \
          test-sdt.bin                           \
          test-cxx.bin                           \
+         test-gettid.bin                       \
          test-jvmti.bin                                \
          test-sched_getcpu.bin                 \
          test-setns.bin
@@ -77,6 +81,9 @@ $(OUTPUT)test-hello.bin:
 $(OUTPUT)test-pthread-attr-setaffinity-np.bin:
        $(BUILD) -D_GNU_SOURCE -lpthread
 
+$(OUTPUT)test-pthread-barrier.bin:
+       $(BUILD) -lpthread
+
 $(OUTPUT)test-stackprotector-all.bin:
        $(BUILD) -fstack-protector-all
 
@@ -89,6 +96,12 @@ $(OUTPUT)test-bionic.bin:
 $(OUTPUT)test-libelf.bin:
        $(BUILD) -lelf
 
+$(OUTPUT)test-eventfd.bin:
+       $(BUILD)
+
+$(OUTPUT)test-get_current_dir_name.bin:
+       $(BUILD)
+
 $(OUTPUT)test-glibc.bin:
        $(BUILD)
 
@@ -234,6 +247,9 @@ $(OUTPUT)test-sdt.bin:
 $(OUTPUT)test-cxx.bin:
        $(BUILDXX) -std=gnu++11
 
+$(OUTPUT)test-gettid.bin:
+       $(BUILD)
+
 $(OUTPUT)test-jvmti.bin:
        $(BUILD)
 
diff --git a/tools/build/feature/test-all.c b/tools/build/feature/test-all.c
index 4112702e4aed..d89af04af8ec 100644
--- a/tools/build/feature/test-all.c
+++ b/tools/build/feature/test-all.c
@@ -34,6 +34,14 @@
 # include "test-libelf-mmap.c"
 #undef main
 
+#define main main_test_get_current_dir_name
+# include "test-get_current_dir_name.c"
+#undef main
+
+#define main main_test_gettid
+# include "test-gettid.c"
+#undef main
+
 #define main main_test_glibc
 # include "test-glibc.c"
 #undef main
@@ -46,6 +54,10 @@
 # include "test-dwarf_getlocations.c"
 #undef main
 
+#define main main_test_eventfd
+# include "test-eventfd.c"
+#undef main
+
 #define main main_test_libelf_getphdrnum
 # include "test-libelf-getphdrnum.c"
 #undef main
@@ -118,6 +130,10 @@
 # include "test-pthread-attr-setaffinity-np.c"
 #undef main
 
+#define main main_test_pthread_barrier
+# include "test-pthread-barrier.c"
+#undef main
+
 #define main main_test_sched_getcpu
 # include "test-sched_getcpu.c"
 #undef main
@@ -166,9 +182,12 @@ int main(int argc, char *argv[])
        main_test_hello();
        main_test_libelf();
        main_test_libelf_mmap();
+       main_test_get_current_dir_name();
+       main_test_gettid();
        main_test_glibc();
        main_test_dwarf();
        main_test_dwarf_getlocations();
+       main_test_eventfd();
        main_test_libelf_getphdrnum();
        main_test_libelf_gelf_getnote();
        main_test_libelf_getshdrstrndx();
@@ -187,6 +206,7 @@ int main(int argc, char *argv[])
        main_test_sync_compare_and_swap(argc, argv);
        main_test_zlib();
        main_test_pthread_attr_setaffinity_np();
+       main_test_pthread_barrier();
        main_test_lzma();
        main_test_get_cpuid();
        main_test_bpf();
diff --git a/tools/build/feature/test-eventfd.c 
b/tools/build/feature/test-eventfd.c
new file mode 100644
index 000000000000..f4de7ef00ccb
--- /dev/null
+++ b/tools/build/feature/test-eventfd.c
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018, Red Hat Inc, Arnaldo Carvalho de Melo <[email protected]>
+
+#include <sys/eventfd.h>
+
+int main(void)
+{
+       return eventfd(0, EFD_NONBLOCK);
+}
diff --git a/tools/build/feature/test-get_current_dir_name.c 
b/tools/build/feature/test-get_current_dir_name.c
new file mode 100644
index 000000000000..573000f93212
--- /dev/null
+++ b/tools/build/feature/test-get_current_dir_name.c
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <stdlib.h>
+
+int main(void)
+{
+       free(get_current_dir_name());
+       return 0;
+}
diff --git a/tools/build/feature/test-gettid.c 
b/tools/build/feature/test-gettid.c
new file mode 100644
index 000000000000..ef24e42d3f1b
--- /dev/null
+++ b/tools/build/feature/test-gettid.c
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2019, Red Hat Inc, Arnaldo Carvalho de Melo <[email protected]>
+#define _GNU_SOURCE
+#include <unistd.h>
+
+int main(void)
+{
+       return gettid();
+}
+
+#undef _GNU_SOURCE
diff --git a/tools/build/feature/test-pthread-barrier.c 
b/tools/build/feature/test-pthread-barrier.c
new file mode 100644
index 000000000000..0558d9334d97
--- /dev/null
+++ b/tools/build/feature/test-pthread-barrier.c
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <stdint.h>
+#include <pthread.h>
+
+int main(void)
+{
+       pthread_barrier_t barrier;
+
+       pthread_barrier_init(&barrier, NULL, 1);
+       pthread_barrier_wait(&barrier);
+       return pthread_barrier_destroy(&barrier);
+}
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 8baaf9797101..63cf4b690043 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -272,6 +272,10 @@ ifeq ($(feature-pthread-attr-setaffinity-np), 1)
   CFLAGS += -DHAVE_PTHREAD_ATTR_SETAFFINITY_NP
 endif
 
+ifeq ($(feature-pthread-barrier), 1)
+  CFLAGS += -DHAVE_PTHREAD_BARRIER
+endif
+
 ifndef NO_BIONIC
   $(call feature_check,bionic)
   ifeq ($(feature-bionic), 1)
@@ -281,6 +285,18 @@ ifndef NO_BIONIC
   endif
 endif
 
+ifeq ($(feature-eventfd), 1)
+  CFLAGS += -DHAVE_EVENTFD
+endif
+
+ifeq ($(feature-get_current_dir_name), 1)
+  CFLAGS += -DHAVE_GET_CURRENT_DIR_NAME
+endif
+
+ifeq ($(feature-gettid), 1)
+  CFLAGS += -DHAVE_GETTID
+endif
+
 ifdef NO_LIBELF
   NO_DWARF := 1
   NO_DEMANGLE := 1
diff --git a/tools/perf/jvmti/jvmti_agent.c b/tools/perf/jvmti/jvmti_agent.c
index 4ad9948fe594..7ff0bd5036af 100644
--- a/tools/perf/jvmti/jvmti_agent.c
+++ b/tools/perf/jvmti/jvmti_agent.c
@@ -45,10 +45,12 @@
 static char jit_path[PATH_MAX];
 static void *marker_addr;
 
+#ifndef HAVE_GETTID
 static inline pid_t gettid(void)
 {
        return (pid_t)syscall(__NR_gettid);
 }
+#endif
 
 static int get_e_machine(struct jitheader *hdr)
 {
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 94518c1bf8b6..af20bf0d1f4d 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -10,6 +10,7 @@ libperf-y += evlist.o
 libperf-y += evsel.o
 libperf-y += evsel_fprintf.o
 libperf-y += find_bit.o
+libperf-y += get_current_dir_name.o
 libperf-y += kallsyms.o
 libperf-y += levenshtein.o
 libperf-y += llvm-utils.o
diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y
index 432b8560cf51..e7bd19c384ae 100644
--- a/tools/perf/util/expr.y
+++ b/tools/perf/util/expr.y
@@ -10,7 +10,8 @@
 #define MAXIDLEN 256
 %}
 
-%pure-parser
+%define api.pure full
+
 %parse-param { double *final_val }
 %parse-param { struct parse_ctx *ctx }
 %parse-param { const char **pp }
diff --git a/tools/perf/util/get_current_dir_name.c 
b/tools/perf/util/get_current_dir_name.c
new file mode 100644
index 000000000000..267aa609a582
--- /dev/null
+++ b/tools/perf/util/get_current_dir_name.c
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018, Red Hat Inc, Arnaldo Carvalho de Melo <[email protected]>
+//
+#ifndef HAVE_GET_CURRENT_DIR_NAME
+#include "util.h"
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdlib.h>
+
+/* Android's 'bionic' library, for one, doesn't have this */
+
+char *get_current_dir_name(void)
+{
+       char pwd[PATH_MAX];
+
+       return getcwd(pwd, sizeof(pwd)) == NULL ? NULL : strdup(pwd);
+}
+#endif // HAVE_GET_CURRENT_DIR_NAME
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index b6115cbdf842..ed2bae1fd721 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -1,4 +1,4 @@
-%pure-parser
+%define api.pure full
 %parse-param {void *_parse_state}
 %parse-param {void *scanner}
 %lex-param {void* scanner}
diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c
index 4105682afc7a..774412c4d98c 100644
--- a/tools/perf/util/srcline.c
+++ b/tools/perf/util/srcline.c
@@ -139,16 +139,30 @@ static void find_address_in_section(bfd *abfd, asection 
*section, void *data)
        bfd_vma pc, vma;
        bfd_size_type size;
        struct a2l_data *a2l = data;
+       flagword flags;
 
        if (a2l->found)
                return;
 
-       if ((bfd_get_section_flags(abfd, section) & SEC_ALLOC) == 0)
+#ifdef bfd_get_section_flags
+       flags = bfd_get_section_flags(abfd, section);
+#else
+       flags = bfd_section_flags(section);
+#endif
+       if ((flags & SEC_ALLOC) == 0)
                return;
 
        pc = a2l->addr;
+#ifdef bfd_get_section_vma
        vma = bfd_get_section_vma(abfd, section);
+#else
+       vma = bfd_section_vma(section);
+#endif
+#ifdef bfd_get_section_size
        size = bfd_get_section_size(section);
+#else
+       size = bfd_section_size(section);
+#endif
 
        if (pc < vma || pc >= vma + size)
                return;
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index b52765e6d7b4..ac2227d4ec05 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -57,6 +57,10 @@ int fetch_kernel_version(unsigned int *puint,
 
 const char *perf_tip(const char *dirpath);
 
+#ifndef HAVE_GET_CURRENT_DIR_NAME
+char *get_current_dir_name(void);
+#endif
+
 #ifndef HAVE_SCHED_GETCPU_SUPPORT
 int sched_getcpu(void);
 #endif
  • Linux 4.14.227 Greg Kroah-Hartman
    • Re: Linux 4.14.227 Greg Kroah-Hartman

Reply via email to