Patch "cxl/core: Always hold region_rwsem while reading poison lists" has been added to the 6.6-stable tree

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

 



This is a note to let you know that I've just added the patch titled

    cxl/core: Always hold region_rwsem while reading poison lists

to the 6.6-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     cxl-core-always-hold-region_rwsem-while-reading-pois.patch
and it can be found in the queue-6.6 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 203884f9753f21acf3a2cd94f71156f6f30d5501
Author: Alison Schofield <alison.schofield@xxxxxxxxx>
Date:   Sun Nov 26 16:09:29 2023 -0800

    cxl/core: Always hold region_rwsem while reading poison lists
    
    [ Upstream commit 5558b92e8d39e18aa19619be2ee37274e9592528 ]
    
    A read of a device poison list is triggered via a sysfs attribute
    and the results are logged as kernel trace events of type cxl_poison.
    The work is managed by either: a) the region driver when one of more
    regions map the device, or by b) the memdev driver when no regions
    map the device.
    
    In the case of a) the region driver holds the region_rwsem while
    reading the poison by committed endpoint decoder mappings and for
    any unmapped resources. This makes sure that the cxl_poison trace
    event trace reports valid region info. (Region name, HPA, and UUID).
    
    In the case of b) the memdev driver holds the dpa_rwsem preventing
    new DPA resources from being attached to a region. However, it leaves
    a gap between region attach and decoder commit actions. If a DPA in
    the gap is in the poison list, the cxl_poison trace event will omit
    the region info.
    
    Close the gap by holding the region_rwsem and the dpa_rwsem when
    reading poison per memdev. Since both methods now hold both locks,
    down_read both from the caller. Doing so also addresses the lockdep
    assert that found this issue:
    Commit 458ba8189cb4 ("cxl: Add cxl_decoders_committed() helper")
    
    Fixes: f0832a586396 ("cxl/region: Provide region info to the cxl_poison trace event")
    Signed-off-by: Alison Schofield <alison.schofield@xxxxxxxxx>
    Reviewed-by: Davidlohr Bueso <dave@xxxxxxxxxxxx>
    Reviewed-by: Dave Jiang <dave.jiang@xxxxxxxxx>
    Link: https://lore.kernel.org/r/08e8e7ec9a3413b91d51de39e385653494b1eed0.1701041440.git.alison.schofield@xxxxxxxxx
    Signed-off-by: Dan Williams <dan.j.williams@xxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
index fc5c2b414793b..5ad1b13e780af 100644
--- a/drivers/cxl/core/memdev.c
+++ b/drivers/cxl/core/memdev.c
@@ -227,10 +227,16 @@ int cxl_trigger_poison_list(struct cxl_memdev *cxlmd)
 	if (!port || !is_cxl_endpoint(port))
 		return -EINVAL;
 
-	rc = down_read_interruptible(&cxl_dpa_rwsem);
+	rc = down_read_interruptible(&cxl_region_rwsem);
 	if (rc)
 		return rc;
 
+	rc = down_read_interruptible(&cxl_dpa_rwsem);
+	if (rc) {
+		up_read(&cxl_region_rwsem);
+		return rc;
+	}
+
 	if (cxl_num_decoders_committed(port) == 0) {
 		/* No regions mapped to this memdev */
 		rc = cxl_get_poison_by_memdev(cxlmd);
@@ -239,6 +245,7 @@ int cxl_trigger_poison_list(struct cxl_memdev *cxlmd)
 		rc =  cxl_get_poison_by_endpoint(port);
 	}
 	up_read(&cxl_dpa_rwsem);
+	up_read(&cxl_region_rwsem);
 
 	return rc;
 }
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index 9d60020c5cb3b..e7206367ec669 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -2467,10 +2467,6 @@ int cxl_get_poison_by_endpoint(struct cxl_port *port)
 	struct cxl_poison_context ctx;
 	int rc = 0;
 
-	rc = down_read_interruptible(&cxl_region_rwsem);
-	if (rc)
-		return rc;
-
 	ctx = (struct cxl_poison_context) {
 		.port = port
 	};
@@ -2480,7 +2476,6 @@ int cxl_get_poison_by_endpoint(struct cxl_port *port)
 		rc = cxl_get_poison_unmapped(to_cxl_memdev(port->uport_dev),
 					     &ctx);
 
-	up_read(&cxl_region_rwsem);
 	return rc;
 }
 




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux