[PATCH 1/5] qedf: fixup bit operations

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



test_bit() is atomic, test_bit() || test_bit() is not.
So protect consecutive bit tests with a lock to avoid races.

Signed-off-by: Hannes Reinecke <hare@xxxxxxxx>
---
 drivers/scsi/qedf/qedf_els.c  | 9 +++++++--
 drivers/scsi/qedf/qedf_main.c | 5 ++++-
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/qedf/qedf_els.c b/drivers/scsi/qedf/qedf_els.c
index 04f0c4d2e256..acb8157a96a8 100644
--- a/drivers/scsi/qedf/qedf_els.c
+++ b/drivers/scsi/qedf/qedf_els.c
@@ -335,20 +335,25 @@ void qedf_restart_rport(struct qedf_rport *fcport)
 	struct fc_lport *lport;
 	struct fc_rport_priv *rdata;
 	u32 port_id;
+	unsigned long flags;
 
 	if (!fcport)
 		return;
 
+	spin_lock_irqsave(&fcport->rport_lock, flags);
 	if (test_bit(QEDF_RPORT_IN_RESET, &fcport->flags) ||
 	    !test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags) ||
 	    test_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags)) {
-		QEDF_ERR(&(fcport->qedf->dbg_ctx), "fcport %p already in reset or not offloaded.\n",
-		    fcport);
+		QEDF_ERR(&(fcport->qedf->dbg_ctx),
+			 "fcport %p already in reset or not offloaded.\n",
+			 fcport);
+		spin_unlock_irqrestore(&fcport->rport_lock, flags);
 		return;
 	}
 
 	/* Set that we are now in reset */
 	set_bit(QEDF_RPORT_IN_RESET, &fcport->flags);
+	spin_unlock_irqrestore(&fcport->rport_lock, flags);
 
 	rdata = fcport->rdata;
 	if (rdata) {
diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c
index 0a5dd5595dd3..dd64236ef4c4 100644
--- a/drivers/scsi/qedf/qedf_main.c
+++ b/drivers/scsi/qedf/qedf_main.c
@@ -1370,8 +1370,10 @@ static void qedf_rport_event_handler(struct fc_lport *lport,
 		fcport = (struct qedf_rport *)&rp[1];
 
 		/* Only free this fcport if it is offloaded already */
+		spin_lock_irqsave(&fcport->rport_lock, flags);
 		if (test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags)) {
 			set_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags);
+			spin_unlock_irqrestore(&fcport->rport_lock, flags);
 			qedf_cleanup_fcport(qedf, fcport);
 
 			/*
@@ -1385,7 +1387,8 @@ static void qedf_rport_event_handler(struct fc_lport *lport,
 			clear_bit(QEDF_RPORT_UPLOADING_CONNECTION,
 			    &fcport->flags);
 			atomic_dec(&qedf->num_offloads);
-		}
+		} else
+			spin_unlock_irqrestore(&fcport->rport_lock, flags);
 
 		break;
 
-- 
2.16.4




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux