[PATCH rdma-core 6/8] verbs: Provide infrastructure to remove kernel headers copies

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Jason Gunthorpe <jgg@xxxxxxxxxxxx>

The remaining kernel headers are all inlined into a struct. To avoid
major code changes we want to retain this arrangement, but still use the
kernel headers directly.

This solution is to mangle the kernel headers by script into an anonymous
and tagless struct that can be used in place of the copied data.

With the support of a few macros the whole thing becomes fairly
straightforward.

Signed-off-by: Jason Gunthorpe <jgg@xxxxxxxxxxxx>
---
 buildlib/make_abi_structs.py  | 56 +++++++++++++++++++++++++++++++++++++++++++
 kernel-headers/CMakeLists.txt | 35 +++++++++++++++++++++++++++
 kernel-headers/kern-abi.c     |  1 +
 libibverbs/CMakeLists.txt     |  1 +
 4 files changed, 93 insertions(+)
 create mode 100644 buildlib/make_abi_structs.py
 create mode 100644 kernel-headers/kern-abi.c

diff --git a/buildlib/make_abi_structs.py b/buildlib/make_abi_structs.py
new file mode 100644
index 00000000000000..029f10428ad300
--- /dev/null
+++ b/buildlib/make_abi_structs.py
@@ -0,0 +1,56 @@
+#/usr/bin/env python
+"""This script transforms the structs inside the kernel ABI headers into a define
+of an anonymous struct.
+
+eg
+  struct abc {int foo;};
+becomes
+  #define _STRUCT_abc struct {int foo;};
+
+This allows the exact same struct to be included in the provider wrapper struct:
+
+struct abc_resp {
+   struct ibv_abc ibv_resp;
+   _STRUCT_abc;
+};
+
+Which duplicates the struct layout and naming we have historically used, but
+sources the data directly from the kernel headers instead of manually copying."""
+import re;
+import functools;
+import sys;
+
+def in_struct(ln,FO,nesting=0):
+    """Copy a top level structure over to the #define output, keeping track of
+    nested structures."""
+    if nesting == 0:
+        if ln == "};":
+            FO.write("}\n\n");
+            return find_struct;
+
+    FO.write(ln + " \\\n");
+
+    if ln == "struct {" or ln == "union {":
+        return functools.partial(in_struct,nesting=nesting+1);
+
+    if  re.match(r"}.*;",ln):
+        return functools.partial(in_struct,nesting=nesting-1);
+    return functools.partial(in_struct,nesting=nesting);
+
+def find_struct(ln,FO):
+    """Look for the start of a top level structure"""
+    if ln.startswith("struct ") or ln.startswith("union "):
+        g = re.match(r"(struct|union)\s+(\S+)\s+{",ln);
+        FO.write("#define _STRUCT_%s %s { \\\n"%(g.group(2),g.group(1)));
+        return in_struct;
+    return find_struct;
+
+with open(sys.argv[1]) as FI:
+    with open(sys.argv[2],"w") as FO:
+        state = find_struct;
+        for ln in FI:
+            # Drop obvious comments
+            ln = ln.strip();
+            ln = re.sub(r"/\*.*\*/","",ln);
+            ln = re.sub(r"//.*$","",ln);
+            state = state(ln,FO);
diff --git a/kernel-headers/CMakeLists.txt b/kernel-headers/CMakeLists.txt
index 64bc5e66c21b18..0e163bd86c184d 100644
--- a/kernel-headers/CMakeLists.txt
+++ b/kernel-headers/CMakeLists.txt
@@ -25,3 +25,38 @@ publish_internal_headers(rdma/hfi
   rdma/hfi/hfi1_ioctl.h
   rdma/hfi/hfi1_user.h
   )
+
+function(rdma_kernel_provider_abi)
+  # Older versions of cmake do not create the output directory automatically
+  set(DDIR "${BUILD_INCLUDE}/kernel-abi")
+  if(NOT EXISTS "${DDIR}/")
+    execute_process(COMMAND "${CMAKE_COMMAND}" "-E" "make_directory"
+      "${DDIR}" RESULT_VARIABLE retcode)
+    if(NOT "${retcode}" STREQUAL "0")
+      message(FATAL_ERROR "Failed to create directory ${DDIR}")
+    endif()
+  endif()
+
+  set(HDRS "")
+  foreach(IHDR ${ARGN})
+    get_filename_component(FIL ${IHDR} NAME)
+    set(OHDR "${DDIR}/${FIL}")
+    set(HDRS ${HDRS} ${OHDR})
+    add_custom_command(
+      OUTPUT "${OHDR}"
+      COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_SOURCE_DIR}/buildlib/make_abi_structs.py" "${IHDR}" "${OHDR}"
+      MAIN_DEPENDENCY "${IHDR}"
+      DEPENDS "${CMAKE_SOURCE_DIR}/buildlib/make_abi_structs.py"
+      WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+      COMMENT "Creating ABI wrapper ${OHDR}"
+      )
+  endforeach()
+
+  # This weird construction is needed to ensure ordering of the build.
+  add_library(kern-abi STATIC kern-abi.c ${HDRS})
+endfunction()
+
+# Transform the kernel ABIs used by the providers
+rdma_kernel_provider_abi(
+  rdma/ib_user_verbs.h
+  )
diff --git a/kernel-headers/kern-abi.c b/kernel-headers/kern-abi.c
new file mode 100644
index 00000000000000..cd2941ed829a5a
--- /dev/null
+++ b/kernel-headers/kern-abi.c
@@ -0,0 +1 @@
+/* empty file for cmake */
diff --git a/libibverbs/CMakeLists.txt b/libibverbs/CMakeLists.txt
index fd4374d9c8428b..6fdec63ac0c54c 100644
--- a/libibverbs/CMakeLists.txt
+++ b/libibverbs/CMakeLists.txt
@@ -46,4 +46,5 @@ target_link_libraries(ibverbs LINK_PRIVATE
   ${NL_LIBRARIES}
   ${CMAKE_THREAD_LIBS_INIT}
   ${CMAKE_DL_LIBS}
+  kern-abi
   )
-- 
2.16.1

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux