[PATCH 2/2] zfcp: clarify access to erp_action in zfcp_fsf_req_complete()

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

 



From: Julian Wiedmann <jwi@xxxxxxxxxxxxx>

While reviewing
commit 936e6b85da04 ("scsi: zfcp: Fix panic on ERP timeout for previously
dismissed ERP action"),
I stumbled over zfcp_fsf_req_complete() and wondered whether it has
similar issues wrt concurrent modification of req->erp_action
by zfcp_erp_strategy_check_fsfreq().

But a closer look shows that both its two callers
[zfcp_fsf_reqid_check(), zfcp_fsf_req_dismiss_all()] remove the request
from the adapter's req_list under the req_list's lock.
Hence we can trust that if zfcp_erp_strategy_check_fsfreq() concurrently
looks up the corresponding req_id, it won't find this request and is thus
unable to modify it while it's being processed by zfcp_fsf_req_complete().

Add a code comment that hopefully makes this easier for future readers,
and condense the two accesses to ->erp_action that made me trip over
this code path in the first place.

Signed-off-by: Julian Wiedmann <jwi@xxxxxxxxxxxxx>
Reviewed-by: Steffen Maier <maier@xxxxxxxxxxxxx>
Reviewed-by: Benjamin Block <bblock@xxxxxxxxxxxxx>
Signed-off-by: Benjamin Block <bblock@xxxxxxxxxxxxx>
---
 drivers/s390/scsi/zfcp_fsf.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index c795f22249d8..d9de26157da2 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -426,9 +426,14 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req)
  * or it has been dismissed due to a queue shutdown, this function
  * is called to process the completion status and trigger further
  * events related to the FSF request.
+ * Caller must ensure that the request has been removed from
+ * adapter->req_list, to protect against concurrent modification
+ * by zfcp_erp_strategy_check_fsfreq().
  */
 static void zfcp_fsf_req_complete(struct zfcp_fsf_req *req)
 {
+	struct zfcp_erp_action *erp_action;
+
 	if (unlikely(zfcp_fsf_req_is_status_read_buffer(req))) {
 		zfcp_fsf_status_read_handler(req);
 		return;
@@ -439,8 +444,9 @@ static void zfcp_fsf_req_complete(struct zfcp_fsf_req *req)
 	zfcp_fsf_fsfstatus_eval(req);
 	req->handler(req);
 
-	if (req->erp_action)
-		zfcp_erp_notify(req->erp_action, 0);
+	erp_action = req->erp_action;
+	if (erp_action)
+		zfcp_erp_notify(erp_action, 0);
 
 	if (likely(req->status & ZFCP_STATUS_FSFREQ_CLEANUP))
 		zfcp_fsf_req_free(req);
-- 
2.26.2




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Kernel Development]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Info]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Linux Media]     [Device Mapper]

  Powered by Linux