This is a note to let you know that I've just added the patch titled
scsi: lpfc: Fix crash receiving ELS while detaching driver
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
scsi-lpfc-fix-crash-receiving-els-while-detaching-driver.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 1234a6d54fed8a00091968c4eb2fb52e1cbb8e2e Mon Sep 17 00:00:00 2001
From: Dick Kennedy <dick.kennedy(a)broadcom.com>
Date: Fri, 29 Sep 2017 17:34:29 -0700
Subject: scsi: lpfc: Fix crash receiving ELS while detaching driver
From: Dick Kennedy <dick.kennedy(a)broadcom.com>
commit 1234a6d54fed8a00091968c4eb2fb52e1cbb8e2e upstream.
The driver crashes when attempting to use a freed ndpl pointer.
The pci_remove_one handler runs on a separate kernel thread. The order
of the removal is starting by freeing all of the ndlps and then
disabling interrupts. In between these two events the driver can still
receive an ELS and process it. When it tries to use the ndlp pointer
will be NULL
Change the order of the pci_remove_one vs disable interrupts so that
interrupts are disabled before the ndlp's are freed.
Signed-off-by: Dick Kennedy <dick.kennedy(a)broadcom.com>
Signed-off-by: James Smart <james.smart(a)broadcom.com>
Reviewed-by: Johannes Thumshirn <jthumshirn(a)suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen(a)oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/scsi/lpfc/lpfc_attr.c | 6 ++++--
drivers/scsi/lpfc/lpfc_bsg.c | 4 +++-
drivers/scsi/lpfc/lpfc_els.c | 7 ++++++-
drivers/scsi/lpfc/lpfc_hbadisc.c | 5 ++++-
drivers/scsi/lpfc/lpfc_init.c | 14 +++++++-------
drivers/scsi/lpfc/lpfc_nportdisc.c | 2 +-
drivers/scsi/lpfc/lpfc_sli.c | 12 ++++++++++++
7 files changed, 37 insertions(+), 13 deletions(-)
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -3134,7 +3134,8 @@ lpfc_txq_hw_show(struct device *dev, str
struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba;
struct lpfc_sli_ring *pring = lpfc_phba_elsring(phba);
- return snprintf(buf, PAGE_SIZE, "%d\n", pring->txq_max);
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ pring ? pring->txq_max : 0);
}
static DEVICE_ATTR(txq_hw, S_IRUGO,
@@ -3147,7 +3148,8 @@ lpfc_txcmplq_hw_show(struct device *dev,
struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba;
struct lpfc_sli_ring *pring = lpfc_phba_elsring(phba);
- return snprintf(buf, PAGE_SIZE, "%d\n", pring->txcmplq_max);
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ pring ? pring->txcmplq_max : 0);
}
static DEVICE_ATTR(txcmplq_hw, S_IRUGO,
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -2911,7 +2911,7 @@ static int lpfcdiag_loop_post_rxbufs(str
}
}
- if (!cmdiocbq || !rxbmp || !rxbpl || !rxbuffer) {
+ if (!cmdiocbq || !rxbmp || !rxbpl || !rxbuffer || !pring) {
ret_val = -ENOMEM;
goto err_post_rxbufs_exit;
}
@@ -5421,6 +5421,8 @@ lpfc_bsg_timeout(struct bsg_job *job)
struct lpfc_iocbq *check_iocb, *next_iocb;
pring = lpfc_phba_elsring(phba);
+ if (unlikely(!pring))
+ return -EIO;
/* if job's driver data is NULL, the command completed or is in the
* the process of completing. In this case, return status to request
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -7430,6 +7430,8 @@ lpfc_els_timeout_handler(struct lpfc_vpo
timeout = (uint32_t)(phba->fc_ratov << 1);
pring = lpfc_phba_elsring(phba);
+ if (unlikely(!pring))
+ return;
if ((phba->pport->load_flag & FC_UNLOADING))
return;
@@ -9310,6 +9312,9 @@ void lpfc_fabric_abort_nport(struct lpfc
pring = lpfc_phba_elsring(phba);
+ if (unlikely(!pring))
+ return;
+
spin_lock_irq(&phba->hbalock);
list_for_each_entry_safe(piocb, tmp_iocb, &phba->fabric_iocb_list,
list) {
@@ -9416,7 +9421,7 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hb
rxid, 1);
/* Check if TXQ queue needs to be serviced */
- if (!(list_empty(&pring->txq)))
+ if (pring && !list_empty(&pring->txq))
lpfc_worker_wake_up(phba);
return;
}
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -3324,7 +3324,8 @@ lpfc_mbx_cmpl_read_topology(struct lpfc_
/* Unblock ELS traffic */
pring = lpfc_phba_elsring(phba);
- pring->flag &= ~LPFC_STOP_IOCB_EVENT;
+ if (pring)
+ pring->flag &= ~LPFC_STOP_IOCB_EVENT;
/* Check for error */
if (mb->mbxStatus) {
@@ -5430,6 +5431,8 @@ lpfc_free_tx(struct lpfc_hba *phba, stru
psli = &phba->sli;
pring = lpfc_phba_elsring(phba);
+ if (unlikely(!pring))
+ return;
/* Error matching iocb on txq or txcmplq
* First check the txq.
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -11404,6 +11404,13 @@ lpfc_pci_remove_one_s4(struct pci_dev *p
/* Remove FC host and then SCSI host with the physical port */
fc_remove_host(shost);
scsi_remove_host(shost);
+ /*
+ * Bring down the SLI Layer. This step disables all interrupts,
+ * clears the rings, discards all mailbox commands, and resets
+ * the HBA FCoE function.
+ */
+ lpfc_debugfs_terminate(vport);
+ lpfc_sli4_hba_unset(phba);
/* Perform ndlp cleanup on the physical port. The nvme and nvmet
* localports are destroyed after to cleanup all transport memory.
@@ -11412,13 +11419,6 @@ lpfc_pci_remove_one_s4(struct pci_dev *p
lpfc_nvmet_destroy_targetport(phba);
lpfc_nvme_destroy_localport(vport);
- /*
- * Bring down the SLI Layer. This step disables all interrupts,
- * clears the rings, discards all mailbox commands, and resets
- * the HBA FCoE function.
- */
- lpfc_debugfs_terminate(vport);
- lpfc_sli4_hba_unset(phba);
lpfc_stop_hba_timers(phba);
spin_lock_irq(&phba->hbalock);
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -216,7 +216,7 @@ lpfc_els_abort(struct lpfc_hba *phba, st
pring = lpfc_phba_elsring(phba);
/* In case of error recovery path, we might have a NULL pring here */
- if (!pring)
+ if (unlikely(!pring))
return;
/* Abort outstanding I/O on NPort <nlp_DID> */
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -10632,6 +10632,14 @@ lpfc_sli_issue_abort_iotag(struct lpfc_h
(cmdiocb->iocb_flag & LPFC_DRIVER_ABORTED) != 0)
return 0;
+ if (!pring) {
+ if (cmdiocb->iocb_flag & LPFC_IO_FABRIC)
+ cmdiocb->fabric_iocb_cmpl = lpfc_ignore_els_cmpl;
+ else
+ cmdiocb->iocb_cmpl = lpfc_ignore_els_cmpl;
+ goto abort_iotag_exit;
+ }
+
/*
* If we're unloading, don't abort iocb on the ELS ring, but change
* the callback so that nothing happens when it finishes.
@@ -12500,6 +12508,8 @@ lpfc_sli4_els_wcqe_to_rspiocbq(struct lp
unsigned long iflags;
pring = lpfc_phba_elsring(phba);
+ if (unlikely(!pring))
+ return NULL;
wcqe = &irspiocbq->cq_event.cqe.wcqe_cmpl;
spin_lock_irqsave(&pring->ring_lock, iflags);
@@ -18694,6 +18704,8 @@ lpfc_drain_txq(struct lpfc_hba *phba)
uint32_t txq_cnt = 0;
pring = lpfc_phba_elsring(phba);
+ if (unlikely(!pring))
+ return 0;
spin_lock_irqsave(&pring->ring_lock, iflags);
list_for_each_entry(piocbq, &pring->txq, list) {
Patches currently in stable-queue which might be from dick.kennedy(a)broadcom.com are
queue-4.14/scsi-lpfc-fix-crash-receiving-els-while-detaching-driver.patch
queue-4.14/scsi-lpfc-fix-pci-hot-plug-crash-in-list_add-call.patch
queue-4.14/scsi-lpfc-fix-pci-hot-plug-crash-in-timer-management-routines.patch
queue-4.14/scsi-lpfc-fix-fcp-hba_wqidx-assignment.patch
queue-4.14/scsi-lpfc-fix-oops-if-nvmet_fc_register_targetport-fails.patch
This is a note to let you know that I've just added the patch titled
rtlwifi: rtl8192ee: Fix memory leak when loading firmware
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
rtlwifi-rtl8192ee-fix-memory-leak-when-loading-firmware.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 519ce2f933fa14acf69d5c8cabcc18711943d629 Mon Sep 17 00:00:00 2001
From: Larry Finger <Larry.Finger(a)lwfinger.net>
Date: Thu, 14 Sep 2017 13:17:44 -0500
Subject: rtlwifi: rtl8192ee: Fix memory leak when loading firmware
From: Larry Finger <Larry.Finger(a)lwfinger.net>
commit 519ce2f933fa14acf69d5c8cabcc18711943d629 upstream.
In routine rtl92ee_set_fw_rsvdpagepkt(), the driver allocates an skb, but
never calls rtl_cmd_send_packet(), which will free the buffer. All other
rtlwifi drivers perform this operation correctly.
This problem has been in the driver since it was included in the kernel.
Fortunately, each firmware load only leaks 4 buffers, which likely
explains why it has not previously been detected.
Signed-off-by: Larry Finger <Larry.Finger(a)lwfinger.net>
Signed-off-by: Kalle Valo <kvalo(a)codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c
@@ -682,7 +682,7 @@ void rtl92ee_set_fw_rsvdpagepkt(struct i
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct sk_buff *skb = NULL;
-
+ bool rtstatus;
u32 totalpacketlen;
u8 u1rsvdpageloc[5] = { 0 };
bool b_dlok = false;
@@ -768,7 +768,9 @@ void rtl92ee_set_fw_rsvdpagepkt(struct i
skb = dev_alloc_skb(totalpacketlen);
skb_put_data(skb, &reserved_page_packet, totalpacketlen);
- b_dlok = true;
+ rtstatus = rtl_cmd_send_packet(hw, skb);
+ if (rtstatus)
+ b_dlok = true;
if (b_dlok) {
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD ,
Patches currently in stable-queue which might be from Larry.Finger(a)lwfinger.net are
queue-4.14/rtlwifi-fix-uninitialized-rtlhal-last_suspend_sec-time.patch
queue-4.14/rtlwifi-rtl8192ee-fix-memory-leak-when-loading-firmware.patch
This is a note to let you know that I've just added the patch titled
rtlwifi: fix uninitialized rtlhal->last_suspend_sec time
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
rtlwifi-fix-uninitialized-rtlhal-last_suspend_sec-time.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 3f2a162fab15aee243178b5308bb5d1206fc4043 Mon Sep 17 00:00:00 2001
From: Arnd Bergmann <arnd(a)arndb.de>
Date: Mon, 6 Nov 2017 14:55:35 +0100
Subject: rtlwifi: fix uninitialized rtlhal->last_suspend_sec time
From: Arnd Bergmann <arnd(a)arndb.de>
commit 3f2a162fab15aee243178b5308bb5d1206fc4043 upstream.
We set rtlhal->last_suspend_sec to an uninitialized stack variable,
but unfortunately gcc never warned about this, I only found it
while working on another patch. I opened a gcc bug for this.
Presumably the value of rtlhal->last_suspend_sec is not all that
important, but it does get used, so we probably want the
patch backported to stable kernels.
Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82839
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
Acked-by: Larry Finger <Larry.Finger(a)lwfinger.net>
Signed-off-by: Kalle Valo <kvalo(a)codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
@@ -1372,6 +1372,7 @@ static void _rtl8821ae_get_wakeup_reason
ppsc->wakeup_reason = 0;
+ do_gettimeofday(&ts);
rtlhal->last_suspend_sec = ts.tv_sec;
switch (fw_reason) {
Patches currently in stable-queue which might be from arnd(a)arndb.de are
queue-4.14/rtlwifi-fix-uninitialized-rtlhal-last_suspend_sec-time.patch
queue-4.14/isofs-fix-timestamps-beyond-2027.patch
This is a note to let you know that I've just added the patch titled
rt2x00usb: mark device removed when get ENOENT usb error
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
rt2x00usb-mark-device-removed-when-get-enoent-usb-error.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From bfa62a52cad93686bb8d8171ea5288813248a7c6 Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <sgruszka(a)redhat.com>
Date: Thu, 9 Nov 2017 11:59:24 +0100
Subject: rt2x00usb: mark device removed when get ENOENT usb error
From: Stanislaw Gruszka <sgruszka(a)redhat.com>
commit bfa62a52cad93686bb8d8171ea5288813248a7c6 upstream.
ENOENT usb error mean "specified interface or endpoint does not exist or
is not enabled". Mark device not present when we encounter this error
similar like we do with ENODEV error.
Otherwise we can have infinite loop in rt2x00usb_work_rxdone(), because
we remove and put again RX entries to the queue infinitely.
We can have similar situation when submit urb will fail all the time
with other error, so we need consider to limit number of entries
processed by rxdone work. But for now, since the patch fixes
reproducible soft lockup issue on single processor systems
and taken ENOENT error meaning, let apply this fix.
Patch adds additional ENOENT check not only in rx kick routine, but
also on other places where we check for ENODEV error.
Reported-by: Richard Genoud <richard.genoud(a)gmail.com>
Debugged-by: Richard Genoud <richard.genoud(a)gmail.com>
Signed-off-by: Stanislaw Gruszka <sgruszka(a)redhat.com>
Tested-by: Richard Genoud <richard.genoud(a)gmail.com>
Signed-off-by: Kalle Valo <kvalo(a)codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/net/wireless/ralink/rt2x00/rt2x00usb.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
@@ -57,7 +57,7 @@ int rt2x00usb_vendor_request(struct rt2x
if (status >= 0)
return 0;
- if (status == -ENODEV) {
+ if (status == -ENODEV || status == -ENOENT) {
/* Device has disappeared. */
clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
break;
@@ -321,7 +321,7 @@ static bool rt2x00usb_kick_tx_entry(stru
status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
if (status) {
- if (status == -ENODEV)
+ if (status == -ENODEV || status == -ENOENT)
clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
rt2x00lib_dmadone(entry);
@@ -410,7 +410,7 @@ static bool rt2x00usb_kick_rx_entry(stru
status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
if (status) {
- if (status == -ENODEV)
+ if (status == -ENODEV || status == -ENOENT)
clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
rt2x00lib_dmadone(entry);
Patches currently in stable-queue which might be from sgruszka(a)redhat.com are
queue-4.14/rt2x00usb-mark-device-removed-when-get-enoent-usb-error.patch
This is a note to let you know that I've just added the patch titled
raid1: prevent freeze_array/wait_all_barriers deadlock
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
raid1-prevent-freeze_array-wait_all_barriers-deadlock.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From f6eca2d43ed694ab8124dd24c88277f7eca93b7d Mon Sep 17 00:00:00 2001
From: Nate Dailey <nate.dailey(a)stratus.com>
Date: Tue, 17 Oct 2017 08:17:03 -0400
Subject: raid1: prevent freeze_array/wait_all_barriers deadlock
From: Nate Dailey <nate.dailey(a)stratus.com>
commit f6eca2d43ed694ab8124dd24c88277f7eca93b7d upstream.
If freeze_array is attempted in the middle of close_sync/
wait_all_barriers, deadlock can occur.
freeze_array will wait for nr_pending and nr_queued to line up.
wait_all_barriers increments nr_pending for each barrier bucket, one
at a time, but doesn't actually issue IO that could be counted in
nr_queued. So freeze_array is blocked until wait_all_barriers
completes and allow_all_barriers runs. At the same time, when
_wait_barrier sees array_frozen == 1, it stops and waits for
freeze_array to complete.
Prevent the deadlock by making close_sync call _wait_barrier and
_allow_barrier for one bucket at a time, instead of deferring the
_allow_barrier calls until after all _wait_barriers are complete.
Signed-off-by: Nate Dailey <nate.dailey(a)stratus.com>
Fix: fd76863e37fe(RAID1: a new I/O barrier implementation to remove resync window)
Reviewed-by: Coly Li <colyli(a)suse.de>
Signed-off-by: Shaohua Li <shli(a)fb.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/md/raid1.c | 24 ++++++------------------
1 file changed, 6 insertions(+), 18 deletions(-)
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -990,14 +990,6 @@ static void wait_barrier(struct r1conf *
_wait_barrier(conf, idx);
}
-static void wait_all_barriers(struct r1conf *conf)
-{
- int idx;
-
- for (idx = 0; idx < BARRIER_BUCKETS_NR; idx++)
- _wait_barrier(conf, idx);
-}
-
static void _allow_barrier(struct r1conf *conf, int idx)
{
atomic_dec(&conf->nr_pending[idx]);
@@ -1011,14 +1003,6 @@ static void allow_barrier(struct r1conf
_allow_barrier(conf, idx);
}
-static void allow_all_barriers(struct r1conf *conf)
-{
- int idx;
-
- for (idx = 0; idx < BARRIER_BUCKETS_NR; idx++)
- _allow_barrier(conf, idx);
-}
-
/* conf->resync_lock should be held */
static int get_unqueued_pending(struct r1conf *conf)
{
@@ -1654,8 +1638,12 @@ static void print_conf(struct r1conf *co
static void close_sync(struct r1conf *conf)
{
- wait_all_barriers(conf);
- allow_all_barriers(conf);
+ int idx;
+
+ for (idx = 0; idx < BARRIER_BUCKETS_NR; idx++) {
+ _wait_barrier(conf, idx);
+ _allow_barrier(conf, idx);
+ }
mempool_destroy(conf->r1buf_pool);
conf->r1buf_pool = NULL;
Patches currently in stable-queue which might be from nate.dailey(a)stratus.com are
queue-4.14/raid1-prevent-freeze_array-wait_all_barriers-deadlock.patch
This is a note to let you know that I've just added the patch titled
p54: don't unregister leds when they are not initialized
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
p54-don-t-unregister-leds-when-they-are-not-initialized.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From fc09785de0a364427a5df63d703bae9a306ed116 Mon Sep 17 00:00:00 2001
From: Andrey Konovalov <andreyknvl(a)google.com>
Date: Tue, 26 Sep 2017 17:11:33 +0200
Subject: p54: don't unregister leds when they are not initialized
From: Andrey Konovalov <andreyknvl(a)google.com>
commit fc09785de0a364427a5df63d703bae9a306ed116 upstream.
ieee80211_register_hw() in p54_register_common() may fail and leds won't
get initialized. Currently p54_unregister_common() doesn't check that and
always calls p54_unregister_leds(). The fix is to check priv->registered
flag before calling p54_unregister_leds().
Found by syzkaller.
INFO: trying to register non-static key.
the code is fine but needs lockdep annotation.
turning off the locking correctness validator.
CPU: 1 PID: 1404 Comm: kworker/1:1 Not tainted
4.14.0-rc1-42251-gebb2c2437d80-dirty #205
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
Workqueue: usb_hub_wq hub_event
Call Trace:
__dump_stack lib/dump_stack.c:16
dump_stack+0x292/0x395 lib/dump_stack.c:52
register_lock_class+0x6c4/0x1a00 kernel/locking/lockdep.c:769
__lock_acquire+0x27e/0x4550 kernel/locking/lockdep.c:3385
lock_acquire+0x259/0x620 kernel/locking/lockdep.c:4002
flush_work+0xf0/0x8c0 kernel/workqueue.c:2886
__cancel_work_timer+0x51d/0x870 kernel/workqueue.c:2961
cancel_delayed_work_sync+0x1f/0x30 kernel/workqueue.c:3081
p54_unregister_leds+0x6c/0xc0 drivers/net/wireless/intersil/p54/led.c:160
p54_unregister_common+0x3d/0xb0 drivers/net/wireless/intersil/p54/main.c:856
p54u_disconnect+0x86/0x120 drivers/net/wireless/intersil/p54/p54usb.c:1073
usb_unbind_interface+0x21c/0xa90 drivers/usb/core/driver.c:423
__device_release_driver drivers/base/dd.c:861
device_release_driver_internal+0x4f4/0x5c0 drivers/base/dd.c:893
device_release_driver+0x1e/0x30 drivers/base/dd.c:918
bus_remove_device+0x2f4/0x4b0 drivers/base/bus.c:565
device_del+0x5c4/0xab0 drivers/base/core.c:1985
usb_disable_device+0x1e9/0x680 drivers/usb/core/message.c:1170
usb_disconnect+0x260/0x7a0 drivers/usb/core/hub.c:2124
hub_port_connect drivers/usb/core/hub.c:4754
hub_port_connect_change drivers/usb/core/hub.c:5009
port_event drivers/usb/core/hub.c:5115
hub_event+0x1318/0x3740 drivers/usb/core/hub.c:5195
process_one_work+0xc7f/0x1db0 kernel/workqueue.c:2119
process_scheduled_works kernel/workqueue.c:2179
worker_thread+0xb2b/0x1850 kernel/workqueue.c:2255
kthread+0x3a1/0x470 kernel/kthread.c:231
ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431
Signed-off-by: Andrey Konovalov <andreyknvl(a)google.com>
Acked-by: Christian Lamparter <chunkeey(a)googlemail.com>
Signed-off-by: Kalle Valo <kvalo(a)codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/net/wireless/intersil/p54/main.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
--- a/drivers/net/wireless/intersil/p54/main.c
+++ b/drivers/net/wireless/intersil/p54/main.c
@@ -852,12 +852,11 @@ void p54_unregister_common(struct ieee80
{
struct p54_common *priv = dev->priv;
-#ifdef CONFIG_P54_LEDS
- p54_unregister_leds(priv);
-#endif /* CONFIG_P54_LEDS */
-
if (priv->registered) {
priv->registered = false;
+#ifdef CONFIG_P54_LEDS
+ p54_unregister_leds(priv);
+#endif /* CONFIG_P54_LEDS */
ieee80211_unregister_hw(dev);
}
Patches currently in stable-queue which might be from andreyknvl(a)google.com are
queue-4.14/p54-don-t-unregister-leds-when-they-are-not-initialized.patch
queue-4.14/alsa-usb-audio-add-sanity-checks-in-v2-clock-parsers.patch
queue-4.14/alsa-usb-audio-add-sanity-checks-to-fe-parser.patch
This is a note to let you know that I've just added the patch titled
nilfs2: fix race condition that causes file system corruption
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
nilfs2-fix-race-condition-that-causes-file-system-corruption.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 31ccb1f7ba3cfe29631587d451cf5bb8ab593550 Mon Sep 17 00:00:00 2001
From: Andreas Rohner <andreas.rohner(a)gmx.net>
Date: Fri, 17 Nov 2017 15:29:35 -0800
Subject: nilfs2: fix race condition that causes file system corruption
From: Andreas Rohner <andreas.rohner(a)gmx.net>
commit 31ccb1f7ba3cfe29631587d451cf5bb8ab593550 upstream.
There is a race condition between nilfs_dirty_inode() and
nilfs_set_file_dirty().
When a file is opened, nilfs_dirty_inode() is called to update the
access timestamp in the inode. It calls __nilfs_mark_inode_dirty() in a
separate transaction. __nilfs_mark_inode_dirty() caches the ifile
buffer_head in the i_bh field of the inode info structure and marks it
as dirty.
After some data was written to the file in another transaction, the
function nilfs_set_file_dirty() is called, which adds the inode to the
ns_dirty_files list.
Then the segment construction calls nilfs_segctor_collect_dirty_files(),
which goes through the ns_dirty_files list and checks the i_bh field.
If there is a cached buffer_head in i_bh it is not marked as dirty
again.
Since nilfs_dirty_inode() and nilfs_set_file_dirty() use separate
transactions, it is possible that a segment construction that writes out
the ifile occurs in-between the two. If this happens the inode is not
on the ns_dirty_files list, but its ifile block is still marked as dirty
and written out.
In the next segment construction, the data for the file is written out
and nilfs_bmap_propagate() updates the b-tree. Eventually the bmap root
is written into the i_bh block, which is not dirty, because it was
written out in another segment construction.
As a result the bmap update can be lost, which leads to file system
corruption. Either the virtual block address points to an unallocated
DAT block, or the DAT entry will be reused for something different.
The error can remain undetected for a long time. A typical error
message would be one of the "bad btree" errors or a warning that a DAT
entry could not be found.
This bug can be reproduced reliably by a simple benchmark that creates
and overwrites millions of 4k files.
Link: http://lkml.kernel.org/r/1509367935-3086-2-git-send-email-konishi.ryusuke@l…
Signed-off-by: Andreas Rohner <andreas.rohner(a)gmx.net>
Signed-off-by: Ryusuke Konishi <konishi.ryusuke(a)lab.ntt.co.jp>
Tested-by: Andreas Rohner <andreas.rohner(a)gmx.net>
Tested-by: Ryusuke Konishi <konishi.ryusuke(a)lab.ntt.co.jp>
Signed-off-by: Andrew Morton <akpm(a)linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds(a)linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
fs/nilfs2/segment.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -1958,8 +1958,6 @@ static int nilfs_segctor_collect_dirty_f
err, ii->vfs_inode.i_ino);
return err;
}
- mark_buffer_dirty(ibh);
- nilfs_mdt_mark_dirty(ifile);
spin_lock(&nilfs->ns_inode_lock);
if (likely(!ii->i_bh))
ii->i_bh = ibh;
@@ -1968,6 +1966,10 @@ static int nilfs_segctor_collect_dirty_f
goto retry;
}
+ // Always redirty the buffer to avoid race condition
+ mark_buffer_dirty(ii->i_bh);
+ nilfs_mdt_mark_dirty(ifile);
+
clear_bit(NILFS_I_QUEUED, &ii->i_state);
set_bit(NILFS_I_BUSY, &ii->i_state);
list_move_tail(&ii->i_dirty, &sci->sc_dirty_files);
Patches currently in stable-queue which might be from andreas.rohner(a)gmx.net are
queue-4.14/nilfs2-fix-race-condition-that-causes-file-system-corruption.patch
This is a note to let you know that I've just added the patch titled
NFS: Revert "NFS: Move the flock open mode check into nfs_flock()"
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
nfs-revert-nfs-move-the-flock-open-mode-check-into-nfs_flock.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From fcfa447062b2061e11f68b846d61cbfe60d0d604 Mon Sep 17 00:00:00 2001
From: Benjamin Coddington <bcodding(a)redhat.com>
Date: Fri, 10 Nov 2017 06:27:49 -0500
Subject: NFS: Revert "NFS: Move the flock open mode check into nfs_flock()"
From: Benjamin Coddington <bcodding(a)redhat.com>
commit fcfa447062b2061e11f68b846d61cbfe60d0d604 upstream.
Commit e12937279c8b "NFS: Move the flock open mode check into nfs_flock()"
changed NFSv3 behavior for flock() such that the open mode must match the
lock type, however that requirement shouldn't be enforced for flock().
Signed-off-by: Benjamin Coddington <bcodding(a)redhat.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker(a)Netapp.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
fs/nfs/file.c | 18 ++----------------
fs/nfs/nfs4proc.c | 14 ++++++++++++++
2 files changed, 16 insertions(+), 16 deletions(-)
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -829,23 +829,9 @@ int nfs_flock(struct file *filp, int cmd
if (NFS_SERVER(inode)->flags & NFS_MOUNT_LOCAL_FLOCK)
is_local = 1;
- /*
- * VFS doesn't require the open mode to match a flock() lock's type.
- * NFS, however, may simulate flock() locking with posix locking which
- * requires the open mode to match the lock type.
- */
- switch (fl->fl_type) {
- case F_UNLCK:
+ /* We're simulating flock() locks using posix locks on the server */
+ if (fl->fl_type == F_UNLCK)
return do_unlk(filp, cmd, fl, is_local);
- case F_RDLCK:
- if (!(filp->f_mode & FMODE_READ))
- return -EBADF;
- break;
- case F_WRLCK:
- if (!(filp->f_mode & FMODE_WRITE))
- return -EBADF;
- }
-
return do_setlk(filp, cmd, fl, is_local);
}
EXPORT_SYMBOL_GPL(nfs_flock);
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -6568,6 +6568,20 @@ nfs4_proc_lock(struct file *filp, int cm
!test_bit(NFS_STATE_POSIX_LOCKS, &state->flags))
return -ENOLCK;
+ /*
+ * Don't rely on the VFS having checked the file open mode,
+ * since it won't do this for flock() locks.
+ */
+ switch (request->fl_type) {
+ case F_RDLCK:
+ if (!(filp->f_mode & FMODE_READ))
+ return -EBADF;
+ break;
+ case F_WRLCK:
+ if (!(filp->f_mode & FMODE_WRITE))
+ return -EBADF;
+ }
+
status = nfs4_set_lock_state(state, request);
if (status != 0)
return status;
Patches currently in stable-queue which might be from bcodding(a)redhat.com are
queue-4.14/nfs-revert-nfs-move-the-flock-open-mode-check-into-nfs_flock.patch
This is a note to let you know that I've just added the patch titled
nfsd: deal with revoked delegations appropriately
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
nfsd-deal-with-revoked-delegations-appropriately.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 95da1b3a5aded124dd1bda1e3cdb876184813140 Mon Sep 17 00:00:00 2001
From: Andrew Elble <aweits(a)rit.edu>
Date: Fri, 3 Nov 2017 14:06:31 -0400
Subject: nfsd: deal with revoked delegations appropriately
From: Andrew Elble <aweits(a)rit.edu>
commit 95da1b3a5aded124dd1bda1e3cdb876184813140 upstream.
If a delegation has been revoked by the server, operations using that
delegation should error out with NFS4ERR_DELEG_REVOKED in the >4.1
case, and NFS4ERR_BAD_STATEID otherwise.
The server needs NFSv4.1 clients to explicitly free revoked delegations.
If the server returns NFS4ERR_DELEG_REVOKED, the client will do that;
otherwise it may just forget about the delegation and be unable to
recover when it later sees SEQ4_STATUS_RECALLABLE_STATE_REVOKED set on a
SEQUENCE reply. That can cause the Linux 4.1 client to loop in its
stage manager.
Signed-off-by: Andrew Elble <aweits(a)rit.edu>
Reviewed-by: Trond Myklebust <trond.myklebust(a)primarydata.com>
Signed-off-by: J. Bruce Fields <bfields(a)redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
fs/nfsd/nfs4state.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -3966,7 +3966,8 @@ static struct nfs4_delegation *find_dele
{
struct nfs4_stid *ret;
- ret = find_stateid_by_type(cl, s, NFS4_DELEG_STID);
+ ret = find_stateid_by_type(cl, s,
+ NFS4_DELEG_STID|NFS4_REVOKED_DELEG_STID);
if (!ret)
return NULL;
return delegstateid(ret);
@@ -3989,6 +3990,12 @@ nfs4_check_deleg(struct nfs4_client *cl,
deleg = find_deleg_stateid(cl, &open->op_delegate_stateid);
if (deleg == NULL)
goto out;
+ if (deleg->dl_stid.sc_type == NFS4_REVOKED_DELEG_STID) {
+ nfs4_put_stid(&deleg->dl_stid);
+ if (cl->cl_minorversion)
+ status = nfserr_deleg_revoked;
+ goto out;
+ }
flags = share_access_to_flags(open->op_share_access);
status = nfs4_check_delegmode(deleg, flags);
if (status) {
@@ -4858,6 +4865,16 @@ nfsd4_lookup_stateid(struct nfsd4_compou
struct nfs4_stid **s, struct nfsd_net *nn)
{
__be32 status;
+ bool return_revoked = false;
+
+ /*
+ * only return revoked delegations if explicitly asked.
+ * otherwise we report revoked or bad_stateid status.
+ */
+ if (typemask & NFS4_REVOKED_DELEG_STID)
+ return_revoked = true;
+ else if (typemask & NFS4_DELEG_STID)
+ typemask |= NFS4_REVOKED_DELEG_STID;
if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
return nfserr_bad_stateid;
@@ -4872,6 +4889,12 @@ nfsd4_lookup_stateid(struct nfsd4_compou
*s = find_stateid_by_type(cstate->clp, stateid, typemask);
if (!*s)
return nfserr_bad_stateid;
+ if (((*s)->sc_type == NFS4_REVOKED_DELEG_STID) && !return_revoked) {
+ nfs4_put_stid(*s);
+ if (cstate->minorversion)
+ return nfserr_deleg_revoked;
+ return nfserr_bad_stateid;
+ }
return nfs_ok;
}
Patches currently in stable-queue which might be from aweits(a)rit.edu are
queue-4.14/nfsd-deal-with-revoked-delegations-appropriately.patch
This is a note to let you know that I've just added the patch titled
NFS: revalidate "." etc correctly on "open".
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
nfs-revalidate-.-etc-correctly-on-open.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From b688741cb06695312f18b730653d6611e1bad28d Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb(a)suse.com>
Date: Fri, 25 Aug 2017 17:34:41 +1000
Subject: NFS: revalidate "." etc correctly on "open".
From: NeilBrown <neilb(a)suse.com>
commit b688741cb06695312f18b730653d6611e1bad28d upstream.
For correct close-to-open semantics, NFS must validate
the change attribute of a directory (or file) on open.
Since commit ecf3d1f1aa74 ("vfs: kill FS_REVAL_DOT by adding a
d_weak_revalidate dentry op"), open() of "." or a path ending ".." is
not revalidated reliably (except when that direct is a mount point).
Prior to that commit, "." was revalidated using nfs_lookup_revalidate()
which checks the LOOKUP_OPEN flag and forces revalidation if the flag is
set.
Since that commit, nfs_weak_revalidate() is used for NFSv3 (which
ignores the flags) and nothing is used for NFSv4.
This is fixed by using nfs_lookup_verify_inode() in
nfs_weak_revalidate(). This does the revalidation exactly when needed.
Also, add a definition of .d_weak_revalidate for NFSv4.
The incorrect behavior is easily demonstrated by running "echo *" in
some non-mountpoint NFS directory while watching network traffic.
Without this patch, "echo *" sometimes doesn't produce any traffic.
With the patch it always does.
Fixes: ecf3d1f1aa74 ("vfs: kill FS_REVAL_DOT by adding a d_weak_revalidate dentry op")
Signed-off-by: NeilBrown <neilb(a)suse.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker(a)Netapp.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
fs/nfs/dir.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1241,8 +1241,7 @@ static int nfs_weak_revalidate(struct de
return 0;
}
- if (nfs_mapping_need_revalidate_inode(inode))
- error = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
+ error = nfs_lookup_verify_inode(inode, flags);
dfprintk(LOOKUPCACHE, "NFS: %s: inode %lu is %s\n",
__func__, inode->i_ino, error ? "invalid" : "valid");
return !error;
@@ -1393,6 +1392,7 @@ static int nfs4_lookup_revalidate(struct
const struct dentry_operations nfs4_dentry_operations = {
.d_revalidate = nfs4_lookup_revalidate,
+ .d_weak_revalidate = nfs_weak_revalidate,
.d_delete = nfs_dentry_delete,
.d_iput = nfs_dentry_iput,
.d_automount = nfs_d_automount,
Patches currently in stable-queue which might be from neilb(a)suse.com are
queue-4.14/md-fix-deadlock-error-in-recent-patch.patch
queue-4.14/autofs-don-t-fail-mount-for-transient-error.patch
queue-4.14/md-bitmap-revert-a-patch.patch
queue-4.14/nfs-revalidate-.-etc-correctly-on-open.patch