LCOV - code coverage report
Current view: top level - kernel - itimer.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 77 104 74.0 %
Date: 2014-04-07 Functions: 8 9 88.9 %
Branches: 45 70 64.3 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * linux/kernel/itimer.c
       3                 :            :  *
       4                 :            :  * Copyright (C) 1992 Darren Senn
       5                 :            :  */
       6                 :            : 
       7                 :            : /* These are all the functions necessary to implement itimers */
       8                 :            : 
       9                 :            : #include <linux/mm.h>
      10                 :            : #include <linux/interrupt.h>
      11                 :            : #include <linux/syscalls.h>
      12                 :            : #include <linux/time.h>
      13                 :            : #include <linux/posix-timers.h>
      14                 :            : #include <linux/hrtimer.h>
      15                 :            : #include <trace/events/timer.h>
      16                 :            : 
      17                 :            : #include <asm/uaccess.h>
      18                 :            : 
      19                 :            : /**
      20                 :            :  * itimer_get_remtime - get remaining time for the timer
      21                 :            :  *
      22                 :            :  * @timer: the timer to read
      23                 :            :  *
      24                 :            :  * Returns the delta between the expiry time and now, which can be
      25                 :            :  * less than zero or 1usec for an pending expired timer
      26                 :            :  */
      27                 :          0 : static struct timeval itimer_get_remtime(struct hrtimer *timer)
      28                 :            : {
      29                 :       5287 :         ktime_t rem = hrtimer_get_remaining(timer);
      30                 :            : 
      31                 :            :         /*
      32                 :            :          * Racy but safe: if the itimer expires after the above
      33                 :            :          * hrtimer_get_remtime() call but before this condition
      34                 :            :          * then we return 0 - which is correct.
      35                 :            :          */
      36         [ +  + ]:       5287 :         if (hrtimer_active(timer)) {
      37         [ -  + ]:       1929 :                 if (rem.tv64 <= 0)
      38                 :            :                         rem.tv64 = NSEC_PER_USEC;
      39                 :            :         } else
      40                 :            :                 rem.tv64 = 0;
      41                 :            : 
      42                 :       5287 :         return ktime_to_timeval(rem);
      43                 :            : }
      44                 :            : 
      45                 :          0 : static void get_cpu_itimer(struct task_struct *tsk, unsigned int clock_id,
      46                 :            :                            struct itimerval *const value)
      47                 :            : {
      48                 :            :         cputime_t cval, cinterval;
      49                 :          2 :         struct cpu_itimer *it = &tsk->signal->it[clock_id];
      50                 :            : 
      51                 :          2 :         spin_lock_irq(&tsk->sighand->siglock);
      52                 :            : 
      53                 :          2 :         cval = it->expires;
      54                 :          2 :         cinterval = it->incr;
      55         [ -  + ]:          2 :         if (cval) {
      56                 :            :                 struct task_cputime cputime;
      57                 :            :                 cputime_t t;
      58                 :            : 
      59                 :          0 :                 thread_group_cputimer(tsk, &cputime);
      60         [ +  - ]:          2 :                 if (clock_id == CPUCLOCK_PROF)
      61                 :          2 :                         t = cputime.utime + cputime.stime;
      62                 :            :                 else
      63                 :            :                         /* CPUCLOCK_VIRT */
      64                 :          0 :                         t = cputime.utime;
      65                 :            : 
      66         [ #  # ]:          0 :                 if (cval < t)
      67                 :            :                         /* about to fire */
      68                 :            :                         cval = cputime_one_jiffy;
      69                 :            :                 else
      70                 :          0 :                         cval = cval - t;
      71                 :            :         }
      72                 :            : 
      73                 :          2 :         spin_unlock_irq(&tsk->sighand->siglock);
      74                 :            : 
      75                 :          2 :         cputime_to_timeval(cval, &value->it_value);
      76                 :          2 :         cputime_to_timeval(cinterval, &value->it_interval);
      77                 :          2 : }
      78                 :            : 
      79                 :          0 : int do_getitimer(int which, struct itimerval *value)
      80                 :            : {
      81                 :          5 :         struct task_struct *tsk = current;
      82                 :            : 
      83   [ +  +  +  + ]:          5 :         switch (which) {
      84                 :            :         case ITIMER_REAL:
      85                 :          2 :                 spin_lock_irq(&tsk->sighand->siglock);
      86                 :          2 :                 value->it_value = itimer_get_remtime(&tsk->signal->real_timer);
      87                 :          2 :                 value->it_interval =
      88                 :          2 :                         ktime_to_timeval(tsk->signal->it_real_incr);
      89                 :          2 :                 spin_unlock_irq(&tsk->sighand->siglock);
      90                 :            :                 break;
      91                 :            :         case ITIMER_VIRTUAL:
      92                 :          1 :                 get_cpu_itimer(tsk, CPUCLOCK_VIRT, value);
      93                 :          1 :                 break;
      94                 :            :         case ITIMER_PROF:
      95                 :          1 :                 get_cpu_itimer(tsk, CPUCLOCK_PROF, value);
      96                 :          1 :                 break;
      97                 :            :         default:
      98                 :            :                 return(-EINVAL);
      99                 :            :         }
     100                 :            :         return 0;
     101                 :            : }
     102                 :            : 
     103                 :          0 : SYSCALL_DEFINE2(getitimer, int, which, struct itimerval __user *, value)
     104                 :            : {
     105                 :            :         int error = -EFAULT;
     106                 :            :         struct itimerval get_buffer;
     107                 :            : 
     108         [ +  - ]:          5 :         if (value) {
     109                 :          5 :                 error = do_getitimer(which, &get_buffer);
     110 [ +  + ][ +  + ]:         14 :                 if (!error &&
     111                 :            :                     copy_to_user(value, &get_buffer, sizeof(get_buffer)))
     112                 :            :                         error = -EFAULT;
     113                 :            :         }
     114                 :            :         return error;
     115                 :            : }
     116                 :            : 
     117                 :            : 
     118                 :            : /*
     119                 :            :  * The timer is automagically restarted, when interval != 0
     120                 :            :  */
     121                 :          0 : enum hrtimer_restart it_real_fn(struct hrtimer *timer)
     122                 :            : {
     123                 :            :         struct signal_struct *sig =
     124                 :            :                 container_of(timer, struct signal_struct, real_timer);
     125                 :            : 
     126                 :         22 :         trace_itimer_expire(ITIMER_REAL, sig->leader_pid, 0);
     127                 :         22 :         kill_pid_info(SIGALRM, SEND_SIG_PRIV, sig->leader_pid);
     128                 :            : 
     129                 :         22 :         return HRTIMER_NORESTART;
     130                 :            : }
     131                 :            : 
     132                 :            : static inline u32 cputime_sub_ns(cputime_t ct, s64 real_ns)
     133                 :            : {
     134                 :            :         struct timespec ts;
     135                 :            :         s64 cpu_ns;
     136                 :            : 
     137                 :         14 :         cputime_to_timespec(ct, &ts);
     138                 :            :         cpu_ns = timespec_to_ns(&ts);
     139                 :            : 
     140 [ +  + ][ +  + ]:         14 :         return (cpu_ns <= real_ns) ? 0 : cpu_ns - real_ns;
     141                 :            : }
     142                 :            : 
     143                 :          0 : static void set_cpu_itimer(struct task_struct *tsk, unsigned int clock_id,
     144                 :            :                            const struct itimerval *const value,
     145                 :            :                            struct itimerval *const ovalue)
     146                 :            : {
     147                 :            :         cputime_t cval, nval, cinterval, ninterval;
     148                 :            :         s64 ns_ninterval, ns_nval;
     149                 :            :         u32 error, incr_error;
     150                 :          7 :         struct cpu_itimer *it = &tsk->signal->it[clock_id];
     151                 :            : 
     152                 :          7 :         nval = timeval_to_cputime(&value->it_value);
     153                 :            :         ns_nval = timeval_to_ns(&value->it_value);
     154                 :          7 :         ninterval = timeval_to_cputime(&value->it_interval);
     155                 :            :         ns_ninterval = timeval_to_ns(&value->it_interval);
     156                 :            : 
     157                 :          7 :         error = cputime_sub_ns(nval, ns_nval);
     158                 :            :         incr_error = cputime_sub_ns(ninterval, ns_ninterval);
     159                 :            : 
     160                 :          7 :         spin_lock_irq(&tsk->sighand->siglock);
     161                 :            : 
     162                 :          7 :         cval = it->expires;
     163                 :          7 :         cinterval = it->incr;
     164         [ +  - ]:          7 :         if (cval || nval) {
     165         [ +  + ]:          7 :                 if (nval > 0)
     166                 :          4 :                         nval += cputime_one_jiffy;
     167                 :          7 :                 set_process_cpu_timer(tsk, clock_id, &nval, &cval);
     168                 :            :         }
     169                 :          7 :         it->expires = nval;
     170                 :          7 :         it->incr = ninterval;
     171                 :          7 :         it->error = error;
     172                 :          7 :         it->incr_error = incr_error;
     173         [ +  - ]:         14 :         trace_itimer_state(clock_id == CPUCLOCK_VIRT ?
     174                 :            :                            ITIMER_VIRTUAL : ITIMER_PROF, value, nval);
     175                 :            : 
     176                 :          7 :         spin_unlock_irq(&tsk->sighand->siglock);
     177                 :            : 
     178         [ +  + ]:          7 :         if (ovalue) {
     179                 :          4 :                 cputime_to_timeval(cval, &ovalue->it_value);
     180                 :          4 :                 cputime_to_timeval(cinterval, &ovalue->it_interval);
     181                 :            :         }
     182                 :          7 : }
     183                 :            : 
     184                 :            : /*
     185                 :            :  * Returns true if the timeval is in canonical form
     186                 :            :  */
     187                 :            : #define timeval_valid(t) \
     188                 :            :         (((t)->tv_sec >= 0) && (((unsigned long) (t)->tv_usec) < USEC_PER_SEC))
     189                 :            : 
     190                 :          0 : int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
     191                 :            : {
     192                 :       5296 :         struct task_struct *tsk = current;
     193                 :            :         struct hrtimer *timer;
     194                 :            :         ktime_t expires;
     195                 :            : 
     196                 :            :         /*
     197                 :            :          * Validate the timevals in value.
     198                 :            :          */
     199 [ +  + ][ +  - ]:       5296 :         if (!timeval_valid(&value->it_value) ||
                 [ +  - ]
     200         [ +  - ]:       5294 :             !timeval_valid(&value->it_interval))
     201                 :            :                 return -EINVAL;
     202                 :            : 
     203   [ +  -  +  + ]:       5294 :         switch (which) {
     204                 :            :         case ITIMER_REAL:
     205                 :            : again:
     206                 :       5286 :                 spin_lock_irq(&tsk->sighand->siglock);
     207                 :       5286 :                 timer = &tsk->signal->real_timer;
     208         [ +  + ]:       5286 :                 if (ovalue) {
     209                 :       5285 :                         ovalue->it_value = itimer_get_remtime(timer);
     210                 :            :                         ovalue->it_interval
     211                 :       5285 :                                 = ktime_to_timeval(tsk->signal->it_real_incr);
     212                 :            :                 }
     213                 :            :                 /* We are sharing ->siglock with it_real_fn() */
     214         [ -  + ]:       5286 :                 if (hrtimer_try_to_cancel(timer) < 0) {
     215                 :          0 :                         spin_unlock_irq(&tsk->sighand->siglock);
     216                 :            :                         goto again;
     217                 :            :                 }
     218                 :            :                 expires = timeval_to_ktime(value->it_value);
     219         [ +  + ]:       5286 :                 if (expires.tv64 != 0) {
     220                 :       3970 :                         tsk->signal->it_real_incr =
     221                 :            :                                 timeval_to_ktime(value->it_interval);
     222                 :       1985 :                         hrtimer_start(timer, expires, HRTIMER_MODE_REL);
     223                 :            :                 } else
     224                 :       3301 :                         tsk->signal->it_real_incr.tv64 = 0;
     225                 :            : 
     226                 :            :                 trace_itimer_state(ITIMER_REAL, value, 0);
     227                 :       5286 :                 spin_unlock_irq(&tsk->sighand->siglock);
     228                 :            :                 break;
     229                 :            :         case ITIMER_VIRTUAL:
     230                 :          0 :                 set_cpu_itimer(tsk, CPUCLOCK_VIRT, value, ovalue);
     231                 :          0 :                 break;
     232                 :            :         case ITIMER_PROF:
     233                 :          7 :                 set_cpu_itimer(tsk, CPUCLOCK_PROF, value, ovalue);
     234                 :          7 :                 break;
     235                 :            :         default:
     236                 :            :                 return -EINVAL;
     237                 :            :         }
     238                 :            :         return 0;
     239                 :            : }
     240                 :            : 
     241                 :            : /**
     242                 :            :  * alarm_setitimer - set alarm in seconds
     243                 :            :  *
     244                 :            :  * @seconds:    number of seconds until alarm
     245                 :            :  *              0 disables the alarm
     246                 :            :  *
     247                 :            :  * Returns the remaining time in seconds of a pending timer or 0 when
     248                 :            :  * the timer is not active.
     249                 :            :  *
     250                 :            :  * On 32 bit machines the seconds value is limited to (INT_MAX/2) to avoid
     251                 :            :  * negative timeval settings which would cause immediate expiry.
     252                 :            :  */
     253                 :          0 : unsigned int alarm_setitimer(unsigned int seconds)
     254                 :            : {
     255                 :            :         struct itimerval it_new, it_old;
     256                 :            : 
     257                 :            : #if BITS_PER_LONG < 64
     258         [ #  # ]:          0 :         if (seconds > INT_MAX)
     259                 :            :                 seconds = INT_MAX;
     260                 :            : #endif
     261                 :          0 :         it_new.it_value.tv_sec = seconds;
     262                 :          0 :         it_new.it_value.tv_usec = 0;
     263                 :          0 :         it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0;
     264                 :            : 
     265                 :          0 :         do_setitimer(ITIMER_REAL, &it_new, &it_old);
     266                 :            : 
     267                 :            :         /*
     268                 :            :          * We can't return 0 if we have an alarm pending ...  And we'd
     269                 :            :          * better return too much than too little anyway
     270                 :            :          */
     271 [ #  # ][ #  # ]:          0 :         if ((!it_old.it_value.tv_sec && it_old.it_value.tv_usec) ||
                 [ #  # ]
     272                 :          0 :               it_old.it_value.tv_usec >= 500000)
     273                 :          0 :                 it_old.it_value.tv_sec++;
     274                 :            : 
     275                 :          0 :         return it_old.it_value.tv_sec;
     276                 :            : }
     277                 :            : 
     278                 :          0 : SYSCALL_DEFINE3(setitimer, int, which, struct itimerval __user *, value,
     279                 :            :                 struct itimerval __user *, ovalue)
     280                 :            : {
     281                 :            :         struct itimerval set_buffer, get_buffer;
     282                 :            :         int error;
     283                 :            : 
     284         [ +  - ]:       5296 :         if (value) {
     285         [ +  - ]:      10592 :                 if(copy_from_user(&set_buffer, value, sizeof(set_buffer)))
     286                 :            :                         return -EFAULT;
     287                 :            :         } else {
     288                 :          0 :                 memset(&set_buffer, 0, sizeof(set_buffer));
     289         [ #  # ]:          0 :                 printk_once(KERN_WARNING "%s calls setitimer() with new_value NULL pointer."
     290                 :            :                             " Misfeature support will be removed\n",
     291                 :            :                             current->comm);
     292                 :            :         }
     293                 :            : 
     294         [ +  + ]:       5296 :         error = do_setitimer(which, &set_buffer, ovalue ? &get_buffer : NULL);
     295         [ +  + ]:       5296 :         if (error || !ovalue)
     296                 :            :                 return error;
     297                 :            : 
     298         [ +  + ]:       5289 :         if (copy_to_user(ovalue, &get_buffer, sizeof(get_buffer)))
     299                 :            :                 return -EFAULT;
     300                 :            :         return 0;
     301                 :            : }

Generated by: LCOV version 1.9