lkml.org 
[lkml]   [1999]   [Dec]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: What I suspect : [PATCH] sysdat driver for faster gettimeofday()
On Wed, 8 Dec 1999, Linus Torvalds wrote:
>On Wed, 8 Dec 1999, Rogier Wolff wrote:
>> The other would be one with system info: hostname, domainname, time
>> etc etc (I'm too lazy right now to run through the whole list of
>> syscalls again.)
>
>gettimeofday() is a great example of global state that really =is=
>timing-critical. But very little else is (nobody _really_ cares whether it
>takes 50 cycles or 2 microseconds to get the hostname)
>
> Linus

Here's a patch for implementing an interface to system global state. It
currently carves out a page of the kernel image and keeps xtime in it.
This page is then made mmap'able though a driver called /dev/sysdat
(all under CONFIG_SYSDAT). gettimeofday() can now be written as a library
doing a mmap on the first call and just reads on each call after that.

The patch is against 2.2.13. I have it on my list to update to 2.3 soon.
I'm interested in comments on the code including what other structures
could be added to it. We've been using it to increase database
performance, but I'd guess it would be useful to many other apps.

And here's a loop test of the fast gtod and the current gtod:

root@martyr /root]# time ./fgtod
108.63user 0.01system 1:48.99elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (71major+9minor)pagefaults 0swaps
[root@martyr /root]# time ./gtod
739.04user 1524.50system 37:43.89elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (66major+8minor)pagefaults 0swaps
--
John Wright (jwright@engr.sgi.com)

diff -u -N -r linux2.2/kern/arch/i386/defconfig linux2.2.13-sysdat/kern/arch/i386/defconfig
--- linux2.2/kern/arch/i386/defconfig Wed Dec 8 16:17:04 1999
+++ linux2.2.13-sysdat/kern/arch/i386/defconfig Wed Dec 8 16:34:31 1999
@@ -268,6 +268,7 @@
CONFIG_UNIX98_PTYS=y
CONFIG_UNIX98_PTY_COUNT=256
CONFIG_MOUSE=y
+# CONFIG_SYSDAT is not set

#
# Mice
diff -u -N -r linux2.2/kern/arch/i386/vmlinux.lds.S linux2.2.13-sysdat/kern/arch/i386/vmlinux.lds.S
--- linux2.2/kern/arch/i386/vmlinux.lds.S Wed Dec 8 16:17:06 1999
+++ linux2.2.13-sysdat/kern/arch/i386/vmlinux.lds.S Wed Dec 8 16:50:30 1999
@@ -38,6 +38,14 @@
. = ALIGN(8192); /* init_task */
.data.init_task : { *(.data.init_task) }

+ #if defined(CONFIG_SYSDAT)
+ . = ALIGN(4096); /* Sysdat page */
+ _sysdat_start = .;
+ xtime = .;
+ . = . + 4096;
+ _sysdat_end = .;
+ #endif
+
. = ALIGN(4096); /* Init code and data */
__init_begin = .;
.text.init : { *(.text.init) }
diff -u -N -r linux2.2/kern/drivers/char/Config.in linux2.2.13-sysdat/kern/drivers/char/Config.in
--- linux2.2/kern/drivers/char/Config.in Wed Dec 8 16:17:22 1999
+++ linux2.2.13-sysdat/kern/drivers/char/Config.in Wed Dec 8 16:35:51 1999
@@ -74,6 +74,8 @@
endmenu
fi

+bool '/dev/sysdat support' CONFIG_SYSDAT
+
tristate 'QIC-02 tape support' CONFIG_QIC02_TAPE
if [ "$CONFIG_QIC02_TAPE" != "n" ]; then
bool 'Do you want runtime configuration for QIC-02' CONFIG_QIC02_DYNCONF
diff -u -N -r linux2.2/kern/drivers/char/Makefile linux2.2.13-sysdat/kern/drivers/char/Makefile
--- linux2.2/kern/drivers/char/Makefile Wed Dec 8 16:17:22 1999
+++ linux2.2.13-sysdat/kern/drivers/char/Makefile Wed Dec 8 16:36:49 1999
@@ -28,6 +28,10 @@
LX_OBJS += console.o selection.o
endif

+ifeq ($(CONFIG_SYSDAT),y)
+L_OBJS += sysdat.o
+endif
+
ifeq ($(CONFIG_SERIAL),y)
ifeq ($(CONFIG_SUN_SERIAL),)
ifeq ($(CONFIG_SGI_SERIAL),)
diff -u -N -r linux2.2/kern/drivers/char/mem.c linux2.2.13-sysdat/kern/drivers/char/mem.c
--- linux2.2/kern/drivers/char/mem.c Wed Dec 8 16:17:26 1999
+++ linux2.2.13-sysdat/kern/drivers/char/mem.c Wed Dec 8 18:56:23 1999
@@ -17,6 +17,9 @@
#include <linux/joystick.h>
#include <linux/i2c.h>
#include <linux/capability.h>
+#ifdef CONFIG_SYSDAT
+#include <linux/sysdat.h>
+#endif

#include <asm/uaccess.h>
#include <asm/io.h>
@@ -617,6 +620,9 @@
if (register_chrdev(MEM_MAJOR,"mem",&memory_fops))
printk("unable to get major %d for memory devs\n", MEM_MAJOR);
rand_initialize();
+#ifdef CONFIG_SYSDAT
+ sysdat_init();
+#endif
#ifdef CONFIG_USB
#ifdef CONFIG_USB_UHCI
uhci_init();
diff -u -N -r linux2.2/kern/drivers/char/sysdat.c linux2.2.13-sysdat/kern/drivers/char/sysdat.c
--- linux2.2/kern/drivers/char/sysdat.c Wed Dec 31 16:00:00 1969
+++ linux2.2.13-sysdat/kern/drivers/char/sysdat.c Wed Dec 8 16:24:01 1999
@@ -0,0 +1,87 @@
+/*
+ * linux/drivers/char/sysdat.c
+ *
+ * Mmapable interface to kernel structs. Implemented for a fast mechanism
+ * for gettimeofday().
+ *
+ */
+
+#ifndef __KERNEL__
+# define __KERNEL__
+#endif
+
+#include <linux/errno.h> /* error codes */
+#include <linux/fs.h> /* everything... */
+#include <linux/init.h> /* __init */
+#include <linux/kernel.h> /* printk() */
+#include <linux/mm.h> /* everything */
+#include <linux/time.h> /* timeval, do_gettimeofday */
+#include <linux/wrapper.h> /* mem_map_reserve */
+#include <linux/sysdat.h>
+
+static int sysdat_major = SYSDAT_MAJOR;
+static sysdat_dev *sysdat_device;
+
+static int sysdat_mmap(struct file *, struct vm_area_struct *);
+static unsigned long sysdat_vma_nopage(struct vm_area_struct *, unsigned long, int);
+
+
+static struct file_operations sysdat_fops = {
+ NULL, /* sysdat_llseek */
+ NULL, /* sysdat_read */
+ NULL, /* sysdat_write */
+ NULL, /* sysdat_readdir */
+ NULL, /* sysdat_poll */
+ NULL, /* sysdat_ioctl */
+ sysdat_mmap,
+ NULL, /* sysdat_open */
+ NULL, /* sysdat_flush */
+ NULL, /* sysdat_release */
+ NULL, /* sysdat_fsync */
+ /* nothing more, fill with NULLs */
+};
+
+struct vm_operations_struct sysdat_vm_ops = {
+ NULL, /* sysdat_vma_open */
+ NULL, /* sysdat_vma_release */
+ NULL, /* sysdat_vma_unmap */
+ NULL, /* sysdat_vma_protect */
+ NULL, /* sysdat_vma_sync */
+ NULL, /* sysdat_vma_advise */
+ sysdat_vma_nopage,
+ /* nothing more, fill with NULLs */
+};
+
+int __init sysdat_init(void)
+{
+ int result;
+
+ /* register the major, if SYSDAT_MAJOR == 0 accept a dynamic number */
+ result = register_chrdev(sysdat_major, "sysdat", &sysdat_fops);
+ if (result < 0) {
+ printk(KERN_WARNING "sysdat: can't get major %d\n", sysdat_major);
+ return result;
+ }
+ if (sysdat_major == 0) sysdat_major = result;
+
+ sysdat_device = (sysdat_dev *) &xtime;
+
+ mem_map_reserve(MAP_NR(sysdat_device)); /* don't mess with me */
+ return 0;
+}
+
+int sysdat_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ if (vma->vm_offset & (PAGE_SIZE-1))
+ return -ENXIO; /* need aligned offsets */
+ vma->vm_ops = &sysdat_vm_ops;
+ vma->vm_flags |= VM_LOCKED;
+
+ return 0;
+}
+
+unsigned long sysdat_vma_nopage(struct vm_area_struct *vma,
+ unsigned long address, int write)
+{
+ return (unsigned long)sysdat_device;
+}
diff -u -N -r linux2.2/kern/drivers/char/sysdat.h linux2.2.13-sysdat/kern/drivers/char/sysdat.h
--- linux2.2/kern/drivers/char/sysdat.h Wed Dec 31 16:00:00 1969
+++ linux2.2.13-sysdat/kern/drivers/char/sysdat.h Wed Dec 8 16:24:27 1999
@@ -0,0 +1,19 @@
+#ifndef __LINUX_SYSDAT_H
+#define __LINUX_SYSDAT_H
+
+#include <linux/types.h>
+
+#define SYSDAT_MAJOR 60 /* dynamic major if 0 */
+
+typedef struct sysdat_dev {
+ struct timeval tv;
+} sysdat_dev;
+
+#ifdef __KERNEL__
+
+/* drivers/char/sysdat.c */
+extern int sysdat_init(void);
+
+#endif /* __KERNEL__ */
+
+#endif /* __LINUX_SYSDAT_H */
diff -u -N -r linux2.2/kern/kernel/sched.c linux2.2.13-sysdat/kern/kernel/sched.c
--- linux2.2/kern/kernel/sched.c Wed Dec 8 16:18:24 1999
+++ linux2.2.13-sysdat/kern/kernel/sched.c Wed Dec 8 18:47:33 1999
@@ -49,7 +49,10 @@
long tick = (1000000 + HZ/2) / HZ; /* timer interrupt period */

/* The current time */
+/* If sysdat device is config'd, xtime is kept in init_task.xtime */
+#ifndef CONFIG_SYSDAT
volatile struct timeval xtime __attribute__ ((aligned (16)));
+#endif

/* Don't completely fail for HZ > 500. */
int tickadj = 500/HZ ? : 1; /* microsecs */
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:55    [W:2.242 / U:0.072 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site