On Tue, 17 Feb 2026 11:56:20 -0600 John Groves <[email protected]> wrote:
> On 26/02/13 03:05PM, Ira Weiny wrote: > > John Groves wrote: > > > From: John Groves <[email protected]> > > > > > > The new fsdev driver provides pages/folios initialized compatibly with > > > fsdax - normal rather than devdax-style refcounting, and starting out > > > with order-0 folios. > > > > > > When fsdev binds to a daxdev, it is usually (always?) switching from the > > > devdax mode (device.c), which pre-initializes compound folios according > > > to its alignment. Fsdev uses fsdev_clear_folio_state() to switch the > > > folios into a fsdax-compatible state. > > > > > > A side effect of this is that raw mmap doesn't (can't?) work on an fsdev > > > dax instance. Accordingly, The fsdev driver does not provide raw mmap - > > > devices must be put in 'devdax' mode (drivers/dax/device.c) to get raw > > > mmap capability. > > > > > > In this commit is just the framework, which remaps pages/folios compatibly > > > with fsdax. > > > > > > Enabling dax changes: > > > > > > - bus.h: add DAXDRV_FSDEV_TYPE driver type > > > - bus.c: allow DAXDRV_FSDEV_TYPE drivers to bind to daxdevs > > > - dax.h: prototype inode_dax(), which fsdev needs > > > > > > Suggested-by: Dan Williams <[email protected]> > > > Suggested-by: Gregory Price <[email protected]> > > > Signed-off-by: John Groves <[email protected]> > > > --- > > > MAINTAINERS | 8 ++ > > > drivers/dax/Makefile | 6 ++ > > > drivers/dax/bus.c | 4 + > > > drivers/dax/bus.h | 1 + > > > drivers/dax/fsdev.c | 242 +++++++++++++++++++++++++++++++++++++++++++ > > > fs/dax.c | 1 + > > > include/linux/dax.h | 5 + > > > 7 files changed, 267 insertions(+) > > > create mode 100644 drivers/dax/fsdev.c > > > > > > > [snip] > > > > > + > > > +static int fsdev_dax_probe(struct dev_dax *dev_dax) > > > +{ > > > + struct dax_device *dax_dev = dev_dax->dax_dev; > > > + struct device *dev = &dev_dax->dev; > > > + struct dev_pagemap *pgmap; > > > + u64 data_offset = 0; > > > + struct inode *inode; > > > + struct cdev *cdev; > > > + void *addr; > > > + int rc, i; > > > + > > > + if (static_dev_dax(dev_dax)) { > > > + if (dev_dax->nr_range > 1) { > > > + dev_warn(dev, "static pgmap / multi-range device > > > conflict\n"); > > > + return -EINVAL; > > > + } > > > + > > > + pgmap = dev_dax->pgmap; > > > + } else { > > > + size_t pgmap_size; > > > + > > > + if (dev_dax->pgmap) { > > > + dev_warn(dev, "dynamic-dax with pre-populated page > > > map\n"); > > > + return -EINVAL; > > > + } > > > + > > > + pgmap_size = struct_size(pgmap, ranges, dev_dax->nr_range - 1); > > > + pgmap = devm_kzalloc(dev, pgmap_size, GFP_KERNEL); > > > + if (!pgmap) > > > + return -ENOMEM; > > > + > > > + pgmap->nr_range = dev_dax->nr_range; > > > + dev_dax->pgmap = pgmap; > > > + > > > + for (i = 0; i < dev_dax->nr_range; i++) { > > > + struct range *range = &dev_dax->ranges[i].range; > > > + > > > + pgmap->ranges[i] = *range; > > > + } > > > + } > > > + > > > + for (i = 0; i < dev_dax->nr_range; i++) { > > > + struct range *range = &dev_dax->ranges[i].range; > > > + > > > + if (!devm_request_mem_region(dev, range->start, > > > + range_len(range), dev_name(dev))) { > > > + dev_warn(dev, "mapping%d: %#llx-%#llx could not reserve > > > range\n", > > > + i, range->start, range->end); > > > + return -EBUSY; > > > + } > > > + } > > > > All of the above code is AFAICT exactly the same as the dev_dax driver. > > Isn't there a way to make this common? > > > > The rest of the common code is simple enough. > > dev_dax_probe() and fsdev_dax_probe() do indeed have some "same code" - > range validity checking and pgmap setup, from the top of probe through > the for loop above. After that they're different. Also, I just did a scan > and the probe function seems like the only remaining common code between > device.c and fsdev.c. > > These are separate kmods; that code could certainly be factored out and > shared, but it would need to go somewhere common (maybe bus.c)? Given I made a similar comment on new version. I'll reply here. Could move it to core code, or if you want to keep stuff kmod, it's common enough to have helper / library modules. They are non userselectable Kconfig options that are selected by the visible parts that need them. Then dependency management ensures the helper gets loaded first. > > So both device.c and fsdev.c would call bus.c:dax_prepare_pgmap() or > some such. > > I feel like this might not be worth factoring out, but I'm happy to do it > if you and/or the dax team prefer it factored out and shared. I think I'd like to see what it looks like. Maybe as a series on top. But not my area so over to Dax folk ;) Jonathan >

