From: Greg Kroah-Hartman Date: Sat, 2 May 2015 17:46:01 +0000 (+0200) Subject: 3.14-stable patches X-Git-Tag: v3.10.77~27 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=566caf94903b62138215f0e98226f17f1071fe33;p=thirdparty%2Fkernel%2Fstable-queue.git 3.14-stable patches added patches: drm-i915-cope-with-large-i2c-transfers.patch drm-radeon-fix-doublescan-modes-v2.patch ksoftirqd-enable-irqs-and-call-cond_resched-before-poking-rcu.patch rcu-pathwalk-breakage-when-running-into-a-symlink-overmounting-something.patch --- diff --git a/queue-3.14/drm-i915-cope-with-large-i2c-transfers.patch b/queue-3.14/drm-i915-cope-with-large-i2c-transfers.patch new file mode 100644 index 00000000000..104846fe00f --- /dev/null +++ b/queue-3.14/drm-i915-cope-with-large-i2c-transfers.patch @@ -0,0 +1,145 @@ +From 9535c4757b881e06fae72a857485ad57c422b8d2 Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Tue, 21 Apr 2015 09:49:11 -0700 +Subject: drm/i915: cope with large i2c transfers + +From: Dmitry Torokhov + +commit 9535c4757b881e06fae72a857485ad57c422b8d2 upstream. + +The hardware, according to the specs, is limited to 256 byte transfers, +and current driver has no protections in case users attempt to do larger +transfers. The code will just stomp over status register and mayhem +ensues. + +Let's split larger transfers into digestable chunks. Doing this allows +Atmel MXT driver on Pixel 1 function properly (it hasn't since commit +9d8dc3e529a19e427fd379118acd132520935c5d "Input: atmel_mxt_ts - +implement T44 message handling" which tries to consume multiple +touchscreen/touchpad reports in a single transaction). + +Reviewed-by: Chris Wilson +Signed-off-by: Dmitry Torokhov +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_i2c.c | 66 +++++++++++++++++++++++++++++++++------ + 2 files changed, 57 insertions(+), 10 deletions(-) + +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -1181,6 +1181,7 @@ + #define GMBUS_CYCLE_INDEX (2<<25) + #define GMBUS_CYCLE_STOP (4<<25) + #define GMBUS_BYTE_COUNT_SHIFT 16 ++#define GMBUS_BYTE_COUNT_MAX 256U + #define GMBUS_SLAVE_INDEX_SHIFT 8 + #define GMBUS_SLAVE_ADDR_SHIFT 1 + #define GMBUS_SLAVE_READ (1<<0) +--- a/drivers/gpu/drm/i915/intel_i2c.c ++++ b/drivers/gpu/drm/i915/intel_i2c.c +@@ -324,18 +324,17 @@ gmbus_wait_idle(struct drm_i915_private + } + + static int +-gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg, +- u32 gmbus1_index) ++gmbus_xfer_read_chunk(struct drm_i915_private *dev_priv, ++ unsigned short addr, u8 *buf, unsigned int len, ++ u32 gmbus1_index) + { + int reg_offset = dev_priv->gpio_mmio_base; +- u16 len = msg->len; +- u8 *buf = msg->buf; + + I915_WRITE(GMBUS1 + reg_offset, + gmbus1_index | + GMBUS_CYCLE_WAIT | + (len << GMBUS_BYTE_COUNT_SHIFT) | +- (msg->addr << GMBUS_SLAVE_ADDR_SHIFT) | ++ (addr << GMBUS_SLAVE_ADDR_SHIFT) | + GMBUS_SLAVE_READ | GMBUS_SW_RDY); + while (len) { + int ret; +@@ -357,11 +356,35 @@ gmbus_xfer_read(struct drm_i915_private + } + + static int +-gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg) ++gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg, ++ u32 gmbus1_index) + { +- int reg_offset = dev_priv->gpio_mmio_base; +- u16 len = msg->len; + u8 *buf = msg->buf; ++ unsigned int rx_size = msg->len; ++ unsigned int len; ++ int ret; ++ ++ do { ++ len = min(rx_size, GMBUS_BYTE_COUNT_MAX); ++ ++ ret = gmbus_xfer_read_chunk(dev_priv, msg->addr, ++ buf, len, gmbus1_index); ++ if (ret) ++ return ret; ++ ++ rx_size -= len; ++ buf += len; ++ } while (rx_size != 0); ++ ++ return 0; ++} ++ ++static int ++gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv, ++ unsigned short addr, u8 *buf, unsigned int len) ++{ ++ int reg_offset = dev_priv->gpio_mmio_base; ++ unsigned int chunk_size = len; + u32 val, loop; + + val = loop = 0; +@@ -373,8 +396,8 @@ gmbus_xfer_write(struct drm_i915_private + I915_WRITE(GMBUS3 + reg_offset, val); + I915_WRITE(GMBUS1 + reg_offset, + GMBUS_CYCLE_WAIT | +- (msg->len << GMBUS_BYTE_COUNT_SHIFT) | +- (msg->addr << GMBUS_SLAVE_ADDR_SHIFT) | ++ (chunk_size << GMBUS_BYTE_COUNT_SHIFT) | ++ (addr << GMBUS_SLAVE_ADDR_SHIFT) | + GMBUS_SLAVE_WRITE | GMBUS_SW_RDY); + while (len) { + int ret; +@@ -391,6 +414,29 @@ gmbus_xfer_write(struct drm_i915_private + if (ret) + return ret; + } ++ ++ return 0; ++} ++ ++static int ++gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg) ++{ ++ u8 *buf = msg->buf; ++ unsigned int tx_size = msg->len; ++ unsigned int len; ++ int ret; ++ ++ do { ++ len = min(tx_size, GMBUS_BYTE_COUNT_MAX); ++ ++ ret = gmbus_xfer_write_chunk(dev_priv, msg->addr, buf, len); ++ if (ret) ++ return ret; ++ ++ buf += len; ++ tx_size -= len; ++ } while (tx_size != 0); ++ + return 0; + } + diff --git a/queue-3.14/drm-radeon-fix-doublescan-modes-v2.patch b/queue-3.14/drm-radeon-fix-doublescan-modes-v2.patch new file mode 100644 index 00000000000..baae5e8a923 --- /dev/null +++ b/queue-3.14/drm-radeon-fix-doublescan-modes-v2.patch @@ -0,0 +1,46 @@ +From fd99a0943ffaa0320ea4f69d09ed188f950c0432 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Tue, 24 Feb 2015 11:29:21 -0500 +Subject: drm/radeon: fix doublescan modes (v2) + +From: Alex Deucher + +commit fd99a0943ffaa0320ea4f69d09ed188f950c0432 upstream. + +Use the correct flags for atom. + +v2: handle DRM_MODE_FLAG_DBLCLK + +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/atombios_crtc.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/radeon/atombios_crtc.c ++++ b/drivers/gpu/drm/radeon/atombios_crtc.c +@@ -330,8 +330,10 @@ atombios_set_crtc_dtd_timing(struct drm_ + misc |= ATOM_COMPOSITESYNC; + if (mode->flags & DRM_MODE_FLAG_INTERLACE) + misc |= ATOM_INTERLACE; +- if (mode->flags & DRM_MODE_FLAG_DBLSCAN) ++ if (mode->flags & DRM_MODE_FLAG_DBLCLK) + misc |= ATOM_DOUBLE_CLOCK_MODE; ++ if (mode->flags & DRM_MODE_FLAG_DBLSCAN) ++ misc |= ATOM_H_REPLICATIONBY2 | ATOM_V_REPLICATIONBY2; + + args.susModeMiscInfo.usAccess = cpu_to_le16(misc); + args.ucCRTC = radeon_crtc->crtc_id; +@@ -374,8 +376,10 @@ static void atombios_crtc_set_timing(str + misc |= ATOM_COMPOSITESYNC; + if (mode->flags & DRM_MODE_FLAG_INTERLACE) + misc |= ATOM_INTERLACE; +- if (mode->flags & DRM_MODE_FLAG_DBLSCAN) ++ if (mode->flags & DRM_MODE_FLAG_DBLCLK) + misc |= ATOM_DOUBLE_CLOCK_MODE; ++ if (mode->flags & DRM_MODE_FLAG_DBLSCAN) ++ misc |= ATOM_H_REPLICATIONBY2 | ATOM_V_REPLICATIONBY2; + + args.susModeMiscInfo.usAccess = cpu_to_le16(misc); + args.ucCRTC = radeon_crtc->crtc_id; diff --git a/queue-3.14/ksoftirqd-enable-irqs-and-call-cond_resched-before-poking-rcu.patch b/queue-3.14/ksoftirqd-enable-irqs-and-call-cond_resched-before-poking-rcu.patch new file mode 100644 index 00000000000..b32ffb8c6df --- /dev/null +++ b/queue-3.14/ksoftirqd-enable-irqs-and-call-cond_resched-before-poking-rcu.patch @@ -0,0 +1,51 @@ +From 28423ad283d5348793b0c45cc9b1af058e776fd6 Mon Sep 17 00:00:00 2001 +From: Calvin Owens +Date: Tue, 13 Jan 2015 13:16:18 -0800 +Subject: ksoftirqd: Enable IRQs and call cond_resched() before poking RCU + +From: Calvin Owens + +commit 28423ad283d5348793b0c45cc9b1af058e776fd6 upstream. + +While debugging an issue with excessive softirq usage, I encountered the +following note in commit 3e339b5dae24a706 ("softirq: Use hotplug thread +infrastructure"): + + [ paulmck: Call rcu_note_context_switch() with interrupts enabled. ] + +...but despite this note, the patch still calls RCU with IRQs disabled. + +This seemingly innocuous change caused a significant regression in softirq +CPU usage on the sending side of a large TCP transfer (~1 GB/s): when +introducing 0.01% packet loss, the softirq usage would jump to around 25%, +spiking as high as 50%. Before the change, the usage would never exceed 5%. + +Moving the call to rcu_note_context_switch() after the cond_sched() call, +as it was originally before the hotplug patch, completely eliminated this +problem. + +Signed-off-by: Calvin Owens +Signed-off-by: Paul E. McKenney +Signed-off-by: Mike Galbraith +Signed-off-by: Greg Kroah-Hartman +--- + kernel/softirq.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/kernel/softirq.c ++++ b/kernel/softirq.c +@@ -657,9 +657,13 @@ static void run_ksoftirqd(unsigned int c + * in the task stack here. + */ + __do_softirq(); +- rcu_note_context_switch(cpu); + local_irq_enable(); + cond_resched(); ++ ++ preempt_disable(); ++ rcu_note_context_switch(cpu); ++ preempt_enable(); ++ + return; + } + local_irq_enable(); diff --git a/queue-3.14/rcu-pathwalk-breakage-when-running-into-a-symlink-overmounting-something.patch b/queue-3.14/rcu-pathwalk-breakage-when-running-into-a-symlink-overmounting-something.patch new file mode 100644 index 00000000000..0b335f04758 --- /dev/null +++ b/queue-3.14/rcu-pathwalk-breakage-when-running-into-a-symlink-overmounting-something.patch @@ -0,0 +1,45 @@ +From 3cab989afd8d8d1bc3d99fef0e7ed87c31e7b647 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Fri, 24 Apr 2015 15:47:07 -0400 +Subject: RCU pathwalk breakage when running into a symlink overmounting something + +From: Al Viro + +commit 3cab989afd8d8d1bc3d99fef0e7ed87c31e7b647 upstream. + +Calling unlazy_walk() in walk_component() and do_last() when we find +a symlink that needs to be followed doesn't acquire a reference to vfsmount. +That's fine when the symlink is on the same vfsmount as the parent directory +(which is almost always the case), but it's not always true - one _can_ +manage to bind a symlink on top of something. And in such cases we end up +with excessive mntput(). + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/namei.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -1545,7 +1545,8 @@ static inline int walk_component(struct + + if (should_follow_link(path->dentry, follow)) { + if (nd->flags & LOOKUP_RCU) { +- if (unlikely(unlazy_walk(nd, path->dentry))) { ++ if (unlikely(nd->path.mnt != path->mnt || ++ unlazy_walk(nd, path->dentry))) { + err = -ECHILD; + goto out_err; + } +@@ -2992,7 +2993,8 @@ finish_lookup: + + if (should_follow_link(path->dentry, !symlink_ok)) { + if (nd->flags & LOOKUP_RCU) { +- if (unlikely(unlazy_walk(nd, path->dentry))) { ++ if (unlikely(nd->path.mnt != path->mnt || ++ unlazy_walk(nd, path->dentry))) { + error = -ECHILD; + goto out; + } diff --git a/queue-3.14/series b/queue-3.14/series index e97ef5834f1..359dc6e1451 100644 --- a/queue-3.14/series +++ b/queue-3.14/series @@ -78,3 +78,7 @@ ib-core-disallow-registering-0-sized-memory-region.patch ib-core-don-t-disallow-registering-region-starting-at-0x0.patch ib-mlx4-fix-wqe-lso-segment-calculation.patch i2c-core-export-bus-recovery-functions.patch +drm-radeon-fix-doublescan-modes-v2.patch +drm-i915-cope-with-large-i2c-transfers.patch +rcu-pathwalk-breakage-when-running-into-a-symlink-overmounting-something.patch +ksoftirqd-enable-irqs-and-call-cond_resched-before-poking-rcu.patch