Re: [ck] [PATCH] Timer Top was: i386 No-Idle-Hz aka Dynamic-Ticks 3

From: Daniel Petrini
Date: Fri Aug 05 2005 - 07:41:41 EST


Hi,

> --
> Jens Axboe
>

Thanks for your corrections. Here we have a new version.

Daniel Petrini
--
10LE - Linux
INdT - Manaus - Brazil
diff -uprN linux-2.6.12-orig/kernel/Makefile linux-dyn-tick/kernel/Makefile
--- linux-2.6.12-orig/kernel/Makefile 2005-08-03 23:50:26.000000000 -0400
+++ linux-dyn-tick/kernel/Makefile 2005-08-04 16:56:14.000000000 -0400
@@ -7,7 +7,7 @@ obj-y = sched.o fork.o exec_domain.o
sysctl.o capability.o ptrace.o timer.o user.o \
signal.o sys.o kmod.o workqueue.o pid.o \
rcupdate.o intermodule.o extable.o params.o posix-timers.o \
- kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o
+ kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o timer_top.o

obj-$(CONFIG_FUTEX) += futex.o
obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
diff -uprN linux-2.6.12-orig/kernel/timer.c linux-dyn-tick/kernel/timer.c
--- linux-2.6.12-orig/kernel/timer.c 2005-08-03 23:50:27.000000000 -0400
+++ linux-dyn-tick/kernel/timer.c 2005-08-04 16:56:27.000000000 -0400
@@ -508,6 +508,8 @@ static inline void __run_timers(tvec_bas
}

#ifdef CONFIG_NO_IDLE_HZ
+extern struct timer_top_info top_info;
+extern int account_timer(unsigned int function, struct timer_top_info * top_info);
/*
* Find out when the next timer event is due to happen. This
* is used on S/390 to stop all activity when a cpus is idle.
@@ -571,6 +573,7 @@ found:
expires = nte->expires;
}
}
+ account_timer((unsigned int)nte->function, &top_info);
spin_unlock(&base->t_base.lock);
return expires;
}
diff -uprN linux-2.6.12-orig/kernel/timer_top.c linux-dyn-tick/kernel/timer_top.c
--- linux-2.6.12-orig/kernel/timer_top.c 1969-12-31 20:00:00.000000000 -0400
+++ linux-dyn-tick/kernel/timer_top.c 2005-08-05 08:31:08.000000000 -0400
@@ -0,0 +1,111 @@
+/*
+ * kernel/timer_top.c
+ *
+ * Export Timers information to /proc/top_info
+ *
+ * Copyright (C) 2005 Instituto Nokia de Tecnologia - INdT - Manaus
+ * Written by Daniel Petrini <d.pensator@xxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
+#include <linux/list.h>
+#include <linux/proc_fs.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+
+static LIST_HEAD(timer_list);
+
+struct timer_top_info {
+ unsigned int func_pointer;
+ unsigned int long counter;
+ struct list_head list;
+};
+
+struct timer_top_info top_info;
+
+static spinlock_t timer_lock = SPIN_LOCK_UNLOCKED;
+static unsigned long flags;
+
+
+int account_timer(unsigned int function, struct timer_top_info * top_info)
+{
+ struct timer_top_info *top;
+
+ spin_lock_irqsave(&timer_lock, flags);
+
+ list_for_each_entry (top, &timer_list, list) {
+ /* if it is in the list increment its count */
+ if (top->func_pointer == function) {
+ top->counter += 1;
+ spin_unlock_irqrestore(&timer_lock, flags);
+ return 0;
+ }
+ }
+
+ /* if you are here then it didnt find so inserts in the list */
+
+ top = kmalloc(sizeof(struct timer_top_info), GFP_ATOMIC);
+ if (!top)
+ return -ENOMEM;
+ top->func_pointer = function;
+ top->counter = 1;
+ list_add(&top->list, &timer_list);
+
+ spin_unlock_irqrestore(&timer_lock, flags);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(account_timer);
+
+struct top_info_poll {
+ char value[18];
+};
+
+static struct top_info_poll top_info_poll_dt;
+static struct proc_dir_entry *top_info_file;
+
+static int proc_read_top_info(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ char aux[18];
+ struct timer_top_info *top;
+
+ struct top_info_poll *info_poll_data=(struct top_info_poll *)data;
+
+ sprintf(page, "Function counter - %s\n", info_poll_data->value);
+
+ list_for_each_entry (top, &timer_list, list) {
+ sprintf(aux, "%x %lu\n", top->func_pointer, top->counter);
+ strcat(page, aux);
+ }
+
+ return strlen(page);
+
+}
+
+static int init_top_info(void)
+{
+ top_info_file = create_proc_entry("top_info", 0666, NULL);
+ if(top_info_file == NULL) {
+ return -ENOMEM;
+ }
+
+ strcpy(top_info_poll_dt.value, "Timer Top v0.9.1");
+
+ top_info_file->data = &top_info_poll_dt;
+ top_info_file->read_proc = &proc_read_top_info;
+ top_info_file->owner = THIS_MODULE;
+
+ return 0;
+}
+
+module_init(init_top_info);
+//module_exit();
+
+
+