On Wed, May 07, 2025 at 09:37:07AM +0700, Bagas Sanjaya wrote:
On Mon, May 05, 2025 at 11:18:32AM -0300, Jason Gunthorpe wrote:
+Since each compilation unit can only access one underlying format at a time, +code that is intended to be generic across multiple formats has to compile +itself multiple times.
+In an implementation compilation unit the headers would normally be included as +follows::
- #include <linux/generic_pt/common.h>
- #include "fmt/defs_amdv1.h"
- #include "pt_defs.h"
- #include "fmt/amdv1.h"
- #include "pt_common.h"
- #include "pt_iter.h"
What do you mean by compiling generic code multiple times? Including their headers at multiple places like above?
How about like this:
Instead the function pointers can end up at the higher level API (ie map/unmap, etc) and the per-format code can be directly inlined into the per-format compilation unit. For something like iommu each format will be compiled into a per-format iommu operations kernel module.
For this to work the .c file for each compilation unit will include both the format headers and the generic code for the implementation. For instance in an implementation compilation unit the headers would normally be included as follows::
#include <linux/generic_pt/common.h> #include "fmt/defs_amdv1.h" #include "pt_defs.h" #include "fmt/amdv1.h" #include "pt_common.h" #include "pt_iter.h" #include "iommut_pt.h" /* The iommu implementation */
iommu_pt.h includes definitions that will generate the operations functions for map/unmap/etc using the definitions provided by AMDv1. The resulting module will have exported symbols named like pt_iommu_amdv1_init().
Thanks, Jason