From: Nadia.Derbey@bull.net
To: akpm@osdl.org, randy.dunlap@oracle.com
Cc: linux-kernel@vger.kernel.org, Nadia Derbey <Nadia.Derbey@bull.net>
Subject: [PATCH 6/6] AKT - automatic tuning applied to some kernel components
Date: Tue, 30 Jan 2007 11:11:49 +0100 [thread overview]
Message-ID: <20070130102911.103873000@bull.net> (raw)
In-Reply-To: 20070130101143.296619000@bull.net
[-- Attachment #1: auto_tune_applied.patch --]
[-- Type: text/plain, Size: 14631 bytes --]
[PATCH 06/06]
The following kernel components register a tunable structure and call the
auto-tuning routine:
. file system
. shared memory (per namespace)
. semaphore (per namespace)
. message queues (per namespace)
Signed-off-by: Nadia Derbey <Nadia.Derbey@bull.net>
---
fs/file_table.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/akt.h | 1
include/linux/ipc.h | 6 +++
init/main.c | 1
ipc/msg.c | 20 ++++++++++++
ipc/sem.c | 43 +++++++++++++++++++++++++++
ipc/shm.c | 76 +++++++++++++++++++++++++++++++++++++++++++++---
7 files changed, 224 insertions(+), 5 deletions(-)
Index: linux-2.6.20-rc4/include/linux/akt.h
===================================================================
--- linux-2.6.20-rc4.orig/include/linux/akt.h 2007-01-29 15:57:59.000000000 +0100
+++ linux-2.6.20-rc4/include/linux/akt.h 2007-01-29 16:05:58.000000000 +0100
@@ -262,5 +262,6 @@ static inline void init_auto_tuning(void
#endif /* CONFIG_AKT */
extern void fork_late_init(void);
+extern void files_late_init(void);
#endif /* AKT_H */
Index: linux-2.6.20-rc4/include/linux/ipc.h
===================================================================
--- linux-2.6.20-rc4.orig/include/linux/ipc.h 2007-01-29 12:39:30.000000000 +0100
+++ linux-2.6.20-rc4/include/linux/ipc.h 2007-01-29 16:07:37.000000000 +0100
@@ -52,6 +52,7 @@ struct ipc_perm
#ifdef __KERNEL__
#include <linux/kref.h>
+#include <linux/akt.h>
#define IPCMNI 32768 /* <= MAX_INT limit for ipc arrays (including sysctl changes) */
@@ -77,15 +78,20 @@ struct ipc_namespace {
int sem_ctls[4];
int used_sems;
+ DECLARE_TUNABLE(semmni_akt);
+ DECLARE_TUNABLE(semmns_akt);
int msg_ctlmax;
int msg_ctlmnb;
int msg_ctlmni;
+ DECLARE_TUNABLE(msgmni_akt);
size_t shm_ctlmax;
size_t shm_ctlall;
int shm_ctlmni;
int shm_tot;
+ DECLARE_TUNABLE(shmmni_akt);
+ DECLARE_TUNABLE(shmall_akt);
};
extern struct ipc_namespace init_ipc_ns;
Index: linux-2.6.20-rc4/init/main.c
===================================================================
--- linux-2.6.20-rc4.orig/init/main.c 2007-01-29 15:33:43.000000000 +0100
+++ linux-2.6.20-rc4/init/main.c 2007-01-29 16:08:31.000000000 +0100
@@ -616,6 +616,7 @@ asmlinkage void __init start_kernel(void
page_writeback_init();
init_auto_tuning();
fork_late_init();
+ files_late_init();
#ifdef CONFIG_PROC_FS
proc_root_init();
#endif
Index: linux-2.6.20-rc4/fs/file_table.c
===================================================================
--- linux-2.6.20-rc4.orig/fs/file_table.c 2007-01-29 12:39:30.000000000 +0100
+++ linux-2.6.20-rc4/fs/file_table.c 2007-01-29 16:10:37.000000000 +0100
@@ -21,6 +21,8 @@
#include <linux/fsnotify.h>
#include <linux/sysctl.h>
#include <linux/percpu_counter.h>
+#include <linux/akt.h>
+#include <linux/akt_ops.h>
#include <asm/atomic.h>
@@ -34,6 +36,71 @@ __cacheline_aligned_in_smp DEFINE_SPINLO
static struct percpu_counter nr_files __cacheline_aligned_in_smp;
+#ifdef CONFIG_AKT
+
+static int get_nr_files(void);
+
+/********** automatic tuning **********/
+#define FILPTHRESH 80 /* threshold = 80% */
+
+/*
+ * FUNCTION: This is the routine called to accomplish auto tuning for the
+ * max_files tunable.
+ *
+ * Upwards adjustment:
+ * Adjustment is needed if nr_files has reached
+ * (threshold / 100 * max_files)
+ * In that case, max_files is set to
+ * (tunable + max_files * (100 - threshold) / 100)
+ *
+ * Downards adjustment:
+ * Adjustment is needed if nr_files has fallen under
+ * (threshold / 100 * max_files previous value)
+ * In that case max_files is set back to its previous value,
+ * i.e. to (max_files * 100 / (200 - threshold))
+ *
+ * PARAMETERS: cmd: controls the adjustment direction (up / down)
+ * params: pointer to the registered tunable structure
+ *
+ * EXECUTION ENVIRONMENT: This routine should be called with the
+ * params->tunable_lck lock held
+ *
+ * RETURN VALUE: 1 if tunable has been adjusted
+ * 0 else
+ */
+static inline int maxfiles_auto_tuning(int cmd, struct auto_tune *params)
+{
+ int thr = params->threshold;
+ int min = params->min.value;
+ int max = params->max.value;
+ int tun = files_stat.max_files;
+
+ if (cmd == AKT_UP) {
+ if (get_nr_files() >= tun * thr / 100 && tun < max) {
+ int new = tun * (200 - thr) / 100;
+
+ files_stat.max_files = min(max, new);
+ return 1;
+ } else
+ return 0;
+ }
+
+ if (get_nr_files() < tun * thr / (200 - thr) && tun > min) {
+ int new = tun * 100 / (200 - thr);
+
+ files_stat.max_files = max(min, new);
+ return 1;
+ } else
+ return 0;
+}
+
+#endif /* CONFIG_AKT */
+
+/* The maximum value will be known later on */
+DEFINE_TUNABLE(maxfiles_akt, FILPTHRESH, 0, 0, &files_stat.max_files,
+ &nr_files, int);
+
+
static inline void file_free_rcu(struct rcu_head *head)
{
struct file *f = container_of(head, struct file, f_u.fu_rcuhead);
@@ -44,6 +111,8 @@ static inline void file_free(struct file
{
percpu_counter_dec(&nr_files);
call_rcu(&f->f_u.fu_rcuhead, file_free_rcu);
+
+ activate_auto_tuning(AKT_DOWN, &maxfiles_akt);
}
/*
@@ -91,6 +160,8 @@ struct file *get_empty_filp(void)
static int old_max;
struct file * f;
+ activate_auto_tuning(AKT_UP, &maxfiles_akt);
+
/*
* Privileged users can go above max_files
*/
@@ -299,6 +370,17 @@ void __init files_init(unsigned long mem
files_stat.max_files = n;
if (files_stat.max_files < NR_FILE)
files_stat.max_files = NR_FILE;
+
+ set_tunable_min_max(maxfiles_akt, n, n * 2);
+ set_autotuning_routine(&maxfiles_akt, maxfiles_auto_tuning);
+
files_defer_init();
percpu_counter_init(&nr_files, 0);
}
+
+void __init files_late_init(void)
+{
+ if (register_tunable(&maxfiles_akt))
+ printk(KERN_WARNING
+ "AKT: Failed registering tunable file-max\n");
+}
Index: linux-2.6.20-rc4/ipc/msg.c
===================================================================
--- linux-2.6.20-rc4.orig/ipc/msg.c 2007-01-29 12:39:30.000000000 +0100
+++ linux-2.6.20-rc4/ipc/msg.c 2007-01-29 16:11:57.000000000 +0100
@@ -36,6 +36,8 @@
#include <linux/seq_file.h>
#include <linux/mutex.h>
#include <linux/nsproxy.h>
+#include <linux/akt.h>
+#include <linux/akt_ops.h>
#include <asm/current.h>
#include <asm/uaccess.h>
@@ -94,6 +96,11 @@ static void __ipc_init __msg_init_ns(str
ns->msg_ctlmnb = MSGMNB;
ns->msg_ctlmni = MSGMNI;
ipc_init_ids(ids, ns->msg_ctlmni);
+
+#define MSGTHRESH 80
+
+ init_tunable_ipcns(ns, msgmni_akt, MSGTHRESH, MSGMNI, IPCMNI,
+ &ns->msg_ctlmni, &ids->in_use, int);
}
#ifdef CONFIG_IPC_NS
@@ -133,6 +140,11 @@ void msg_exit_ns(struct ipc_namespace *n
void __init msg_init(void)
{
__msg_init_ns(&init_ipc_ns, &init_msg_ids);
+
+ if (register_tunable(&init_ipc_ns.msgmni_akt))
+ printk(KERN_WARNING
+ "AKT: Failed registering tunable msgmni\n");
+
ipc_init_proc_interface("sysvipc/msg",
" key msqid perms cbytes qnum lspid lrpid uid gid cuid cgid stime rtime ctime\n",
IPC_MSG_IDS, sysvipc_msg_proc_show);
@@ -262,6 +274,8 @@ asmlinkage long sys_msgget(key_t key, in
ns = current->nsproxy->ipc_ns;
+ activate_auto_tuning(AKT_UP, &ns->msgmni_akt);
+
mutex_lock(&msg_ids(ns).mutex);
if (key == IPC_PRIVATE)
ret = newque(ns, key, msgflg);
@@ -391,6 +405,7 @@ asmlinkage long sys_msgctl(int msqid, in
struct msg_queue *msq;
int err, version;
struct ipc_namespace *ns;
+ int destroyed = 0;
if (msqid < 0 || cmd < 0)
return -EINVAL;
@@ -555,11 +570,16 @@ asmlinkage long sys_msgctl(int msqid, in
}
case IPC_RMID:
freeque(ns, msq, msqid);
+ destroyed = 1;
break;
}
err = 0;
out_up:
mutex_unlock(&msg_ids(ns).mutex);
+
+ if (destroyed)
+ activate_auto_tuning(AKT_DOWN, &ns->msgmni_akt);
+
return err;
out_unlock_up:
msg_unlock(msq);
Index: linux-2.6.20-rc4/ipc/shm.c
===================================================================
--- linux-2.6.20-rc4.orig/ipc/shm.c 2007-01-29 12:39:30.000000000 +0100
+++ linux-2.6.20-rc4/ipc/shm.c 2007-01-29 16:12:22.000000000 +0100
@@ -37,6 +37,8 @@
#include <linux/seq_file.h>
#include <linux/mutex.h>
#include <linux/nsproxy.h>
+#include <linux/akt.h>
+#include <linux/akt_ops.h>
#include <asm/uaccess.h>
@@ -75,17 +77,27 @@ static void __ipc_init __shm_init_ns(str
ns->shm_ctlmni = SHMMNI;
ns->shm_tot = 0;
ipc_init_ids(ids, 1);
+
+#define SHMTHRESH 80
+ init_tunable_ipcns(ns, shmmni_akt, SHMTHRESH, SHMMNI, IPCMNI,
+ &ns->shm_ctlmni, &ids->in_use, int);
+ init_tunable_ipcns(ns, shmall_akt, SHMTHRESH, SHMALL,
+ SHMMAX / PAGE_SIZE * (IPCMNI / 16), &ns->shm_ctlall,
+ &ns->shm_tot, size_t);
}
-static void do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp)
+static int do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp)
{
if (shp->shm_nattch){
shp->shm_perm.mode |= SHM_DEST;
/* Do not find it any more */
shp->shm_perm.key = IPC_PRIVATE;
shm_unlock(shp);
- } else
+ return 0;
+ } else {
shm_destroy(ns, shp);
+ return 1;
+ }
}
#ifdef CONFIG_IPC_NS
@@ -125,6 +137,15 @@ void shm_exit_ns(struct ipc_namespace *n
void __init shm_init (void)
{
__shm_init_ns(&init_ipc_ns, &init_shm_ids);
+
+ if (register_tunable(&init_ipc_ns.shmmni_akt))
+ printk(KERN_WARNING
+ "AKT: Failed registering tunable shmmni\n");
+
+ if (register_tunable(&init_ipc_ns.shmall_akt))
+ printk(KERN_WARNING
+ "AKT: Failed registering tunable shmall\n");
+
ipc_init_proc_interface("sysvipc/shm",
" key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime\n",
IPC_SHM_IDS, sysvipc_shm_proc_show);
@@ -206,6 +227,7 @@ static void shm_close (struct vm_area_st
int id = file->f_path.dentry->d_inode->i_ino;
struct shmid_kernel *shp;
struct ipc_namespace *ns;
+ int destroyed = 0;
ns = shm_file_ns(file);
@@ -217,11 +239,27 @@ static void shm_close (struct vm_area_st
shp->shm_dtim = get_seconds();
shp->shm_nattch--;
if(shp->shm_nattch == 0 &&
- shp->shm_perm.mode & SHM_DEST)
+ shp->shm_perm.mode & SHM_DEST) {
shm_destroy(ns, shp);
- else
+ destroyed = 1;
+ } else
shm_unlock(shp);
mutex_unlock(&shm_ids(ns).mutex);
+
+ if (destroyed) {
+ int rc;
+
+ rc = activate_auto_tuning(AKT_DOWN, &ns->shmmni_akt);
+ if (rc)
+ /*
+ * shm_ctlmni has been adjusted == > change
+ * shm_ctlall value
+ */
+ ns->shm_ctlall = ns->shm_ctlmax / PAGE_SIZE *
+ (ns->shm_ctlmni / 16);
+
+ activate_auto_tuning(AKT_DOWN, &ns->shmall_akt);
+ }
}
static int shm_mmap(struct file * file, struct vm_area_struct * vma)
@@ -355,9 +393,20 @@ asmlinkage long sys_shmget (key_t key, s
struct shmid_kernel *shp;
int err, id = 0;
struct ipc_namespace *ns;
+ int rc;
ns = current->nsproxy->ipc_ns;
+ rc = activate_auto_tuning(AKT_UP, &ns->shmmni_akt);
+ if (rc)
+ /*
+ * shm_ctlmni has been adjusted == > change shm_ctlall value
+ */
+ ns->shm_ctlall = ns->shm_ctlmax / PAGE_SIZE
+ * (ns->shm_ctlmni / 16);
+
+ activate_auto_tuning(AKT_UP, &ns->shmall_akt);
+
mutex_lock(&shm_ids(ns).mutex);
if (key == IPC_PRIVATE) {
err = newseg(ns, key, shmflg, size);
@@ -516,6 +565,7 @@ asmlinkage long sys_shmctl (int shmid, i
struct shmid_kernel *shp;
int err, version;
struct ipc_namespace *ns;
+ int destroyed;
if (cmd < 0 || shmid < 0) {
err = -EINVAL;
@@ -701,8 +751,24 @@ asmlinkage long sys_shmctl (int shmid, i
if (err)
goto out_unlock_up;
- do_shm_rmid(ns, shp);
+ destroyed = do_shm_rmid(ns, shp);
mutex_unlock(&shm_ids(ns).mutex);
+
+ if (destroyed) {
+ int rc;
+
+ rc = activate_auto_tuning(AKT_DOWN, &ns->shmmni_akt);
+ if (rc)
+ /*
+ * shm_ctlmni has been adjusted == > change
+ * shm_ctlall value
+ */
+ ns->shm_ctlall = ns->shm_ctlmax / PAGE_SIZE *
+ (ns->shm_ctlmni / 16);
+
+ activate_auto_tuning(AKT_DOWN, &ns->shmall_akt);
+ }
+
goto out;
}
Index: linux-2.6.20-rc4/ipc/sem.c
===================================================================
--- linux-2.6.20-rc4.orig/ipc/sem.c 2007-01-29 12:39:30.000000000 +0100
+++ linux-2.6.20-rc4/ipc/sem.c 2007-01-29 16:12:47.000000000 +0100
@@ -83,6 +83,8 @@
#include <linux/seq_file.h>
#include <linux/mutex.h>
#include <linux/nsproxy.h>
+#include <linux/akt.h>
+#include <linux/akt_ops.h>
#include <asm/uaccess.h>
#include "util.h"
@@ -131,6 +133,12 @@ static void __ipc_init __sem_init_ns(str
ns->sc_semmni = SEMMNI;
ns->used_sems = 0;
ipc_init_ids(ids, ns->sc_semmni);
+
+#define SEMTHRESH 80
+ init_tunable_ipcns(ns, semmni_akt, SEMTHRESH, SEMMNI, IPCMNI,
+ &(ns->sc_semmni), &ids->in_use, int);
+ init_tunable_ipcns(ns, semmns_akt, SEMTHRESH, SEMMNS,
+ IPCMNI * SEMMSL, &(ns->sc_semmns), &ns->used_sems, int);
}
#ifdef CONFIG_IPC_NS
@@ -170,6 +178,15 @@ void sem_exit_ns(struct ipc_namespace *n
void __init sem_init (void)
{
__sem_init_ns(&init_ipc_ns, &init_sem_ids);
+
+ if (register_tunable(&init_ipc_ns.semmni_akt))
+ printk(KERN_WARNING
+ "AKT: Failed registering tunable semmni\n");
+
+ if (register_tunable(&init_ipc_ns.semmns_akt))
+ printk(KERN_WARNING
+ "AKT: Failed registering tunable semmns\n");
+
ipc_init_proc_interface("sysvipc/sem",
" key semid perms nsems uid gid cuid cgid otime ctime\n",
IPC_SEM_IDS, sysvipc_sem_proc_show);
@@ -263,11 +280,22 @@ asmlinkage long sys_semget (key_t key, i
int id, err = -EINVAL;
struct sem_array *sma;
struct ipc_namespace *ns;
+ int rc;
ns = current->nsproxy->ipc_ns;
if (nsems < 0 || nsems > ns->sc_semmsl)
return -EINVAL;
+
+ rc = activate_auto_tuning(AKT_UP, &ns->semmni_akt);
+ if (rc)
+ /*
+ * sc_semmni has been adjusted == > change sc_semmns value
+ */
+ ns->sc_semmns = ns->sc_semmni * ns->sc_semmsl;
+
+ activate_auto_tuning(AKT_UP, &ns->semmns_akt);
+
mutex_lock(&sem_ids(ns).mutex);
if (key == IPC_PRIVATE) {
@@ -899,6 +927,21 @@ static int semctl_down(struct ipc_namesp
case IPC_RMID:
freeary(ns, sma, semid);
err = 0;
+
+ {
+ int rc;
+
+ rc = activate_auto_tuning(AKT_DOWN, &ns->semmni_akt);
+ if (rc)
+ /*
+ * sc_semmni has been adjusted ==>
+ * change sc_semmns value
+ */
+ ns->sc_semmns = ns->sc_semmni * ns->sc_semmsl;
+
+ activate_auto_tuning(AKT_DOWN, &ns->semmns_akt);
+ }
+
break;
case IPC_SET:
ipcp->uid = setbuf.uid;
--
prev parent reply other threads:[~2007-01-30 10:27 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-01-30 10:11 [PATCH 0/6] AKT - Automatic Kernel Tunables Nadia.Derbey
2007-01-30 10:11 ` [PATCH 1/6] AKT - Tunable structure and registration routines Nadia.Derbey
2007-02-12 15:07 ` Andi Kleen
2007-02-13 10:18 ` Nadia Derbey
2007-02-13 10:51 ` Andi Kleen
2007-01-30 10:11 ` [PATCH 2/6] AKT - auto_tuning activation Nadia.Derbey
2007-01-30 10:11 ` [PATCH 3/6] AKT - tunables associated kobjects Nadia.Derbey
2007-01-30 10:11 ` [PATCH 4/6] AKT - min and max kobjects Nadia.Derbey
2007-01-30 10:11 ` [PATCH 5/6] AKT - per namespace tunables Nadia.Derbey
2007-01-30 10:11 ` Nadia.Derbey [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070130102911.103873000@bull.net \
--to=nadia.derbey@bull.net \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
--cc=randy.dunlap@oracle.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.