]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
fixes for 5.2
authorSasha Levin <sashal@kernel.org>
Sat, 21 Sep 2019 19:23:44 +0000 (15:23 -0400)
committerSasha Levin <sashal@kernel.org>
Sat, 21 Sep 2019 19:23:44 +0000 (15:23 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.2/net-ibmvnic-free-reset-work-of-removed-device-from-q.patch [new file with mode: 0644]
queue-5.2/phy-qcom-qmp-correct-ready-status-again.patch [new file with mode: 0644]
queue-5.2/phy-qcom-qmp-raise-qcom_qmp_phy_enable-polling-delay.patch [new file with mode: 0644]
queue-5.2/revert-bluetooth-validate-ble-connection-interval-up.patch [new file with mode: 0644]
queue-5.2/series [new file with mode: 0644]
queue-5.2/smb3-fix-unmount-hang-in-open_shroot.patch [new file with mode: 0644]

diff --git a/queue-5.2/net-ibmvnic-free-reset-work-of-removed-device-from-q.patch b/queue-5.2/net-ibmvnic-free-reset-work-of-removed-device-from-q.patch
new file mode 100644 (file)
index 0000000..6ef8be9
--- /dev/null
@@ -0,0 +1,54 @@
+From e57f3ee82409a3e9ef11a3184cef762b8dec6616 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Sep 2019 17:30:01 -0400
+Subject: net/ibmvnic: free reset work of removed device from queue
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Juliet Kim <julietk@linux.vnet.ibm.com>
+
+[ Upstream commit 1c2977c094998de032fee6e898c88b4a05483d08 ]
+
+Commit 36f1031c51a2 ("ibmvnic: Do not process reset during or after
+ device removal") made the change to exit reset if the driver has been
+removed, but does not free reset work items of the adapter from queue.
+
+Ensure all reset work items are freed when breaking out of the loop early.
+
+Fixes: 36f1031c51a2 ("ibmnvic: Do not process reset during or after device removal”)
+Signed-off-by: Juliet Kim <julietk@linux.vnet.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ibm/ibmvnic.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index fa4bb940665c2..6644cabc8e756 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -1985,7 +1985,10 @@ static void __ibmvnic_reset(struct work_struct *work)
+       while (rwi) {
+               if (adapter->state == VNIC_REMOVING ||
+                   adapter->state == VNIC_REMOVED)
+-                      goto out;
++                      kfree(rwi);
++                      rc = EBUSY;
++                      break;
++              }
+               if (adapter->force_reset_recovery) {
+                       adapter->force_reset_recovery = false;
+@@ -2011,7 +2014,7 @@ static void __ibmvnic_reset(struct work_struct *work)
+               netdev_dbg(adapter->netdev, "Reset failed\n");
+               free_all_rwi(adapter);
+       }
+-out:
++
+       adapter->resetting = false;
+       if (we_lock_rtnl)
+               rtnl_unlock();
+-- 
+2.20.1
+
diff --git a/queue-5.2/phy-qcom-qmp-correct-ready-status-again.patch b/queue-5.2/phy-qcom-qmp-correct-ready-status-again.patch
new file mode 100644 (file)
index 0000000..8573eba
--- /dev/null
@@ -0,0 +1,187 @@
+From 96b15efd11adbe396e3b8adba06e0e07f2d86fb4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Aug 2019 17:42:56 -0700
+Subject: phy: qcom-qmp: Correct ready status, again
+
+From: Bjorn Andersson <bjorn.andersson@linaro.org>
+
+[ Upstream commit 14ced7e3a1ae9bed7051df3718c8c7b583854a5c ]
+
+Despite extensive testing of commit 885bd765963b ("phy: qcom-qmp: Correct
+READY_STATUS poll break condition") I failed to conclude that the
+PHYSTATUS bit of the PCS_STATUS register used in PCIe and USB3 falls as
+the PHY gets ready. Similar to the prior bug with UFS the code will
+generally get past the check before the transition and thereby
+"succeed".
+
+Correct the name of the register used PCIe and USB3 PHYs, replace
+mask_pcs_ready with a constant expression depending on the type of the
+PHY and check for the appropriate ready state.
+
+Cc: stable@vger.kernel.org
+Cc: Vivek Gautam <vivek.gautam@codeaurora.org>
+Cc: Evan Green <evgreen@chromium.org>
+Cc: Niklas Cassel <niklas.cassel@linaro.org>
+Reported-by: Marc Gonzalez <marc.w.gonzalez@free.fr>
+Fixes: 885bd765963b ("phy: qcom-qmp: Correct READY_STATUS poll break condition")
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Tested-by: Marc Gonzalez <marc.w.gonzalez@free.fr>
+Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/qualcomm/phy-qcom-qmp.c | 33 ++++++++++++++---------------
+ 1 file changed, 16 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
+index 99b3bc04d215a..7e171d37bcd6f 100644
+--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
++++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
+@@ -35,7 +35,7 @@
+ #define PLL_READY_GATE_EN                     BIT(3)
+ /* QPHY_PCS_STATUS bit */
+ #define PHYSTATUS                             BIT(6)
+-/* QPHY_COM_PCS_READY_STATUS bit */
++/* QPHY_PCS_READY_STATUS & QPHY_COM_PCS_READY_STATUS bit */
+ #define PCS_READY                             BIT(0)
+ /* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */
+@@ -115,6 +115,7 @@ enum qphy_reg_layout {
+       QPHY_SW_RESET,
+       QPHY_START_CTRL,
+       QPHY_PCS_READY_STATUS,
++      QPHY_PCS_STATUS,
+       QPHY_PCS_AUTONOMOUS_MODE_CTRL,
+       QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR,
+       QPHY_PCS_LFPS_RXTERM_IRQ_STATUS,
+@@ -133,7 +134,7 @@ static const unsigned int pciephy_regs_layout[] = {
+       [QPHY_FLL_MAN_CODE]             = 0xd4,
+       [QPHY_SW_RESET]                 = 0x00,
+       [QPHY_START_CTRL]               = 0x08,
+-      [QPHY_PCS_READY_STATUS]         = 0x174,
++      [QPHY_PCS_STATUS]               = 0x174,
+ };
+ static const unsigned int usb3phy_regs_layout[] = {
+@@ -144,7 +145,7 @@ static const unsigned int usb3phy_regs_layout[] = {
+       [QPHY_FLL_MAN_CODE]             = 0xd0,
+       [QPHY_SW_RESET]                 = 0x00,
+       [QPHY_START_CTRL]               = 0x08,
+-      [QPHY_PCS_READY_STATUS]         = 0x17c,
++      [QPHY_PCS_STATUS]               = 0x17c,
+       [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x0d4,
+       [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR]  = 0x0d8,
+       [QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x178,
+@@ -153,7 +154,7 @@ static const unsigned int usb3phy_regs_layout[] = {
+ static const unsigned int qmp_v3_usb3phy_regs_layout[] = {
+       [QPHY_SW_RESET]                 = 0x00,
+       [QPHY_START_CTRL]               = 0x08,
+-      [QPHY_PCS_READY_STATUS]         = 0x174,
++      [QPHY_PCS_STATUS]               = 0x174,
+       [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = 0x0d8,
+       [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR]  = 0x0dc,
+       [QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x170,
+@@ -911,7 +912,6 @@ struct qmp_phy_cfg {
+       unsigned int start_ctrl;
+       unsigned int pwrdn_ctrl;
+-      unsigned int mask_pcs_ready;
+       unsigned int mask_com_pcs_ready;
+       /* true, if PHY has a separate PHY_COM control block */
+@@ -1074,7 +1074,6 @@ static const struct qmp_phy_cfg msm8996_pciephy_cfg = {
+       .start_ctrl             = PCS_START | PLL_READY_GATE_EN,
+       .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
+-      .mask_pcs_ready         = PHYSTATUS,
+       .mask_com_pcs_ready     = PCS_READY,
+       .has_phy_com_ctrl       = true,
+@@ -1106,7 +1105,6 @@ static const struct qmp_phy_cfg msm8996_usb3phy_cfg = {
+       .start_ctrl             = SERDES_START | PCS_START,
+       .pwrdn_ctrl             = SW_PWRDN,
+-      .mask_pcs_ready         = PHYSTATUS,
+ };
+ /* list of resets */
+@@ -1136,7 +1134,6 @@ static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
+       .start_ctrl             = SERDES_START | PCS_START,
+       .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
+-      .mask_pcs_ready         = PHYSTATUS,
+       .has_phy_com_ctrl       = false,
+       .has_lane_rst           = false,
+@@ -1167,7 +1164,6 @@ static const struct qmp_phy_cfg qmp_v3_usb3phy_cfg = {
+       .start_ctrl             = SERDES_START | PCS_START,
+       .pwrdn_ctrl             = SW_PWRDN,
+-      .mask_pcs_ready         = PHYSTATUS,
+       .has_pwrdn_delay        = true,
+       .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
+@@ -1199,7 +1195,6 @@ static const struct qmp_phy_cfg qmp_v3_usb3_uniphy_cfg = {
+       .start_ctrl             = SERDES_START | PCS_START,
+       .pwrdn_ctrl             = SW_PWRDN,
+-      .mask_pcs_ready         = PHYSTATUS,
+       .has_pwrdn_delay        = true,
+       .pwrdn_delay_min        = POWER_DOWN_DELAY_US_MIN,
+@@ -1226,7 +1221,6 @@ static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
+       .start_ctrl             = SERDES_START,
+       .pwrdn_ctrl             = SW_PWRDN,
+-      .mask_pcs_ready         = PCS_READY,
+       .is_dual_lane_phy       = true,
+       .no_pcs_sw_reset        = true,
+@@ -1254,7 +1248,6 @@ static const struct qmp_phy_cfg msm8998_pciephy_cfg = {
+       .start_ctrl             = SERDES_START | PCS_START,
+       .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
+-      .mask_pcs_ready         = PHYSTATUS,
+       .mask_com_pcs_ready     = PCS_READY,
+ };
+@@ -1280,7 +1273,6 @@ static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
+       .start_ctrl             = SERDES_START | PCS_START,
+       .pwrdn_ctrl             = SW_PWRDN,
+-      .mask_pcs_ready         = PHYSTATUS,
+       .is_dual_lane_phy       = true,
+ };
+@@ -1458,7 +1450,7 @@ static int qcom_qmp_phy_enable(struct phy *phy)
+       void __iomem *pcs = qphy->pcs;
+       void __iomem *dp_com = qmp->dp_com;
+       void __iomem *status;
+-      unsigned int mask, val;
++      unsigned int mask, val, ready;
+       int ret;
+       dev_vdbg(qmp->dev, "Initializing QMP phy\n");
+@@ -1546,10 +1538,17 @@ static int qcom_qmp_phy_enable(struct phy *phy)
+       /* start SerDes and Phy-Coding-Sublayer */
+       qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
+-      status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
+-      mask = cfg->mask_pcs_ready;
++      if (cfg->type == PHY_TYPE_UFS) {
++              status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
++              mask = PCS_READY;
++              ready = PCS_READY;
++      } else {
++              status = pcs + cfg->regs[QPHY_PCS_STATUS];
++              mask = PHYSTATUS;
++              ready = 0;
++      }
+-      ret = readl_poll_timeout(status, val, val & mask, 10,
++      ret = readl_poll_timeout(status, val, (val & mask) == ready, 10,
+                                PHY_INIT_COMPLETE_TIMEOUT);
+       if (ret) {
+               dev_err(qmp->dev, "phy initialization timed-out\n");
+-- 
+2.20.1
+
diff --git a/queue-5.2/phy-qcom-qmp-raise-qcom_qmp_phy_enable-polling-delay.patch b/queue-5.2/phy-qcom-qmp-raise-qcom_qmp_phy_enable-polling-delay.patch
new file mode 100644 (file)
index 0000000..a617817
--- /dev/null
@@ -0,0 +1,38 @@
+From daff961350b7177a1d30f6aa4ceaad564c5ad632 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Jun 2019 13:32:08 +0200
+Subject: phy: qcom-qmp: Raise qcom_qmp_phy_enable() polling delay
+
+From: Marc Gonzalez <marc.w.gonzalez@free.fr>
+
+[ Upstream commit 5206026404190125436f81088eb3667076e56083 ]
+
+readl_poll_timeout() calls usleep_range() to sleep between reads.
+usleep_range() doesn't work efficiently for tiny values.
+
+Raise the polling delay in qcom_qmp_phy_enable() to bring it in line
+with the delay in qcom_qmp_phy_com_init().
+
+Signed-off-by: Marc Gonzalez <marc.w.gonzalez@free.fr>
+Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/qualcomm/phy-qcom-qmp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
+index 43abdfd0deed9..99b3bc04d215a 100644
+--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
++++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
+@@ -1549,7 +1549,7 @@ static int qcom_qmp_phy_enable(struct phy *phy)
+       status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
+       mask = cfg->mask_pcs_ready;
+-      ret = readl_poll_timeout(status, val, val & mask, 1,
++      ret = readl_poll_timeout(status, val, val & mask, 10,
+                                PHY_INIT_COMPLETE_TIMEOUT);
+       if (ret) {
+               dev_err(qmp->dev, "phy initialization timed-out\n");
+-- 
+2.20.1
+
diff --git a/queue-5.2/revert-bluetooth-validate-ble-connection-interval-up.patch b/queue-5.2/revert-bluetooth-validate-ble-connection-interval-up.patch
new file mode 100644 (file)
index 0000000..6e52aa4
--- /dev/null
@@ -0,0 +1,62 @@
+From d70dbbb1556c07caaff0e3295e8486ea7cb6a201 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Sep 2019 20:13:08 +0200
+Subject: Revert "Bluetooth: validate BLE connection interval updates"
+
+From: Marcel Holtmann <marcel@holtmann.org>
+
+[ Upstream commit 68d19d7d995759b96169da5aac313363f92a9075 ]
+
+This reverts commit c49a8682fc5d298d44e8d911f4fa14690ea9485e.
+
+There are devices which require low connection intervals for usable operation
+including keyboards and mice. Forcing a static connection interval for
+these types of devices has an impact in latency and causes a regression.
+
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c  | 5 -----
+ net/bluetooth/l2cap_core.c | 9 +--------
+ 2 files changed, 1 insertion(+), 13 deletions(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 17c50a98e7f78..9e4fcf406d9cd 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -5588,11 +5588,6 @@ static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev,
+               return send_conn_param_neg_reply(hdev, handle,
+                                                HCI_ERROR_UNKNOWN_CONN_ID);
+-      if (min < hcon->le_conn_min_interval ||
+-          max > hcon->le_conn_max_interval)
+-              return send_conn_param_neg_reply(hdev, handle,
+-                                               HCI_ERROR_INVALID_LL_PARAMS);
+-
+       if (hci_check_conn_params(min, max, latency, timeout))
+               return send_conn_param_neg_reply(hdev, handle,
+                                                HCI_ERROR_INVALID_LL_PARAMS);
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 32d2be9d68585..771e3e17bb6a3 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -5297,14 +5297,7 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
+       memset(&rsp, 0, sizeof(rsp));
+-      if (min < hcon->le_conn_min_interval ||
+-          max > hcon->le_conn_max_interval) {
+-              BT_DBG("requested connection interval exceeds current bounds.");
+-              err = -EINVAL;
+-      } else {
+-              err = hci_check_conn_params(min, max, latency, to_multiplier);
+-      }
+-
++      err = hci_check_conn_params(min, max, latency, to_multiplier);
+       if (err)
+               rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
+       else
+-- 
+2.20.1
+
diff --git a/queue-5.2/series b/queue-5.2/series
new file mode 100644 (file)
index 0000000..5152a31
--- /dev/null
@@ -0,0 +1,5 @@
+revert-bluetooth-validate-ble-connection-interval-up.patch
+smb3-fix-unmount-hang-in-open_shroot.patch
+phy-qcom-qmp-raise-qcom_qmp_phy_enable-polling-delay.patch
+phy-qcom-qmp-correct-ready-status-again.patch
+net-ibmvnic-free-reset-work-of-removed-device-from-q.patch
diff --git a/queue-5.2/smb3-fix-unmount-hang-in-open_shroot.patch b/queue-5.2/smb3-fix-unmount-hang-in-open_shroot.patch
new file mode 100644 (file)
index 0000000..c8e13e7
--- /dev/null
@@ -0,0 +1,89 @@
+From 61502da68219b3ede6a61a2fdf3a873eed29da7f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Sep 2019 17:52:54 -0500
+Subject: smb3: fix unmount hang in open_shroot
+
+From: Steve French <stfrench@microsoft.com>
+
+[ Upstream commit 96d9f7ed00b86104bf03adeffc8980897e9694ab ]
+
+An earlier patch "CIFS: fix deadlock in cached root handling"
+did not completely address the deadlock in open_shroot. This
+patch addresses the deadlock.
+
+In testing the recent patch:
+  smb3: improve handling of share deleted (and share recreated)
+we were able to reproduce the open_shroot deadlock to one
+of the target servers in unmount in a delete share scenario.
+
+Fixes: 7e5a70ad88b1e ("CIFS: fix deadlock in cached root handling")
+
+This is version 2 of this patch. An earlier version of this
+patch "smb3: fix unmount hang in open_shroot" had a problem
+found by Dan.
+
+Reported-by: kbuild test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+
+Suggested-by: Pavel Shilovsky <pshilov@microsoft.com>
+Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+CC: Aurelien Aptel <aaptel@suse.com>
+CC: Stable <stable@vger.kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/smb2ops.c | 21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
+index 42de31d206169..8ae8ef526b4a5 100644
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -656,6 +656,15 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid *pfid)
+               return 0;
+       }
++      /*
++       * We do not hold the lock for the open because in case
++       * SMB2_open needs to reconnect, it will end up calling
++       * cifs_mark_open_files_invalid() which takes the lock again
++       * thus causing a deadlock
++       */
++
++      mutex_unlock(&tcon->crfid.fid_mutex);
++
+       if (smb3_encryption_required(tcon))
+               flags |= CIFS_TRANSFORM_REQ;
+@@ -677,7 +686,7 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid *pfid)
+       rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, &utf16_path);
+       if (rc)
+-              goto oshr_exit;
++              goto oshr_free;
+       smb2_set_next_command(tcon, &rqst[0]);
+       memset(&qi_iov, 0, sizeof(qi_iov));
+@@ -690,18 +699,10 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid *pfid)
+                                 sizeof(struct smb2_file_all_info) +
+                                 PATH_MAX * 2, 0, NULL);
+       if (rc)
+-              goto oshr_exit;
++              goto oshr_free;
+       smb2_set_related(&rqst[1]);
+-      /*
+-       * We do not hold the lock for the open because in case
+-       * SMB2_open needs to reconnect, it will end up calling
+-       * cifs_mark_open_files_invalid() which takes the lock again
+-       * thus causing a deadlock
+-       */
+-
+-      mutex_unlock(&tcon->crfid.fid_mutex);
+       rc = compound_send_recv(xid, ses, flags, 2, rqst,
+                               resp_buftype, rsp_iov);
+       mutex_lock(&tcon->crfid.fid_mutex);
+-- 
+2.20.1
+