Page MenuHomeFreeBSD

D20310.id57545.diff
No OneTemporary

D20310.id57545.diff

Index: share/man/man9/DEFINE_IFUNC.9
===================================================================
--- /dev/null
+++ share/man/man9/DEFINE_IFUNC.9
@@ -0,0 +1,141 @@
+.\" Copyright (c) 2019 The FreeBSD Foundation
+.\"
+.\" This documentation was written by Mark Johnston <markj@FreeBSD.org>
+.\" under sponsorship from the FreeBSD Foundation.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd May 18, 2019
+.Dt DEFINE_IFUNC 9
+.Os
+.Sh NAME
+.Nm DEFINE_IFUNC
+.Nd define a kernel function with a dynamically selected implementation
+.Sh SYNOPSIS
+.In machine/ifunc.h
+.Fn DEFINE_IFUNC qual ret_type name args
+.Sh DESCRIPTION
+ifuncs are a linker feature which allows the programmer to define functions
+with a dynamically selected implementation.
+The
+.Nm
+macro can be used to define an ifunc.
+The selection is performed by a resolver function, which returns a pointer
+to the selected function.
+An ifunc's resolver is invoked very early during the machine-dependent
+initialization routine.
+This must occur before the first call to an ifunc.
+ifunc resolution is performed after CPU features are enumerated and after the
+kernel's environment is initialized.
+The typical use-case for an ifunc is a routine whose behavior depends on
+optional CPU features.
+For example, newer generations of a given CPU architecture may provide an
+instruction to optimize a common operation.
+To avoid the overhead of testing for the CPU feature each time the operation
+is performed, an ifunc can be used to provide two implementations for the
+operation: one targeting platforms with the extra instruction, and one
+for older platforms.
+.Pp
+Because
+.Nm
+is a macro that defines a dynamically typed function, its usage looks somewhat
+unusual.
+The
+.Ar qual
+parameter is a list of zero or more C function qualifiers to be applied to the
+ifunc.
+This parameter is typically empty or the
+.Dv static
+qualifier.
+.Ar ret_type
+is the return type of the ifunc.
+.Ar name
+is the name of the ifunc.
+.Ar args
+is a parenthesized, comma-separated list of the parameter types of the function,
+as they would appear in a C function declaration.
+.Pp
+The
+.Nm
+usage must be followed by the resolver function body.
+The resolver must return a function with return type
+.Ar ret_type
+and parameter types
+.Ar args .
+The resolver function is defined with the
+.Ql resolver
+function attribute, causing the corresponding
+.Xr elf 5
+function symbol to be of type
+.Dv STT_GNU_IFUNC
+instead of
+.Dv STT_FUNC .
+The kernel linker invokes the resolver to process relocations referencing
+such symbols.
+.Sh EXAMPLES
+ifunc resolvers are executed early during boot, before most kernel facilities
+are available.
+They are effectively limited to checking CPU feature flags and tunables.
+.Bd -literal
+static size_t
+fast_strlen(const char *s __unused)
+{
+ size_t len;
+
+ __asm("movq $42,%0\\n" : "=r" (len));
+ return (len);
+}
+
+static size_t
+slow_strlen(const char *s)
+{
+ const char *t;
+
+ for (t = s; *t != '\0'; t++);
+ return (t - s);
+}
+
+DEFINE_IFUNC(, size_t, strlen, (const char *))
+{
+ int enabled;
+
+ enabled = 1;
+ TUNABLE_INT_FETCH("debug.use_fast_strlen", &enabled);
+ if (enabled && (cpu_features & CPUID_FAST_STRLEN) != 0)
+ return (fast_strlen);
+ else
+ return (slow_strlen);
+}
+.Ed
+.Pp
+This defines a
+.Fn strlen
+function with an optimized implementation for CPUs that advertise support.
+.Sh SEE_ALSO
+.Xr elf 5
+.Sh NOTES
+ifuncs are not supported on all architectures.
+They require both toolchain support, to emit function symbols of type
+.Dv STT_GNU_IFUNC ,
+and kernel linker support to invoke ifunc resolvers during boot.

File Metadata

Mime Type
text/plain
Expires
Sat, Feb 22, 7:23 PM (3 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16778087
Default Alt Text
D20310.id57545.diff (4 KB)

Event Timeline