lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <201704180505.dI4AIR8C%fengguang.wu@intel.com>
Date:   Tue, 18 Apr 2017 05:27:07 +0800
From:   kbuild test robot <fengguang.wu@...el.com>
To:     Anna-Maria Gleixner <anna-maria@...utronix.de>
Cc:     kbuild-all@...org, linux-kernel@...r.kernel.org,
        tipbuild@...or.com, Thomas Gleixner <tglx@...utronix.de>
Subject: [tip:WIP.timers 8/10] kernel//time/timer_migration.c:190:4: error:
 implicit declaration of function 'timer_expire_remote'

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git WIP.timers
head:   c0b7a5dbb870d1660aa5e566c5ce9972290a2bed
commit: 6a3164fa4cd35a587b5bb2e4bd86b75900af8286 [8/10] timer: Implement the hierarchical pull model
config: i386-randconfig-r0-201716 (attached as .config)
compiler: gcc-5 (Debian 5.4.1-2) 5.4.1 20160904
reproduce:
        git checkout 6a3164fa4cd35a587b5bb2e4bd86b75900af8286
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   In file included from kernel//time/timer_migration.c:16:0:
   kernel//time/timer_migration.h: In function 'tmigr_cpu_idle':
   kernel//time/timer_migration.h:26:1: warning: no return statement in function returning non-void [-Wreturn-type]
    static inline u64 tmigr_cpu_idle(u64 nextevt) { }
    ^
   kernel//time/timer_migration.c: In function '__tmigr_handle_remote':
>> kernel//time/timer_migration.c:190:4: error: implicit declaration of function 'timer_expire_remote' [-Werror=implicit-function-declaration]
       timer_expire_remote(evt->cpu);
       ^
   kernel//time/timer_migration.c: At top level:
>> kernel//time/timer_migration.c:223:6: error: redefinition of 'tmigr_handle_remote'
    void tmigr_handle_remote(void)
         ^
   In file included from kernel//time/timer_migration.c:16:0:
   kernel//time/timer_migration.h:25:20: note: previous definition of 'tmigr_handle_remote' was here
    static inline void tmigr_handle_remote(void) { }
                       ^
>> kernel//time/timer_migration.c:348:5: error: redefinition of 'tmigr_cpu_idle'
    u64 tmigr_cpu_idle(u64 nextevt)
        ^
   In file included from kernel//time/timer_migration.c:16:0:
   kernel//time/timer_migration.h:26:19: note: previous definition of 'tmigr_cpu_idle' was here
    static inline u64 tmigr_cpu_idle(u64 nextevt) { }
                      ^
>> kernel//time/timer_migration.c:406:6: error: redefinition of 'tmigr_cpu_activate'
    void tmigr_cpu_activate(void)
         ^
   In file included from kernel//time/timer_migration.c:16:0:
   kernel//time/timer_migration.h:27:20: note: previous definition of 'tmigr_cpu_activate' was here
    static inline void tmigr_cpu_activate(void) { }
                       ^
   cc1: some warnings being treated as errors

vim +/timer_expire_remote +190 kernel//time/timer_migration.c

    10	#include <linux/slab.h>
    11	#include <linux/smp.h>
    12	#include <linux/spinlock.h>
    13	#include <linux/timerqueue.h>
    14	#include <linux/timer.h>
    15	
  > 16	#include "timer_migration.h"
    17	#include "tick-internal.h"
    18	
    19	#ifdef DEBUG
    20	# define DBG_BUG_ON(x)	BUG_ON(x)
    21	#else
    22	# define DBG_BUG_ON(x)
    23	#endif
    24	
    25	/* Per group capacity. Must be a power of 2! */
    26	static const unsigned int tmigr_childs_per_group = 8;
    27	
    28	bool tmigr_enabled __read_mostly;
    29	static unsigned int tmigr_hierarchy_levels __read_mostly;
    30	static unsigned int tmigr_crossnode_level __read_mostly;
    31	static struct list_head *tmigr_level_list __read_mostly;
    32	
    33	static DEFINE_MUTEX(tmigr_mutex);
    34	
    35	static DEFINE_PER_CPU(struct tmigr_cpu, tmigr_cpu);
    36	
    37	static void tmigr_add_evt(struct tmigr_group *group, struct tmigr_event *evt)
    38	{
    39		/*
    40		 * Can be called with @evt == NULL, an already queued @evt or
    41		 * an event that do not need to be queued (expires ==
    42		 * KTIME_MAX)
    43		 */
    44		if (!evt || !RB_EMPTY_NODE(&evt->nextevt.node) ||
    45		    evt->nextevt.expires == KTIME_MAX)
    46			return;
    47	
    48		/* @group->group event must not be queued in the parent group */
    49		DBG_BUG_ON(!RB_EMPTY_NODE(&group->groupevt.nextevt.node));
    50	
    51		/*  If this is the new first to expire event, update group event */
    52		if (timerqueue_add(&group->events, &evt->nextevt)) {
    53			group->groupevt.nextevt.expires = evt->nextevt.expires;
    54			group->groupevt.cpu = evt->cpu;
    55		}
    56	}
    57	
    58	static void tmigr_remove_evt(struct tmigr_group *group, struct tmigr_event *evt)
    59	{
    60		struct timerqueue_node *next;
    61		struct tmigr_event *nextevt;
    62		bool first;
    63	
    64		/*
    65		 * It's safe to modify the group event of this group, because it is
    66		 * not queued in the parent group.
    67		 */
    68		DBG_BUG_ON(!RB_EMPTY_NODE(&group->groupevt.nextevt.node));
    69	
    70		/* Remove the child event, if pending */
    71		if (!evt || RB_EMPTY_NODE(&evt->nextevt.node))
    72			return;
    73		/*
    74		 * If this was the last queued event in the group, clear
    75		 * the group event. If this was the first event to expire,
    76		 * update the group.
    77		 */
    78		first = (timerqueue_getnext(&group->events) == &evt->nextevt);
    79	
    80		if (!timerqueue_del(&group->events, &evt->nextevt)) {
    81			group->groupevt.nextevt.expires = KTIME_MAX;
    82			group->groupevt.cpu = TMIGR_NONE;
    83		} else if (first) {
    84			next = timerqueue_getnext(&group->events);
    85			nextevt = container_of(next, struct tmigr_event, nextevt);
    86			group->groupevt.nextevt.expires = nextevt->nextevt.expires;
    87			group->groupevt.cpu = nextevt->cpu;
    88		}
    89	}
    90	
    91	static void tmigr_update_remote(unsigned int cpu, u64 now, unsigned long jif)
    92	{
    93		struct tmigr_cpu *tmc = per_cpu_ptr(&tmigr_cpu, cpu);
    94		struct tmigr_group *group = tmc->tmgroup;
    95		u64 next_local, next_global;
    96	
    97		/*
    98		 * Here the migrator CPU races with the target CPU.  The migrator
    99		 * removed @tmc->nextevt from the group's queue, but it then dropped
   100		 * the group lock.  Concurrently the target CPU might have serviced
   101		 * an interrupt and therefore have called tmigr_cpu_activate() and
   102		 * possibly tmigr_cpu_idle() which requeued CPUs @tmc into @group.
   103		 *
   104		 * Must hold @tmc->lock for changing @tmc->nextevt and @group->lock
   105		 * to protect the timer queue of @group.
   106		 */
   107		raw_spin_lock_irq(&tmc->lock);
   108		raw_spin_lock(&group->lock);
   109	
   110		/*
   111		 * If the cpu went offline or marked itself active again, nothing
   112		 * more to do.
   113		 */
   114		if (!tmc->online || cpumask_test_cpu(cpu, group->cpus))
   115			goto done;
   116	
   117		/*
   118		 * Although __timgr_handle_remote() just dequeued the event, still
   119		 * the target CPU might have added it again after the lock got
   120		 * dropped. If it's queued the group queue is up to date.
   121		 */
   122		if (!RB_EMPTY_NODE(&tmc->cpuevt.nextevt.node))
   123			goto done;
   124	
   125		/*
   126		 * Recalculate next event. Needs to be calculated while holding the
   127		 * lock because the first expiring global timer could have been
   128		 * removed since the last evaluation.
   129		 */
   130		next_local = get_next_timer_interrupt(jif, now, &next_global);
   131	
   132		/*
   133		 * If next_global is after next_local, event does not have to
   134		 * be queued.
   135		 */
   136		if (next_global >= next_local)
   137			next_global = KTIME_MAX;
   138	
   139		tmc->cpuevt.nextevt.expires = next_global;
   140	
   141		/* Queue @cpu event (is not ne queued if expires == KTIME_MAX) */
   142		tmigr_add_evt(group, &tmc->cpuevt);
   143	
   144	done:
   145		raw_spin_unlock(&group->lock);
   146		raw_spin_unlock_irq(&tmc->lock);
   147	}
   148	
   149	static void __tmigr_handle_remote(struct tmigr_group *group, unsigned int cpu,
   150					  u64 now, unsigned long jif, bool walkup)
   151	{
   152		struct timerqueue_node *tmr;
   153		struct tmigr_group *parent;
   154		struct tmigr_event *evt;
   155	
   156	again:
   157		raw_spin_lock_irq(&group->lock);
   158		/*
   159		 * Handle the group only if @cpu is the migrator or if the group
   160		 * has no migrator. Otherwise the group is active and is handled by
   161		 * its own migrator.
   162		 */
   163		if (group->migrator != cpu && group->migrator != TMIGR_NONE) {
   164			raw_spin_unlock_irq(&group->lock);
   165			return;
   166		}
   167	
   168		tmr = timerqueue_getnext(&group->events);
   169		if (tmr && now >= tmr->expires) {
   170			/*
   171			 * Remove the expired entry from the queue and handle
   172			 * it. If this is a leaf group, call the timer poll
   173			 * function for the given cpu. Otherwise handle the group
   174			 * itself.  Drop the group lock here in both cases to avoid
   175			 * lock ordering inversions.
   176			 */
   177			evt = container_of(tmr, struct tmigr_event, nextevt);
   178			tmigr_remove_evt(group, evt);
   179	
   180			raw_spin_unlock_irq(&group->lock);
   181	
   182			/*
   183			 * If the event is a group event walk down the hierarchy of
   184			 * that group to the CPU leafs. If not, handle the expired
   185			 * timer from the remote CPU.
   186			 */
   187			if (evt->group) {
   188				__tmigr_handle_remote(evt->group, cpu, now, jif, false);
   189			} else {
 > 190				timer_expire_remote(evt->cpu);
   191				tmigr_update_remote(evt->cpu, now, jif);
   192			}
   193			goto again;
   194		}
   195	
   196		/*
   197		 * If @group is not active, queue the next event in the parent
   198		 * group. This is required, because the next event of @group
   199		 * could have been changed by tmigr_update_remote() above.
   200		 */
   201		parent = group->parent;
   202		if (parent && !group->active) {
   203			raw_spin_lock_nested(&parent->lock, parent->level);
   204			tmigr_add_evt(parent, &group->groupevt);
   205			raw_spin_unlock(&parent->lock);
   206		}
   207		raw_spin_unlock_irq(&group->lock);
   208	
   209		/* Walk the hierarchy up? */
   210		if (!walkup || !parent)
   211			return;
   212	
   213		/* Racy lockless check: See comment in tmigr_handle_remote() */
   214		if (parent->migrator == cpu)
   215			__tmigr_handle_remote(parent, cpu, now, jif, true);
   216	}
   217	
   218	/**
   219	 * tmigr_handle_remote - Handle migratable timers on remote idle CPUs
   220	 *
   221	 * Called from the timer soft interrupt with interrupts enabled.
   222	 */
 > 223	void tmigr_handle_remote(void)
   224	{
   225		struct tmigr_cpu *tmc = this_cpu_ptr(&tmigr_cpu);
   226		int cpu = smp_processor_id();
   227		unsigned long basej;
   228		ktime_t now;
   229	
   230		if (!tmigr_enabled)
   231			return;
   232	
   233		/*
   234		 * Check whether this CPU is responsible for handling the global
   235		 * timers of other CPUs. Do a racy lockless check to avoid lock
   236		 * contention for the busy case where timer soft interrupts happen
   237		 * in parallel. It's not an issue, if the CPU misses a concurrent
   238		 * update of the migrator role for its base group. It's not more
   239		 * racy than doing this check under the lock, if the update happens
   240		 * right after the lock is dropped. There is no damage in such a
   241		 * case other than potentially expiring a global timer one tick
   242		 * late.
   243		 */
   244		if (tmc->tmgroup->migrator != cpu)
   245			return;
   246	
   247		now = get_jiffies_update(&basej);
   248		__tmigr_handle_remote(tmc->tmgroup, cpu, now, basej, true);
   249	}
   250	
   251	/**
   252	 * tmigr_set_cpu_inactive - Set a CPU inactive in the group
   253	 * @group:	The group from which @cpu is removed
   254	 * @child:	The child group which was updated before
   255	 * @evt:	The event to queue in @group
   256	 * @cpu:	The CPU which becomes inactive
   257	 *
   258	 * Remove @cpu from @group and propagate it through the hierarchy if
   259	 * @cpu was the migrator of @group.
   260	 *
   261	 * Returns KTIME_MAX if @cpu is not the last outgoing CPU in the
   262	 * hierarchy. Otherwise it returns the first expiring global event.
   263	 */
   264	static u64 tmigr_set_cpu_inactive(struct tmigr_group *group,
   265					  struct tmigr_group *child,
   266					  struct tmigr_event *evt,
   267					  unsigned int cpu)
   268	{
   269		struct tmigr_group *parent;
   270		u64 nextevt = KTIME_MAX;
   271	
   272		raw_spin_lock_nested(&group->lock, group->level);
   273	
   274		DBG_BUG_ON(!group->active);
   275	
   276		cpumask_clear_cpu(cpu, group->cpus);
   277		group->active--;
   278	
   279		/*
   280		 * If @child is not NULL, then this is a recursive invocation to
   281		 * propagate the deactivation of @cpu. If @child has a new migrator
   282		 * set it active in @group.
   283		 */
   284		if (child && child->migrator != TMIGR_NONE) {
   285			cpumask_set_cpu(child->migrator, group->cpus);
   286			group->active++;
   287		}
   288	
   289		/* Add @evt to @group */
   290		tmigr_add_evt(group, evt);
   291	
   292		/* If @cpu is not the active migrator, everything is up to date */
   293		if (group->migrator != cpu)
   294			goto done;
   295	
   296		/* Update the migrator. */
   297		if (!group->active)
   298			group->migrator = TMIGR_NONE;
   299		else
   300			group->migrator = cpumask_first(group->cpus);
   301	
   302		parent = group->parent;
   303		if (parent) {
   304			/*
   305			 * @cpu was the migrator in @group, so it is marked as
   306			 * active in its parent group(s) as well. Propagate the
   307			 * migrator change.
   308			 */
   309			evt = group->active ? NULL : &group->groupevt;
   310			nextevt = tmigr_set_cpu_inactive(parent, group, evt, cpu);
   311		} else {
   312			/*
   313			 * This is the top level of the hierarchy. If @cpu is about
   314			 * to go offline wake up some random other cpu so it will
   315			 * take over the migrator duty and program its timer
   316			 * proper. Ideally wake the cpu with the closest expiry
   317			 * time, but that's overkill to figure out.
   318			 */
   319			if (!per_cpu(tmigr_cpu, cpu).online) {
   320				cpu = cpumask_any_but(cpu_online_mask, cpu);
   321				smp_send_reschedule(cpu);
   322			}
   323			/*
   324			 * Return the earliest event of the top level group to make
   325			 * sure that its handled.
   326			 *
   327			 * This could be optimized by keeping track of the last
   328			 * global scheduled event and only arming it on @cpu if the
   329			 * new event is earlier. Not sure if its worth the
   330			 * complexity.
   331			 */
   332			nextevt = group->groupevt.nextevt.expires;
   333		}
   334	done:
   335		raw_spin_unlock(&group->lock);
   336		return nextevt;
   337	}
   338	
   339	/**
   340	 * tmigr_cpu_idle - Put current CPU into idle state
   341	 * @nextevt:	The next timer event set in the current CPU
   342	 *
   343	 * Returns either the next event of the current CPU or the next event from
   344	 * the hierarchy if this CPU is the top level migrator.
   345	 *
   346	 * Must be called with interrupts disabled.
   347	 */
 > 348	u64 tmigr_cpu_idle(u64 nextevt)
   349	{
   350		struct tmigr_cpu *tmc = this_cpu_ptr(&tmigr_cpu);
   351		struct tmigr_group *group = tmc->tmgroup;

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

Download attachment ".config.gz" of type "application/gzip" (26520 bytes)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ