Attempt to reduce stack usage in itimer.c (linux-2.6.12-rc1-mm3). Stack
usage was noted using checkstack.pl. Specifically

Before patch
------------
do_setitimer - 160

After patch
-----------
do_setitimer - none
do_setitimer_real 52
do_setitimer_virtual 52
do_setitimer_prof 52

A singularly heavy stack user do_setitimer(...) was broken down into 3
separate functions. Stack usage will now be lower depending on the path taken.

Signed-off-by: Yum Rayan <[EMAIL PROTECTED]>

--- a/kernel/itimer.c   2005-03-25 22:10:33.000000000 -0800
+++ b/kernel/itimer.c   2005-03-30 15:59:11.000000000 -0800
@@ -141,83 +141,95 @@
        it_real_arm(p, p->signal->it_real_incr);
 }
 
-int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
+static void do_setitimer_real(struct itimerval *value, struct
itimerval *ovalue)
 {
        struct task_struct *tsk = current;
        unsigned long val, interval;
+
+       spin_lock_irq(&tsk->sighand->siglock);
+       interval = tsk->signal->it_real_incr;
+       val = it_real_value(tsk->signal);
+       if (val)
+               del_timer_sync(&tsk->signal->real_timer);
+       tsk->signal->it_real_incr = timeval_to_jiffies(&value->it_interval);
+       it_real_arm(tsk, timeval_to_jiffies(&value->it_value));
+       spin_unlock_irq(&tsk->sighand->siglock);
+       if (ovalue) {
+               jiffies_to_timeval(val, &ovalue->it_value);
+               jiffies_to_timeval(interval, &ovalue->it_interval);
+       }
+}
+
+static void do_setitimer_virtual(struct itimerval *value,
+                                struct itimerval *ovalue)
+{
+       struct task_struct *tsk = current;
+       cputime_t cval, cinterval, nval, ninterval;
+
+       nval = timeval_to_cputime(&value->it_value);
+       ninterval = timeval_to_cputime(&value->it_interval);
+       read_lock(&tasklist_lock);
+       spin_lock_irq(&tsk->sighand->siglock);
+       cval = tsk->signal->it_virt_expires;
+       cinterval = tsk->signal->it_virt_incr;
+       if (!cputime_eq(cval, cputime_zero) ||
+           !cputime_eq(nval, cputime_zero)) {
+               if (cputime_gt(nval, cputime_zero))
+                       nval = cputime_add(nval, jiffies_to_cputime(1));
+               set_process_cpu_timer(tsk, CPUCLOCK_VIRT, &nval, &cval);
+       }
+       tsk->signal->it_virt_expires = nval;
+       tsk->signal->it_virt_incr = ninterval;
+       spin_unlock_irq(&tsk->sighand->siglock);
+       read_unlock(&tasklist_lock);
+       if (ovalue) {
+               cputime_to_timeval(cval, &ovalue->it_value);
+               cputime_to_timeval(cinterval, &ovalue->it_interval);
+       }
+}
+static void do_setitimer_prof(struct itimerval *value, struct
itimerval *ovalue)
+{
+       struct task_struct *tsk = current;
        cputime_t cval, cinterval, nval, ninterval;
+       nval = timeval_to_cputime(&value->it_value);
+       ninterval = timeval_to_cputime(&value->it_interval);
+       read_lock(&tasklist_lock);
+       spin_lock_irq(&tsk->sighand->siglock);
+       cval = tsk->signal->it_prof_expires;
+       cinterval = tsk->signal->it_prof_incr;
+       if (!cputime_eq(cval, cputime_zero) ||
+               !cputime_eq(nval, cputime_zero)) {
+               if (cputime_gt(nval, cputime_zero))
+                       nval = cputime_add(nval, jiffies_to_cputime(1));
+               set_process_cpu_timer(tsk, CPUCLOCK_PROF, &nval, &cval);
+       }
+       tsk->signal->it_prof_expires = nval;
+       tsk->signal->it_prof_incr = ninterval;
+       spin_unlock_irq(&tsk->sighand->siglock);
+       read_unlock(&tasklist_lock);
+       if (ovalue) {
+               cputime_to_timeval(cval, &ovalue->it_value);
+               cputime_to_timeval(cinterval, &ovalue->it_interval);
+       }
+}
 
+int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
+{
        switch (which) {
        case ITIMER_REAL:
-               spin_lock_irq(&tsk->sighand->siglock);
-               interval = tsk->signal->it_real_incr;
-               val = it_real_value(tsk->signal);
-               if (val)
-                       del_timer_sync(&tsk->signal->real_timer);
-               tsk->signal->it_real_incr =
-                       timeval_to_jiffies(&value->it_interval);
-               it_real_arm(tsk, timeval_to_jiffies(&value->it_value));
-               spin_unlock_irq(&tsk->sighand->siglock);
-               if (ovalue) {
-                       jiffies_to_timeval(val, &ovalue->it_value);
-                       jiffies_to_timeval(interval,
-                                          &ovalue->it_interval);
-               }
+               do_setitimer_real(value, ovalue);
                break;
        case ITIMER_VIRTUAL:
-               nval = timeval_to_cputime(&value->it_value);
-               ninterval = timeval_to_cputime(&value->it_interval);
-               read_lock(&tasklist_lock);
-               spin_lock_irq(&tsk->sighand->siglock);
-               cval = tsk->signal->it_virt_expires;
-               cinterval = tsk->signal->it_virt_incr;
-               if (!cputime_eq(cval, cputime_zero) ||
-                   !cputime_eq(nval, cputime_zero)) {
-                       if (cputime_gt(nval, cputime_zero))
-                               nval = cputime_add(nval,
-                                                  jiffies_to_cputime(1));
-                       set_process_cpu_timer(tsk, CPUCLOCK_VIRT,
-                                             &nval, &cval);
-               }
-               tsk->signal->it_virt_expires = nval;
-               tsk->signal->it_virt_incr = ninterval;
-               spin_unlock_irq(&tsk->sighand->siglock);
-               read_unlock(&tasklist_lock);
-               if (ovalue) {
-                       cputime_to_timeval(cval, &ovalue->it_value);
-                       cputime_to_timeval(cinterval, &ovalue->it_interval);
-               }
+               do_setitimer_virtual(value, ovalue);
                break;
        case ITIMER_PROF:
-               nval = timeval_to_cputime(&value->it_value);
-               ninterval = timeval_to_cputime(&value->it_interval);
-               read_lock(&tasklist_lock);
-               spin_lock_irq(&tsk->sighand->siglock);
-               cval = tsk->signal->it_prof_expires;
-               cinterval = tsk->signal->it_prof_incr;
-               if (!cputime_eq(cval, cputime_zero) ||
-                   !cputime_eq(nval, cputime_zero)) {
-                       if (cputime_gt(nval, cputime_zero))
-                               nval = cputime_add(nval,
-                                                  jiffies_to_cputime(1));
-                       set_process_cpu_timer(tsk, CPUCLOCK_PROF,
-                                             &nval, &cval);
-               }
-               tsk->signal->it_prof_expires = nval;
-               tsk->signal->it_prof_incr = ninterval;
-               spin_unlock_irq(&tsk->sighand->siglock);
-               read_unlock(&tasklist_lock);
-               if (ovalue) {
-                       cputime_to_timeval(cval, &ovalue->it_value);
-                       cputime_to_timeval(cinterval, &ovalue->it_interval);
-               }
+               do_setitimer_prof(value, ovalue);
                break;
        default:
                return -EINVAL;
        }
        return 0;
 }
-
 asmlinkage long sys_setitimer(int which,
                              struct itimerval __user *value,
                              struct itimerval __user *ovalue)
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to