summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/kern/sys_generic.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2015-04-08 15:37:49 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2015-05-20 09:58:21 +0200
commit165dd8ea1256d71d6a4f52c0a66dcc2799ef8f99 (patch)
treec42072a99573d4d7cc03b2263e2c0c6d53f9c691 /freebsd/sys/kern/sys_generic.c
parentrtems-bsd-chunk: Include missing header file (diff)
downloadrtems-libbsd-165dd8ea1256d71d6a4f52c0a66dcc2799ef8f99.tar.bz2
Update to FreeBSD Stable/9 2015-04-08
Diffstat (limited to 'freebsd/sys/kern/sys_generic.c')
-rw-r--r--freebsd/sys/kern/sys_generic.c33
1 files changed, 25 insertions, 8 deletions
diff --git a/freebsd/sys/kern/sys_generic.c b/freebsd/sys/kern/sys_generic.c
index eb1ed37d..0ed027d5 100644
--- a/freebsd/sys/kern/sys_generic.c
+++ b/freebsd/sys/kern/sys_generic.c
@@ -79,6 +79,20 @@ __FBSDID("$FreeBSD$");
#include <machine/rtems-bsd-syscall-api.h>
#endif /* __rtems__ */
+/*
+ * The following macro defines how many bytes will be allocated from
+ * the stack instead of memory allocated when passing the IOCTL data
+ * structures from userspace and to the kernel. Some IOCTLs having
+ * small data structures are used very frequently and this small
+ * buffer on the stack gives a significant speedup improvement for
+ * those requests. The value of this define should be greater or equal
+ * to 64 bytes and should also be power of two. The data structure is
+ * currently hard-aligned to a 8-byte boundary on the stack. This
+ * should currently be sufficient for all supported platforms.
+ */
+#define SYS_IOCTL_SMALL_SIZE 128 /* bytes */
+#define SYS_IOCTL_SMALL_ALIGN 8 /* bytes */
+
#ifndef __rtems__
int iosize_max_clamp = 1;
SYSCTL_INT(_debug, OID_AUTO, iosize_max_clamp, CTLFLAG_RW,
@@ -652,6 +666,7 @@ struct ioctl_args {
int
sys_ioctl(struct thread *td, struct ioctl_args *uap)
{
+ u_char smalldata[SYS_IOCTL_SMALL_SIZE] __aligned(SYS_IOCTL_SMALL_ALIGN);
u_long com;
int arg, error;
u_int size;
@@ -686,17 +701,18 @@ sys_ioctl(struct thread *td, struct ioctl_args *uap)
arg = (intptr_t)uap->data;
data = (void *)&arg;
size = 0;
- } else
- data = malloc((u_long)size, M_IOCTLOPS, M_WAITOK);
+ } else {
+ if (size > SYS_IOCTL_SMALL_SIZE)
+ data = malloc((u_long)size, M_IOCTLOPS, M_WAITOK);
+ else
+ data = smalldata;
+ }
} else
data = (void *)&uap->data;
if (com & IOC_IN) {
error = copyin(uap->data, data, (u_int)size);
- if (error) {
- if (size > 0)
- free(data, M_IOCTLOPS);
- return (error);
- }
+ if (error != 0)
+ goto out;
} else if (com & IOC_OUT) {
/*
* Zero the buffer so the user always
@@ -710,7 +726,8 @@ sys_ioctl(struct thread *td, struct ioctl_args *uap)
if (error == 0 && (com & IOC_OUT))
error = copyout(data, uap->data, (u_int)size);
- if (size > 0)
+out:
+ if (size > SYS_IOCTL_SMALL_SIZE)
free(data, M_IOCTLOPS);
return (error);
}