aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2016-07-24 18:55:42 -0400
committerDan Williams <dan.j.williams@intel.com>2016-08-24 01:58:51 -0400
commitba09c01d2fa866f22e42ac2af405fe386f491879 (patch)
treec0028867440d5d50709bf787221bb4c64f29586b
parentebd84d724c85f22037a5c9cb04b9e6631309cb78 (diff)
dax: convert to the cdev api
A goal of the device-DAX interface is to be able to support many exclusive allocations (partitions) of performance / feature differentiated memory. This count may exceed the default minors limit of 256. As a result of switching to an embedded cdev the inode-to-dax_dev conversion is simplified, as well as reference counting which can switch to the cdev kobject lifetime. Cc: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--drivers/dax/Kconfig5
-rw-r--r--drivers/dax/dax.c82
2 files changed, 46 insertions, 41 deletions
diff --git a/drivers/dax/Kconfig b/drivers/dax/Kconfig
index cedab7572de3..daadd20aa936 100644
--- a/drivers/dax/Kconfig
+++ b/drivers/dax/Kconfig
@@ -23,4 +23,9 @@ config DEV_DAX_PMEM
23 23
24 Say Y if unsure 24 Say Y if unsure
25 25
26config NR_DEV_DAX
27 int "Maximum number of Device-DAX instances"
28 default 32768
29 range 256 2147483647
30
26endif 31endif
diff --git a/drivers/dax/dax.c b/drivers/dax/dax.c
index 181d2a5a21e4..17715773c097 100644
--- a/drivers/dax/dax.c
+++ b/drivers/dax/dax.c
@@ -14,15 +14,19 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/device.h> 15#include <linux/device.h>
16#include <linux/pfn_t.h> 16#include <linux/pfn_t.h>
17#include <linux/cdev.h>
17#include <linux/slab.h> 18#include <linux/slab.h>
18#include <linux/dax.h> 19#include <linux/dax.h>
19#include <linux/fs.h> 20#include <linux/fs.h>
20#include <linux/mm.h> 21#include <linux/mm.h>
21#include "dax.h" 22#include "dax.h"
22 23
23static int dax_major; 24static dev_t dax_devt;
24static struct class *dax_class; 25static struct class *dax_class;
25static DEFINE_IDA(dax_minor_ida); 26static DEFINE_IDA(dax_minor_ida);
27static int nr_dax = CONFIG_NR_DEV_DAX;
28module_param(nr_dax, int, S_IRUGO);
29MODULE_PARM_DESC(nr_dax, "max number of device-dax instances");
26 30
27/** 31/**
28 * struct dax_region - mapping infrastructure for dax devices 32 * struct dax_region - mapping infrastructure for dax devices
@@ -49,6 +53,7 @@ struct dax_region {
49 * struct dax_dev - subdivision of a dax region 53 * struct dax_dev - subdivision of a dax region
50 * @region - parent region 54 * @region - parent region
51 * @dev - device backing the character device 55 * @dev - device backing the character device
56 * @cdev - core chardev data
52 * @alive - !alive + rcu grace period == no new mappings can be established 57 * @alive - !alive + rcu grace period == no new mappings can be established
53 * @id - child id in the region 58 * @id - child id in the region
54 * @num_resources - number of physical address extents in this device 59 * @num_resources - number of physical address extents in this device
@@ -57,6 +62,7 @@ struct dax_region {
57struct dax_dev { 62struct dax_dev {
58 struct dax_region *region; 63 struct dax_region *region;
59 struct device dev; 64 struct device dev;
65 struct cdev cdev;
60 bool alive; 66 bool alive;
61 int id; 67 int id;
62 int num_resources; 68 int num_resources;
@@ -367,29 +373,12 @@ static unsigned long dax_get_unmapped_area(struct file *filp,
367 return current->mm->get_unmapped_area(filp, addr, len, pgoff, flags); 373 return current->mm->get_unmapped_area(filp, addr, len, pgoff, flags);
368} 374}
369 375
370static int __match_devt(struct device *dev, const void *data)
371{
372 const dev_t *devt = data;
373
374 return dev->devt == *devt;
375}
376
377static struct device *dax_dev_find(dev_t dev_t)
378{
379 return class_find_device(dax_class, NULL, &dev_t, __match_devt);
380}
381
382static int dax_open(struct inode *inode, struct file *filp) 376static int dax_open(struct inode *inode, struct file *filp)
383{ 377{
384 struct dax_dev *dax_dev = NULL; 378 struct dax_dev *dax_dev;
385 struct device *dev;
386
387 dev = dax_dev_find(inode->i_rdev);
388 if (!dev)
389 return -ENXIO;
390 379
391 dax_dev = to_dax_dev(dev); 380 dax_dev = container_of(inode->i_cdev, struct dax_dev, cdev);
392 dev_dbg(dev, "%s\n", __func__); 381 dev_dbg(&dax_dev->dev, "%s\n", __func__);
393 filp->private_data = dax_dev; 382 filp->private_data = dax_dev;
394 inode->i_flags = S_DAX; 383 inode->i_flags = S_DAX;
395 384
@@ -399,11 +388,8 @@ static int dax_open(struct inode *inode, struct file *filp)
399static int dax_release(struct inode *inode, struct file *filp) 388static int dax_release(struct inode *inode, struct file *filp)
400{ 389{
401 struct dax_dev *dax_dev = filp->private_data; 390 struct dax_dev *dax_dev = filp->private_data;
402 struct device *dev = &dax_dev->dev;
403
404 dev_dbg(dev, "%s\n", __func__);
405 put_device(dev);
406 391
392 dev_dbg(&dax_dev->dev, "%s\n", __func__);
407 return 0; 393 return 0;
408} 394}
409 395
@@ -430,6 +416,7 @@ static void dax_dev_release(struct device *dev)
430static void unregister_dax_dev(void *dev) 416static void unregister_dax_dev(void *dev)
431{ 417{
432 struct dax_dev *dax_dev = to_dax_dev(dev); 418 struct dax_dev *dax_dev = to_dax_dev(dev);
419 struct cdev *cdev = &dax_dev->cdev;
433 420
434 dev_dbg(dev, "%s\n", __func__); 421 dev_dbg(dev, "%s\n", __func__);
435 422
@@ -442,6 +429,7 @@ static void unregister_dax_dev(void *dev)
442 */ 429 */
443 dax_dev->alive = false; 430 dax_dev->alive = false;
444 synchronize_rcu(); 431 synchronize_rcu();
432 cdev_del(cdev);
445 device_unregister(dev); 433 device_unregister(dev);
446} 434}
447 435
@@ -451,17 +439,13 @@ int devm_create_dax_dev(struct dax_region *dax_region, struct resource *res,
451 struct device *parent = dax_region->dev; 439 struct device *parent = dax_region->dev;
452 struct dax_dev *dax_dev; 440 struct dax_dev *dax_dev;
453 struct device *dev; 441 struct device *dev;
442 struct cdev *cdev;
454 int rc, minor; 443 int rc, minor;
455 dev_t dev_t; 444 dev_t dev_t;
456 445
457 dax_dev = kzalloc(sizeof(*dax_dev) + sizeof(*res) * count, GFP_KERNEL); 446 dax_dev = kzalloc(sizeof(*dax_dev) + sizeof(*res) * count, GFP_KERNEL);
458 if (!dax_dev) 447 if (!dax_dev)
459 return -ENOMEM; 448 return -ENOMEM;
460 memcpy(dax_dev->res, res, sizeof(*res) * count);
461 dax_dev->num_resources = count;
462 dax_dev->alive = true;
463 dax_dev->region = dax_region;
464 kref_get(&dax_region->kref);
465 449
466 dax_dev->id = ida_simple_get(&dax_region->ida, 0, 0, GFP_KERNEL); 450 dax_dev->id = ida_simple_get(&dax_region->ida, 0, 0, GFP_KERNEL);
467 if (dax_dev->id < 0) { 451 if (dax_dev->id < 0) {
@@ -475,10 +459,26 @@ int devm_create_dax_dev(struct dax_region *dax_region, struct resource *res,
475 goto err_minor; 459 goto err_minor;
476 } 460 }
477 461
478 dev_t = MKDEV(dax_major, minor); 462 /* device_initialize() so cdev can reference kobj parent */
479 463 dev_t = MKDEV(MAJOR(dax_devt), minor);
480 dev = &dax_dev->dev; 464 dev = &dax_dev->dev;
481 device_initialize(dev); 465 device_initialize(dev);
466
467 cdev = &dax_dev->cdev;
468 cdev_init(cdev, &dax_fops);
469 cdev->owner = parent->driver->owner;
470 cdev->kobj.parent = &dev->kobj;
471 rc = cdev_add(&dax_dev->cdev, dev_t, 1);
472 if (rc)
473 goto err_cdev;
474
475 /* from here on we're committed to teardown via dax_dev_release() */
476 memcpy(dax_dev->res, res, sizeof(*res) * count);
477 dax_dev->num_resources = count;
478 dax_dev->alive = true;
479 dax_dev->region = dax_region;
480 kref_get(&dax_region->kref);
481
482 dev->devt = dev_t; 482 dev->devt = dev_t;
483 dev->class = dax_class; 483 dev->class = dax_class;
484 dev->parent = parent; 484 dev->parent = parent;
@@ -493,6 +493,8 @@ int devm_create_dax_dev(struct dax_region *dax_region, struct resource *res,
493 493
494 return devm_add_action_or_reset(dax_region->dev, unregister_dax_dev, dev); 494 return devm_add_action_or_reset(dax_region->dev, unregister_dax_dev, dev);
495 495
496 err_cdev:
497 ida_simple_remove(&dax_minor_ida, minor);
496 err_minor: 498 err_minor:
497 ida_simple_remove(&dax_region->ida, dax_dev->id); 499 ida_simple_remove(&dax_region->ida, dax_dev->id);
498 err_id: 500 err_id:
@@ -506,24 +508,22 @@ static int __init dax_init(void)
506{ 508{
507 int rc; 509 int rc;
508 510
509 rc = register_chrdev(0, "dax", &dax_fops); 511 nr_dax = max(nr_dax, 256);
510 if (rc < 0) 512 rc = alloc_chrdev_region(&dax_devt, 0, nr_dax, "dax");
513 if (rc)
511 return rc; 514 return rc;
512 dax_major = rc;
513 515
514 dax_class = class_create(THIS_MODULE, "dax"); 516 dax_class = class_create(THIS_MODULE, "dax");
515 if (IS_ERR(dax_class)) { 517 if (IS_ERR(dax_class))
516 unregister_chrdev(dax_major, "dax"); 518 unregister_chrdev_region(dax_devt, nr_dax);
517 return PTR_ERR(dax_class);
518 }
519 519
520 return 0; 520 return PTR_ERR_OR_ZERO(dax_class);
521} 521}
522 522
523static void __exit dax_exit(void) 523static void __exit dax_exit(void)
524{ 524{
525 class_destroy(dax_class); 525 class_destroy(dax_class);
526 unregister_chrdev(dax_major, "dax"); 526 unregister_chrdev_region(dax_devt, nr_dax);
527 ida_destroy(&dax_minor_ida); 527 ida_destroy(&dax_minor_ida);
528} 528}
529 529