cregit-Linux how code gets into the kernel

Release 4.11 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.gnu.org/licenses/gpl-2.0.html
 *
 * 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	BIT(STTIMER_MINPOLL)

#define STTIMER_SLOTTIMEMASK   (~(STTIMER_SLOTTIME - 1))

#define STTIMER_NSLOTS		BIT(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 Tao11292.56%133.33%
Bhumika Goyal64.96%133.33%
Arnd 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 Tao7497.37%150.00%
Bhumika 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 Tao9292.93%125.00%
Bhumika Goyal44.04%125.00%
Arnd Bergmann22.02%125.00%
Anton 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 Tao8692.47%125.00%
Greg Kroah-Hartman44.30%125.00%
Arnd Bergmann22.15%125.00%
Anton 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 Tao6888.31%133.33%
James Simmons810.39%133.33%
Anton 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 Tao6695.65%133.33%
Greg Kroah-Hartman22.90%133.33%
Anton 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 Tao9498.95%150.00%
Arnd 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 Tao8498.82%150.00%
James Simmons11.18%150.00%
Total85100.00%2100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Peng Tao73794.13%18.33%
James Simmons121.53%433.33%
Bhumika Goyal121.53%18.33%
Arnd Bergmann81.02%18.33%
Greg Kroah-Hartman81.02%216.67%
Anton Saraev40.51%18.33%
Jeremiah Mahler10.13%18.33%
Oleg Drokin10.13%18.33%
Total783100.00%12100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.