cxl/region: Recycle region ids

At region creation time the next region-id is atomically cached so that
there is predictability of region device names. If that region is
destroyed and then a new one is created the region id increments. That
ends up looking like a memory leak, or is otherwise surprising that
identifiers roll forward even after destroying all previously created
regions.

Try to reuse rather than free old region ids at region release time.

While this fixes a cosmetic issue, the needlessly advancing memory
region-id gives the appearance of a memory leak, hence the "Fixes" tag,
but no "Cc: stable" tag.

Cc: Ben Widawsky <bwidawsk@kernel.org>
Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Fixes: 779dd20cfb56 ("cxl/region: Add region creation support")
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Vishal Verma <vishal.l.verma@intel.com>
Link: https://lore.kernel.org/r/166752186062.947915.13200195701224993317.stgit@dwillia2-xfh.jf.intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>

Changed files
+20
drivers
cxl
core
+20
drivers/cxl/core/region.c
··· 1534 1534 1535 1535 static void cxl_region_release(struct device *dev) 1536 1536 { 1537 + struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(dev->parent); 1537 1538 struct cxl_region *cxlr = to_cxl_region(dev); 1539 + int id = atomic_read(&cxlrd->region_id); 1540 + 1541 + /* 1542 + * Try to reuse the recently idled id rather than the cached 1543 + * next id to prevent the region id space from increasing 1544 + * unnecessarily. 1545 + */ 1546 + if (cxlr->id < id) 1547 + if (atomic_try_cmpxchg(&cxlrd->region_id, &id, cxlr->id)) { 1548 + memregion_free(id); 1549 + goto out; 1550 + } 1538 1551 1539 1552 memregion_free(cxlr->id); 1553 + out: 1554 + put_device(dev->parent); 1540 1555 kfree(cxlr); 1541 1556 } 1542 1557 ··· 1613 1598 device_initialize(dev); 1614 1599 lockdep_set_class(&dev->mutex, &cxl_region_key); 1615 1600 dev->parent = &cxlrd->cxlsd.cxld.dev; 1601 + /* 1602 + * Keep root decoder pinned through cxl_region_release to fixup 1603 + * region id allocations 1604 + */ 1605 + get_device(dev->parent); 1616 1606 device_set_pm_not_required(dev); 1617 1607 dev->bus = &cxl_bus_type; 1618 1608 dev->type = &cxl_region_type;