linux-device-driverprintk

Proper usage of %pad specifier in Linux kernel function printk?


I am working on a DMA driver. I found in documentation that there is special printk specifier for dma_addr_t:

%pad 0x01234567 or 0x0123456789abcdef

For printing a dma_addr_t type which can vary based on build options, regardless of the width of the CPU data path.

However, when I tried to utilise it for debug messages I got compiler warnings:

In file included from /usr/src/linux-headers-5.10.0-33-common/include/linux/printk.h:7,
                 from /usr/src/linux-headers-5.10.0-33-common/include/linux/kernel.h:17,
                 from /usr/src/linux-headers-5.10.0-33-common/include/linux/list.h:9,
                 from /usr/src/linux-headers-5.10.0-33-common/include/linux/module.h:12,
                 from /home/andrey/IOXOS/XDMA_driver/XDMA/linux-kernel/xdma/libxdma.c:22:
/usr/src/linux-headers-5.10.0-33-common/include/linux/kern_levels.h:5:18: warning: format ??%p?? expects argument of type ??void *??, but argument 5 has type ??dma_addr_t?? {aka ??long long unsigned int??} [-Wformat=]
    5 | #define KERN_SOH "\001"  /* ASCII Start Of Header */
      |                  ^~~~~~
/usr/src/linux-headers-5.10.0-33-common/include/linux/kern_levels.h:14:19: note: in expansion of macro ??KERN_SOH??
   14 | #define KERN_INFO KERN_SOH "6" /* informational */
      |                   ^~~~~~~~
/usr/src/linux-headers-5.10.0-33-common/include/linux/printk.h:373:9: note: in expansion of macro ??KERN_INFO??
  373 |  printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
      |         ^~~~~~~~~
/home/andrey/IOXOS/XDMA_driver/XDMA/linux-kernel/xdma/libxdma.h:213:17: note: in expansion of macro ??pr_info??
  213 | #define dbg_sg  pr_info
      |                 ^~~~~~~
/home/andrey/mypath/file.c:1692:3: note: in expansion of macro ??dbg_sg??
 1692 |   pr_info("Descriptor DMA record %u: virtual address %p, DMA address %pad\n",

Obviously gcc doesn't recognise the specifier. ?? above are copy-paste artefacts.

But even way worse: attempting to use the driver with the specifier leads to hard freeze of my development system. I confidently traced back the freeze to the specifier by selectively commenting out the code.

How the specifier is supposed to be used so it doesn't causes these problems?

System is Debian 11 (5.10 Linux kernel) with gcc 10.2.1


Solution

  • I overlooked that the DMA address must be passed "by reference", that is by pointer. Correcting this resolved the problem.

    Thanks to @NateEldredge for pointing this out.