[PATCH] Reduce stack usage in itimer.c

From: Yum Rayan (yum.rayan_at_gmail.com)
Date: 03/31/05

  • Next message: DervishD: "Re: linux-libc-headers scsi headers vs libc scsi headers"
    Date:	Wed, 30 Mar 2005 23:43:05 -0800
    To: linux-kernel@vger.kernel.org
    
    

    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 <yum.rayan@gmail.com>

    --- 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 majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/


  • Next message: DervishD: "Re: linux-libc-headers scsi headers vs libc scsi headers"

    Relevant Pages

    • Re: Light-weight dynamically extended stacks
      ... > I'm really looking forward to seeing your patch. ... > stack usage since there's no longer a hard limit, ... course serve as a red flag for code review. ... It's entirely possible that this idea won't be needed on x86 because ...
      (Linux-Kernel)
    • Re: [PATCH] xfs: do not pass unused params to xfs_flush_pages
      ... This patch removes these parameters from all callsites. ... FWIW this one actually does not seem to reduce stack usage anywhere. ... You do not see reduced stack usage in "make checkstack", ... they are pushed on stack with push instruction, ...
      (Linux-Kernel)
    • Re: 4k stacks
      ... >Yesterday I sent a patch to add stack-poison so the stack usage ... >Today I wrote a small program and tested the stack usage. ... >the program and the patch is attached. ... Prev by Date: ...
      (Linux-Kernel)
    • Re: [PATCH] x86: unify x86 Makefile(s)
      ... The problem isn't that gcc 3.4 and gcc 4.x inlined different functions, ... the problem is that with gcc 3.4 the stack usage was higher. ... static void foo ... There had been need of rain for many days. ...
      (Linux-Kernel)
    • [PATCH] checkstack: pirnt module names
      ... Finding "init_module" high stack usage problems is challenging ... when there are over 1600 "init_module" functions in the kernel tree, ... For built-in code, it just prints the kernel image file name, ... (before patch:) ...
      (Linux-Kernel)