Message ID | 20190904010819.11012-2-vishal.l.verma@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [ndctl,1/2] libdaxctl: fix the system-ram capability check | expand |
On Tue, Sep 3, 2019 at 6:08 PM Vishal Verma <vishal.l.verma@intel.com> wrote: > > When the driver of a given reconfiguration mode is builtin, libdaxctl > isn't able to build a module lookup list using kmod. However, it doesn't > need to fail in this case, as it is acceptable for a driver to be > builtin. > > Use the kmod 'initstate' to determine whether the target driver may be > builtin, and ensure it is available by probing it via a named lookup. > If it is available, skip the modalias based list walk, and bind to it > directly. > > Link: https://github.com/pmem/ndctl/issues/108 > Cc: Dan Williams <dan.j.williams@intel.com> > Reported-by: Brice Goglin <Brice.Goglin@inria.fr> > Reported-by: Dave Hansen <dave.hansen@linux.intel.com> > Signed-off-by: Vishal Verma <vishal.l.verma@intel.com> > --- > daxctl/lib/libdaxctl.c | 33 +++++++++++++++++++++++++++++++++ > 1 file changed, 33 insertions(+) > > diff --git a/daxctl/lib/libdaxctl.c b/daxctl/lib/libdaxctl.c > index d9f2c33..7a65bed 100644 > --- a/daxctl/lib/libdaxctl.c > +++ b/daxctl/lib/libdaxctl.c > @@ -868,6 +868,37 @@ DAXCTL_EXPORT int daxctl_dev_is_enabled(struct daxctl_dev *dev) > return is_enabled(path); > } > > +static int try_kmod_builtin(struct daxctl_dev *dev, const char *mod_name) > +{ > + const char *devname = daxctl_dev_get_devname(dev); > + struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev); > + struct kmod_module *kmod; > + int rc = -ENXIO; > + > + rc = kmod_module_new_from_name(ctx->kmod_ctx, mod_name, &kmod); > + if (rc < 0) { > + err(ctx, "%s: failed getting module for: %s: %s\n", > + devname, mod_name, strerror(-rc)); > + return rc; > + } > + > + if (kmod_module_get_initstate(kmod) != KMOD_MODULE_BUILTIN) > + return -ENXIO; > + > + dbg(ctx, "%s inserting module: %s\n", devname, > + kmod_module_get_name(kmod)); > + rc = kmod_module_probe_insert_module(kmod, > + KMOD_PROBE_APPLY_BLACKLIST, > + NULL, NULL, NULL, NULL); > + if (rc < 0) { > + err(ctx, "%s: insert failure: %d\n", devname, rc); > + return rc; > + } > + dev->module = kmod; > + > + return 0; > +} > + > static int daxctl_insert_kmod_for_mode(struct daxctl_dev *dev, > const char *mod_name) > { > @@ -877,6 +908,8 @@ static int daxctl_insert_kmod_for_mode(struct daxctl_dev *dev, > int rc = -ENXIO; > > if (dev->kmod_list == NULL) { Hmm, why wait until now to check if this list is NULL. How about fall back to kmod_module_new_from_name() at to_module_list() time? That would seem to simplify this follow up routine to not need to worry about working around a NULL list.
Thanks, this works here (on a Debian testing with vanilla 5.2.11 and 5.3-rc7). Brice Le 04/09/2019 à 03:08, Vishal Verma a écrit : > When the driver of a given reconfiguration mode is builtin, libdaxctl > isn't able to build a module lookup list using kmod. However, it doesn't > need to fail in this case, as it is acceptable for a driver to be > builtin. > > Use the kmod 'initstate' to determine whether the target driver may be > builtin, and ensure it is available by probing it via a named lookup. > If it is available, skip the modalias based list walk, and bind to it > directly. > > Link: https://github.com/pmem/ndctl/issues/108 > Cc: Dan Williams <dan.j.williams@intel.com> > Reported-by: Brice Goglin <Brice.Goglin@inria.fr> > Reported-by: Dave Hansen <dave.hansen@linux.intel.com> > Signed-off-by: Vishal Verma <vishal.l.verma@intel.com> > --- > daxctl/lib/libdaxctl.c | 33 +++++++++++++++++++++++++++++++++ > 1 file changed, 33 insertions(+) > > diff --git a/daxctl/lib/libdaxctl.c b/daxctl/lib/libdaxctl.c > index d9f2c33..7a65bed 100644 > --- a/daxctl/lib/libdaxctl.c > +++ b/daxctl/lib/libdaxctl.c > @@ -868,6 +868,37 @@ DAXCTL_EXPORT int daxctl_dev_is_enabled(struct daxctl_dev *dev) > return is_enabled(path); > } > > +static int try_kmod_builtin(struct daxctl_dev *dev, const char *mod_name) > +{ > + const char *devname = daxctl_dev_get_devname(dev); > + struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev); > + struct kmod_module *kmod; > + int rc = -ENXIO; > + > + rc = kmod_module_new_from_name(ctx->kmod_ctx, mod_name, &kmod); > + if (rc < 0) { > + err(ctx, "%s: failed getting module for: %s: %s\n", > + devname, mod_name, strerror(-rc)); > + return rc; > + } > + > + if (kmod_module_get_initstate(kmod) != KMOD_MODULE_BUILTIN) > + return -ENXIO; > + > + dbg(ctx, "%s inserting module: %s\n", devname, > + kmod_module_get_name(kmod)); > + rc = kmod_module_probe_insert_module(kmod, > + KMOD_PROBE_APPLY_BLACKLIST, > + NULL, NULL, NULL, NULL); > + if (rc < 0) { > + err(ctx, "%s: insert failure: %d\n", devname, rc); > + return rc; > + } > + dev->module = kmod; > + > + return 0; > +} > + > static int daxctl_insert_kmod_for_mode(struct daxctl_dev *dev, > const char *mod_name) > { > @@ -877,6 +908,8 @@ static int daxctl_insert_kmod_for_mode(struct daxctl_dev *dev, > int rc = -ENXIO; > > if (dev->kmod_list == NULL) { > + if (try_kmod_builtin(dev, mod_name) == 0) > + return 0; > err(ctx, "%s: a modalias lookup list was not created\n", > devname); > return rc;
On Tue, 2019-09-03 at 19:20 -0700, Dan Williams wrote: > > > +static int try_kmod_builtin(struct daxctl_dev *dev, const char *mod_name) > > +{ > > + const char *devname = daxctl_dev_get_devname(dev); > > + struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev); > > + struct kmod_module *kmod; > > + int rc = -ENXIO; > > + > > + rc = kmod_module_new_from_name(ctx->kmod_ctx, mod_name, &kmod); > > + if (rc < 0) { > > + err(ctx, "%s: failed getting module for: %s: %s\n", > > + devname, mod_name, strerror(-rc)); > > + return rc; > > + } > > + > > + if (kmod_module_get_initstate(kmod) != KMOD_MODULE_BUILTIN) > > + return -ENXIO; > > + > > + dbg(ctx, "%s inserting module: %s\n", devname, > > + kmod_module_get_name(kmod)); > > + rc = kmod_module_probe_insert_module(kmod, > > + KMOD_PROBE_APPLY_BLACKLIST, > > + NULL, NULL, NULL, NULL); > > + if (rc < 0) { > > + err(ctx, "%s: insert failure: %d\n", devname, rc); > > + return rc; > > + } > > + dev->module = kmod; > > + > > + return 0; > > +} > > + > > static int daxctl_insert_kmod_for_mode(struct daxctl_dev *dev, > > const char *mod_name) > > { > > @@ -877,6 +908,8 @@ static int daxctl_insert_kmod_for_mode(struct daxctl_dev *dev, > > int rc = -ENXIO; > > > > if (dev->kmod_list == NULL) { > > Hmm, why wait until now to check if this list is NULL. How about fall > back to kmod_module_new_from_name() at to_module_list() time? That > would seem to simplify this follow up routine to not need to worry > about working around a NULL list. So we moved the list checking to later in the process around v4 of the original series, so that we don't unnecessarily fail add_dax_dev() if for some reason a list wasn't created. Also, we use mod_name = dax_modules[mode] during an 'enable' to determine the module name to use for the fallback - we wouldn't have this at add_dax_dev() time.
On Wed, Sep 4, 2019 at 1:27 PM Verma, Vishal L <vishal.l.verma@intel.com> wrote: > > On Tue, 2019-09-03 at 19:20 -0700, Dan Williams wrote: > > > > > +static int try_kmod_builtin(struct daxctl_dev *dev, const char *mod_name) > > > +{ > > > + const char *devname = daxctl_dev_get_devname(dev); > > > + struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev); > > > + struct kmod_module *kmod; > > > + int rc = -ENXIO; > > > + > > > + rc = kmod_module_new_from_name(ctx->kmod_ctx, mod_name, &kmod); > > > + if (rc < 0) { > > > + err(ctx, "%s: failed getting module for: %s: %s\n", > > > + devname, mod_name, strerror(-rc)); > > > + return rc; > > > + } > > > + > > > + if (kmod_module_get_initstate(kmod) != KMOD_MODULE_BUILTIN) > > > + return -ENXIO; > > > + > > > + dbg(ctx, "%s inserting module: %s\n", devname, > > > + kmod_module_get_name(kmod)); > > > + rc = kmod_module_probe_insert_module(kmod, > > > + KMOD_PROBE_APPLY_BLACKLIST, > > > + NULL, NULL, NULL, NULL); > > > + if (rc < 0) { > > > + err(ctx, "%s: insert failure: %d\n", devname, rc); > > > + return rc; > > > + } > > > + dev->module = kmod; > > > + > > > + return 0; > > > +} > > > + > > > static int daxctl_insert_kmod_for_mode(struct daxctl_dev *dev, > > > const char *mod_name) > > > { > > > @@ -877,6 +908,8 @@ static int daxctl_insert_kmod_for_mode(struct daxctl_dev *dev, > > > int rc = -ENXIO; > > > > > > if (dev->kmod_list == NULL) { > > > > Hmm, why wait until now to check if this list is NULL. How about fall > > back to kmod_module_new_from_name() at to_module_list() time? That > > would seem to simplify this follow up routine to not need to worry > > about working around a NULL list. > > So we moved the list checking to later in the process around v4 of the > original series, so that we don't unnecessarily fail add_dax_dev() if > for some reason a list wasn't created. Ah true, I forgot that wrinkle, however... > Also, we use mod_name = dax_modules[mode] during an 'enable' to > determine the module name to use for the fallback - we wouldn't have > this at add_dax_dev() time. Since modalias is already not reliable it seems the implementation should go ahead never do module lookups and just do everything based on module names. In other words the libndctl panacea of not needing to hard code module names is already lost in libdaxctl land. If the code drops modalias usage does that clean up some of these flows?
On Wed, 2019-09-04 at 14:01 -0700, Dan Williams wrote: > On Wed, Sep 4, 2019 at 1:27 PM Verma, Vishal L <vishal.l.verma@intel.com> wrote: > > On Tue, 2019-09-03 at 19:20 -0700, Dan Williams wrote: > > > > > > Hmm, why wait until now to check if this list is NULL. How about fall > > > back to kmod_module_new_from_name() at to_module_list() time? That > > > would seem to simplify this follow up routine to not need to worry > > > about working around a NULL list. > > > > So we moved the list checking to later in the process around v4 of the > > original series, so that we don't unnecessarily fail add_dax_dev() if > > for some reason a list wasn't created. > > Ah true, I forgot that wrinkle, however... > > > Also, we use mod_name = dax_modules[mode] during an 'enable' to > > determine the module name to use for the fallback - we wouldn't have > > this at add_dax_dev() time. > > Since modalias is already not reliable it seems the implementation > should go ahead never do module lookups and just do everything based > on module names. > > In other words the libndctl panacea of not needing to hard code module > names is already lost in libdaxctl land. If the code drops modalias > usage does that clean up some of these flows? Yep I think so - we use modalias to construct a lookup list, but we still have to use the name to resolve to the final module based on the mode. I think we can remove the list lookup and replace it with simply: kmod_module_new_from_name(ctx->kmod_ctx, mod_name, &kmod); It would clean up the module related flows, but is there any disadvantage to doing this?
On Wed, Sep 4, 2019 at 2:17 PM Verma, Vishal L <vishal.l.verma@intel.com> wrote: > > On Wed, 2019-09-04 at 14:01 -0700, Dan Williams wrote: > > On Wed, Sep 4, 2019 at 1:27 PM Verma, Vishal L <vishal.l.verma@intel.com> wrote: > > > On Tue, 2019-09-03 at 19:20 -0700, Dan Williams wrote: > > > > > > > > Hmm, why wait until now to check if this list is NULL. How about fall > > > > back to kmod_module_new_from_name() at to_module_list() time? That > > > > would seem to simplify this follow up routine to not need to worry > > > > about working around a NULL list. > > > > > > So we moved the list checking to later in the process around v4 of the > > > original series, so that we don't unnecessarily fail add_dax_dev() if > > > for some reason a list wasn't created. > > > > Ah true, I forgot that wrinkle, however... > > > > > Also, we use mod_name = dax_modules[mode] during an 'enable' to > > > determine the module name to use for the fallback - we wouldn't have > > > this at add_dax_dev() time. > > > > Since modalias is already not reliable it seems the implementation > > should go ahead never do module lookups and just do everything based > > on module names. > > > > In other words the libndctl panacea of not needing to hard code module > > names is already lost in libdaxctl land. If the code drops modalias > > usage does that clean up some of these flows? > > Yep I think so - we use modalias to construct a lookup list, but we > still have to use the name to resolve to the final module based on the > mode. I think we can remove the list lookup and replace it with simply: > > kmod_module_new_from_name(ctx->kmod_ctx, mod_name, &kmod); > > It would clean up the module related flows, but is there any > disadvantage to doing this? The small disadvantage is that now libdaxctl is not immune to upstream kernel reworks that might rename, or eliminate the module. libndctl has that immunity to those type of reworks, but it is only a theoretical problem. In practice modules don't renamed or eliminated all that often. In the case of dax the device-model reworks almost violated that assumption, but CONFIG_DEV_DAX_PMEM_COMPAT covered the gap.
diff --git a/daxctl/lib/libdaxctl.c b/daxctl/lib/libdaxctl.c index d9f2c33..7a65bed 100644 --- a/daxctl/lib/libdaxctl.c +++ b/daxctl/lib/libdaxctl.c @@ -868,6 +868,37 @@ DAXCTL_EXPORT int daxctl_dev_is_enabled(struct daxctl_dev *dev) return is_enabled(path); } +static int try_kmod_builtin(struct daxctl_dev *dev, const char *mod_name) +{ + const char *devname = daxctl_dev_get_devname(dev); + struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev); + struct kmod_module *kmod; + int rc = -ENXIO; + + rc = kmod_module_new_from_name(ctx->kmod_ctx, mod_name, &kmod); + if (rc < 0) { + err(ctx, "%s: failed getting module for: %s: %s\n", + devname, mod_name, strerror(-rc)); + return rc; + } + + if (kmod_module_get_initstate(kmod) != KMOD_MODULE_BUILTIN) + return -ENXIO; + + dbg(ctx, "%s inserting module: %s\n", devname, + kmod_module_get_name(kmod)); + rc = kmod_module_probe_insert_module(kmod, + KMOD_PROBE_APPLY_BLACKLIST, + NULL, NULL, NULL, NULL); + if (rc < 0) { + err(ctx, "%s: insert failure: %d\n", devname, rc); + return rc; + } + dev->module = kmod; + + return 0; +} + static int daxctl_insert_kmod_for_mode(struct daxctl_dev *dev, const char *mod_name) { @@ -877,6 +908,8 @@ static int daxctl_insert_kmod_for_mode(struct daxctl_dev *dev, int rc = -ENXIO; if (dev->kmod_list == NULL) { + if (try_kmod_builtin(dev, mod_name) == 0) + return 0; err(ctx, "%s: a modalias lookup list was not created\n", devname); return rc;
When the driver of a given reconfiguration mode is builtin, libdaxctl isn't able to build a module lookup list using kmod. However, it doesn't need to fail in this case, as it is acceptable for a driver to be builtin. Use the kmod 'initstate' to determine whether the target driver may be builtin, and ensure it is available by probing it via a named lookup. If it is available, skip the modalias based list walk, and bind to it directly. Link: https://github.com/pmem/ndctl/issues/108 Cc: Dan Williams <dan.j.williams@intel.com> Reported-by: Brice Goglin <Brice.Goglin@inria.fr> Reported-by: Dave Hansen <dave.hansen@linux.intel.com> Signed-off-by: Vishal Verma <vishal.l.verma@intel.com> --- daxctl/lib/libdaxctl.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+)