xref: /freebsd/sys/contrib/openzfs/config/kernel.m4 (revision ac77b2621508c6a50ab01d07fe8d43795d908f05)
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_SET_NLINK
77	ZFS_AC_KERNEL_SRC_SGET
78	ZFS_AC_KERNEL_SRC_VFS_FILEMAP_DIRTY_FOLIO
79	ZFS_AC_KERNEL_SRC_VFS_READ_FOLIO
80	ZFS_AC_KERNEL_SRC_VFS_RELEASE_FOLIO
81	ZFS_AC_KERNEL_SRC_VFS_INVALIDATE_FOLIO
82	ZFS_AC_KERNEL_SRC_VFS_FSYNC_2ARGS
83	ZFS_AC_KERNEL_SRC_VFS_DIRECT_IO
84	ZFS_AC_KERNEL_SRC_VFS_READPAGES
85	ZFS_AC_KERNEL_SRC_VFS_SET_PAGE_DIRTY_NOBUFFERS
86	ZFS_AC_KERNEL_SRC_VFS_IOV_ITER
87	ZFS_AC_KERNEL_SRC_VFS_GENERIC_COPY_FILE_RANGE
88	ZFS_AC_KERNEL_SRC_VFS_SPLICE_COPY_FILE_RANGE
89	ZFS_AC_KERNEL_SRC_VFS_REMAP_FILE_RANGE
90	ZFS_AC_KERNEL_SRC_VFS_CLONE_FILE_RANGE
91	ZFS_AC_KERNEL_SRC_VFS_DEDUPE_FILE_RANGE
92	ZFS_AC_KERNEL_SRC_KMAP_ATOMIC_ARGS
93	ZFS_AC_KERNEL_SRC_KMAP_LOCAL_PAGE
94	ZFS_AC_KERNEL_SRC_FOLLOW_DOWN_ONE
95	ZFS_AC_KERNEL_SRC_MAKE_REQUEST_FN
96	ZFS_AC_KERNEL_SRC_GENERIC_IO_ACCT
97	ZFS_AC_KERNEL_SRC_FPU
98	ZFS_AC_KERNEL_SRC_FMODE_T
99	ZFS_AC_KERNEL_SRC_KUIDGID_T
100	ZFS_AC_KERNEL_SRC_KUID_HELPERS
101	ZFS_AC_KERNEL_SRC_RENAME
102	ZFS_AC_KERNEL_SRC_TOTALRAM_PAGES_FUNC
103	ZFS_AC_KERNEL_SRC_TOTALHIGH_PAGES
104	ZFS_AC_KERNEL_SRC_PERCPU
105	ZFS_AC_KERNEL_SRC_GENERIC_FILLATTR
106	ZFS_AC_KERNEL_SRC_MKNOD
107	ZFS_AC_KERNEL_SRC_SYMLINK
108	ZFS_AC_KERNEL_SRC_BIO_MAX_SEGS
109	ZFS_AC_KERNEL_SRC_SIGINFO
110	ZFS_AC_KERNEL_SRC_SYSFS
111	ZFS_AC_KERNEL_SRC_STANDALONE_LINUX_STDARG
112	ZFS_AC_KERNEL_SRC_STRLCPY
113	ZFS_AC_KERNEL_SRC_PAGEMAP_FOLIO_WAIT_BIT
114	ZFS_AC_KERNEL_SRC_ADD_DISK
115	ZFS_AC_KERNEL_SRC_KTHREAD
116	ZFS_AC_KERNEL_SRC_ZERO_PAGE
117	ZFS_AC_KERNEL_SRC___COPY_FROM_USER_INATOMIC
118	ZFS_AC_KERNEL_SRC_IDMAP_MNT_API
119	ZFS_AC_KERNEL_SRC_IDMAP_NO_USERNS
120	ZFS_AC_KERNEL_SRC_IATTR_VFSID
121	ZFS_AC_KERNEL_SRC_WRITEPAGE_T
122	ZFS_AC_KERNEL_SRC_RECLAIMED
123	ZFS_AC_KERNEL_SRC_REGISTER_SYSCTL_TABLE
124	ZFS_AC_KERNEL_SRC_REGISTER_SYSCTL_SZ
125	ZFS_AC_KERNEL_SRC_PROC_HANDLER_CTL_TABLE_CONST
126	ZFS_AC_KERNEL_SRC_COPY_SPLICE_READ
127	ZFS_AC_KERNEL_SRC_SYNC_BDEV
128	ZFS_AC_KERNEL_SRC_MM_PAGE_FLAGS
129	ZFS_AC_KERNEL_SRC_MM_PAGE_SIZE
130	ZFS_AC_KERNEL_SRC_MM_PAGE_MAPPING
131	ZFS_AC_KERNEL_SRC_FILE
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_SET_NLINK
189	ZFS_AC_KERNEL_SGET
190	ZFS_AC_KERNEL_VFS_FILEMAP_DIRTY_FOLIO
191	ZFS_AC_KERNEL_VFS_READ_FOLIO
192	ZFS_AC_KERNEL_VFS_RELEASE_FOLIO
193	ZFS_AC_KERNEL_VFS_INVALIDATE_FOLIO
194	ZFS_AC_KERNEL_VFS_FSYNC_2ARGS
195	ZFS_AC_KERNEL_VFS_DIRECT_IO
196	ZFS_AC_KERNEL_VFS_READPAGES
197	ZFS_AC_KERNEL_VFS_SET_PAGE_DIRTY_NOBUFFERS
198	ZFS_AC_KERNEL_VFS_IOV_ITER
199	ZFS_AC_KERNEL_VFS_GENERIC_COPY_FILE_RANGE
200	ZFS_AC_KERNEL_VFS_SPLICE_COPY_FILE_RANGE
201	ZFS_AC_KERNEL_VFS_REMAP_FILE_RANGE
202	ZFS_AC_KERNEL_VFS_CLONE_FILE_RANGE
203	ZFS_AC_KERNEL_VFS_DEDUPE_FILE_RANGE
204	ZFS_AC_KERNEL_KMAP_ATOMIC_ARGS
205	ZFS_AC_KERNEL_KMAP_LOCAL_PAGE
206	ZFS_AC_KERNEL_FOLLOW_DOWN_ONE
207	ZFS_AC_KERNEL_MAKE_REQUEST_FN
208	ZFS_AC_KERNEL_GENERIC_IO_ACCT
209	ZFS_AC_KERNEL_FPU
210	ZFS_AC_KERNEL_FMODE_T
211	ZFS_AC_KERNEL_KUIDGID_T
212	ZFS_AC_KERNEL_KUID_HELPERS
213	ZFS_AC_KERNEL_RENAME
214	ZFS_AC_KERNEL_TOTALRAM_PAGES_FUNC
215	ZFS_AC_KERNEL_TOTALHIGH_PAGES
216	ZFS_AC_KERNEL_PERCPU
217	ZFS_AC_KERNEL_GENERIC_FILLATTR
218	ZFS_AC_KERNEL_MKNOD
219	ZFS_AC_KERNEL_SYMLINK
220	ZFS_AC_KERNEL_BIO_MAX_SEGS
221	ZFS_AC_KERNEL_SIGINFO
222	ZFS_AC_KERNEL_SYSFS
223	ZFS_AC_KERNEL_STANDALONE_LINUX_STDARG
224	ZFS_AC_KERNEL_STRLCPY
225	ZFS_AC_KERNEL_PAGEMAP_FOLIO_WAIT_BIT
226	ZFS_AC_KERNEL_ADD_DISK
227	ZFS_AC_KERNEL_KTHREAD
228	ZFS_AC_KERNEL_ZERO_PAGE
229	ZFS_AC_KERNEL___COPY_FROM_USER_INATOMIC
230	ZFS_AC_KERNEL_IDMAP_MNT_API
231	ZFS_AC_KERNEL_IDMAP_NO_USERNS
232	ZFS_AC_KERNEL_IATTR_VFSID
233	ZFS_AC_KERNEL_WRITEPAGE_T
234	ZFS_AC_KERNEL_RECLAIMED
235	ZFS_AC_KERNEL_REGISTER_SYSCTL_TABLE
236	ZFS_AC_KERNEL_REGISTER_SYSCTL_SZ
237	ZFS_AC_KERNEL_PROC_HANDLER_CTL_TABLE_CONST
238	ZFS_AC_KERNEL_COPY_SPLICE_READ
239	ZFS_AC_KERNEL_SYNC_BDEV
240	ZFS_AC_KERNEL_MM_PAGE_FLAGS
241	ZFS_AC_KERNEL_MM_PAGE_SIZE
242	ZFS_AC_KERNEL_MM_PAGE_MAPPING
243	ZFS_AC_KERNEL_1ARG_ASSIGN_STR
244	ZFS_AC_KERNEL_FILE
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_TRY_COMMAND([
687	    KBUILD_MODPOST_NOFINAL="$5" KBUILD_MODPOST_WARN="$6"
688	    make modules -k -j$TEST_JOBS ${KERNEL_CC:+CC=$KERNEL_CC}
689	    ${KERNEL_LD:+LD=$KERNEL_LD} ${KERNEL_LLVM:+LLVM=$KERNEL_LLVM}
690	    CONFIG_MODULES=y CFLAGS_MODULE=-DCONFIG_MODULES
691	    -C $LINUX_OBJ $ARCH_UM M=$PWD/$1 >$1/build.log 2>&1])
692	AS_IF([AC_TRY_COMMAND([$2])], [$3], [$4])
693])
694
695dnl #
696dnl # ZFS_LINUX_TEST_COMPILE
697dnl #
698dnl # Perform a full compile excluding the final modpost phase.
699dnl #
700AC_DEFUN([ZFS_LINUX_TEST_COMPILE], [
701	ZFS_LINUX_COMPILE([$2], [test -f $2/build.log], [
702		mv $2/Makefile $2/Makefile.compile.$1
703		mv $2/build.log $2/build.log.$1
704	],[
705	        AC_MSG_ERROR([
706        *** Unable to compile test source to determine kernel interfaces.])
707	], [yes], [])
708])
709
710dnl #
711dnl # ZFS_LINUX_TEST_MODPOST
712dnl #
713dnl # Perform a full compile including the modpost phase.  This may
714dnl # be an incremental build if the objects have already been built.
715dnl #
716AC_DEFUN([ZFS_LINUX_TEST_MODPOST], [
717	ZFS_LINUX_COMPILE([$2], [test -f $2/build.log], [
718		mv $2/Makefile $2/Makefile.modpost.$1
719		cat $2/build.log >>build/build.log.$1
720	],[
721	        AC_MSG_ERROR([
722        *** Unable to modpost test source to determine kernel interfaces.])
723	], [], [yes])
724])
725
726dnl #
727dnl # Perform the compilation of the test cases in two phases.
728dnl #
729dnl # Phase 1) attempt to build the object files for all of the tests
730dnl #          defined by the ZFS_LINUX_TEST_SRC macro.  But do not
731dnl #          perform the final modpost stage.
732dnl #
733dnl # Phase 2) disable all tests which failed the initial compilation,
734dnl #          then invoke the final modpost step for the remaining tests.
735dnl #
736dnl # This allows us efficiently build the test cases in parallel while
737dnl # remaining resilient to build failures which are expected when
738dnl # detecting the available kernel interfaces.
739dnl #
740dnl # The maximum allowed parallelism can be controlled by setting the
741dnl # TEST_JOBS environment variable.  Otherwise, it default to $(nproc).
742dnl #
743AC_DEFUN([ZFS_LINUX_TEST_COMPILE_ALL], [
744	dnl # Phase 1 - Compilation only, final linking is skipped.
745	ZFS_LINUX_TEST_COMPILE([$1], [build])
746
747	dnl #
748	dnl # Phase 2 - When building external modules disable test cases
749	dnl # which failed to compile and invoke modpost to verify the
750	dnl # final linking.
751	dnl #
752	dnl # Test names suffixed with '_license' call modpost independently
753	dnl # to ensure that a single incompatibility does not result in the
754	dnl # modpost phase exiting early.  This check is not performed on
755	dnl # every symbol since the majority are compatible and doing so
756	dnl # would significantly slow down this phase.
757	dnl #
758	dnl # When configuring for builtin (--enable-linux-builtin)
759	dnl # fake the linking step artificially create the expected .ko
760	dnl # files for tests which did compile.  This is required for
761	dnl # kernels which do not have loadable module support or have
762	dnl # not yet been built.
763	dnl #
764	AS_IF([test "x$enable_linux_builtin" = "xno"], [
765		for dir in $(awk '/^obj-m/ { print [$]3 }' \
766		    build/Makefile.compile.$1); do
767			name=${dir%/}
768			AS_IF([test -f build/$name/$name.o], [
769				AS_IF([test "${name##*_}" = "license"], [
770					ZFS_LINUX_TEST_MODPOST([$1],
771					    [build/$name])
772					echo "obj-n += $dir" >>build/Makefile
773				], [
774					echo "obj-m += $dir" >>build/Makefile
775				])
776			], [
777				echo "obj-n += $dir" >>build/Makefile
778			])
779		done
780
781		ZFS_LINUX_TEST_MODPOST([$1], [build])
782	], [
783		for dir in $(awk '/^obj-m/ { print [$]3 }' \
784		    build/Makefile.compile.$1); do
785			name=${dir%/}
786			AS_IF([test -f build/$name/$name.o], [
787				touch build/$name/$name.ko
788			])
789		done
790	])
791])
792
793dnl #
794dnl # ZFS_LINUX_TEST_SRC
795dnl #
796dnl # $1 - name
797dnl # $2 - global
798dnl # $3 - source
799dnl # $4 - extra cflags
800dnl # $5 - check license-compatibility
801dnl #
802dnl # Check if the test source is buildable at all and then if it is
803dnl # license compatible.
804dnl #
805dnl # N.B because all of the test cases are compiled in parallel they
806dnl # must never depend on the results of previous tests.  Each test
807dnl # needs to be entirely independent.
808dnl #
809AC_DEFUN([ZFS_LINUX_TEST_SRC], [
810	ZFS_LINUX_CONFTEST_C([ZFS_LINUX_TEST_PROGRAM([[$2]], [[$3]],
811	    [["Dual BSD/GPL"]])], [$1])
812	ZFS_LINUX_CONFTEST_MAKEFILE([$1], [yes], [$4])
813
814	AS_IF([ test -n "$5" ], [
815		ZFS_LINUX_CONFTEST_C([ZFS_LINUX_TEST_PROGRAM(
816		    [[$2]], [[$3]], [[$5]])], [$1_license])
817		ZFS_LINUX_CONFTEST_MAKEFILE([$1_license], [yes], [$4])
818	])
819])
820
821dnl #
822dnl # ZFS_LINUX_TEST_RESULT
823dnl #
824dnl # $1 - name of a test source (ZFS_LINUX_TEST_SRC)
825dnl # $2 - run on success (valid .ko generated)
826dnl # $3 - run on failure (unable to compile)
827dnl #
828AC_DEFUN([ZFS_LINUX_TEST_RESULT], [
829	AS_IF([test -d build/$1], [
830		AS_IF([test -f build/$1/$1.ko], [$2], [$3])
831	], [
832		AC_MSG_ERROR([
833	*** No matching source for the "$1" test, check that
834	*** both the test source and result macros refer to the same name.
835		])
836	])
837])
838
839dnl #
840dnl # ZFS_LINUX_TEST_ERROR
841dnl #
842dnl # Generic error message which can be used when none of the expected
843dnl # kernel interfaces were detected.
844dnl #
845AC_DEFUN([ZFS_LINUX_TEST_ERROR], [
846	AC_MSG_ERROR([
847	*** None of the expected "$1" interfaces were detected.
848	*** This may be because your kernel version is newer than what is
849	*** supported, or you are using a patched custom kernel with
850	*** incompatible modifications.
851	***
852	*** ZFS Version: $ZFS_META_ALIAS
853	*** Compatible Kernels: $ZFS_META_KVER_MIN - $ZFS_META_KVER_MAX
854	])
855])
856
857dnl #
858dnl # ZFS_LINUX_TEST_RESULT_SYMBOL
859dnl #
860dnl # Like ZFS_LINUX_TEST_RESULT except ZFS_CHECK_SYMBOL_EXPORT is called to
861dnl # verify symbol exports, unless --enable-linux-builtin was provided to
862dnl # configure.
863dnl #
864AC_DEFUN([ZFS_LINUX_TEST_RESULT_SYMBOL], [
865	AS_IF([ ! test -f build/$1/$1.ko], [
866		$5
867	], [
868		AS_IF([test "x$enable_linux_builtin" != "xyes"], [
869			ZFS_CHECK_SYMBOL_EXPORT([$2], [$3], [$4], [$5])
870		], [
871			$4
872		])
873	])
874])
875
876dnl #
877dnl # ZFS_LINUX_COMPILE_IFELSE
878dnl #
879AC_DEFUN([ZFS_LINUX_COMPILE_IFELSE], [
880	ZFS_LINUX_TEST_REMOVE([conftest])
881
882	m4_ifvaln([$1], [ZFS_LINUX_CONFTEST_C([$1], [conftest])])
883	m4_ifvaln([$5], [ZFS_LINUX_CONFTEST_H([$5], [conftest])],
884	    [ZFS_LINUX_CONFTEST_H([], [conftest])])
885
886	ZFS_LINUX_CONFTEST_MAKEFILE([conftest], [no],
887	    [m4_ifvaln([$5], [-I$PWD/build/conftest], [])])
888	ZFS_LINUX_COMPILE([build/conftest], [$2], [$3], [$4], [], [])
889])
890
891dnl #
892dnl # ZFS_LINUX_TRY_COMPILE
893dnl #
894dnl # $1 - global
895dnl # $2 - source
896dnl # $3 - run on success (valid .ko generated)
897dnl # $4 - run on failure (unable to compile)
898dnl #
899dnl # When configuring as builtin (--enable-linux-builtin) for kernels
900dnl # without loadable module support (CONFIG_MODULES=n) only the object
901dnl # file is created.  See ZFS_LINUX_TEST_COMPILE_ALL for details.
902dnl #
903AC_DEFUN([ZFS_LINUX_TRY_COMPILE], [
904	AS_IF([test "x$enable_linux_builtin" = "xyes"], [
905		ZFS_LINUX_COMPILE_IFELSE(
906		    [ZFS_LINUX_TEST_PROGRAM([[$1]], [[$2]],
907		    [[ZFS_META_LICENSE]])],
908		    [test -f build/conftest/conftest.o], [$3], [$4])
909	], [
910		ZFS_LINUX_COMPILE_IFELSE(
911		    [ZFS_LINUX_TEST_PROGRAM([[$1]], [[$2]],
912		    [[ZFS_META_LICENSE]])],
913		    [test -f build/conftest/conftest.ko], [$3], [$4])
914	])
915])
916
917dnl #
918dnl # ZFS_CHECK_SYMBOL_EXPORT
919dnl #
920dnl # Check if a symbol is exported on not by consulting the symbols
921dnl # file, or optionally the source code.
922dnl #
923AC_DEFUN([ZFS_CHECK_SYMBOL_EXPORT], [
924	grep -q -E '[[[:space:]]]$1[[[:space:]]]' \
925		$LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null
926	rc=$?
927	if test $rc -ne 0; then
928		export=0
929		for file in $2; do
930			grep -q -E "EXPORT_SYMBOL.*($1)" \
931				"$LINUX/$file" 2>/dev/null
932			rc=$?
933			if test $rc -eq 0; then
934				export=1
935				break;
936			fi
937		done
938		if test $export -eq 0; then :
939			$4
940		else :
941			$3
942		fi
943	else :
944		$3
945	fi
946])
947
948dnl #
949dnl # ZFS_LINUX_TRY_COMPILE_SYMBOL
950dnl #
951dnl # Like ZFS_LINUX_TRY_COMPILER except ZFS_CHECK_SYMBOL_EXPORT is called
952dnl # to verify symbol exports, unless --enable-linux-builtin was provided
953dnl # to configure.
954dnl #
955AC_DEFUN([ZFS_LINUX_TRY_COMPILE_SYMBOL], [
956	ZFS_LINUX_TRY_COMPILE([$1], [$2], [rc=0], [rc=1])
957	if test $rc -ne 0; then :
958		$6
959	else
960		if test "x$enable_linux_builtin" != xyes; then
961			ZFS_CHECK_SYMBOL_EXPORT([$3], [$4], [rc=0], [rc=1])
962		fi
963		if test $rc -ne 0; then :
964			$6
965		else :
966			$5
967		fi
968	fi
969])
970
971dnl #
972dnl # ZFS_LINUX_TRY_COMPILE_HEADER
973dnl # like ZFS_LINUX_TRY_COMPILE, except the contents conftest.h are
974dnl # provided via the fifth parameter
975dnl #
976AC_DEFUN([ZFS_LINUX_TRY_COMPILE_HEADER], [
977	AS_IF([test "x$enable_linux_builtin" = "xyes"], [
978		ZFS_LINUX_COMPILE_IFELSE(
979		    [ZFS_LINUX_TEST_PROGRAM([[$1]], [[$2]],
980		    [[ZFS_META_LICENSE]])],
981		    [test -f build/conftest/conftest.o], [$3], [$4], [$5])
982	], [
983		ZFS_LINUX_COMPILE_IFELSE(
984		    [ZFS_LINUX_TEST_PROGRAM([[$1]], [[$2]],
985		    [[ZFS_META_LICENSE]])],
986		    [test -f build/conftest/conftest.ko], [$3], [$4], [$5])
987	])
988])
989
990dnl #
991dnl # AS_VERSION_COMPARE_LE
992dnl # like AS_VERSION_COMPARE_LE, but runs $3 if (and only if) $1 <= $2
993dnl # AS_VERSION_COMPARE_LE (version-1, version-2, [action-if-less-or-equal], [action-if-greater])
994dnl #
995AC_DEFUN([AS_VERSION_COMPARE_LE], [
996	AS_VERSION_COMPARE([$1], [$2], [$3], [$3], [$4])
997])
998
999dnl #
1000dnl # ZFS_LINUX_REQUIRE_API
1001dnl # like ZFS_LINUX_TEST_ERROR, except only fails if the kernel is
1002dnl # at least some specified version.
1003dnl #
1004AC_DEFUN([ZFS_LINUX_REQUIRE_API], [
1005	AS_VERSION_COMPARE_LE([$2], [$kernsrcver], [
1006		AC_MSG_ERROR([
1007		*** None of the expected "$1" interfaces were detected. This
1008		*** interface is expected for kernels version "$2" and above.
1009		*** This may be because your kernel version is newer than what is
1010		*** supported, or you are using a patched custom kernel with
1011		*** incompatible modifications.  Newer kernels may have incompatible
1012		*** APIs.
1013		***
1014		*** ZFS Version: $ZFS_META_ALIAS
1015		*** Compatible Kernels: $ZFS_META_KVER_MIN - $ZFS_META_KVER_MAX
1016		])
1017	], [
1018		AC_MSG_RESULT(no)
1019	])
1020])
1021