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