1850 lines · 49.4 KB · C
RawDownload
			/*			 * This is not really a fixup. The timer was			 * statically initialized. We just make sure that it			 * is tracked in the object tracker.			 */			debug_object_init(timer, &timer_debug_descr);			return 0;		} else {			setup_timer(timer, stub_timer, 0);			return 1;		}	default:		return 0;	}} static struct debug_obj_descr timer_debug_descr = {	.name			= "timer_list",	.debug_hint		= timer_debug_hint,	.fixup_init		= timer_fixup_init,	.fixup_activate		= timer_fixup_activate,	.fixup_free		= timer_fixup_free,	.fixup_assert_init	= timer_fixup_assert_init,}; static inline void debug_timer_init(struct timer_list *timer){	debug_object_init(timer, &timer_debug_descr);} static inline void debug_timer_activate(struct timer_list *timer){	debug_object_activate(timer, &timer_debug_descr);} static inline void debug_timer_deactivate(struct timer_list *timer){	debug_object_deactivate(timer, &timer_debug_descr);} static inline void debug_timer_free(struct timer_list *timer){	debug_object_free(timer, &timer_debug_descr);} static inline void debug_timer_assert_init(struct timer_list *timer){	debug_object_assert_init(timer, &timer_debug_descr);} static void __init_timer(struct timer_list *timer,			 const char *name,			 struct lock_class_key *key); void init_timer_on_stack_key(struct timer_list *timer,			     const char *name,			     struct lock_class_key *key){	debug_object_init_on_stack(timer, &timer_debug_descr);	__init_timer(timer, name, key);}EXPORT_SYMBOL_GPL(init_timer_on_stack_key); void destroy_timer_on_stack(struct timer_list *timer){	debug_object_free(timer, &timer_debug_descr);}EXPORT_SYMBOL_GPL(destroy_timer_on_stack); #elsestatic inline void debug_timer_init(struct timer_list *timer) { }static inline void debug_timer_activate(struct timer_list *timer) { }static inline void debug_timer_deactivate(struct timer_list *timer) { }static inline void debug_timer_assert_init(struct timer_list *timer) { }#endif static inline void debug_init(struct timer_list *timer){	debug_timer_init(timer);	trace_timer_init(timer);} static inline voiddebug_activate(struct timer_list *timer, unsigned long expires){	debug_timer_activate(timer);	trace_timer_start(timer, expires);} static inline void debug_deactivate(struct timer_list *timer){	debug_timer_deactivate(timer);	trace_timer_cancel(timer);} static inline void debug_assert_init(struct timer_list *timer){	debug_timer_assert_init(timer);} static void __init_timer(struct timer_list *timer,			 const char *name,			 struct lock_class_key *key){	timer->entry.next = NULL;	timer->base = __raw_get_cpu_var(tvec_bases);	timer->slack = -1;#ifdef CONFIG_TIMER_STATS	timer->start_site = NULL;	timer->start_pid = -1;	memset(timer->start_comm, 0, TASK_COMM_LEN);#endif	lockdep_init_map(&timer->lockdep_map, name, key, 0);} void setup_deferrable_timer_on_stack_key(struct timer_list *timer,					 const char *name,					 struct lock_class_key *key,					 void (*function)(unsigned long),					 unsigned long data){	timer->function = function;	timer->data = data;	init_timer_on_stack_key(timer, name, key);	timer_set_deferrable(timer);}EXPORT_SYMBOL_GPL(setup_deferrable_timer_on_stack_key); /** * init_timer_key - initialize a timer * @timer: the timer to be initialized * @name: name of the timer * @key: lockdep class key of the fake lock used for tracking timer *       sync lock dependencies * * init_timer_key() must be done to a timer prior calling *any* of the * other timer functions. */void init_timer_key(struct timer_list *timer,		    const char *name,		    struct lock_class_key *key){	debug_init(timer);	__init_timer(timer, name, key);}EXPORT_SYMBOL(init_timer_key); void init_timer_deferrable_key(struct timer_list *timer,			       const char *name,			       struct lock_class_key *key){	init_timer_key(timer, name, key);	timer_set_deferrable(timer);}EXPORT_SYMBOL(init_timer_deferrable_key); static inline void detach_timer(struct timer_list *timer,				int clear_pending){	struct list_head *entry = &timer->entry; 	debug_deactivate(timer); 	__list_del(entry->prev, entry->next);	if (clear_pending)		entry->next = NULL;	entry->prev = LIST_POISON2;} /* * We are using hashed locking: holding per_cpu(tvec_bases).lock * means that all timers which are tied to this base via timer->base are * locked, and the base itself is locked too. * * So __run_timers/migrate_timers can safely modify all timers which could * be found on ->tvX lists. * * When the timer's base is locked, and the timer removed from list, it is * possible to set timer->base = NULL and drop the lock: the timer remains * locked. */static struct tvec_base *lock_timer_base(struct timer_list *timer,					unsigned long *flags)	__acquires(timer->base->lock){	struct tvec_base *base; 	for (;;) {		struct tvec_base *prelock_base = timer->base;		base = tbase_get_base(prelock_base);		if (likely(base != NULL)) {			spin_lock_irqsave(&base->lock, *flags);			if (likely(prelock_base == timer->base))				return base;			/* The timer has migrated to another CPU */			spin_unlock_irqrestore(&base->lock, *flags);		}		cpu_relax();	}} static inline int__mod_timer(struct timer_list *timer, unsigned long expires,						bool pending_only, int pinned){	struct tvec_base *base, *new_base;	unsigned long flags;	int ret = 0 , cpu; 	timer_stats_timer_set_start_info(timer);	BUG_ON(!timer->function); 	base = lock_timer_base(timer, &flags); 	if (timer_pending(timer)) {		detach_timer(timer, 0);		if (timer->expires == base->next_timer &&		    !tbase_get_deferrable(timer->base))			base->next_timer = base->timer_jiffies;		ret = 1;	} else {		if (pending_only)			goto out_unlock;	} 	debug_activate(timer, expires); 	cpu = smp_processor_id(); #if defined(CONFIG_NO_HZ) && defined(CONFIG_SMP)	if (!pinned && get_sysctl_timer_migration() && idle_cpu(cpu))		cpu = get_nohz_timer_target();#endif	new_base = per_cpu(tvec_bases, cpu); 	if (base != new_base) {		/*		 * We are trying to schedule the timer on the local CPU.		 * However we can't change timer's base while it is running,		 * otherwise del_timer_sync() can't detect that the timer's		 * handler yet has not finished. This also guarantees that		 * the timer is serialized wrt itself.		 */		if (likely(base->running_timer != timer)) {			/* See the comment in lock_timer_base() */			timer_set_base(timer, NULL);			spin_unlock(&base->lock);			base = new_base;			spin_lock(&base->lock);			timer_set_base(timer, base);		}	} 	timer->expires = expires;	if (time_before(timer->expires, base->next_timer) &&	    !tbase_get_deferrable(timer->base))		base->next_timer = timer->expires;	internal_add_timer(base, timer); out_unlock:	spin_unlock_irqrestore(&base->lock, flags); 	return ret;} /** * mod_timer_pending - modify a pending timer's timeout * @timer: the pending timer to be modified * @expires: new timeout in jiffies * * mod_timer_pending() is the same for pending timers as mod_timer(), * but will not re-activate and modify already deleted timers. * * It is useful for unserialized use of timers. */int mod_timer_pending(struct timer_list *timer, unsigned long expires){	return __mod_timer(timer, expires, true, TIMER_NOT_PINNED);}EXPORT_SYMBOL(mod_timer_pending); /* * Decide where to put the timer while taking the slack into account * * Algorithm: *   1) calculate the maximum (absolute) time *   2) calculate the highest bit where the expires and new max are different *   3) use this bit to make a mask *   4) use the bitmask to round down the maximum time, so that all last *      bits are zeros */static inlineunsigned long apply_slack(struct timer_list *timer, unsigned long expires){	unsigned long expires_limit, mask;	int bit; 	if (timer->slack >= 0) {		expires_limit = expires + timer->slack;	} else {		long delta = expires - jiffies; 		if (delta < 256)			return expires; 		expires_limit = expires + delta / 256;	}	mask = expires ^ expires_limit;	if (mask == 0)		return expires; 	bit = find_last_bit(&mask, BITS_PER_LONG); 	mask = (1 << bit) - 1; 	expires_limit = expires_limit & ~(mask); 	return expires_limit;} /** * mod_timer - modify a timer's timeout * @timer: the timer to be modified * @expires: new timeout in jiffies * * mod_timer() is a more efficient way to update the expire field of an * active timer (if the timer is inactive it will be activated) * * mod_timer(timer, expires) is equivalent to: * *     del_timer(timer); timer->expires = expires; add_timer(timer); * * Note that if there are multiple unserialized concurrent users of the * same timer, then mod_timer() is the only safe way to modify the timeout, * since add_timer() cannot modify an already running timer. * * The function returns whether it has modified a pending timer or not. * (ie. mod_timer() of an inactive timer returns 0, mod_timer() of an * active timer returns 1.) */int mod_timer(struct timer_list *timer, unsigned long expires){	expires = apply_slack(timer, expires); 	/*	 * This is a common optimization triggered by the	 * networking code - if the timer is re-modified	 * to be the same thing then just return:	 */	if (timer_pending(timer) && timer->expires == expires)		return 1; 	return __mod_timer(timer, expires, false, TIMER_NOT_PINNED);}EXPORT_SYMBOL(mod_timer); /** * mod_timer_pinned - modify a timer's timeout * @timer: the timer to be modified * @expires: new timeout in jiffies * * mod_timer_pinned() is a way to update the expire field of an * active timer (if the timer is inactive it will be activated) * and to ensure that the timer is scheduled on the current CPU. * * Note that this does not prevent the timer from being migrated * when the current CPU goes offline.  If this is a problem for * you, use CPU-hotplug notifiers to handle it correctly, for * example, cancelling the timer when the corresponding CPU goes * offline. * * mod_timer_pinned(timer, expires) is equivalent to: * *     del_timer(timer); timer->expires = expires; add_timer(timer); */int mod_timer_pinned(struct timer_list *timer, unsigned long expires){	if (timer->expires == expires && timer_pending(timer))		return 1; 	return __mod_timer(timer, expires, false, TIMER_PINNED);}EXPORT_SYMBOL(mod_timer_pinned); /** * add_timer - start a timer * @timer: the timer to be added * * The kernel will do a ->function(->data) callback from the * timer interrupt at the ->expires point in the future. The * current time is 'jiffies'. * * The timer's ->expires, ->function (and if the handler uses it, ->data) * fields must be set prior calling this function. * * Timers with an ->expires field in the past will be executed in the next * timer tick. */void add_timer(struct timer_list *timer){	BUG_ON(timer_pending(timer));	mod_timer(timer, timer->expires);}EXPORT_SYMBOL(add_timer); /** * add_timer_on - start a timer on a particular CPU * @timer: the timer to be added * @cpu: the CPU to start it on * * This is not very scalable on SMP. Double adds are not possible. */void add_timer_on(struct timer_list *timer, int cpu){	struct tvec_base *base = per_cpu(tvec_bases, cpu);	unsigned long flags; 	timer_stats_timer_set_start_info(timer);	BUG_ON(timer_pending(timer) || !timer->function);	spin_lock_irqsave(&base->lock, flags);	timer_set_base(timer, base);	debug_activate(timer, timer->expires);	if (time_before(timer->expires, base->next_timer) &&	    !tbase_get_deferrable(timer->base))		base->next_timer = timer->expires;	internal_add_timer(base, timer);	/*	 * Check whether the other CPU is idle and needs to be	 * triggered to reevaluate the timer wheel when nohz is	 * active. We are protected against the other CPU fiddling	 * with the timer by holding the timer base lock. This also	 * makes sure that a CPU on the way to idle can not evaluate	 * the timer wheel.	 */	wake_up_idle_cpu(cpu);	spin_unlock_irqrestore(&base->lock, flags);}EXPORT_SYMBOL_GPL(add_timer_on); /** * del_timer - deactive a timer. * @timer: the timer to be deactivated * * del_timer() deactivates a timer - this works on both active and inactive * timers. * * The function returns whether it has deactivated a pending timer or not. * (ie. del_timer() of an inactive timer returns 0, del_timer() of an * active timer returns 1.) */int del_timer(struct timer_list *timer){	struct tvec_base *base;	unsigned long flags;	int ret = 0; 	debug_assert_init(timer); 	timer_stats_timer_clear_start_info(timer);	if (timer_pending(timer)) {		base = lock_timer_base(timer, &flags);		if (timer_pending(timer)) {			detach_timer(timer, 1);			if (timer->expires == base->next_timer &&			    !tbase_get_deferrable(timer->base))				base->next_timer = base->timer_jiffies;			ret = 1;		}		spin_unlock_irqrestore(&base->lock, flags);	} 	return ret;}EXPORT_SYMBOL(del_timer); /** * try_to_del_timer_sync - Try to deactivate a timer * @timer: timer do del * * This function tries to deactivate a timer. Upon successful (ret >= 0) * exit the timer is not queued and the handler is not running on any CPU. */int try_to_del_timer_sync(struct timer_list *timer){	struct tvec_base *base;	unsigned long flags;	int ret = -1; 	debug_assert_init(timer); 	base = lock_timer_base(timer, &flags); 	if (base->running_timer == timer)		goto out; 	timer_stats_timer_clear_start_info(timer);	ret = 0;	if (timer_pending(timer)) {		detach_timer(timer, 1);		if (timer->expires == base->next_timer &&

Lines 501–1000 of 1850. Previous lines