aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAkinobu Mita <akinobu.mita@gmail.com>2008-10-13 05:35:05 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-13 12:51:39 -0400
commit9d020a2e5fd2c79f5b08a6cab2b02e7231d7cb84 (patch)
tree2c3d42f2a0fd4617d2e708e91dae6bbc4b4a5c15
parentf1ddfd950221cca4d7ba753a71bc4b8930a42a43 (diff)
ip2: avoid add_timer with pending timer
add_timer() is not supposed to be called when the timer is pending. ip2 driver attempts to avoid that condition by setting and resetting a flag (TimerOn) in timer function. But there is some gap between add_timer() and setting TimerOn. This patch fix this problem by using mod_timer() and remove TimerOn which has been unnecessary by this change. Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> Signed-off-by: Jiri Slaby <jirislaby@gmail.com> Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/char/ip2/ip2main.c19
1 files changed, 4 insertions, 15 deletions
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index 39269d19a02d..66f52a28c40b 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -249,7 +249,6 @@ static unsigned long bh_counter;
249 */ 249 */
250#define POLL_TIMEOUT (jiffies + 1) 250#define POLL_TIMEOUT (jiffies + 1)
251static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0); 251static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0);
252static char TimerOn;
253 252
254#ifdef IP2DEBUG_TRACE 253#ifdef IP2DEBUG_TRACE
255/* Trace (debug) buffer data */ 254/* Trace (debug) buffer data */
@@ -374,11 +373,7 @@ static void __exit ip2_cleanup_module(void)
374 int err; 373 int err;
375 int i; 374 int i;
376 375
377 /* Stop poll timer if we had one. */ 376 del_timer_sync(&PollTimer);
378 if (TimerOn) {
379 del_timer(&PollTimer);
380 TimerOn = 0;
381 }
382 377
383 /* Reset the boards we have. */ 378 /* Reset the boards we have. */
384 for (i = 0; i < IP2_MAX_BOARDS; i++) 379 for (i = 0; i < IP2_MAX_BOARDS; i++)
@@ -774,10 +769,8 @@ static int __init ip2_loadmain(void)
774 } 769 }
775 if (ip2config.irq[i] == CIR_POLL) { 770 if (ip2config.irq[i] == CIR_POLL) {
776retry: 771retry:
777 if (!TimerOn) { 772 if (!timer_pending(&PollTimer)) {
778 PollTimer.expires = POLL_TIMEOUT; 773 mod_timer(&PollTimer, POLL_TIMEOUT);
779 add_timer(&PollTimer);
780 TimerOn = 1;
781 printk(KERN_INFO "IP2: polling\n"); 774 printk(KERN_INFO "IP2: polling\n");
782 } 775 }
783 } else { 776 } else {
@@ -1283,16 +1276,12 @@ ip2_poll(unsigned long arg)
1283{ 1276{
1284 ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 ); 1277 ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 );
1285 1278
1286 TimerOn = 0; // it's the truth but not checked in service
1287
1288 // Just polled boards, IRQ = 0 will hit all non-interrupt boards. 1279 // Just polled boards, IRQ = 0 will hit all non-interrupt boards.
1289 // It will NOT poll boards handled by hard interrupts. 1280 // It will NOT poll boards handled by hard interrupts.
1290 // The issue of queued BH interrupts is handled in ip2_interrupt(). 1281 // The issue of queued BH interrupts is handled in ip2_interrupt().
1291 ip2_polled_interrupt(); 1282 ip2_polled_interrupt();
1292 1283
1293 PollTimer.expires = POLL_TIMEOUT; 1284 mod_timer(&PollTimer, POLL_TIMEOUT);
1294 add_timer( &PollTimer );
1295 TimerOn = 1;
1296 1285
1297 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 ); 1286 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
1298} 1287}