Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.17-rc5 203 lines 4.6 kB view raw
1/* krxtimod.c: RXRPC timeout daemon 2 * 3 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 */ 11 12#include <linux/module.h> 13#include <linux/init.h> 14#include <linux/sched.h> 15#include <linux/completion.h> 16#include <rxrpc/rxrpc.h> 17#include <rxrpc/krxtimod.h> 18#include <asm/errno.h> 19#include "internal.h" 20 21static DECLARE_COMPLETION(krxtimod_alive); 22static DECLARE_COMPLETION(krxtimod_dead); 23static DECLARE_WAIT_QUEUE_HEAD(krxtimod_sleepq); 24static int krxtimod_die; 25 26static LIST_HEAD(krxtimod_list); 27static DEFINE_SPINLOCK(krxtimod_lock); 28 29static int krxtimod(void *arg); 30 31/*****************************************************************************/ 32/* 33 * start the timeout daemon 34 */ 35int rxrpc_krxtimod_start(void) 36{ 37 int ret; 38 39 ret = kernel_thread(krxtimod, NULL, 0); 40 if (ret < 0) 41 return ret; 42 43 wait_for_completion(&krxtimod_alive); 44 45 return ret; 46} /* end rxrpc_krxtimod_start() */ 47 48/*****************************************************************************/ 49/* 50 * stop the timeout daemon 51 */ 52void rxrpc_krxtimod_kill(void) 53{ 54 /* get rid of my daemon */ 55 krxtimod_die = 1; 56 wake_up(&krxtimod_sleepq); 57 wait_for_completion(&krxtimod_dead); 58 59} /* end rxrpc_krxtimod_kill() */ 60 61/*****************************************************************************/ 62/* 63 * timeout processing daemon 64 */ 65static int krxtimod(void *arg) 66{ 67 DECLARE_WAITQUEUE(myself, current); 68 69 rxrpc_timer_t *timer; 70 71 printk("Started krxtimod %d\n", current->pid); 72 73 daemonize("krxtimod"); 74 75 complete(&krxtimod_alive); 76 77 /* loop around looking for things to attend to */ 78 loop: 79 set_current_state(TASK_INTERRUPTIBLE); 80 add_wait_queue(&krxtimod_sleepq, &myself); 81 82 for (;;) { 83 unsigned long jif; 84 long timeout; 85 86 /* deal with the server being asked to die */ 87 if (krxtimod_die) { 88 remove_wait_queue(&krxtimod_sleepq, &myself); 89 _leave(""); 90 complete_and_exit(&krxtimod_dead, 0); 91 } 92 93 try_to_freeze(); 94 95 /* discard pending signals */ 96 rxrpc_discard_my_signals(); 97 98 /* work out the time to elapse before the next event */ 99 spin_lock(&krxtimod_lock); 100 if (list_empty(&krxtimod_list)) { 101 timeout = MAX_SCHEDULE_TIMEOUT; 102 } 103 else { 104 timer = list_entry(krxtimod_list.next, 105 rxrpc_timer_t, link); 106 timeout = timer->timo_jif; 107 jif = jiffies; 108 109 if (time_before_eq((unsigned long) timeout, jif)) 110 goto immediate; 111 112 else { 113 timeout = (long) timeout - (long) jiffies; 114 } 115 } 116 spin_unlock(&krxtimod_lock); 117 118 schedule_timeout(timeout); 119 120 set_current_state(TASK_INTERRUPTIBLE); 121 } 122 123 /* the thing on the front of the queue needs processing 124 * - we come here with the lock held and timer pointing to the expired 125 * entry 126 */ 127 immediate: 128 remove_wait_queue(&krxtimod_sleepq, &myself); 129 set_current_state(TASK_RUNNING); 130 131 _debug("@@@ Begin Timeout of %p", timer); 132 133 /* dequeue the timer */ 134 list_del_init(&timer->link); 135 spin_unlock(&krxtimod_lock); 136 137 /* call the timeout function */ 138 timer->ops->timed_out(timer); 139 140 _debug("@@@ End Timeout"); 141 goto loop; 142 143} /* end krxtimod() */ 144 145/*****************************************************************************/ 146/* 147 * (re-)queue a timer 148 */ 149void rxrpc_krxtimod_add_timer(rxrpc_timer_t *timer, unsigned long timeout) 150{ 151 struct list_head *_p; 152 rxrpc_timer_t *ptimer; 153 154 _enter("%p,%lu", timer, timeout); 155 156 spin_lock(&krxtimod_lock); 157 158 list_del(&timer->link); 159 160 /* the timer was deferred or reset - put it back in the queue at the 161 * right place */ 162 timer->timo_jif = jiffies + timeout; 163 164 list_for_each(_p, &krxtimod_list) { 165 ptimer = list_entry(_p, rxrpc_timer_t, link); 166 if (time_before(timer->timo_jif, ptimer->timo_jif)) 167 break; 168 } 169 170 list_add_tail(&timer->link, _p); /* insert before stopping point */ 171 172 spin_unlock(&krxtimod_lock); 173 174 wake_up(&krxtimod_sleepq); 175 176 _leave(""); 177} /* end rxrpc_krxtimod_add_timer() */ 178 179/*****************************************************************************/ 180/* 181 * dequeue a timer 182 * - returns 0 if the timer was deleted or -ENOENT if it wasn't queued 183 */ 184int rxrpc_krxtimod_del_timer(rxrpc_timer_t *timer) 185{ 186 int ret = 0; 187 188 _enter("%p", timer); 189 190 spin_lock(&krxtimod_lock); 191 192 if (list_empty(&timer->link)) 193 ret = -ENOENT; 194 else 195 list_del_init(&timer->link); 196 197 spin_unlock(&krxtimod_lock); 198 199 wake_up(&krxtimod_sleepq); 200 201 _leave(" = %d", ret); 202 return ret; 203} /* end rxrpc_krxtimod_del_timer() */