xref: /freebsd/sys/contrib/openzfs/config/kernel.m4 (revision 61145dc2b94f12f6a47344fb9aac702321880e43)
1dnl #
2dnl # Default ZFS kernel configuration
3dnl #
4AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
5	AM_COND_IF([BUILD_LINUX], [
6		dnl # Setup the kernel build environment.
7		ZFS_AC_KERNEL
8		ZFS_AC_QAT
9
10		dnl # Sanity checks for module building and CONFIG_* defines
11		ZFS_AC_KERNEL_CONFIG_DEFINED
12		ZFS_AC_MODULE_SYMVERS
13
14		dnl # Sequential ZFS_LINUX_TRY_COMPILE tests
15		ZFS_AC_KERNEL_FPU_HEADER
16		ZFS_AC_KERNEL_OBJTOOL_HEADER
17		ZFS_AC_KERNEL_MISC_MINOR
18		ZFS_AC_KERNEL_DECLARE_EVENT_CLASS
19
20		dnl # Parallel ZFS_LINUX_TEST_SRC / ZFS_LINUX_TEST_RESULT tests
21		ZFS_AC_KERNEL_TEST_SRC
22		ZFS_AC_KERNEL_TEST_RESULT
23
24		AS_IF([test "$LINUX_OBJ" != "$LINUX"], [
25			KERNEL_MAKE="$KERNEL_MAKE O=$LINUX_OBJ"
26		])
27
28		AC_SUBST(KERNEL_MAKE)
29	])
30])
31
32dnl #
33dnl # Generate and compile all of the kernel API test cases to determine
34dnl # which interfaces are available.  By invoking the kernel build system
35dnl # only once the compilation can be done in parallel significantly
36dnl # speeding up the process.
37dnl #
38AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
39	ZFS_AC_KERNEL_SRC_TYPES
40	ZFS_AC_KERNEL_SRC_OBJTOOL
41	ZFS_AC_KERNEL_SRC_ACCESS_OK_TYPE
42	ZFS_AC_KERNEL_SRC_PDE_DATA
43	ZFS_AC_KERNEL_SRC_GENERIC_FADVISE
44	ZFS_AC_KERNEL_SRC_SCHED
45	ZFS_AC_KERNEL_SRC_USLEEP_RANGE
46	ZFS_AC_KERNEL_SRC_VMALLOC_PAGE_KERNEL
47	ZFS_AC_KERNEL_SRC_INODE_TIMES
48	ZFS_AC_KERNEL_SRC_PROC_OPERATIONS
49	ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS
50	ZFS_AC_KERNEL_SRC_BIO
51	ZFS_AC_KERNEL_SRC_BLKDEV
52	ZFS_AC_KERNEL_SRC_BLK_QUEUE
53	ZFS_AC_KERNEL_SRC_GENHD_FLAGS
54	ZFS_AC_KERNEL_SRC_REVALIDATE_DISK
55	ZFS_AC_KERNEL_SRC_GET_DISK_RO
56	ZFS_AC_KERNEL_SRC_DISCARD_GRANULARITY
57	ZFS_AC_KERNEL_SRC_INODE_OWNER_OR_CAPABLE
58	ZFS_AC_KERNEL_SRC_XATTR
59	ZFS_AC_KERNEL_SRC_ACL
60	ZFS_AC_KERNEL_SRC_INODE_SETATTR
61	ZFS_AC_KERNEL_SRC_INODE_GETATTR
62	ZFS_AC_KERNEL_SRC_SHOW_OPTIONS
63	ZFS_AC_KERNEL_SRC_SHRINKER
64	ZFS_AC_KERNEL_SRC_MKDIR
65	ZFS_AC_KERNEL_SRC_LOOKUP_FLAGS
66	ZFS_AC_KERNEL_SRC_CREATE
67	ZFS_AC_KERNEL_SRC_PERMISSION
68	ZFS_AC_KERNEL_SRC_TMPFILE
69	ZFS_AC_KERNEL_SRC_AUTOMOUNT
70	ZFS_AC_KERNEL_SRC_COMMIT_METADATA
71	ZFS_AC_KERNEL_SRC_SETATTR_PREPARE
72	ZFS_AC_KERNEL_SRC_INSERT_INODE_LOCKED
73	ZFS_AC_KERNEL_SRC_TRUNCATE_SETSIZE
74	ZFS_AC_KERNEL_SRC_SECURITY_INODE
75	ZFS_AC_KERNEL_SRC_FST_MOUNT
76	ZFS_AC_KERNEL_SRC_SB_DYING
77	ZFS_AC_KERNEL_SRC_SET_NLINK
78	ZFS_AC_KERNEL_SRC_SGET
79	ZFS_AC_KERNEL_SRC_VFS_FILEMAP_DIRTY_FOLIO
80	ZFS_AC_KERNEL_SRC_VFS_READ_FOLIO
81	ZFS_AC_KERNEL_SRC_VFS_MIGRATE_FOLIO
82	ZFS_AC_KERNEL_SRC_VFS_FSYNC_2ARGS
83	ZFS_AC_KERNEL_SRC_VFS_READPAGES
84	ZFS_AC_KERNEL_SRC_VFS_SET_PAGE_DIRTY_NOBUFFERS
85	ZFS_AC_KERNEL_SRC_VFS_IOV_ITER
86	ZFS_AC_KERNEL_SRC_VFS_GENERIC_COPY_FILE_RANGE
87	ZFS_AC_KERNEL_SRC_VFS_SPLICE_COPY_FILE_RANGE
88	ZFS_AC_KERNEL_SRC_VFS_REMAP_FILE_RANGE
89	ZFS_AC_KERNEL_SRC_VFS_CLONE_FILE_RANGE
90	ZFS_AC_KERNEL_SRC_VFS_DEDUPE_FILE_RANGE
91	ZFS_AC_KERNEL_SRC_KMAP_ATOMIC_ARGS
92	ZFS_AC_KERNEL_SRC_KMAP_LOCAL_PAGE
93	ZFS_AC_KERNEL_SRC_FOLLOW_DOWN_ONE
94	ZFS_AC_KERNEL_SRC_MAKE_REQUEST_FN
95	ZFS_AC_KERNEL_SRC_GENERIC_IO_ACCT
96	ZFS_AC_KERNEL_SRC_FPU
97	ZFS_AC_KERNEL_SRC_FMODE_T
98	ZFS_AC_KERNEL_SRC_KUIDGID_T
99	ZFS_AC_KERNEL_SRC_KUID_HELPERS
100	ZFS_AC_KERNEL_SRC_RENAME
101	ZFS_AC_KERNEL_SRC_TOTALRAM_PAGES_FUNC
102	ZFS_AC_KERNEL_SRC_TOTALHIGH_PAGES
103	ZFS_AC_KERNEL_SRC_PERCPU
104	ZFS_AC_KERNEL_SRC_GENERIC_FILLATTR
105	ZFS_AC_KERNEL_SRC_MKNOD
106	ZFS_AC_KERNEL_SRC_SYMLINK
107	ZFS_AC_KERNEL_SRC_BIO_MAX_SEGS
108	ZFS_AC_KERNEL_SRC_SIGINFO
109	ZFS_AC_KERNEL_SRC_SYSFS
110	ZFS_AC_KERNEL_SRC_STANDALONE_LINUX_STDARG
111	ZFS_AC_KERNEL_SRC_STRLCPY
112	ZFS_AC_KERNEL_SRC_PAGEMAP_FOLIO_WAIT_BIT
113	ZFS_AC_KERNEL_SRC_ADD_DISK
114	ZFS_AC_KERNEL_SRC_KTHREAD
115	ZFS_AC_KERNEL_SRC_ZERO_PAGE
116	ZFS_AC_KERNEL_SRC___COPY_FROM_USER_INATOMIC
117	ZFS_AC_KERNEL_SRC_IDMAP_MNT_API
118	ZFS_AC_KERNEL_SRC_IDMAP_NO_USERNS
119	ZFS_AC_KERNEL_SRC_IATTR_VFSID
120	ZFS_AC_KERNEL_SRC_WRITEPAGE_T
121	ZFS_AC_KERNEL_SRC_RECLAIMED
122	ZFS_AC_KERNEL_SRC_REGISTER_SYSCTL_TABLE
123	ZFS_AC_KERNEL_SRC_REGISTER_SYSCTL_SZ
124	ZFS_AC_KERNEL_SRC_PROC_HANDLER_CTL_TABLE_CONST
125	ZFS_AC_KERNEL_SRC_COPY_SPLICE_READ
126	ZFS_AC_KERNEL_SRC_SYNC_BDEV
127	ZFS_AC_KERNEL_SRC_MM_PAGE_FLAGS
128	ZFS_AC_KERNEL_SRC_MM_PAGE_SIZE
129	ZFS_AC_KERNEL_SRC_MM_PAGE_MAPPING
130	ZFS_AC_KERNEL_SRC_FILE
131	ZFS_AC_KERNEL_SRC_PIN_USER_PAGES
132	case "$host_cpu" in
133		powerpc*)
134			ZFS_AC_KERNEL_SRC_CPU_HAS_FEATURE
135			ZFS_AC_KERNEL_SRC_FLUSH_DCACHE_PAGE
136			;;
137		riscv*)
138			ZFS_AC_KERNEL_SRC_FLUSH_DCACHE_PAGE
139			;;
140	esac
141
142	AC_MSG_CHECKING([for available kernel interfaces])
143	ZFS_LINUX_TEST_COMPILE_ALL([kabi])
144	AC_MSG_RESULT([done])
145])
146
147dnl #
148dnl # Check results of kernel interface tests.
149dnl #
150AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
151	ZFS_AC_KERNEL_TYPES
152	ZFS_AC_KERNEL_ACCESS_OK_TYPE
153	ZFS_AC_KERNEL_OBJTOOL
154	ZFS_AC_KERNEL_PDE_DATA
155	ZFS_AC_KERNEL_GENERIC_FADVISE
156	ZFS_AC_KERNEL_SCHED
157	ZFS_AC_KERNEL_USLEEP_RANGE
158	ZFS_AC_KERNEL_VMALLOC_PAGE_KERNEL
159	ZFS_AC_KERNEL_INODE_TIMES
160	ZFS_AC_KERNEL_PROC_OPERATIONS
161	ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS
162	ZFS_AC_KERNEL_BIO
163	ZFS_AC_KERNEL_BLKDEV
164	ZFS_AC_KERNEL_BLK_QUEUE
165	ZFS_AC_KERNEL_GENHD_FLAGS
166	ZFS_AC_KERNEL_REVALIDATE_DISK
167	ZFS_AC_KERNEL_GET_DISK_RO
168	ZFS_AC_KERNEL_DISCARD_GRANULARITY
169	ZFS_AC_KERNEL_INODE_OWNER_OR_CAPABLE
170	ZFS_AC_KERNEL_XATTR
171	ZFS_AC_KERNEL_ACL
172	ZFS_AC_KERNEL_INODE_SETATTR
173	ZFS_AC_KERNEL_INODE_GETATTR
174	ZFS_AC_KERNEL_SHOW_OPTIONS
175	ZFS_AC_KERNEL_SHRINKER
176	ZFS_AC_KERNEL_MKDIR
177	ZFS_AC_KERNEL_LOOKUP_FLAGS
178	ZFS_AC_KERNEL_CREATE
179	ZFS_AC_KERNEL_PERMISSION
180	ZFS_AC_KERNEL_TMPFILE
181	ZFS_AC_KERNEL_AUTOMOUNT
182	ZFS_AC_KERNEL_COMMIT_METADATA
183	ZFS_AC_KERNEL_SETATTR_PREPARE
184	ZFS_AC_KERNEL_INSERT_INODE_LOCKED
185	ZFS_AC_KERNEL_TRUNCATE_SETSIZE
186	ZFS_AC_KERNEL_SECURITY_INODE
187	ZFS_AC_KERNEL_FST_MOUNT
188	ZFS_AC_KERNEL_SB_DYING
189	ZFS_AC_KERNEL_SET_NLINK
190	ZFS_AC_KERNEL_SGET
191	ZFS_AC_KERNEL_VFS_FILEMAP_DIRTY_FOLIO
192	ZFS_AC_KERNEL_VFS_READ_FOLIO
193	ZFS_AC_KERNEL_VFS_MIGRATE_FOLIO
194	ZFS_AC_KERNEL_VFS_FSYNC_2ARGS
195	ZFS_AC_KERNEL_VFS_READPAGES
196	ZFS_AC_KERNEL_VFS_SET_PAGE_DIRTY_NOBUFFERS
197	ZFS_AC_KERNEL_VFS_IOV_ITER
198	ZFS_AC_KERNEL_VFS_GENERIC_COPY_FILE_RANGE
199	ZFS_AC_KERNEL_VFS_SPLICE_COPY_FILE_RANGE
200	ZFS_AC_KERNEL_VFS_REMAP_FILE_RANGE
201	ZFS_AC_KERNEL_VFS_CLONE_FILE_RANGE
202	ZFS_AC_KERNEL_VFS_DEDUPE_FILE_RANGE
203	ZFS_AC_KERNEL_KMAP_ATOMIC_ARGS
204	ZFS_AC_KERNEL_KMAP_LOCAL_PAGE
205	ZFS_AC_KERNEL_FOLLOW_DOWN_ONE
206	ZFS_AC_KERNEL_MAKE_REQUEST_FN
207	ZFS_AC_KERNEL_GENERIC_IO_ACCT
208	ZFS_AC_KERNEL_FPU
209	ZFS_AC_KERNEL_FMODE_T
210	ZFS_AC_KERNEL_KUIDGID_T
211	ZFS_AC_KERNEL_KUID_HELPERS
212	ZFS_AC_KERNEL_RENAME
213	ZFS_AC_KERNEL_TOTALRAM_PAGES_FUNC
214	ZFS_AC_KERNEL_TOTALHIGH_PAGES
215	ZFS_AC_KERNEL_PERCPU
216	ZFS_AC_KERNEL_GENERIC_FILLATTR
217	ZFS_AC_KERNEL_MKNOD
218	ZFS_AC_KERNEL_SYMLINK
219	ZFS_AC_KERNEL_BIO_MAX_SEGS
220	ZFS_AC_KERNEL_SIGINFO
221	ZFS_AC_KERNEL_SYSFS
222	ZFS_AC_KERNEL_STANDALONE_LINUX_STDARG
223	ZFS_AC_KERNEL_STRLCPY
224	ZFS_AC_KERNEL_PAGEMAP_FOLIO_WAIT_BIT
225	ZFS_AC_KERNEL_ADD_DISK
226	ZFS_AC_KERNEL_KTHREAD
227	ZFS_AC_KERNEL_ZERO_PAGE
228	ZFS_AC_KERNEL___COPY_FROM_USER_INATOMIC
229	ZFS_AC_KERNEL_IDMAP_MNT_API
230	ZFS_AC_KERNEL_IDMAP_NO_USERNS
231	ZFS_AC_KERNEL_IATTR_VFSID
232	ZFS_AC_KERNEL_WRITEPAGE_T
233	ZFS_AC_KERNEL_RECLAIMED
234	ZFS_AC_KERNEL_REGISTER_SYSCTL_TABLE
235	ZFS_AC_KERNEL_REGISTER_SYSCTL_SZ
236	ZFS_AC_KERNEL_PROC_HANDLER_CTL_TABLE_CONST
237	ZFS_AC_KERNEL_COPY_SPLICE_READ
238	ZFS_AC_KERNEL_SYNC_BDEV
239	ZFS_AC_KERNEL_MM_PAGE_FLAGS
240	ZFS_AC_KERNEL_MM_PAGE_SIZE
241	ZFS_AC_KERNEL_MM_PAGE_MAPPING
242	ZFS_AC_KERNEL_1ARG_ASSIGN_STR
243	ZFS_AC_KERNEL_FILE
244	ZFS_AC_KERNEL_PIN_USER_PAGES
245	case "$host_cpu" in
246		powerpc*)
247			ZFS_AC_KERNEL_CPU_HAS_FEATURE
248			ZFS_AC_KERNEL_FLUSH_DCACHE_PAGE
249			;;
250		riscv*)
251			ZFS_AC_KERNEL_FLUSH_DCACHE_PAGE
252			;;
253	esac
254])
255
256dnl #
257dnl # Detect name used for Module.symvers file in kernel
258dnl #
259AC_DEFUN([ZFS_AC_MODULE_SYMVERS], [
260	modpost=$LINUX/scripts/Makefile.modpost
261	AC_MSG_CHECKING([kernel file name for module symbols])
262	AS_IF([test "x$enable_linux_builtin" != xyes -a -f "$modpost"], [
263		AS_IF([grep -q Modules.symvers $modpost], [
264			LINUX_SYMBOLS=Modules.symvers
265		], [
266			LINUX_SYMBOLS=Module.symvers
267		])
268
269		AS_IF([test ! -f "$LINUX_OBJ/$LINUX_SYMBOLS"], [
270			AC_MSG_ERROR([
271	*** Please make sure the kernel devel package for your distribution
272	*** is installed.  If you are building with a custom kernel, make sure
273	*** the kernel is configured, built, and the '--with-linux=PATH'
274	*** configure option refers to the location of the kernel source.
275			])
276		])
277	], [
278		LINUX_SYMBOLS=NONE
279	])
280	AC_MSG_RESULT($LINUX_SYMBOLS)
281	AC_SUBST(LINUX_SYMBOLS)
282])
283
284dnl #
285dnl # Detect the kernel to be built against
286dnl #
287dnl # Most modern Linux distributions have separate locations for bare
288dnl # source (source) and prebuilt (build) files. Additionally, there are
289dnl # `source` and `build` symlinks in `/lib/modules/$(KERNEL_VERSION)`
290dnl # pointing to them. The directory search order is now:
291dnl #
292dnl # - `configure` command line values if both `--with-linux` and
293dnl #   `--with-linux-obj` were defined
294dnl #
295dnl # - If only `--with-linux` was defined, `--with-linux-obj` is assumed
296dnl #   to have the same value as `--with-linux`
297dnl #
298dnl # - If neither `--with-linux` nor `--with-linux-obj` were defined
299dnl #   autodetection is used:
300dnl #
301dnl #   - `/lib/modules/$(uname -r)/{source,build}` respectively, if exist.
302dnl #
303dnl #   - If only `/lib/modules/$(uname -r)/build` exists, it is assumed
304dnl #     to be both source and build directory.
305dnl #
306dnl #   - The first directory in `/lib/modules` with the highest version
307dnl #     number according to `sort -V` which contains both `source` and
308dnl #     `build` symlinks/directories. If module directory contains only
309dnl #     `build` component, it is assumed to be both source and build
310dnl #     directory.
311dnl #
312dnl #   - Last resort: the first directory matching `/usr/src/kernels/*`
313dnl #     and `/usr/src/linux-*` with the highest version number according
314dnl #     to `sort -V` is assumed to be both source and build directory.
315dnl #
316AC_DEFUN([ZFS_AC_KERNEL], [
317	AC_ARG_WITH([linux],
318		AS_HELP_STRING([--with-linux=PATH],
319		[Path to kernel source]),
320		[kernelsrc="$withval"])
321
322	AC_ARG_WITH(linux-obj,
323		AS_HELP_STRING([--with-linux-obj=PATH],
324		[Path to kernel build objects]),
325		[kernelbuild="$withval"])
326
327	AC_MSG_CHECKING([kernel source and build directories])
328	AS_IF([test -n "$kernelsrc" && test -z "$kernelbuild"], [
329		kernelbuild="$kernelsrc"
330	], [test -z "$kernelsrc"], [
331		AS_IF([test -e "/lib/modules/$(uname -r)/source" && \
332		       test -e "/lib/modules/$(uname -r)/build"], [
333			src="/lib/modules/$(uname -r)/source"
334			build="/lib/modules/$(uname -r)/build"
335		], [test -e "/lib/modules/$(uname -r)/build"], [
336			build="/lib/modules/$(uname -r)/build"
337			src="$build"
338		], [
339			src=
340
341			for d in $(ls -1d /lib/modules/* 2>/dev/null | sort -Vr); do
342				if test -e "$d/source" && test -e "$d/build"; then
343					src="$d/source"
344					build="$d/build"
345					break
346				fi
347
348				if test -e "$d/build"; then
349					src="$d/build"
350					build="$d/build"
351					break
352				fi
353			done
354
355			# the least reliable method
356			if test -z "$src"; then
357				src=$(ls -1d /usr/src/kernels/* /usr/src/linux-* \
358				      2>/dev/null | grep -v obj | sort -Vr | head -1)
359				build="$src"
360			fi
361		])
362
363		AS_IF([test -n "$src" && test -e "$src"], [
364			kernelsrc=$(readlink -e "$src")
365		], [
366			kernelsrc="[Not found]"
367		])
368		AS_IF([test -n "$build" && test -e "$build"], [
369			kernelbuild=$(readlink -e "$build")
370		], [
371			kernelbuild="[Not found]"
372		])
373	], [
374		AS_IF([test "$kernelsrc" = "NONE"], [
375			kernsrcver=NONE
376		])
377		withlinux=yes
378	])
379
380	AC_MSG_RESULT([done])
381	AC_MSG_CHECKING([kernel source directory])
382	AC_MSG_RESULT([$kernelsrc])
383	AC_MSG_CHECKING([kernel build directory])
384	AC_MSG_RESULT([$kernelbuild])
385	AS_IF([test ! -d "$kernelsrc" || test ! -d "$kernelbuild"], [
386		AC_MSG_ERROR([
387	*** Please make sure the kernel devel package for your distribution
388	*** is installed and then try again.  If that fails, you can specify the
389	*** location of the kernel source and build with the '--with-linux=PATH' and
390	*** '--with-linux-obj=PATH' options respectively.])
391	])
392
393	AC_MSG_CHECKING([kernel source version])
394	utsrelease1=$kernelbuild/include/linux/version.h
395	utsrelease2=$kernelbuild/include/linux/utsrelease.h
396	utsrelease3=$kernelbuild/include/generated/utsrelease.h
397	AS_IF([test -r $utsrelease1 && grep -qF UTS_RELEASE $utsrelease1], [
398		utsrelease=$utsrelease1
399	], [test -r $utsrelease2 && grep -qF UTS_RELEASE $utsrelease2], [
400		utsrelease=$utsrelease2
401	], [test -r $utsrelease3 && grep -qF UTS_RELEASE $utsrelease3], [
402		utsrelease=$utsrelease3
403	])
404
405	AS_IF([test -n "$utsrelease"], [
406		kernsrcver=$($AWK '/UTS_RELEASE/ { gsub(/"/, "", $[3]); print $[3] }' $utsrelease)
407		AS_IF([test -z "$kernsrcver"], [
408			AC_MSG_RESULT([Not found])
409			AC_MSG_ERROR([
410	*** Cannot determine kernel version.
411			])
412		])
413	], [
414		AC_MSG_RESULT([Not found])
415		if test "x$enable_linux_builtin" != xyes; then
416			AC_MSG_ERROR([
417	*** Cannot find UTS_RELEASE definition.
418			])
419		else
420			AC_MSG_ERROR([
421	*** Cannot find UTS_RELEASE definition.
422	*** Please run 'make prepare' inside the kernel source tree.])
423		fi
424	])
425
426	AC_MSG_RESULT([$kernsrcver])
427
428	AX_COMPARE_VERSION([$kernsrcver], [ge], [$ZFS_META_KVER_MIN], [], [
429		AC_MSG_ERROR([
430	*** Cannot build against kernel version $kernsrcver.
431	*** The minimum supported kernel version is $ZFS_META_KVER_MIN.
432		])
433	])
434
435	AC_ARG_ENABLE([linux-experimental],
436		AS_HELP_STRING([--enable-linux-experimental],
437		[Allow building against some unsupported kernel versions]))
438
439	AX_COMPARE_VERSION([$kernsrcver], [ge], [$ZFS_META_KVER_MAX], [
440		AX_COMPARE_VERSION([$kernsrcver], [eq2], [$ZFS_META_KVER_MAX], [
441			kern_max_version_ok=yes
442		], [
443			kern_max_version_ok=no
444		])
445	], [
446		kern_max_version_ok=yes
447	])
448
449	AS_IF([test "x$kern_max_version_ok" != "xyes"], [
450		AS_IF([test "x$enable_linux_experimental" == "xyes"], [
451			AC_DEFINE(HAVE_LINUX_EXPERIMENTAL, 1,
452			    [building against unsupported kernel version])
453		], [
454			AC_MSG_ERROR([
455	*** Cannot build against kernel version $kernsrcver.
456	*** The maximum supported kernel version is $ZFS_META_KVER_MAX.
457			])
458		])
459	])
460
461	LINUX=${kernelsrc}
462	LINUX_OBJ=${kernelbuild}
463	LINUX_VERSION=${kernsrcver}
464
465	AC_SUBST(LINUX)
466	AC_SUBST(LINUX_OBJ)
467	AC_SUBST(LINUX_VERSION)
468])
469
470AC_DEFUN([ZFS_AC_KERNEL_VERSION_WARNING], [
471	AS_IF([test "x$enable_linux_experimental" = "xyes" && \
472	    test "x$kern_max_version_ok" != "xyes"], [
473		AC_MSG_WARN([
474
475	You are building OpenZFS against Linux version $kernsrcver.
476
477	This combination is considered EXPERIMENTAL by the OpenZFS project.
478	Even if it appears to build and run correctly, there may be bugs that
479	can cause SERIOUS DATA LOSS.
480
481	YOU HAVE BEEN WARNED!
482
483	If you choose to continue, we'd appreciate if you could report your
484	results on the OpenZFS issue tracker at:
485
486	    https://github.com/openzfs/zfs/issues/new
487
488	Your feedback will help us prepare a new OpenZFS release that supports
489	this version of Linux.
490		])
491	])
492])
493
494dnl #
495dnl # Detect the QAT module to be built against, QAT provides hardware
496dnl # acceleration for data compression:
497dnl #
498dnl # https://01.org/intel-quickassist-technology
499dnl #
500dnl # 1) Download and install QAT driver from the above link
501dnl # 2) Start QAT driver in your system:
502dnl # 	 service qat_service start
503dnl # 3) Enable QAT in ZFS, e.g.:
504dnl # 	 ./configure --with-qat=<qat-driver-path>/QAT1.6
505dnl # 	 make
506dnl # 4) Set GZIP compression in ZFS dataset:
507dnl # 	 zfs set compression = gzip <dataset>
508dnl #
509dnl # Then the data written to this ZFS pool is compressed by QAT accelerator
510dnl # automatically, and de-compressed by QAT when read from the pool.
511dnl #
512dnl # 1) Get QAT hardware statistics with:
513dnl #	 cat /proc/icp_dh895xcc_dev/qat
514dnl # 2) To disable QAT:
515dnl # 	 insmod zfs.ko zfs_qat_disable=1
516dnl #
517AC_DEFUN([ZFS_AC_QAT], [
518	AC_ARG_WITH([qat],
519		AS_HELP_STRING([--with-qat=PATH],
520		[Path to qat source]),
521		AS_IF([test "$withval" = "yes"],
522			AC_MSG_ERROR([--with-qat=PATH requires a PATH]),
523			[qatsrc="$withval"]))
524
525	AC_ARG_WITH([qat-obj],
526		AS_HELP_STRING([--with-qat-obj=PATH],
527		[Path to qat build objects]),
528		[qatbuild="$withval"])
529
530	AS_IF([test ! -z "${qatsrc}"], [
531		AC_MSG_CHECKING([qat source directory])
532		AC_MSG_RESULT([$qatsrc])
533		QAT_SRC="${qatsrc}/quickassist"
534		AS_IF([ test ! -e "$QAT_SRC/include/cpa.h"], [
535			AC_MSG_ERROR([
536	*** Please make sure the qat driver package is installed
537	*** and specify the location of the qat source with the
538	*** '--with-qat=PATH' option then try again. Failed to
539	*** find cpa.h in:
540	${QAT_SRC}/include])
541		])
542	])
543
544	AS_IF([test ! -z "${qatsrc}"], [
545		AC_MSG_CHECKING([qat build directory])
546		AS_IF([test -z "$qatbuild"], [
547			qatbuild="${qatsrc}/build"
548		])
549
550		AC_MSG_RESULT([$qatbuild])
551		QAT_OBJ=${qatbuild}
552		AS_IF([ ! test -e "$QAT_OBJ/icp_qa_al.ko" && ! test -e "$QAT_OBJ/qat_api.ko"], [
553			AC_MSG_ERROR([
554	*** Please make sure the qat driver is installed then try again.
555	*** Failed to find icp_qa_al.ko or qat_api.ko in:
556	$QAT_OBJ])
557		])
558
559		AC_SUBST(QAT_SRC)
560		AC_SUBST(QAT_OBJ)
561
562		AC_DEFINE(HAVE_QAT, 1,
563		[qat is enabled and existed])
564	])
565
566	dnl #
567	dnl # Detect the name used for the QAT Module.symvers file.
568	dnl #
569	AS_IF([test ! -z "${qatsrc}"], [
570		AC_MSG_CHECKING([qat file for module symbols])
571		QAT_SYMBOLS=$QAT_SRC/lookaside/access_layer/src/Module.symvers
572
573		AS_IF([test -r $QAT_SYMBOLS], [
574			AC_MSG_RESULT([$QAT_SYMBOLS])
575			AC_SUBST(QAT_SYMBOLS)
576		],[
577			AC_MSG_ERROR([
578	*** Please make sure the qat driver is installed then try again.
579	*** Failed to find Module.symvers in:
580	$QAT_SYMBOLS
581			])
582		])
583	])
584])
585
586dnl #
587dnl # ZFS_LINUX_CONFTEST_H
588dnl #
589AC_DEFUN([ZFS_LINUX_CONFTEST_H], [
590test -d build/$2 || mkdir -p build/$2
591cat - <<_ACEOF >build/$2/$2.h
592$1
593_ACEOF
594])
595
596dnl #
597dnl # ZFS_LINUX_CONFTEST_C
598dnl #
599AC_DEFUN([ZFS_LINUX_CONFTEST_C], [
600test -d build/$2 || mkdir -p build/$2
601cat confdefs.h - <<_ACEOF >build/$2/$2.c
602$1
603_ACEOF
604])
605
606dnl #
607dnl # ZFS_LINUX_CONFTEST_MAKEFILE
608dnl #
609dnl # $1 - test case name
610dnl # $2 - add to top-level Makefile
611dnl # $3 - additional build flags
612dnl #
613AC_DEFUN([ZFS_LINUX_CONFTEST_MAKEFILE], [
614	test -d build || mkdir -p build
615	test -d build/$1 || mkdir -p build/$1
616
617	file=build/$1/Makefile
618
619	dnl # Example command line to manually build source.
620	cat - <<_ACEOF >$file
621# Example command line to manually build source
622# make modules -C $LINUX_OBJ $ARCH_UM M=$PWD/build/$1
623
624ccflags-y := -Werror $FRAME_LARGER_THAN
625_ACEOF
626
627	dnl # Additional custom CFLAGS as requested.
628	m4_ifval($3, [echo "ccflags-y += $3" >>$file], [])
629
630	dnl # Test case source
631	echo "obj-m := $1.o" >>$file
632
633	AS_IF([test "x$2" = "xyes"], [echo "obj-m += $1/" >>build/Makefile], [])
634])
635
636dnl #
637dnl # ZFS_LINUX_TEST_PROGRAM(C)([PROLOGUE], [BODY])
638dnl #
639m4_define([ZFS_LINUX_TEST_PROGRAM], [
640#include <linux/module.h>
641$1
642
643int
644main (void)
645{
646$2
647	;
648	return 0;
649}
650
651MODULE_DESCRIPTION("conftest");
652MODULE_AUTHOR(ZFS_META_AUTHOR);
653MODULE_VERSION(ZFS_META_VERSION "-" ZFS_META_RELEASE);
654MODULE_LICENSE($3);
655])
656
657dnl #
658dnl # ZFS_LINUX_TEST_REMOVE
659dnl #
660dnl # Removes the specified test source and results.
661dnl #
662AC_DEFUN([ZFS_LINUX_TEST_REMOVE], [
663	test -d build/$1 && rm -Rf build/$1
664	test -f build/Makefile && sed '/$1/d' build/Makefile
665])
666
667dnl #
668dnl # ZFS_LINUX_COMPILE
669dnl #
670dnl # $1 - build dir
671dnl # $2 - test command
672dnl # $3 - pass command
673dnl # $4 - fail command
674dnl # $5 - set KBUILD_MODPOST_NOFINAL='yes'
675dnl # $6 - set KBUILD_MODPOST_WARN='yes'
676dnl #
677dnl # Used internally by ZFS_LINUX_TEST_{COMPILE,MODPOST}
678dnl #
679AC_DEFUN([ZFS_LINUX_COMPILE], [
680	AC_ARG_VAR([KERNEL_CC], [C compiler for
681		building kernel modules])
682	AC_ARG_VAR([KERNEL_LD], [Linker for
683		building kernel modules])
684	AC_ARG_VAR([KERNEL_LLVM], [Binary option to
685		build kernel modules with LLVM/CLANG toolchain])
686	AC_ARG_VAR([KERNEL_CROSS_COMPILE], [Cross compile prefix
687		for kernel module builds])
688	AC_ARG_VAR([KERNEL_ARCH], [Architecture to build kernel modules for])
689	AC_TRY_COMMAND([
690	    KBUILD_MODPOST_NOFINAL="$5" KBUILD_MODPOST_WARN="$6"
691	    make modules -k -j$TEST_JOBS ${KERNEL_CC:+CC=$KERNEL_CC}
692	    ${KERNEL_LD:+LD=$KERNEL_LD} ${KERNEL_LLVM:+LLVM=$KERNEL_LLVM}
693	    CONFIG_MODULES=y CFLAGS_MODULE=-DCONFIG_MODULES
694	    ${KERNEL_CROSS_COMPILE:+CROSS_COMPILE=$KERNEL_CROSS_COMPILE}
695	    ${KERNEL_ARCH:+ARCH=$KERNEL_ARCH}
696	    -C $LINUX_OBJ $ARCH_UM M=$PWD/$1 >$1/build.log 2>&1])
697	AS_IF([AC_TRY_COMMAND([$2])], [$3], [$4])
698])
699
700dnl #
701dnl # ZFS_LINUX_TEST_COMPILE
702dnl #
703dnl # Perform a full compile excluding the final modpost phase.
704dnl #
705AC_DEFUN([ZFS_LINUX_TEST_COMPILE], [
706	ZFS_LINUX_COMPILE([$2], [test -f $2/build.log], [
707		mv $2/Makefile $2/Makefile.compile.$1
708		mv $2/build.log $2/build.log.$1
709	],[
710	        AC_MSG_ERROR([
711        *** Unable to compile test source to determine kernel interfaces.])
712	], [yes], [])
713])
714
715dnl #
716dnl # ZFS_LINUX_TEST_MODPOST
717dnl #
718dnl # Perform a full compile including the modpost phase.  This may
719dnl # be an incremental build if the objects have already been built.
720dnl #
721AC_DEFUN([ZFS_LINUX_TEST_MODPOST], [
722	ZFS_LINUX_COMPILE([$2], [test -f $2/build.log], [
723		mv $2/Makefile $2/Makefile.modpost.$1
724		cat $2/build.log >>build/build.log.$1
725	],[
726	        AC_MSG_ERROR([
727        *** Unable to modpost test source to determine kernel interfaces.])
728	], [], [yes])
729])
730
731dnl #
732dnl # Perform the compilation of the test cases in two phases.
733dnl #
734dnl # Phase 1) attempt to build the object files for all of the tests
735dnl #          defined by the ZFS_LINUX_TEST_SRC macro.  But do not
736dnl #          perform the final modpost stage.
737dnl #
738dnl # Phase 2) disable all tests which failed the initial compilation,
739dnl #          then invoke the final modpost step for the remaining tests.
740dnl #
741dnl # This allows us efficiently build the test cases in parallel while
742dnl # remaining resilient to build failures which are expected when
743dnl # detecting the available kernel interfaces.
744dnl #
745dnl # The maximum allowed parallelism can be controlled by setting the
746dnl # TEST_JOBS environment variable.  Otherwise, it default to $(nproc).
747dnl #
748AC_DEFUN([ZFS_LINUX_TEST_COMPILE_ALL], [
749	dnl # Phase 1 - Compilation only, final linking is skipped.
750	ZFS_LINUX_TEST_COMPILE([$1], [build])
751
752	dnl #
753	dnl # Phase 2 - When building external modules disable test cases
754	dnl # which failed to compile and invoke modpost to verify the
755	dnl # final linking.
756	dnl #
757	dnl # Test names suffixed with '_license' call modpost independently
758	dnl # to ensure that a single incompatibility does not result in the
759	dnl # modpost phase exiting early.  This check is not performed on
760	dnl # every symbol since the majority are compatible and doing so
761	dnl # would significantly slow down this phase.
762	dnl #
763	dnl # When configuring for builtin (--enable-linux-builtin)
764	dnl # fake the linking step artificially create the expected .ko
765	dnl # files for tests which did compile.  This is required for
766	dnl # kernels which do not have loadable module support or have
767	dnl # not yet been built.
768	dnl #
769	AS_IF([test "x$enable_linux_builtin" = "xno"], [
770		for dir in $(awk '/^obj-m/ { print [$]3 }' \
771		    build/Makefile.compile.$1); do
772			name=${dir%/}
773			AS_IF([test -f build/$name/$name.o], [
774				AS_IF([test "${name##*_}" = "license"], [
775					ZFS_LINUX_TEST_MODPOST([$1],
776					    [build/$name])
777					echo "obj-n += $dir" >>build/Makefile
778				], [
779					echo "obj-m += $dir" >>build/Makefile
780				])
781			], [
782				echo "obj-n += $dir" >>build/Makefile
783			])
784		done
785
786		ZFS_LINUX_TEST_MODPOST([$1], [build])
787	], [
788		for dir in $(awk '/^obj-m/ { print [$]3 }' \
789		    build/Makefile.compile.$1); do
790			name=${dir%/}
791			AS_IF([test -f build/$name/$name.o], [
792				touch build/$name/$name.ko
793			])
794		done
795	])
796])
797
798dnl #
799dnl # ZFS_LINUX_TEST_SRC
800dnl #
801dnl # $1 - name
802dnl # $2 - global
803dnl # $3 - source
804dnl # $4 - extra cflags
805dnl # $5 - check license-compatibility
806dnl #
807dnl # Check if the test source is buildable at all and then if it is
808dnl # license compatible.
809dnl #
810dnl # N.B because all of the test cases are compiled in parallel they
811dnl # must never depend on the results of previous tests.  Each test
812dnl # needs to be entirely independent.
813dnl #
814AC_DEFUN([ZFS_LINUX_TEST_SRC], [
815	ZFS_LINUX_CONFTEST_C([ZFS_LINUX_TEST_PROGRAM([[$2]], [[$3]],
816	    [["Dual BSD/GPL"]])], [$1])
817	ZFS_LINUX_CONFTEST_MAKEFILE([$1], [yes], [$4])
818
819	AS_IF([ test -n "$5" ], [
820		ZFS_LINUX_CONFTEST_C([ZFS_LINUX_TEST_PROGRAM(
821		    [[$2]], [[$3]], [[$5]])], [$1_license])
822		ZFS_LINUX_CONFTEST_MAKEFILE([$1_license], [yes], [$4])
823	])
824])
825
826dnl #
827dnl # ZFS_LINUX_TEST_RESULT
828dnl #
829dnl # $1 - name of a test source (ZFS_LINUX_TEST_SRC)
830dnl # $2 - run on success (valid .ko generated)
831dnl # $3 - run on failure (unable to compile)
832dnl #
833AC_DEFUN([ZFS_LINUX_TEST_RESULT], [
834	AS_IF([test -d build/$1], [
835		AS_IF([test -f build/$1/$1.ko], [$2], [$3])
836	], [
837		AC_MSG_ERROR([
838	*** No matching source for the "$1" test, check that
839	*** both the test source and result macros refer to the same name.
840		])
841	])
842])
843
844dnl #
845dnl # ZFS_LINUX_TEST_ERROR
846dnl #
847dnl # Generic error message which can be used when none of the expected
848dnl # kernel interfaces were detected.
849dnl #
850AC_DEFUN([ZFS_LINUX_TEST_ERROR], [
851	AC_MSG_ERROR([
852	*** None of the expected "$1" interfaces were detected.
853	*** This may be because your kernel version is newer than what is
854	*** supported, or you are using a patched custom kernel with
855	*** incompatible modifications.
856	***
857	*** ZFS Version: $ZFS_META_ALIAS
858	*** Compatible Kernels: $ZFS_META_KVER_MIN - $ZFS_META_KVER_MAX
859	])
860])
861
862dnl #
863dnl # ZFS_LINUX_TEST_RESULT_SYMBOL
864dnl #
865dnl # Like ZFS_LINUX_TEST_RESULT except ZFS_CHECK_SYMBOL_EXPORT is called to
866dnl # verify symbol exports, unless --enable-linux-builtin was provided to
867dnl # configure.
868dnl #
869AC_DEFUN([ZFS_LINUX_TEST_RESULT_SYMBOL], [
870	AS_IF([ ! test -f build/$1/$1.ko], [
871		$5
872	], [
873		AS_IF([test "x$enable_linux_builtin" != "xyes"], [
874			ZFS_CHECK_SYMBOL_EXPORT([$2], [$3], [$4], [$5])
875		], [
876			$4
877		])
878	])
879])
880
881dnl #
882dnl # ZFS_LINUX_COMPILE_IFELSE
883dnl #
884AC_DEFUN([ZFS_LINUX_COMPILE_IFELSE], [
885	ZFS_LINUX_TEST_REMOVE([conftest])
886
887	m4_ifvaln([$1], [ZFS_LINUX_CONFTEST_C([$1], [conftest])])
888	m4_ifvaln([$5], [ZFS_LINUX_CONFTEST_H([$5], [conftest])],
889	    [ZFS_LINUX_CONFTEST_H([], [conftest])])
890
891	ZFS_LINUX_CONFTEST_MAKEFILE([conftest], [no],
892	    [m4_ifvaln([$5], [-I$PWD/build/conftest], [])])
893	ZFS_LINUX_COMPILE([build/conftest], [$2], [$3], [$4], [], [])
894])
895
896dnl #
897dnl # ZFS_LINUX_TRY_COMPILE
898dnl #
899dnl # $1 - global
900dnl # $2 - source
901dnl # $3 - run on success (valid .ko generated)
902dnl # $4 - run on failure (unable to compile)
903dnl #
904dnl # When configuring as builtin (--enable-linux-builtin) for kernels
905dnl # without loadable module support (CONFIG_MODULES=n) only the object
906dnl # file is created.  See ZFS_LINUX_TEST_COMPILE_ALL for details.
907dnl #
908AC_DEFUN([ZFS_LINUX_TRY_COMPILE], [
909	AS_IF([test "x$enable_linux_builtin" = "xyes"], [
910		ZFS_LINUX_COMPILE_IFELSE(
911		    [ZFS_LINUX_TEST_PROGRAM([[$1]], [[$2]],
912		    [[ZFS_META_LICENSE]])],
913		    [test -f build/conftest/conftest.o], [$3], [$4])
914	], [
915		ZFS_LINUX_COMPILE_IFELSE(
916		    [ZFS_LINUX_TEST_PROGRAM([[$1]], [[$2]],
917		    [[ZFS_META_LICENSE]])],
918		    [test -f build/conftest/conftest.ko], [$3], [$4])
919	])
920])
921
922dnl #
923dnl # ZFS_CHECK_SYMBOL_EXPORT
924dnl #
925dnl # Check if a symbol is exported on not by consulting the symbols
926dnl # file, or optionally the source code.
927dnl #
928AC_DEFUN([ZFS_CHECK_SYMBOL_EXPORT], [
929	grep -q -E '[[[:space:]]]$1[[[:space:]]]' \
930		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
931	rc=$?
932	if test $rc -ne 0; then
933		export=0
934		for file in $2; do
935			grep -q -E "EXPORT_SYMBOL.*($1)" \
936				"$LINUX/$file" 2>/dev/null
937			rc=$?
938			if test $rc -eq 0; then
939				export=1
940				break;
941			fi
942		done
943		if test $export -eq 0; then :
944			$4
945		else :
946			$3
947		fi
948	else :
949		$3
950	fi
951])
952
953dnl #
954dnl # ZFS_LINUX_TRY_COMPILE_SYMBOL
955dnl #
956dnl # Like ZFS_LINUX_TRY_COMPILER except ZFS_CHECK_SYMBOL_EXPORT is called
957dnl # to verify symbol exports, unless --enable-linux-builtin was provided
958dnl # to configure.
959dnl #
960AC_DEFUN([ZFS_LINUX_TRY_COMPILE_SYMBOL], [
961	ZFS_LINUX_TRY_COMPILE([$1], [$2], [rc=0], [rc=1])
962	if test $rc -ne 0; then :
963		$6
964	else
965		if test "x$enable_linux_builtin" != xyes; then
966			ZFS_CHECK_SYMBOL_EXPORT([$3], [$4], [rc=0], [rc=1])
967		fi
968		if test $rc -ne 0; then :
969			$6
970		else :
971			$5
972		fi
973	fi
974])
975
976dnl #
977dnl # ZFS_LINUX_TRY_COMPILE_HEADER
978dnl # like ZFS_LINUX_TRY_COMPILE, except the contents conftest.h are
979dnl # provided via the fifth parameter
980dnl #
981AC_DEFUN([ZFS_LINUX_TRY_COMPILE_HEADER], [
982	AS_IF([test "x$enable_linux_builtin" = "xyes"], [
983		ZFS_LINUX_COMPILE_IFELSE(
984		    [ZFS_LINUX_TEST_PROGRAM([[$1]], [[$2]],
985		    [[ZFS_META_LICENSE]])],
986		    [test -f build/conftest/conftest.o], [$3], [$4], [$5])
987	], [
988		ZFS_LINUX_COMPILE_IFELSE(
989		    [ZFS_LINUX_TEST_PROGRAM([[$1]], [[$2]],
990		    [[ZFS_META_LICENSE]])],
991		    [test -f build/conftest/conftest.ko], [$3], [$4], [$5])
992	])
993])
994
995dnl #
996dnl # AS_VERSION_COMPARE_LE
997dnl # like AS_VERSION_COMPARE_LE, but runs $3 if (and only if) $1 <= $2
998dnl # AS_VERSION_COMPARE_LE (version-1, version-2, [action-if-less-or-equal], [action-if-greater])
999dnl #
1000AC_DEFUN([AS_VERSION_COMPARE_LE], [
1001	AS_VERSION_COMPARE([$1], [$2], [$3], [$3], [$4])
1002])
1003
1004dnl #
1005dnl # ZFS_LINUX_REQUIRE_API
1006dnl # like ZFS_LINUX_TEST_ERROR, except only fails if the kernel is
1007dnl # at least some specified version.
1008dnl #
1009AC_DEFUN([ZFS_LINUX_REQUIRE_API], [
1010	AS_VERSION_COMPARE_LE([$2], [$kernsrcver], [
1011		AC_MSG_ERROR([
1012		*** None of the expected "$1" interfaces were detected. This
1013		*** interface is expected for kernels version "$2" and above.
1014		*** This may be because your kernel version is newer than what is
1015		*** supported, or you are using a patched custom kernel with
1016		*** incompatible modifications.  Newer kernels may have incompatible
1017		*** APIs.
1018		***
1019		*** ZFS Version: $ZFS_META_ALIAS
1020		*** Compatible Kernels: $ZFS_META_KVER_MIN - $ZFS_META_KVER_MAX
1021		])
1022	], [
1023		AC_MSG_RESULT(no)
1024	])
1025])
1026