On 2024-02-13 00:12, kernel test robot wrote:
tree: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master
head: ae00c445390b349e070a64dc62f08aa878db7248
commit: 9af4599a77df42dba7f32c76a97a19f5703f44b7 [5601/6082] dm: cleanup alloc_dax() error handling
config: openrisc-randconfig-r011-20221209 (https://download.01.org/0day-ci/archive/20240213/202402131351.a0FZOgEG-lkp@xxxxxxxxx/config)
compiler: or1k-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240213/202402131351.a0FZOgEG-lkp@xxxxxxxxx/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@xxxxxxxxx>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402131351.a0FZOgEG-lkp@xxxxxxxxx/
All errors (new ones prefixed by >>):
or1k-linux-ld: drivers/md/dm.o: in function `alloc_dev':
drivers/md/dm.c:2131:(.text+0x9f34): undefined reference to `set_dax_nocache'
drivers/md/dm.c:2131:(.text+0x9f34): relocation truncated to fit: R_OR1K_INSN_REL_26 against undefined symbol `set_dax_nocache'
or1k-linux-ld: drivers/md/dm.c:2132:(.text+0x9f3c): undefined reference to `set_dax_nomc'
drivers/md/dm.c:2132:(.text+0x9f3c): relocation truncated to fit: R_OR1K_INSN_REL_26 against undefined symbol `set_dax_nomc'
pahole: .tmp_vmlinux.btf: Invalid argument
.btf.vmlinux.bin.o: file not recognized: file format not recognized
It comes as a surprise that a call to set_dax_nocache() from within a
branch provably never taken ends up keeping a reference to the missing
symbol. I would have expected compiler optimizations to remove the call
to the missing symbol altogether, but maybe I'm expecting too much.
Basically here we have:
CONFIG_DAX=n
static inline struct dax_device *alloc_dax(void *private,
const struct dax_operations *ops)
{
return ERR_PTR(-EOPNOTSUPP);
}
static struct mapped_device *alloc_dev(int minor)
{
[...]
dax_dev = alloc_dax(md, &dm_dax_ops);
if (IS_ERR(dax_dev)) {
if (PTR_ERR(dax_dev) != -EOPNOTSUPP)
goto bad;
} else {
set_dax_nocache(dax_dev);
set_dax_nomc(dax_dev);
md->dax_dev = dax_dev;
if (dax_add_host(dax_dev, md->disk))
goto bad;
}
The simple fix would be something like this, but I would like to
understand why we observe this specifically on openrisc and loongarch
(https://lore.kernel.org/oe-kbuild-all/202402140037.wGfA1kqX-lkp@xxxxxxxxx/).
diff --git a/include/linux/dax.h b/include/linux/dax.h
index df2d52b8a245..9d3e3327af4c 100644
--- a/include/linux/dax.h
+++ b/include/linux/dax.h
@@ -63,6 +63,8 @@ void kill_dax(struct dax_device *dax_dev);
void dax_write_cache(struct dax_device *dax_dev, bool wc);
bool dax_write_cache_enabled(struct dax_device *dax_dev);
bool dax_synchronous(struct dax_device *dax_dev);
+void set_dax_nocache(struct dax_device *dax_dev);
+void set_dax_nomc(struct dax_device *dax_dev);
void set_dax_synchronous(struct dax_device *dax_dev);
size_t dax_recovery_write(struct dax_device *dax_dev, pgoff_t pgoff,
void *addr, size_t bytes, struct iov_iter *i);
@@ -105,6 +107,12 @@ static inline bool dax_synchronous(struct dax_device *dax_dev)
{
return true;
}
+static inline void set_dax_nocache(struct dax_device *dax_dev)
+{
+}
+static inline void set_dax_nomc(struct dax_device *dax_dev)
+{
+}
static inline void set_dax_synchronous(struct dax_device *dax_dev)
{
}
@@ -120,9 +128,6 @@ static inline size_t dax_recovery_write(struct dax_device *dax_dev,
}
#endif
-void set_dax_nocache(struct dax_device *dax_dev);
-void set_dax_nomc(struct dax_device *dax_dev);
-
struct writeback_control;
#if defined(CONFIG_BLOCK) && defined(CONFIG_FS_DAX)
int dax_add_host(struct dax_device *dax_dev, struct gendisk *disk);
Thanks,
Mathieu
--
Mathieu Desnoyers
EfficiOS Inc.
https://www.efficios.com