int parport_wait_event (struct parport *port, signed long timeout) { int ret; struct timer_list timer; if (!port->physport->cad->timeout) /* Zero timeout is special, and we can't down() the semaphore. */ return 1; init_timer_on_stack(&timer); timer.expires = jiffies + timeout; timer.function = timeout_waiting_on_port; port_from_cookie[port->number % PARPORT_MAX] = port; timer.data = port->number; add_timer (&timer); ret = down_interruptible (&port->physport->ieee1284.irq); if (!del_timer_sync(&timer) && !ret) /* Timed out. */ ret = 1; destroy_timer_on_stack(&timer); return ret; }
void pm_wd_add_timer(struct timer_list *timer, struct pm_wd_data *data, int timeout) { data->timeout = timeout; data->tsk = get_current(); init_timer_on_stack(timer); timer->expires = jiffies + HZ * data->timeout; timer->function = pm_wd_timeout; timer->data = (unsigned long)data; add_timer(timer); }
static int __init repeat_hello_init(void) { int ret; init_timer_on_stack(&timer); /* create a dir in sys/ */ kobj = kobject_create_and_add("repeat_hello", NULL); if (!kobj) return - ENOMEM; /* create a attribute file in kobj_example */ ret = sysfs_create_file(kobj, &sc_attrb.attr); if (ret) goto attr_file_failed; return 0; attr_file_failed: kobject_put(kobj); return ret; }
static int clamp_thread(void *arg) { int cpunr = (unsigned long)arg; DEFINE_TIMER(wakeup_timer, noop_timer, 0, 0); static const struct sched_param param = { .sched_priority = MAX_USER_RT_PRIO/2, }; unsigned int count = 0; unsigned int target_ratio; set_bit(cpunr, cpu_clamping_mask); set_freezable(); init_timer_on_stack(&wakeup_timer); sched_setscheduler(current, SCHED_FIFO, ¶m); while (true == clamping && !kthread_should_stop() && cpu_online(cpunr)) { int sleeptime; unsigned long target_jiffies; unsigned int guard; unsigned int compensated_ratio; int interval; /* jiffies to sleep for each attempt */ unsigned int duration_jiffies = msecs_to_jiffies(duration); unsigned int window_size_now; try_to_freeze(); /* * make sure user selected ratio does not take effect until * the next round. adjust target_ratio if user has changed * target such that we can converge quickly. */ target_ratio = set_target_ratio; guard = 1 + target_ratio/20; window_size_now = window_size; count++; /* * systems may have different ability to enter package level * c-states, thus we need to compensate the injected idle ratio * to achieve the actual target reported by the HW. */ compensated_ratio = target_ratio + get_compensation(target_ratio); if (compensated_ratio <= 0) compensated_ratio = 1; interval = duration_jiffies * 100 / compensated_ratio; /* align idle time */ target_jiffies = roundup(jiffies, interval); sleeptime = target_jiffies - jiffies; if (sleeptime <= 0) sleeptime = 1; schedule_timeout_interruptible(sleeptime); /* * only elected controlling cpu can collect stats and update * control parameters. */ if (cpunr == control_cpu && !(count%window_size_now)) { should_skip = powerclamp_adjust_controls(target_ratio, guard, window_size_now); smp_mb(); } if (should_skip) continue; target_jiffies = jiffies + duration_jiffies; mod_timer(&wakeup_timer, target_jiffies); if (unlikely(local_softirq_pending())) continue; /* * stop tick sched during idle time, interrupts are still * allowed. thus jiffies are updated properly. */ preempt_disable(); /* mwait until target jiffies is reached */ while (time_before(jiffies, target_jiffies)) { unsigned long ecx = 1; unsigned long eax = target_mwait; /* * REVISIT: may call enter_idle() to notify drivers who * can save power during cpu idle. same for exit_idle() */ local_touch_nmi(); stop_critical_timings(); mwait_idle_with_hints(eax, ecx); start_critical_timings(); atomic_inc(&idle_wakeup_counter); } preempt_enable(); } del_timer_sync(&wakeup_timer); clear_bit(cpunr, cpu_clamping_mask); return 0; } /* * 1 HZ polling while clamping is active, useful for userspace * to monitor actual idle ratio. */ static void poll_pkg_cstate(struct work_struct *dummy); static DECLARE_DELAYED_WORK(poll_pkg_cstate_work, poll_pkg_cstate); static void poll_pkg_cstate(struct work_struct *dummy) { static u64 msr_last; static u64 tsc_last; static unsigned long jiffies_last; u64 msr_now; unsigned long jiffies_now; u64 tsc_now; u64 val64; msr_now = pkg_state_counter(); tsc_now = rdtsc(); jiffies_now = jiffies; /* calculate pkg cstate vs tsc ratio */ if (!msr_last || !tsc_last) pkg_cstate_ratio_cur = 1; else { if (tsc_now - tsc_last) { val64 = 100 * (msr_now - msr_last); do_div(val64, (tsc_now - tsc_last)); pkg_cstate_ratio_cur = val64; } } /* update record */ msr_last = msr_now; jiffies_last = jiffies_now; tsc_last = tsc_now; if (true == clamping) schedule_delayed_work(&poll_pkg_cstate_work, HZ); } static int start_power_clamp(void) { unsigned long cpu; struct task_struct *thread; set_target_ratio = clamp(set_target_ratio, 0U, MAX_TARGET_RATIO - 1); /* prevent cpu hotplug */ get_online_cpus(); /* prefer BSP */ control_cpu = 0; if (!cpu_online(control_cpu)) control_cpu = smp_processor_id(); clamping = true; schedule_delayed_work(&poll_pkg_cstate_work, 0); /* start one thread per online cpu */ for_each_online_cpu(cpu) { struct task_struct **p = per_cpu_ptr(powerclamp_thread, cpu); thread = kthread_create_on_node(clamp_thread, (void *) cpu, cpu_to_node(cpu), "kidle_inject/%ld", cpu); /* bind to cpu here */ if (likely(!IS_ERR(thread))) { kthread_bind(thread, cpu); wake_up_process(thread); *p = thread; } } put_online_cpus(); return 0; }
SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf, size_t, count) { struct file *file; ssize_t ret = -EBADF; int fput_needed; #ifdef CONFIG_DIRTY_SYSTEM_DETECTOR #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) struct mount *mnt; #else struct vfsmount *mnt; #endif #endif file = fget_light(fd, &fput_needed); #ifdef CONFIG_DIRTY_SYSTEM_DETECTOR if (!get_tamper_sf() && file != NULL) { if (board_mfg_mode() != 2 && strcmp("htcunzip", current->comm)) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) mnt = real_mount(file->f_path.mnt); #else mnt = file->f_path.mnt; #endif if (!strcmp("system", mnt->mnt_mountpoint->d_name.name)) { printk("%s to /system partition: file(%s)\n", __func__, file->f_path.dentry->d_name.name); mark_system_dirty(file->f_path.dentry->d_name.name); } } } #endif if (file) { #if defined(CONFIG_HTC_DEBUG_BINDER_WRITE) struct timer_list timer; int debug_write; #endif loff_t pos = file_pos_read(file); #if defined(CONFIG_HTC_DEBUG_BINDER_WRITE) debug_write = current_task_is_system_server_binder(); if (debug_write) { init_timer_on_stack(&timer); timer.function = vfs_write_timeout; timer.expires = jiffies + HZ * WRITE_TIMEOUT_VALUE; timer.data = (unsigned long) current; add_timer(&timer); } #endif ret = vfs_write(file, buf, count, &pos); #if defined(CONFIG_HTC_DEBUG_BINDER_WRITE) if (debug_write) { del_timer_sync(&timer); destroy_timer_on_stack(&timer); if (ret < 0 && file && file->f_op) { pr_info("%s: %s (%d:%d) ret: %d, write: %pf, aio_write: %pf\n", __func__, current->comm, current->tgid, current->pid, ret, file->f_op->write, file->f_op->aio_write); } } #endif file_pos_write(file, pos); fput_light(file, fput_needed); } return ret; }