diff options
| -rw-r--r-- | arch/s390/include/asm/timer.h | 1 | ||||
| -rw-r--r-- | arch/s390/kernel/vtime.c | 57 |
2 files changed, 34 insertions, 24 deletions
diff --git a/arch/s390/include/asm/timer.h b/arch/s390/include/asm/timer.h index e4bcab739c19..814243cafdfe 100644 --- a/arch/s390/include/asm/timer.h +++ b/arch/s390/include/asm/timer.h | |||
| @@ -41,6 +41,7 @@ extern void init_virt_timer(struct vtimer_list *timer); | |||
| 41 | extern void add_virt_timer(void *new); | 41 | extern void add_virt_timer(void *new); |
| 42 | extern void add_virt_timer_periodic(void *new); | 42 | extern void add_virt_timer_periodic(void *new); |
| 43 | extern int mod_virt_timer(struct vtimer_list *timer, __u64 expires); | 43 | extern int mod_virt_timer(struct vtimer_list *timer, __u64 expires); |
| 44 | extern int mod_virt_timer_periodic(struct vtimer_list *timer, __u64 expires); | ||
| 44 | extern int del_virt_timer(struct vtimer_list *timer); | 45 | extern int del_virt_timer(struct vtimer_list *timer); |
| 45 | 46 | ||
| 46 | extern void init_cpu_vtimer(void); | 47 | extern void init_cpu_vtimer(void); |
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index ecf0304e61c1..694b44374a2b 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c | |||
| @@ -425,17 +425,7 @@ void add_virt_timer_periodic(void *new) | |||
| 425 | } | 425 | } |
| 426 | EXPORT_SYMBOL(add_virt_timer_periodic); | 426 | EXPORT_SYMBOL(add_virt_timer_periodic); |
| 427 | 427 | ||
| 428 | /* | 428 | int __mod_vtimer(struct vtimer_list *timer, __u64 expires, int periodic) |
| 429 | * If we change a pending timer the function must be called on the CPU | ||
| 430 | * where the timer is running on, e.g. by smp_call_function_single() | ||
| 431 | * | ||
| 432 | * The original mod_timer adds the timer if it is not pending. For | ||
| 433 | * compatibility we do the same. The timer will be added on the current | ||
| 434 | * CPU as a oneshot timer. | ||
| 435 | * | ||
| 436 | * returns whether it has modified a pending timer (1) or not (0) | ||
| 437 | */ | ||
| 438 | int mod_virt_timer(struct vtimer_list *timer, __u64 expires) | ||
| 439 | { | 429 | { |
| 440 | struct vtimer_queue *vq; | 430 | struct vtimer_queue *vq; |
| 441 | unsigned long flags; | 431 | unsigned long flags; |
| @@ -444,39 +434,35 @@ int mod_virt_timer(struct vtimer_list *timer, __u64 expires) | |||
| 444 | BUG_ON(!timer->function); | 434 | BUG_ON(!timer->function); |
| 445 | BUG_ON(!expires || expires > VTIMER_MAX_SLICE); | 435 | BUG_ON(!expires || expires > VTIMER_MAX_SLICE); |
| 446 | 436 | ||
| 447 | /* | ||
| 448 | * This is a common optimization triggered by the | ||
| 449 | * networking code - if the timer is re-modified | ||
| 450 | * to be the same thing then just return: | ||
| 451 | */ | ||
| 452 | if (timer->expires == expires && vtimer_pending(timer)) | 437 | if (timer->expires == expires && vtimer_pending(timer)) |
| 453 | return 1; | 438 | return 1; |
| 454 | 439 | ||
| 455 | cpu = get_cpu(); | 440 | cpu = get_cpu(); |
| 456 | vq = &per_cpu(virt_cpu_timer, cpu); | 441 | vq = &per_cpu(virt_cpu_timer, cpu); |
| 457 | 442 | ||
| 458 | /* check if we run on the right CPU */ | ||
| 459 | BUG_ON(timer->cpu != cpu); | ||
| 460 | |||
| 461 | /* disable interrupts before test if timer is pending */ | 443 | /* disable interrupts before test if timer is pending */ |
| 462 | spin_lock_irqsave(&vq->lock, flags); | 444 | spin_lock_irqsave(&vq->lock, flags); |
| 463 | 445 | ||
| 464 | /* if timer isn't pending add it on the current CPU */ | 446 | /* if timer isn't pending add it on the current CPU */ |
| 465 | if (!vtimer_pending(timer)) { | 447 | if (!vtimer_pending(timer)) { |
| 466 | spin_unlock_irqrestore(&vq->lock, flags); | 448 | spin_unlock_irqrestore(&vq->lock, flags); |
| 467 | /* we do not activate an interval timer with mod_virt_timer */ | 449 | |
| 468 | timer->interval = 0; | 450 | if (periodic) |
| 451 | timer->interval = expires; | ||
| 452 | else | ||
| 453 | timer->interval = 0; | ||
| 469 | timer->expires = expires; | 454 | timer->expires = expires; |
| 470 | timer->cpu = cpu; | 455 | timer->cpu = cpu; |
| 471 | internal_add_vtimer(timer); | 456 | internal_add_vtimer(timer); |
| 472 | return 0; | 457 | return 0; |
| 473 | } | 458 | } |
| 474 | 459 | ||
| 460 | /* check if we run on the right CPU */ | ||
| 461 | BUG_ON(timer->cpu != cpu); | ||
| 462 | |||
| 475 | list_del_init(&timer->entry); | 463 | list_del_init(&timer->entry); |
| 476 | timer->expires = expires; | 464 | timer->expires = expires; |
| 477 | 465 | if (periodic) | |
| 478 | /* also change the interval if we have an interval timer */ | ||
| 479 | if (timer->interval) | ||
| 480 | timer->interval = expires; | 466 | timer->interval = expires; |
| 481 | 467 | ||
| 482 | /* the timer can't expire anymore so we can release the lock */ | 468 | /* the timer can't expire anymore so we can release the lock */ |
| @@ -484,9 +470,32 @@ int mod_virt_timer(struct vtimer_list *timer, __u64 expires) | |||
| 484 | internal_add_vtimer(timer); | 470 | internal_add_vtimer(timer); |
| 485 | return 1; | 471 | return 1; |
| 486 | } | 472 | } |
| 473 | |||
| 474 | /* | ||
| 475 | * If we change a pending timer the function must be called on the CPU | ||
| 476 | * where the timer is running on. | ||
| 477 | * | ||
| 478 | * returns whether it has modified a pending timer (1) or not (0) | ||
| 479 | */ | ||
| 480 | int mod_virt_timer(struct vtimer_list *timer, __u64 expires) | ||
| 481 | { | ||
| 482 | return __mod_vtimer(timer, expires, 0); | ||
| 483 | } | ||
| 487 | EXPORT_SYMBOL(mod_virt_timer); | 484 | EXPORT_SYMBOL(mod_virt_timer); |
| 488 | 485 | ||
| 489 | /* | 486 | /* |
| 487 | * If we change a pending timer the function must be called on the CPU | ||
| 488 | * where the timer is running on. | ||
| 489 | * | ||
| 490 | * returns whether it has modified a pending timer (1) or not (0) | ||
| 491 | */ | ||
| 492 | int mod_virt_timer_periodic(struct vtimer_list *timer, __u64 expires) | ||
| 493 | { | ||
| 494 | return __mod_vtimer(timer, expires, 1); | ||
| 495 | } | ||
| 496 | EXPORT_SYMBOL(mod_virt_timer_periodic); | ||
| 497 | |||
| 498 | /* | ||
| 490 | * delete a virtual timer | 499 | * delete a virtual timer |
| 491 | * | 500 | * |
| 492 | * returns whether the deleted timer was pending (1) or not (0) | 501 | * returns whether the deleted timer was pending (1) or not (0) |
