Skip to content

Commit 70aab28

Browse files
djbwstellarhopper
authored andcommitted
dax: Introduce alloc_dev_dax_id()
The reference counting of dax_region objects is needlessly complicated, has lead to confusion [1], and has hidden a bug [2]. Towards cleaning up that mess introduce alloc_dev_dax_id() to minimize the holding of a dax_region reference to only what dev_dax_release() needs, the dax_region->ida. Part of the reason for the mess was the design to dereference a dax_region in all cases in free_dev_dax_id() even if the id was statically assigned by the upper level dax_region driver. Remove the need to call "is_static(dax_region)" by tracking whether the id is dynamic directly in the dev_dax instance itself. With that flag the dax_region pinning and release per dev_dax instance can move to alloc_dev_dax_id() and free_dev_dax_id() respectively. A follow-on cleanup address the unnecessary references in the dax_region setup and drivers. Fixes: 0f3da14 ("device-dax: introduce 'seed' devices") Link: http://lore.kernel.org/r/20221203095858.612027-1-liuyongqiang13@huawei.com [1] Link: http://lore.kernel.org/r/3cf0890b-4eb0-e70e-cd9c-2ecc3d496263@hpe.com [2] Reported-by: Yongqiang Liu <liuyongqiang13@huawei.com> Reported-by: Paul Cassella <cassella@hpe.com> Reported-by: Ira Weiny <ira.weiny@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com> Link: https://lore.kernel.org/r/168577284563.1672036.13493034988900989554.stgit@dwillia2-xfh.jf.intel.com Reviewed-by: Ira Weiny <ira.weiny@intel.com> Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
1 parent 82b4cee commit 70aab28

2 files changed

Lines changed: 37 additions & 23 deletions

File tree

drivers/dax/bus.c

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -446,18 +446,34 @@ static void unregister_dev_dax(void *dev)
446446
put_device(dev);
447447
}
448448

449+
static void dax_region_free(struct kref *kref)
450+
{
451+
struct dax_region *dax_region;
452+
453+
dax_region = container_of(kref, struct dax_region, kref);
454+
kfree(dax_region);
455+
}
456+
457+
void dax_region_put(struct dax_region *dax_region)
458+
{
459+
kref_put(&dax_region->kref, dax_region_free);
460+
}
461+
EXPORT_SYMBOL_GPL(dax_region_put);
462+
449463
/* a return value >= 0 indicates this invocation invalidated the id */
450464
static int __free_dev_dax_id(struct dev_dax *dev_dax)
451465
{
452-
struct dax_region *dax_region = dev_dax->region;
453466
struct device *dev = &dev_dax->dev;
467+
struct dax_region *dax_region;
454468
int rc = dev_dax->id;
455469

456470
device_lock_assert(dev);
457471

458-
if (is_static(dax_region) || dev_dax->id < 0)
472+
if (!dev_dax->dyn_id || dev_dax->id < 0)
459473
return -1;
474+
dax_region = dev_dax->region;
460475
ida_free(&dax_region->ida, dev_dax->id);
476+
dax_region_put(dax_region);
461477
dev_dax->id = -1;
462478
return rc;
463479
}
@@ -473,6 +489,20 @@ static int free_dev_dax_id(struct dev_dax *dev_dax)
473489
return rc;
474490
}
475491

492+
static int alloc_dev_dax_id(struct dev_dax *dev_dax)
493+
{
494+
struct dax_region *dax_region = dev_dax->region;
495+
int id;
496+
497+
id = ida_alloc(&dax_region->ida, GFP_KERNEL);
498+
if (id < 0)
499+
return id;
500+
kref_get(&dax_region->kref);
501+
dev_dax->dyn_id = true;
502+
dev_dax->id = id;
503+
return id;
504+
}
505+
476506
static ssize_t delete_store(struct device *dev, struct device_attribute *attr,
477507
const char *buf, size_t len)
478508
{
@@ -560,20 +590,6 @@ static const struct attribute_group *dax_region_attribute_groups[] = {
560590
NULL,
561591
};
562592

563-
static void dax_region_free(struct kref *kref)
564-
{
565-
struct dax_region *dax_region;
566-
567-
dax_region = container_of(kref, struct dax_region, kref);
568-
kfree(dax_region);
569-
}
570-
571-
void dax_region_put(struct dax_region *dax_region)
572-
{
573-
kref_put(&dax_region->kref, dax_region_free);
574-
}
575-
EXPORT_SYMBOL_GPL(dax_region_put);
576-
577593
static void dax_region_unregister(void *region)
578594
{
579595
struct dax_region *dax_region = region;
@@ -1297,12 +1313,10 @@ static const struct attribute_group *dax_attribute_groups[] = {
12971313
static void dev_dax_release(struct device *dev)
12981314
{
12991315
struct dev_dax *dev_dax = to_dev_dax(dev);
1300-
struct dax_region *dax_region = dev_dax->region;
13011316
struct dax_device *dax_dev = dev_dax->dax_dev;
13021317

13031318
put_dax(dax_dev);
13041319
free_dev_dax_id(dev_dax);
1305-
dax_region_put(dax_region);
13061320
kfree(dev_dax->pgmap);
13071321
kfree(dev_dax);
13081322
}
@@ -1326,6 +1340,7 @@ struct dev_dax *devm_create_dev_dax(struct dev_dax_data *data)
13261340
if (!dev_dax)
13271341
return ERR_PTR(-ENOMEM);
13281342

1343+
dev_dax->region = dax_region;
13291344
if (is_static(dax_region)) {
13301345
if (dev_WARN_ONCE(parent, data->id < 0,
13311346
"dynamic id specified to static region\n")) {
@@ -1341,13 +1356,11 @@ struct dev_dax *devm_create_dev_dax(struct dev_dax_data *data)
13411356
goto err_id;
13421357
}
13431358

1344-
rc = ida_alloc(&dax_region->ida, GFP_KERNEL);
1359+
rc = alloc_dev_dax_id(dev_dax);
13451360
if (rc < 0)
13461361
goto err_id;
1347-
dev_dax->id = rc;
13481362
}
13491363

1350-
dev_dax->region = dax_region;
13511364
dev = &dev_dax->dev;
13521365
device_initialize(dev);
13531366
dev_set_name(dev, "dax%d.%d", dax_region->id, dev_dax->id);
@@ -1388,7 +1401,6 @@ struct dev_dax *devm_create_dev_dax(struct dev_dax_data *data)
13881401
dev_dax->target_node = dax_region->target_node;
13891402
dev_dax->align = dax_region->align;
13901403
ida_init(&dev_dax->ida);
1391-
kref_get(&dax_region->kref);
13921404

13931405
inode = dax_inode(dax_dev);
13941406
dev->devt = inode->i_rdev;

drivers/dax/dax-private.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ struct dax_mapping {
5252
* @region - parent region
5353
* @dax_dev - core dax functionality
5454
* @target_node: effective numa node if dev_dax memory range is onlined
55-
* @id: ida allocated id
55+
* @dyn_id: is this a dynamic or statically created instance
56+
* @id: ida allocated id when the dax_region is not static
5657
* @ida: mapping id allocator
5758
* @dev - device core
5859
* @pgmap - pgmap for memmap setup / lifetime (driver owned)
@@ -64,6 +65,7 @@ struct dev_dax {
6465
struct dax_device *dax_dev;
6566
unsigned int align;
6667
int target_node;
68+
bool dyn_id;
6769
int id;
6870
struct ida ida;
6971
struct device dev;

0 commit comments

Comments
 (0)