/* * Initialize POSIX timer handling for a thread group. */ static void posix_cpu_timers_init_group(struct signal_struct *sig) { /* Thread group counters. */ thread_group_cputime_init(sig); /* Expiration times and increments. */ sig->it[CPUCLOCK_PROF].expires = cputime_zero; sig->it[CPUCLOCK_PROF].incr = cputime_zero; sig->it[CPUCLOCK_VIRT].expires = cputime_zero; sig->it[CPUCLOCK_VIRT].incr = cputime_zero; /* Cached expiration times. */ sig->cputime_expires.prof_exp = cputime_zero; sig->cputime_expires.virt_exp = cputime_zero; sig->cputime_expires.sched_exp = 0; if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) { sig->cputime_expires.prof_exp = secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur); sig->cputimer.running = 1; } /* The timer lists. */ INIT_LIST_HEAD(&sig->cpu_timers[0]); INIT_LIST_HEAD(&sig->cpu_timers[1]); INIT_LIST_HEAD(&sig->cpu_timers[2]); }
/* * Called after updating RLIMIT_CPU to run cpu timer and update * tsk->signal->cputime_expires expiration cache if necessary. Needs * siglock protection since other code may update expiration cache as * well. */ void update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new) { cputime_t cputime = secs_to_cputime(rlim_new); spin_lock_irq(&task->sighand->siglock); set_process_cpu_timer(task, CPUCLOCK_PROF, &cputime, NULL); spin_unlock_irq(&task->sighand->siglock); }
/* * Called after updating RLIMIT_CPU to set timer expiration if necessary. */ void update_rlimit_cpu(unsigned long rlim_new) { cputime_t cputime = secs_to_cputime(rlim_new); struct signal_struct *const sig = current->signal; if (cputime_eq(sig->it[CPUCLOCK_PROF].expires, cputime_zero) || cputime_lt(sig->it[CPUCLOCK_PROF].expires, cputime)) { spin_lock_irq(¤t->sighand->siglock); set_process_cpu_timer(current, CPUCLOCK_PROF, &cputime, NULL); spin_unlock_irq(¤t->sighand->siglock); } }
/* * Called after updating RLIMIT_CPU to set timer expiration if necessary. */ void update_rlimit_cpu(unsigned long rlim_new) { cputime_t cputime; cputime = secs_to_cputime(rlim_new); if (cputime_eq(current->signal->it_prof_expires, cputime_zero) || cputime_gt(current->signal->it_prof_expires, cputime)) { spin_lock_irq(¤t->sighand->siglock); set_process_cpu_timer(current, CPUCLOCK_PROF, &cputime, NULL); spin_unlock_irq(¤t->sighand->siglock); } }
/* * Initialize POSIX timer handling for a thread group. */ static void posix_cpu_timers_init_group(struct signal_struct *sig) { unsigned long cpu_limit; cpu_limit = READ_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur); if (cpu_limit != RLIM_INFINITY) { sig->cputime_expires.prof_exp = secs_to_cputime(cpu_limit); sig->cputimer.running = 1; } /* The timer lists. */ INIT_LIST_HEAD(&sig->cpu_timers[0]); INIT_LIST_HEAD(&sig->cpu_timers[1]); INIT_LIST_HEAD(&sig->cpu_timers[2]); }
void cs_wfo_mac_table_init(void) { memset((void*)(&mac_table_802_3[0]), 0, sizeof(struct wfo_mac_table_entry)*WFO_MAC_ENTRY_SIZE); memset((void*)(&mac_table_802_11[0]), 0, sizeof(struct wfo_mac_table_entry)*WFO_MAC_ENTRY_SIZE); spin_lock_init(&table_802_3_lock); spin_lock_init(&table_802_11_lock); //aging may not be needed right now, low priority init_timer(&wfo_mac_timer); wfo_mac_timer.expires = jiffies + secs_to_cputime(WFO_MAC_ENTRY_TIMER_PERIOD); wfo_mac_timer.function = &cs_wfo_mac_table_timer_func; return; }
asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim) { struct rlimit new_rlim, *old_rlim; int retval; if (resource >= RLIM_NLIMITS) return -EINVAL; if(copy_from_user(&new_rlim, rlim, sizeof(*rlim))) return -EFAULT; if (new_rlim.rlim_cur > new_rlim.rlim_max) return -EINVAL; old_rlim = current->signal->rlim + resource; if ((new_rlim.rlim_max > old_rlim->rlim_max) && !capable(CAP_SYS_RESOURCE)) return -EPERM; if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > NR_OPEN) return -EPERM; retval = security_task_setrlimit(resource, &new_rlim); if (retval) return retval; task_lock(current->group_leader); *old_rlim = new_rlim; task_unlock(current->group_leader); if (resource == RLIMIT_CPU && new_rlim.rlim_cur != RLIM_INFINITY && (cputime_eq(current->signal->it_prof_expires, cputime_zero) || new_rlim.rlim_cur <= cputime_to_secs( current->signal->it_prof_expires))) { cputime_t cputime = secs_to_cputime(new_rlim.rlim_cur); read_lock(&tasklist_lock); spin_lock_irq(¤t->sighand->siglock); set_process_cpu_timer(current, CPUCLOCK_PROF, &cputime, NULL); spin_unlock_irq(¤t->sighand->siglock); read_unlock(&tasklist_lock); } return 0; }
void cs_wfo_mac_table_timer_func(unsigned long data) { int i; int resched = 0; //age 802.3 MACs spin_lock(&table_802_3_lock); for(i = 0; i < WFO_MAC_ENTRY_SIZE; i++) { if(mac_table_802_3[i].status == WFO_MAC_ENTRY_VALID) { if(mac_table_802_3[i].timeout++ > WFO_MAX_MAC_AGING_COUNT) memset(&mac_table_802_3[i], 0, sizeof(struct wfo_mac_table_entry)); else resched = 1; } } spin_unlock(&table_802_3_lock); //age 802.11 MACs spin_lock(&table_802_11_lock); for(i = 0; i < WFO_MAC_ENTRY_SIZE; i++) { if(mac_table_802_11[i].status == WFO_MAC_ENTRY_VALID) { if(mac_table_802_11[i].timeout++ > WFO_MAX_MAC_AGING_COUNT) memset(&mac_table_802_11[i], 0, sizeof(struct wfo_mac_table_entry)); else resched = 1; } } spin_unlock(&table_802_11_lock); #if 0 if (resched) mod_timer(&wfo_mac_timer, jiffies + secs_to_cputime(WFO_MAC_ENTRY_TIMER_PERIOD)); #endif return; }
static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) { struct signal_struct *sig; int ret; if (clone_flags & CLONE_THREAD) return 0; sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL); tsk->signal = sig; if (!sig) return -ENOMEM; ret = copy_thread_group_keys(tsk); if (ret < 0) { kmem_cache_free(signal_cachep, sig); return ret; } atomic_set(&sig->count, 1); atomic_set(&sig->live, 1); init_waitqueue_head(&sig->wait_chldexit); sig->flags = 0; sig->group_exit_code = 0; sig->group_exit_task = NULL; sig->group_stop_count = 0; sig->curr_target = tsk; init_sigpending(&sig->shared_pending); INIT_LIST_HEAD(&sig->posix_timers); hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); sig->it_real_incr.tv64 = 0; sig->real_timer.function = it_real_fn; sig->it_virt_expires = cputime_zero; sig->it_virt_incr = cputime_zero; sig->it_prof_expires = cputime_zero; sig->it_prof_incr = cputime_zero; sig->leader = 0; /* session leadership doesn't inherit */ sig->tty_old_pgrp = NULL; sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero; sig->gtime = cputime_zero; sig->cgtime = cputime_zero; sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; task_io_accounting_init(&sig->ioac); sig->sum_sched_runtime = 0; INIT_LIST_HEAD(&sig->cpu_timers[0]); INIT_LIST_HEAD(&sig->cpu_timers[1]); INIT_LIST_HEAD(&sig->cpu_timers[2]); taskstats_tgid_init(sig); task_lock(current->group_leader); memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim); task_unlock(current->group_leader); if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) { /* * New sole thread in the process gets an expiry time * of the whole CPU time limit. */ tsk->it_prof_expires = secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur); } acct_init_pacct(&sig->pacct); tty_audit_fork(sig); return 0; }
asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim) { struct rlimit new_rlim, *old_rlim; unsigned long it_prof_secs; int retval; if (resource >= RLIM_NLIMITS) return -EINVAL; if (copy_from_user(&new_rlim, rlim, sizeof(*rlim))) return -EFAULT; if (new_rlim.rlim_cur > new_rlim.rlim_max) return -EINVAL; old_rlim = current->signal->rlim + resource; if ((new_rlim.rlim_max > old_rlim->rlim_max) && !capable(CAP_SYS_RESOURCE)) return -EPERM; if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open) return -EPERM; retval = security_task_setrlimit(resource, &new_rlim); if (retval) return retval; if (resource == RLIMIT_CPU && new_rlim.rlim_cur == 0) { /* * The caller is asking for an immediate RLIMIT_CPU * expiry. But we use the zero value to mean "it was * never set". So let's cheat and make it one second * instead */ new_rlim.rlim_cur = 1; } task_lock(current->group_leader); *old_rlim = new_rlim; task_unlock(current->group_leader); if (resource != RLIMIT_CPU) goto out; /* * RLIMIT_CPU handling. Note that the kernel fails to return an error * code if it rejected the user's attempt to set RLIMIT_CPU. This is a * very long-standing error, and fixing it now risks breakage of * applications, so we live with it */ if (new_rlim.rlim_cur == RLIM_INFINITY) goto out; it_prof_secs = cputime_to_secs(current->signal->it_prof_expires); if (it_prof_secs == 0 || new_rlim.rlim_cur <= it_prof_secs) { unsigned long rlim_cur = new_rlim.rlim_cur; cputime_t cputime; cputime = secs_to_cputime(rlim_cur); read_lock(&tasklist_lock); spin_lock_irq(¤t->sighand->siglock); set_process_cpu_timer(current, CPUCLOCK_PROF, &cputime, NULL); spin_unlock_irq(¤t->sighand->siglock); read_unlock(&tasklist_lock); } out: return 0; }
static inline int copy_signal(unsigned long clone_flags, struct task_struct * tsk) { struct signal_struct *sig; int ret; if (clone_flags & CLONE_THREAD) { atomic_inc(¤t->signal->count); atomic_inc(¤t->signal->live); return 0; } sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL); tsk->signal = sig; if (!sig) return -ENOMEM; ret = copy_thread_group_keys(tsk); if (ret < 0) { kmem_cache_free(signal_cachep, sig); return ret; } atomic_set(&sig->count, 1); atomic_set(&sig->live, 1); init_waitqueue_head(&sig->wait_chldexit); sig->flags = 0; sig->group_exit_code = 0; sig->group_exit_task = NULL; sig->group_stop_count = 0; sig->curr_target = NULL; init_sigpending(&sig->shared_pending); INIT_LIST_HEAD(&sig->posix_timers); sig->it_real_value = sig->it_real_incr = 0; sig->real_timer.function = it_real_fn; sig->real_timer.data = (unsigned long) tsk; init_timer(&sig->real_timer); sig->it_virt_expires = cputime_zero; sig->it_virt_incr = cputime_zero; sig->it_prof_expires = cputime_zero; sig->it_prof_incr = cputime_zero; sig->tty = current->signal->tty; sig->pgrp = process_group(current); sig->session = current->signal->session; sig->leader = 0; /* session leadership doesn't inherit */ sig->tty_old_pgrp = 0; sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero; sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; sig->sched_time = 0; INIT_LIST_HEAD(&sig->cpu_timers[0]); INIT_LIST_HEAD(&sig->cpu_timers[1]); INIT_LIST_HEAD(&sig->cpu_timers[2]); task_lock(current->group_leader); memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim); task_unlock(current->group_leader); if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) { /* * New sole thread in the process gets an expiry time * of the whole CPU time limit. */ tsk->it_prof_expires = secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur); } return 0; }