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