cregit-Linux how code gets into the kernel

Release 4.7 drivers/staging/lustre/lnet/selftest/timer.c

/*
 * GPL HEADER START
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 only,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License version 2 for more details (a copy is included
 * in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU General Public License
 * version 2 along with this program; If not, see
 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 *
 * GPL HEADER END
 */
/*
 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
 * Use is subject to license terms.
 *
 * Copyright (c) 2011, 2012, Intel Corporation.
 */
/*
 * This file is part of Lustre, http://www.lustre.org/
 * Lustre is a trademark of Sun Microsystems, Inc.
 *
 * lnet/selftest/timer.c
 *
 * Author: Isaac Huang <isaac@clusterfs.com>
 */


#define DEBUG_SUBSYSTEM S_LNET

#include "selftest.h"

/*
 * Timers are implemented as a sorted queue of expiry times. The queue
 * is slotted, with each slot holding timers which expire in a
 * 2**STTIMER_MINPOLL (8) second period. The timers in each slot are
 * sorted by increasing expiry time. The number of slots is 2**7 (128),
 * to cover a time period of 1024 seconds into the future before wrapping.
 */

#define STTIMER_MINPOLL        3	
/* log2 min poll interval (8 s) */

#define STTIMER_SLOTTIME       (1 << STTIMER_MINPOLL)

#define STTIMER_SLOTTIMEMASK   (~(STTIMER_SLOTTIME - 1))

#define STTIMER_NSLOTS	       (1 << 7)

#define STTIMER_SLOT(t)	       (&stt_data.stt_hash[(((t) >> STTIMER_MINPOLL) & \
                                                    (STTIMER_NSLOTS - 1))])


static struct st_timer_data {
	
spinlock_t	  stt_lock;
	
unsigned long	  stt_prev_slot; /* start time of the slot processed
                                          * previously */
	
struct list_head  stt_hash[STTIMER_NSLOTS];
	
int		  stt_shuttingdown;
	
wait_queue_head_t stt_waitq;
	
int		  stt_nthreads;
} 
stt_data;


void stt_add_timer(struct stt_timer *timer) { struct list_head *pos; spin_lock(&stt_data.stt_lock); LASSERT(stt_data.stt_nthreads > 0); LASSERT(!stt_data.stt_shuttingdown); LASSERT(timer->stt_func); LASSERT(list_empty(&timer->stt_list)); LASSERT(timer->stt_expires > ktime_get_real_seconds()); /* a simple insertion sort */ list_for_each_prev(pos, STTIMER_SLOT(timer->stt_expires)) { struct stt_timer *old = list_entry(pos, struct stt_timer, stt_list); if (timer->stt_expires >= old->stt_expires) break; } list_add(&timer->stt_list, pos); spin_unlock(&stt_data.stt_lock); }

Contributors

PersonTokensPropCommitsCommitProp
peng taopeng tao11292.56%133.33%
bhumika goyalbhumika goyal64.96%133.33%
arnd bergmannarnd bergmann32.48%133.33%
Total121100.00%3100.00%

/* * 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.) * * CAVEAT EMPTOR: * When 0 is returned, it is possible that timer->stt_func _is_ running on * another CPU. */
int stt_del_timer(struct stt_timer *timer) { int ret = 0; spin_lock(&stt_data.stt_lock); LASSERT(stt_data.stt_nthreads > 0); LASSERT(!stt_data.stt_shuttingdown); if (!list_empty(&timer->stt_list)) { ret = 1; list_del_init(&timer->stt_list); } spin_unlock(&stt_data.stt_lock); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
peng taopeng tao7497.37%150.00%
bhumika goyalbhumika goyal22.63%150.00%
Total76100.00%2100.00%

/* called with stt_data.stt_lock held */
static int stt_expire_list(struct list_head *slot, time64_t now) { int expired = 0; struct stt_timer *timer; while (!list_empty(slot)) { timer = list_entry(slot->next, struct stt_timer, stt_list); if (timer->stt_expires > now) break; list_del_init(&timer->stt_list); spin_unlock(&stt_data.stt_lock); expired++; (*timer->stt_func) (timer->stt_data); spin_lock(&stt_data.stt_lock); } return expired; }

Contributors

PersonTokensPropCommitsCommitProp
peng taopeng tao9292.93%125.00%
bhumika goyalbhumika goyal44.04%125.00%
arnd bergmannarnd bergmann22.02%125.00%
anton saraevanton saraev11.01%125.00%
Total99100.00%4100.00%


static int stt_check_timers(unsigned long *last) { int expired = 0; time64_t now; unsigned long this_slot; now = ktime_get_real_seconds(); this_slot = now & STTIMER_SLOTTIMEMASK; spin_lock(&stt_data.stt_lock); while (cfs_time_aftereq(this_slot, *last)) { expired += stt_expire_list(STTIMER_SLOT(this_slot), now); this_slot = cfs_time_sub(this_slot, STTIMER_SLOTTIME); } *last = now & STTIMER_SLOTTIMEMASK; spin_unlock(&stt_data.stt_lock); return expired; }

Contributors

PersonTokensPropCommitsCommitProp
peng taopeng tao8692.47%125.00%
greg kroah-hartmangreg kroah-hartman44.30%125.00%
arnd bergmannarnd bergmann22.15%125.00%
anton saraevanton saraev11.08%125.00%
Total93100.00%4100.00%


static int stt_timer_main(void *arg) { int rc = 0; cfs_block_allsigs(); while (!stt_data.stt_shuttingdown) { stt_check_timers(&stt_data.stt_prev_slot); rc = wait_event_timeout(stt_data.stt_waitq, stt_data.stt_shuttingdown, cfs_time_seconds(STTIMER_SLOTTIME)); } spin_lock(&stt_data.stt_lock); stt_data.stt_nthreads--; spin_unlock(&stt_data.stt_lock); return rc; }

Contributors

PersonTokensPropCommitsCommitProp
peng taopeng tao6888.31%133.33%
james simmonsjames simmons810.39%133.33%
anton saraevanton saraev11.30%133.33%
Total77100.00%3100.00%


static int stt_start_timer_thread(void) { struct task_struct *task; LASSERT(!stt_data.stt_shuttingdown); task = kthread_run(stt_timer_main, NULL, "st_timer"); if (IS_ERR(task)) return PTR_ERR(task); spin_lock(&stt_data.stt_lock); stt_data.stt_nthreads++; spin_unlock(&stt_data.stt_lock); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
peng taopeng tao6695.65%133.33%
greg kroah-hartmangreg kroah-hartman22.90%133.33%
anton saraevanton saraev11.45%133.33%
Total69100.00%3100.00%


int stt_startup(void) { int rc = 0; int i; stt_data.stt_shuttingdown = 0; stt_data.stt_prev_slot = ktime_get_real_seconds() & STTIMER_SLOTTIMEMASK; spin_lock_init(&stt_data.stt_lock); for (i = 0; i < STTIMER_NSLOTS; i++) INIT_LIST_HEAD(&stt_data.stt_hash[i]); stt_data.stt_nthreads = 0; init_waitqueue_head(&stt_data.stt_waitq); rc = stt_start_timer_thread(); if (rc) CERROR("Can't spawn timer thread: %d\n", rc); return rc; }

Contributors

PersonTokensPropCommitsCommitProp
peng taopeng tao9498.95%150.00%
arnd bergmannarnd bergmann11.05%150.00%
Total95100.00%2100.00%


void stt_shutdown(void) { int i; spin_lock(&stt_data.stt_lock); for (i = 0; i < STTIMER_NSLOTS; i++) LASSERT(list_empty(&stt_data.stt_hash[i])); stt_data.stt_shuttingdown = 1; wake_up(&stt_data.stt_waitq); lst_wait_until(!stt_data.stt_nthreads, stt_data.stt_lock, "waiting for %d threads to terminate\n", stt_data.stt_nthreads); spin_unlock(&stt_data.stt_lock); }

Contributors

PersonTokensPropCommitsCommitProp
peng taopeng tao8498.82%150.00%
james simmonsjames simmons11.18%150.00%
Total85100.00%2100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
peng taopeng tao74094.51%110.00%
bhumika goyalbhumika goyal121.53%110.00%
james simmonsjames simmons91.15%220.00%
greg kroah-hartmangreg kroah-hartman81.02%220.00%
arnd bergmannarnd bergmann81.02%110.00%
anton saraevanton saraev40.51%110.00%
jeremiah mahlerjeremiah mahler10.13%110.00%
mike shueymike shuey10.13%110.00%
Total783100.00%10100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}