]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 12 Jan 2015 15:25:31 +0000 (07:25 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 12 Jan 2015 15:25:31 +0000 (07:25 -0800)
added patches:
ath9k-fix-be-bk-queue-order.patch
ath9k_hw-fix-hardware-queue-allocation.patch
drivers-rtc-rtc-isl12057.c-fix-masking-of-register-values.patch
drivers-rtc-rtc-sirfsoc.c-move-hardware-initilization-earlier-in-probe.patch
ocfs2-fix-journal-commit-deadlock.patch
ocfs2-fix-the-wrong-directory-passed-to-ocfs2_lookup_ino_from_name-when-link-file.patch

queue-3.14/ath9k-fix-be-bk-queue-order.patch [new file with mode: 0644]
queue-3.14/ath9k_hw-fix-hardware-queue-allocation.patch [new file with mode: 0644]
queue-3.14/drivers-rtc-rtc-isl12057.c-fix-masking-of-register-values.patch [new file with mode: 0644]
queue-3.14/drivers-rtc-rtc-sirfsoc.c-move-hardware-initilization-earlier-in-probe.patch [new file with mode: 0644]
queue-3.14/ocfs2-fix-journal-commit-deadlock.patch [new file with mode: 0644]
queue-3.14/ocfs2-fix-the-wrong-directory-passed-to-ocfs2_lookup_ino_from_name-when-link-file.patch [new file with mode: 0644]

diff --git a/queue-3.14/ath9k-fix-be-bk-queue-order.patch b/queue-3.14/ath9k-fix-be-bk-queue-order.patch
new file mode 100644 (file)
index 0000000..314979d
--- /dev/null
@@ -0,0 +1,33 @@
+From 78063d81d353e10cbdd279c490593113b8fdae1c Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Sun, 30 Nov 2014 20:38:41 +0100
+Subject: ath9k: fix BE/BK queue order
+
+From: Felix Fietkau <nbd@openwrt.org>
+
+commit 78063d81d353e10cbdd279c490593113b8fdae1c upstream.
+
+Hardware queues are ordered by priority. Use queue index 0 for BK, which
+has lower priority than BE.
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath9k/hw.h |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath9k/hw.h
++++ b/drivers/net/wireless/ath/ath9k/hw.h
+@@ -216,8 +216,8 @@
+ #define AH_WOW_BEACON_MISS            BIT(3)
+ enum ath_hw_txq_subtype {
+-      ATH_TXQ_AC_BE = 0,
+-      ATH_TXQ_AC_BK = 1,
++      ATH_TXQ_AC_BK = 0,
++      ATH_TXQ_AC_BE = 1,
+       ATH_TXQ_AC_VI = 2,
+       ATH_TXQ_AC_VO = 3,
+ };
diff --git a/queue-3.14/ath9k_hw-fix-hardware-queue-allocation.patch b/queue-3.14/ath9k_hw-fix-hardware-queue-allocation.patch
new file mode 100644 (file)
index 0000000..1f24559
--- /dev/null
@@ -0,0 +1,40 @@
+From ad8fdccf9c197a89e2d2fa78c453283dcc2c343f Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Sun, 30 Nov 2014 20:38:40 +0100
+Subject: ath9k_hw: fix hardware queue allocation
+
+From: Felix Fietkau <nbd@openwrt.org>
+
+commit ad8fdccf9c197a89e2d2fa78c453283dcc2c343f upstream.
+
+The driver passes the desired hardware queue index for a WMM data queue
+in qinfo->tqi_subtype. This was ignored in ath9k_hw_setuptxqueue, which
+instead relied on the order in which the function is called.
+
+Reported-by: Hubert Feurstein <h.feurstein@gmail.com>
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath9k/mac.c |    9 +--------
+ 1 file changed, 1 insertion(+), 8 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath9k/mac.c
++++ b/drivers/net/wireless/ath/ath9k/mac.c
+@@ -311,14 +311,7 @@ int ath9k_hw_setuptxqueue(struct ath_hw
+               q = ATH9K_NUM_TX_QUEUES - 3;
+               break;
+       case ATH9K_TX_QUEUE_DATA:
+-              for (q = 0; q < ATH9K_NUM_TX_QUEUES; q++)
+-                      if (ah->txq[q].tqi_type ==
+-                          ATH9K_TX_QUEUE_INACTIVE)
+-                              break;
+-              if (q == ATH9K_NUM_TX_QUEUES) {
+-                      ath_err(common, "No available TX queue\n");
+-                      return -1;
+-              }
++              q = qinfo->tqi_subtype;
+               break;
+       default:
+               ath_err(common, "Invalid TX queue type: %u\n", type);
diff --git a/queue-3.14/drivers-rtc-rtc-isl12057.c-fix-masking-of-register-values.patch b/queue-3.14/drivers-rtc-rtc-isl12057.c-fix-masking-of-register-values.patch
new file mode 100644 (file)
index 0000000..c6a8a8e
--- /dev/null
@@ -0,0 +1,64 @@
+From 5945b2880363ed7648e62aabba770ec57ff2a316 Mon Sep 17 00:00:00 2001
+From: Arnaud Ebalard <arno@natisbad.org>
+Date: Wed, 10 Dec 2014 15:54:02 -0800
+Subject: drivers/rtc/rtc-isl12057.c: fix masking of register values
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Arnaud Ebalard <arno@natisbad.org>
+
+commit 5945b2880363ed7648e62aabba770ec57ff2a316 upstream.
+
+When Intersil ISL12057 support was added by commit 70e123373c05 ("rtc: Add
+support for Intersil ISL12057 I2C RTC chip"), two masks for time registers
+values imported from the device were either wrong or omitted, leading to
+additional bits from those registers to impact read values:
+
+ - mask for hour register value when reading it in AM/PM mode. As
+   AM/PM mode is not the usual mode used by the driver, this error
+   would only have an impact on an externally configured RTC hour
+   later read by the driver.
+ - mask for month value. The lack of masking would provide an
+   erroneous value if century bit is set.
+
+This patch fixes those two masks.
+
+Fixes: 70e123373c05 ("rtc: Add support for Intersil ISL12057 I2C RTC chip")
+Signed-off-by: Arnaud Ebalard <arno@natisbad.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Alessandro Zummo <a.zummo@towertech.it>
+Cc: Peter Huewe <peter.huewe@infineon.com>
+Cc: Linus Walleij <linus.walleij@linaro.org>
+Cc: Thierry Reding <treding@nvidia.com>
+Cc: Mark Brown <broonie@kernel.org>
+Cc: Grant Likely <grant.likely@linaro.org>
+Acked-by: Uwe Kleine-König <uwe@kleine-koenig.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/rtc/rtc-isl12057.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/rtc/rtc-isl12057.c
++++ b/drivers/rtc/rtc-isl12057.c
+@@ -89,7 +89,7 @@ static void isl12057_rtc_regs_to_tm(stru
+       tm->tm_min = bcd2bin(regs[ISL12057_REG_RTC_MN]);
+       if (regs[ISL12057_REG_RTC_HR] & ISL12057_REG_RTC_HR_MIL) { /* AM/PM */
+-              tm->tm_hour = bcd2bin(regs[ISL12057_REG_RTC_HR] & 0x0f);
++              tm->tm_hour = bcd2bin(regs[ISL12057_REG_RTC_HR] & 0x1f);
+               if (regs[ISL12057_REG_RTC_HR] & ISL12057_REG_RTC_HR_PM)
+                       tm->tm_hour += 12;
+       } else {                                            /* 24 hour mode */
+@@ -98,7 +98,7 @@ static void isl12057_rtc_regs_to_tm(stru
+       tm->tm_mday = bcd2bin(regs[ISL12057_REG_RTC_DT]);
+       tm->tm_wday = bcd2bin(regs[ISL12057_REG_RTC_DW]) - 1; /* starts at 1 */
+-      tm->tm_mon  = bcd2bin(regs[ISL12057_REG_RTC_MO]) - 1; /* starts at 1 */
++      tm->tm_mon  = bcd2bin(regs[ISL12057_REG_RTC_MO] & 0x1f) - 1; /* ditto */
+       tm->tm_year = bcd2bin(regs[ISL12057_REG_RTC_YR]) + 100;
+ }
diff --git a/queue-3.14/drivers-rtc-rtc-sirfsoc.c-move-hardware-initilization-earlier-in-probe.patch b/queue-3.14/drivers-rtc-rtc-sirfsoc.c-move-hardware-initilization-earlier-in-probe.patch
new file mode 100644 (file)
index 0000000..a8c10e9
--- /dev/null
@@ -0,0 +1,57 @@
+From 0e95325525c4383565cea4f402f15a3113162d05 Mon Sep 17 00:00:00 2001
+From: Guo Zeng <guo.zeng@csr.com>
+Date: Wed, 10 Dec 2014 15:52:24 -0800
+Subject: drivers/rtc/rtc-sirfsoc.c: move hardware initilization earlier in probe
+
+From: Guo Zeng <guo.zeng@csr.com>
+
+commit 0e95325525c4383565cea4f402f15a3113162d05 upstream.
+
+Move rtc register to be later than hardware initialization.  The reason
+is that devm_rtc_device_register() will do read_time() which is a
+callback accessing hardware.  This sometimes causes a hang in the
+hardware related callback.
+
+Signed-off-by: Guo Zeng <guo.zeng@csr.com>
+Signed-off-by: Barry Song <Baohua.Song@csr.com>
+Cc: Alessandro Zummo <a.zummo@towertech.it>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/rtc/rtc-sirfsoc.c |   16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/rtc/rtc-sirfsoc.c
++++ b/drivers/rtc/rtc-sirfsoc.c
+@@ -290,14 +290,6 @@ static int sirfsoc_rtc_probe(struct plat
+       rtc_div = ((32768 / RTC_HZ) / 2) - 1;
+       sirfsoc_rtc_iobrg_writel(rtc_div, rtcdrv->rtc_base + RTC_DIV);
+-      rtcdrv->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
+-                      &sirfsoc_rtc_ops, THIS_MODULE);
+-      if (IS_ERR(rtcdrv->rtc)) {
+-              err = PTR_ERR(rtcdrv->rtc);
+-              dev_err(&pdev->dev, "can't register RTC device\n");
+-              return err;
+-      }
+-
+       /* 0x3 -> RTC_CLK */
+       sirfsoc_rtc_iobrg_writel(SIRFSOC_RTC_CLK,
+                       rtcdrv->rtc_base + RTC_CLOCK_SWITCH);
+@@ -312,6 +304,14 @@ static int sirfsoc_rtc_probe(struct plat
+       rtcdrv->overflow_rtc =
+               sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_SW_VALUE);
++      rtcdrv->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
++                      &sirfsoc_rtc_ops, THIS_MODULE);
++      if (IS_ERR(rtcdrv->rtc)) {
++              err = PTR_ERR(rtcdrv->rtc);
++              dev_err(&pdev->dev, "can't register RTC device\n");
++              return err;
++      }
++
+       rtcdrv->irq = platform_get_irq(pdev, 0);
+       err = devm_request_irq(
+                       &pdev->dev,
diff --git a/queue-3.14/ocfs2-fix-journal-commit-deadlock.patch b/queue-3.14/ocfs2-fix-journal-commit-deadlock.patch
new file mode 100644 (file)
index 0000000..e4e0952
--- /dev/null
@@ -0,0 +1,84 @@
+From 136f49b9171074872f2a14ad0ab10486d1ba13ca Mon Sep 17 00:00:00 2001
+From: Junxiao Bi <junxiao.bi@oracle.com>
+Date: Thu, 18 Dec 2014 16:17:37 -0800
+Subject: ocfs2: fix journal commit deadlock
+
+From: Junxiao Bi <junxiao.bi@oracle.com>
+
+commit 136f49b9171074872f2a14ad0ab10486d1ba13ca upstream.
+
+For buffer write, page lock will be got in write_begin and released in
+write_end, in ocfs2_write_end_nolock(), before it unlock the page in
+ocfs2_free_write_ctxt(), it calls ocfs2_run_deallocs(), this will ask
+for the read lock of journal->j_trans_barrier.  Holding page lock and
+ask for journal->j_trans_barrier breaks the locking order.
+
+This will cause a deadlock with journal commit threads, ocfs2cmt will
+get write lock of journal->j_trans_barrier first, then it wakes up
+kjournald2 to do the commit work, at last it waits until done.  To
+commit journal, kjournald2 needs flushing data first, it needs get the
+cache page lock.
+
+Since some ocfs2 cluster locks are holding by write process, this
+deadlock may hung the whole cluster.
+
+unlock pages before ocfs2_run_deallocs() can fix the locking order, also
+put unlock before ocfs2_commit_trans() to make page lock is unlocked
+before j_trans_barrier to preserve unlocking order.
+
+Signed-off-by: Junxiao Bi <junxiao.bi@oracle.com>
+Reviewed-by: Wengang Wang <wen.gang.wang@oracle.com>
+Reviewed-by: Mark Fasheh <mfasheh@suse.de>
+Cc: Joel Becker <jlbec@evilplan.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ocfs2/aops.c |   16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+--- a/fs/ocfs2/aops.c
++++ b/fs/ocfs2/aops.c
+@@ -899,7 +899,7 @@ void ocfs2_unlock_and_free_pages(struct
+       }
+ }
+-static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc)
++static void ocfs2_unlock_pages(struct ocfs2_write_ctxt *wc)
+ {
+       int i;
+@@ -920,7 +920,11 @@ static void ocfs2_free_write_ctxt(struct
+               page_cache_release(wc->w_target_page);
+       }
+       ocfs2_unlock_and_free_pages(wc->w_pages, wc->w_num_pages);
++}
++static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc)
++{
++      ocfs2_unlock_pages(wc);
+       brelse(wc->w_di_bh);
+       kfree(wc);
+ }
+@@ -2045,11 +2049,19 @@ out_write_size:
+       di->i_mtime_nsec = di->i_ctime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec);
+       ocfs2_journal_dirty(handle, wc->w_di_bh);
++      /* unlock pages before dealloc since it needs acquiring j_trans_barrier
++       * lock, or it will cause a deadlock since journal commit threads holds
++       * this lock and will ask for the page lock when flushing the data.
++       * put it here to preserve the unlock order.
++       */
++      ocfs2_unlock_pages(wc);
++
+       ocfs2_commit_trans(osb, handle);
+       ocfs2_run_deallocs(osb, &wc->w_dealloc);
+-      ocfs2_free_write_ctxt(wc);
++      brelse(wc->w_di_bh);
++      kfree(wc);
+       return copied;
+ }
diff --git a/queue-3.14/ocfs2-fix-the-wrong-directory-passed-to-ocfs2_lookup_ino_from_name-when-link-file.patch b/queue-3.14/ocfs2-fix-the-wrong-directory-passed-to-ocfs2_lookup_ino_from_name-when-link-file.patch
new file mode 100644 (file)
index 0000000..4263a0f
--- /dev/null
@@ -0,0 +1,164 @@
+From 53dc20b9a3d928b0744dad5aee65b610de1cc85d Mon Sep 17 00:00:00 2001
+From: Xue jiufei <xuejiufei@huawei.com>
+Date: Thu, 8 Jan 2015 14:32:23 -0800
+Subject: ocfs2: fix the wrong directory passed to ocfs2_lookup_ino_from_name() when link file
+
+From: Xue jiufei <xuejiufei@huawei.com>
+
+commit 53dc20b9a3d928b0744dad5aee65b610de1cc85d upstream.
+
+In ocfs2_link(), the parent directory inode passed to function
+ocfs2_lookup_ino_from_name() is wrong.  Parameter dir is the parent of
+new_dentry not old_dentry.  We should get old_dir from old_dentry and
+lookup old_dentry in old_dir in case another node remove the old dentry.
+
+With this change, hard linking works again, when paths are relative with
+at least one subdirectory.  This is how the problem was reproducable:
+
+  # mkdir a
+  # mkdir b
+  # touch a/test
+  # ln a/test b/test
+  ln: failed to create hard link `b/test' => `a/test': No such file or  directory
+
+However when creating links in the same dir, it worked well.
+
+Now the link gets created.
+
+Fixes: 0e048316ff57 ("ocfs2: check existence of old dentry in ocfs2_link()")
+Signed-off-by: joyce.xue <xuejiufei@huawei.com>
+Reported-by: Szabo Aron - UBIT <aron@ubit.hu>
+Cc: Mark Fasheh <mfasheh@suse.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Tested-by: Aron Szabo <aron@ubit.hu>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ocfs2/namei.c |   43 +++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 35 insertions(+), 8 deletions(-)
+
+--- a/fs/ocfs2/namei.c
++++ b/fs/ocfs2/namei.c
+@@ -94,6 +94,14 @@ static int ocfs2_create_symlink_data(str
+                                    struct inode *inode,
+                                    const char *symname);
++static int ocfs2_double_lock(struct ocfs2_super *osb,
++                           struct buffer_head **bh1,
++                           struct inode *inode1,
++                           struct buffer_head **bh2,
++                           struct inode *inode2,
++                           int rename);
++
++static void ocfs2_double_unlock(struct inode *inode1, struct inode *inode2);
+ /* An orphan dir name is an 8 byte value, printed as a hex string */
+ #define OCFS2_ORPHAN_NAMELEN ((int)(2 * sizeof(u64)))
+@@ -656,8 +664,10 @@ static int ocfs2_link(struct dentry *old
+ {
+       handle_t *handle;
+       struct inode *inode = old_dentry->d_inode;
++      struct inode *old_dir = old_dentry->d_parent->d_inode;
+       int err;
+       struct buffer_head *fe_bh = NULL;
++      struct buffer_head *old_dir_bh = NULL;
+       struct buffer_head *parent_fe_bh = NULL;
+       struct ocfs2_dinode *fe = NULL;
+       struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
+@@ -674,19 +684,33 @@ static int ocfs2_link(struct dentry *old
+       dquot_initialize(dir);
+-      err = ocfs2_inode_lock_nested(dir, &parent_fe_bh, 1, OI_LS_PARENT);
++      err = ocfs2_double_lock(osb, &old_dir_bh, old_dir,
++                      &parent_fe_bh, dir, 0);
+       if (err < 0) {
+               if (err != -ENOENT)
+                       mlog_errno(err);
+               return err;
+       }
++      /* make sure both dirs have bhs
++       * get an extra ref on old_dir_bh if old==new */
++      if (!parent_fe_bh) {
++              if (old_dir_bh) {
++                      parent_fe_bh = old_dir_bh;
++                      get_bh(parent_fe_bh);
++              } else {
++                      mlog(ML_ERROR, "%s: no old_dir_bh!\n", osb->uuid_str);
++                      err = -EIO;
++                      goto out;
++              }
++      }
++
+       if (!dir->i_nlink) {
+               err = -ENOENT;
+               goto out;
+       }
+-      err = ocfs2_lookup_ino_from_name(dir, old_dentry->d_name.name,
++      err = ocfs2_lookup_ino_from_name(old_dir, old_dentry->d_name.name,
+                       old_dentry->d_name.len, &old_de_ino);
+       if (err) {
+               err = -ENOENT;
+@@ -779,10 +803,11 @@ out_unlock_inode:
+       ocfs2_inode_unlock(inode, 1);
+ out:
+-      ocfs2_inode_unlock(dir, 1);
++      ocfs2_double_unlock(old_dir, dir);
+       brelse(fe_bh);
+       brelse(parent_fe_bh);
++      brelse(old_dir_bh);
+       ocfs2_free_dir_lookup_result(&lookup);
+@@ -991,14 +1016,15 @@ leave:
+ }
+ /*
+- * The only place this should be used is rename!
++ * The only place this should be used is rename and link!
+  * if they have the same id, then the 1st one is the only one locked.
+  */
+ static int ocfs2_double_lock(struct ocfs2_super *osb,
+                            struct buffer_head **bh1,
+                            struct inode *inode1,
+                            struct buffer_head **bh2,
+-                           struct inode *inode2)
++                           struct inode *inode2,
++                           int rename)
+ {
+       int status;
+       struct ocfs2_inode_info *oi1 = OCFS2_I(inode1);
+@@ -1028,7 +1054,7 @@ static int ocfs2_double_lock(struct ocfs
+               }
+               /* lock id2 */
+               status = ocfs2_inode_lock_nested(inode2, bh2, 1,
+-                                               OI_LS_RENAME1);
++                              rename == 1 ? OI_LS_RENAME1 : OI_LS_PARENT);
+               if (status < 0) {
+                       if (status != -ENOENT)
+                               mlog_errno(status);
+@@ -1037,7 +1063,8 @@ static int ocfs2_double_lock(struct ocfs
+       }
+       /* lock id1 */
+-      status = ocfs2_inode_lock_nested(inode1, bh1, 1, OI_LS_RENAME2);
++      status = ocfs2_inode_lock_nested(inode1, bh1, 1,
++                      rename == 1 ?  OI_LS_RENAME2 : OI_LS_PARENT);
+       if (status < 0) {
+               /*
+                * An error return must mean that no cluster locks
+@@ -1137,7 +1164,7 @@ static int ocfs2_rename(struct inode *ol
+       /* if old and new are the same, this'll just do one lock. */
+       status = ocfs2_double_lock(osb, &old_dir_bh, old_dir,
+-                                 &new_dir_bh, new_dir);
++                                 &new_dir_bh, new_dir, 1);
+       if (status < 0) {
+               mlog_errno(status);
+               goto bail;