1 /* 2 * arch/s390/kernel/vtime.c 3 * Virtual cpu timer based timer functions. 4 * 5 * S390 version 6 * Copyright (C) 2004 IBM Deutschland Entwicklung GmbH, IBM Corporation 7 * Author(s): Jan Glauber <jan.glauber@de.ibm.com> 8 */ 9 10 #include <linux/module.h> 11 #include <linux/kernel.h> 12 #include <linux/time.h> 13 #include <linux/delay.h> 14 #include <linux/init.h> 15 #include <linux/smp.h> 16 #include <linux/types.h> 17 #include <linux/timex.h> 18 #include <linux/notifier.h> 19 #include <linux/kernel_stat.h> 20 #include <linux/rcupdate.h> 21 #include <linux/posix-timers.h> 22 23 #include <asm/s390_ext.h> 24 #include <asm/timer.h> 25 26 static ext_int_info_t ext_int_info_timer; 27 DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer); 28 29 #ifdef CONFIG_VIRT_CPU_ACCOUNTING 30 /* 31 * Update process times based on virtual cpu times stored by entry.S 32 * to the lowcore fields user_timer, system_timer & steal_clock. 33 */ 34 void account_tick_vtime(struct task_struct *tsk) 35 { 36 cputime_t cputime; 37 __u64 timer, clock; 38 int rcu_user_flag; 39 40 timer = S390_lowcore.last_update_timer; 41 clock = S390_lowcore.last_update_clock; 42 asm volatile (" STPT %0\n" /* Store current cpu timer value */ 43 " STCK %1" /* Store current tod clock value */ 44 : "=m" (S390_lowcore.last_update_timer), 45 "=m" (S390_lowcore.last_update_clock) ); 46 S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer; 47 S390_lowcore.steal_clock += S390_lowcore.last_update_clock - clock; 48 49 cputime = S390_lowcore.user_timer >> 12; 50 rcu_user_flag = cputime != 0; 51 S390_lowcore.user_timer -= cputime << 12; 52 S390_lowcore.steal_clock -= cputime << 12; 53 account_user_time(tsk, cputime); 54 55 cputime = S390_lowcore.system_timer >> 12; 56 S390_lowcore.system_timer -= cputime << 12; 57 S390_lowcore.steal_clock -= cputime << 12; 58 account_system_time(tsk, HARDIRQ_OFFSET, cputime); 59 60 cputime = S390_lowcore.steal_clock; 61 if ((__s64) cputime > 0) { 62 cputime >>= 12; 63 S390_lowcore.steal_clock -= cputime << 12; 64 account_steal_time(tsk, cputime); 65 } 66 67 run_local_timers(); 68 if (rcu_pending(smp_processor_id())) 69 rcu_check_callbacks(smp_processor_id(), rcu_user_flag); 70 scheduler_tick(); 71 run_posix_cpu_timers(tsk); 72 } 73 74 /* 75 * Update process times based on virtual cpu times stored by entry.S 76 * to the lowcore fields user_timer, system_timer & steal_clock. 77 */ 78 void account_vtime(struct task_struct *tsk) 79 { 80 cputime_t cputime; 81 __u64 timer; 82 83 timer = S390_lowcore.last_update_timer; 84 asm volatile (" STPT %0" /* Store current cpu timer value */ 85 : "=m" (S390_lowcore.last_update_timer) ); 86 S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer; 87 88 cputime = S390_lowcore.user_timer >> 12; 89 S390_lowcore.user_timer -= cputime << 12; 90 S390_lowcore.steal_clock -= cputime << 12; 91 account_user_time(tsk, cputime); 92 93 cputime = S390_lowcore.system_timer >> 12; 94 S390_lowcore.system_timer -= cputime << 12; 95 S390_lowcore.steal_clock -= cputime << 12; 96 account_system_time(tsk, 0, cputime); 97 } 98 99 /* 100 * Update process times based on virtual cpu times stored by entry.S 101 * to the lowcore fields user_timer, system_timer & steal_clock. 102 */ 103 void account_system_vtime(struct task_struct *tsk) 104 { 105 cputime_t cputime; 106 __u64 timer; 107 108 timer = S390_lowcore.last_update_timer; 109 asm volatile (" STPT %0" /* Store current cpu timer value */ 110 : "=m" (S390_lowcore.last_update_timer) ); 111 S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer; 112 113 cputime = S390_lowcore.system_timer >> 12; 114 S390_lowcore.system_timer -= cputime << 12; 115 S390_lowcore.steal_clock -= cputime << 12; 116 account_system_time(tsk, 0, cputime); 117 } 118 119 static inline void set_vtimer(__u64 expires) 120 { 121 __u64 timer; 122 123 asm volatile (" STPT %0\n" /* Store current cpu timer value */ 124 " SPT %1" /* Set new value immediatly afterwards */ 125 : "=m" (timer) : "m" (expires) ); 126 S390_lowcore.system_timer += S390_lowcore.last_update_timer - timer; 127 S390_lowcore.last_update_timer = expires; 128 129 /* store expire time for this CPU timer */ 130 per_cpu(virt_cpu_timer, smp_processor_id()).to_expire = expires; 131 } 132 #else 133 static inline void set_vtimer(__u64 expires) 134 { 135 S390_lowcore.last_update_timer = expires; 136 asm volatile ("SPT %0" : : "m" (S390_lowcore.last_update_timer)); 137 138 /* store expire time for this CPU timer */ 139 per_cpu(virt_cpu_timer, smp_processor_id()).to_expire = expires; 140 } 141 #endif 142 143 static void start_cpu_timer(void) 144 { 145 struct vtimer_queue *vt_list; 146 147 vt_list = &per_cpu(virt_cpu_timer, smp_processor_id()); 148 149 /* CPU timer interrupt is pending, don't reprogramm it */ 150 if (vt_list->idle & 1LL<<63) 151 return; 152 153 if (!list_empty(&vt_list->list)) 154 set_vtimer(vt_list->idle); 155 } 156 157 static void stop_cpu_timer(void) 158 { 159 struct vtimer_queue *vt_list; 160 161 vt_list = &per_cpu(virt_cpu_timer, smp_processor_id()); 162 163 /* nothing to do */ 164 if (list_empty(&vt_list->list)) { 165 vt_list->idle = VTIMER_MAX_SLICE; 166 goto fire; 167 } 168 169 /* store the actual expire value */ 170 asm volatile ("STPT %0" : "=m" (vt_list->idle)); 171 172 /* 173 * If the CPU timer is negative we don't reprogramm 174 * it because we will get instantly an interrupt. 175 */ 176 if (vt_list->idle & 1LL<<63) 177 return; 178 179 vt_list->offset += vt_list->to_expire - vt_list->idle; 180 181 /* 182 * We cannot halt the CPU timer, we just write a value that 183 * nearly never expires (only after 71 years) and re-write 184 * the stored expire value if we continue the timer 185 */ 186 fire: 187 set_vtimer(VTIMER_MAX_SLICE); 188 } 189 190 /* 191 * Sorted add to a list. List is linear searched until first bigger 192 * element is found. 193 */ 194 static void list_add_sorted(struct vtimer_list *timer, struct list_head *head) 195 { 196 struct vtimer_list *event; 197 198 list_for_each_entry(event, head, entry) { 199 if (event->expires > timer->expires) { 200 list_add_tail(&timer->entry, &event->entry); 201 return; 202 } 203 } 204 list_add_tail(&timer->entry, head); 205 } 206 207 /* 208 * Do the callback functions of expired vtimer events. 209 * Called from within the interrupt handler. 210 */ 211 static void do_callbacks(struct list_head *cb_list, struct pt_regs *regs) 212 { 213 struct vtimer_queue *vt_list; 214 struct vtimer_list *event, *tmp; 215 void (*fn)(unsigned long, struct pt_regs*); 216 unsigned long data; 217 218 if (list_empty(cb_list)) 219 return; 220 221 vt_list = &per_cpu(virt_cpu_timer, smp_processor_id()); 222 223 list_for_each_entry_safe(event, tmp, cb_list, entry) { 224 fn = event->function; 225 data = event->data; 226 fn(data, regs); 227 228 if (!event->interval) 229 /* delete one shot timer */ 230 list_del_init(&event->entry); 231 else { 232 /* move interval timer back to list */ 233 spin_lock(&vt_list->lock); 234 list_del_init(&event->entry); 235 list_add_sorted(event, &vt_list->list); 236 spin_unlock(&vt_list->lock); 237 } 238 } 239 } 240 241 /* 242 * Handler for the virtual CPU timer. 243 */ 244 static void do_cpu_timer_interrupt(struct pt_regs *regs, __u16 error_code) 245 { 246 int cpu; 247 __u64 next, delta; 248 struct vtimer_queue *vt_list; 249 struct vtimer_list *event, *tmp; 250 struct list_head *ptr; 251 /* the callback queue */ 252 struct list_head cb_list; 253 254 INIT_LIST_HEAD(&cb_list); 255 cpu = smp_processor_id(); 256 vt_list = &per_cpu(virt_cpu_timer, cpu); 257 258 /* walk timer list, fire all expired events */ 259 spin_lock(&vt_list->lock); 260 261 if (vt_list->to_expire < VTIMER_MAX_SLICE) 262 vt_list->offset += vt_list->to_expire; 263 264 list_for_each_entry_safe(event, tmp, &vt_list->list, entry) { 265 if (event->expires > vt_list->offset) 266 /* found first unexpired event, leave */ 267 break; 268 269 /* re-charge interval timer, we have to add the offset */ 270 if (event->interval) 271 event->expires = event->interval + vt_list->offset; 272 273 /* move expired timer to the callback queue */ 274 list_move_tail(&event->entry, &cb_list); 275 } 276 spin_unlock(&vt_list->lock); 277 do_callbacks(&cb_list, regs); 278 279 /* next event is first in list */ 280 spin_lock(&vt_list->lock); 281 if (!list_empty(&vt_list->list)) { 282 ptr = vt_list->list.next; 283 event = list_entry(ptr, struct vtimer_list, entry); 284 next = event->expires - vt_list->offset; 285 286 /* add the expired time from this interrupt handler 287 * and the callback functions 288 */ 289 asm volatile ("STPT %0" : "=m" (delta)); 290 delta = 0xffffffffffffffffLL - delta + 1; 291 vt_list->offset += delta; 292 next -= delta; 293 } else { 294 vt_list->offset = 0; 295 next = VTIMER_MAX_SLICE; 296 } 297 spin_unlock(&vt_list->lock); 298 set_vtimer(next); 299 } 300 301 void init_virt_timer(struct vtimer_list *timer) 302 { 303 timer->function = NULL; 304 INIT_LIST_HEAD(&timer->entry); 305 spin_lock_init(&timer->lock); 306 } 307 EXPORT_SYMBOL(init_virt_timer); 308 309 static inline int vtimer_pending(struct vtimer_list *timer) 310 { 311 return (!list_empty(&timer->entry)); 312 } 313 314 /* 315 * this function should only run on the specified CPU 316 */ 317 static void internal_add_vtimer(struct vtimer_list *timer) 318 { 319 unsigned long flags; 320 __u64 done; 321 struct vtimer_list *event; 322 struct vtimer_queue *vt_list; 323 324 vt_list = &per_cpu(virt_cpu_timer, timer->cpu); 325 spin_lock_irqsave(&vt_list->lock, flags); 326 327 if (timer->cpu != smp_processor_id()) 328 printk("internal_add_vtimer: BUG, running on wrong CPU"); 329 330 /* if list is empty we only have to set the timer */ 331 if (list_empty(&vt_list->list)) { 332 /* reset the offset, this may happen if the last timer was 333 * just deleted by mod_virt_timer and the interrupt 334 * didn't happen until here 335 */ 336 vt_list->offset = 0; 337 goto fire; 338 } 339 340 /* save progress */ 341 asm volatile ("STPT %0" : "=m" (done)); 342 343 /* calculate completed work */ 344 done = vt_list->to_expire - done + vt_list->offset; 345 vt_list->offset = 0; 346 347 list_for_each_entry(event, &vt_list->list, entry) 348 event->expires -= done; 349 350 fire: 351 list_add_sorted(timer, &vt_list->list); 352 353 /* get first element, which is the next vtimer slice */ 354 event = list_entry(vt_list->list.next, struct vtimer_list, entry); 355 356 set_vtimer(event->expires); 357 spin_unlock_irqrestore(&vt_list->lock, flags); 358 /* release CPU acquired in prepare_vtimer or mod_virt_timer() */ 359 put_cpu(); 360 } 361 362 static inline int prepare_vtimer(struct vtimer_list *timer) 363 { 364 if (!timer->function) { 365 printk("add_virt_timer: uninitialized timer\n"); 366 return -EINVAL; 367 } 368 369 if (!timer->expires || timer->expires > VTIMER_MAX_SLICE) { 370 printk("add_virt_timer: invalid timer expire value!\n"); 371 return -EINVAL; 372 } 373 374 if (vtimer_pending(timer)) { 375 printk("add_virt_timer: timer pending\n"); 376 return -EBUSY; 377 } 378 379 timer->cpu = get_cpu(); 380 return 0; 381 } 382 383 /* 384 * add_virt_timer - add an oneshot virtual CPU timer 385 */ 386 void add_virt_timer(void *new) 387 { 388 struct vtimer_list *timer; 389 390 timer = (struct vtimer_list *)new; 391 392 if (prepare_vtimer(timer) < 0) 393 return; 394 395 timer->interval = 0; 396 internal_add_vtimer(timer); 397 } 398 EXPORT_SYMBOL(add_virt_timer); 399 400 /* 401 * add_virt_timer_int - add an interval virtual CPU timer 402 */ 403 void add_virt_timer_periodic(void *new) 404 { 405 struct vtimer_list *timer; 406 407 timer = (struct vtimer_list *)new; 408 409 if (prepare_vtimer(timer) < 0) 410 return; 411 412 timer->interval = timer->expires; 413 internal_add_vtimer(timer); 414 } 415 EXPORT_SYMBOL(add_virt_timer_periodic); 416 417 /* 418 * If we change a pending timer the function must be called on the CPU 419 * where the timer is running on, e.g. by smp_call_function_on() 420 * 421 * The original mod_timer adds the timer if it is not pending. For compatibility 422 * we do the same. The timer will be added on the current CPU as a oneshot timer. 423 * 424 * returns whether it has modified a pending timer (1) or not (0) 425 */ 426 int mod_virt_timer(struct vtimer_list *timer, __u64 expires) 427 { 428 struct vtimer_queue *vt_list; 429 unsigned long flags; 430 int cpu; 431 432 if (!timer->function) { 433 printk("mod_virt_timer: uninitialized timer\n"); 434 return -EINVAL; 435 } 436 437 if (!expires || expires > VTIMER_MAX_SLICE) { 438 printk("mod_virt_timer: invalid expire range\n"); 439 return -EINVAL; 440 } 441 442 /* 443 * This is a common optimization triggered by the 444 * networking code - if the timer is re-modified 445 * to be the same thing then just return: 446 */ 447 if (timer->expires == expires && vtimer_pending(timer)) 448 return 1; 449 450 cpu = get_cpu(); 451 vt_list = &per_cpu(virt_cpu_timer, cpu); 452 453 /* disable interrupts before test if timer is pending */ 454 spin_lock_irqsave(&vt_list->lock, flags); 455 456 /* if timer isn't pending add it on the current CPU */ 457 if (!vtimer_pending(timer)) { 458 spin_unlock_irqrestore(&vt_list->lock, flags); 459 /* we do not activate an interval timer with mod_virt_timer */ 460 timer->interval = 0; 461 timer->expires = expires; 462 timer->cpu = cpu; 463 internal_add_vtimer(timer); 464 return 0; 465 } 466 467 /* check if we run on the right CPU */ 468 if (timer->cpu != cpu) { 469 printk("mod_virt_timer: running on wrong CPU, check your code\n"); 470 spin_unlock_irqrestore(&vt_list->lock, flags); 471 put_cpu(); 472 return -EINVAL; 473 } 474 475 list_del_init(&timer->entry); 476 timer->expires = expires; 477 478 /* also change the interval if we have an interval timer */ 479 if (timer->interval) 480 timer->interval = expires; 481 482 /* the timer can't expire anymore so we can release the lock */ 483 spin_unlock_irqrestore(&vt_list->lock, flags); 484 internal_add_vtimer(timer); 485 return 1; 486 } 487 EXPORT_SYMBOL(mod_virt_timer); 488 489 /* 490 * delete a virtual timer 491 * 492 * returns whether the deleted timer was pending (1) or not (0) 493 */ 494 int del_virt_timer(struct vtimer_list *timer) 495 { 496 unsigned long flags; 497 struct vtimer_queue *vt_list; 498 499 /* check if timer is pending */ 500 if (!vtimer_pending(timer)) 501 return 0; 502 503 vt_list = &per_cpu(virt_cpu_timer, timer->cpu); 504 spin_lock_irqsave(&vt_list->lock, flags); 505 506 /* we don't interrupt a running timer, just let it expire! */ 507 list_del_init(&timer->entry); 508 509 /* last timer removed */ 510 if (list_empty(&vt_list->list)) { 511 vt_list->to_expire = 0; 512 vt_list->offset = 0; 513 } 514 515 spin_unlock_irqrestore(&vt_list->lock, flags); 516 return 1; 517 } 518 EXPORT_SYMBOL(del_virt_timer); 519 520 /* 521 * Start the virtual CPU timer on the current CPU. 522 */ 523 void init_cpu_vtimer(void) 524 { 525 struct vtimer_queue *vt_list; 526 unsigned long cr0; 527 528 /* kick the virtual timer */ 529 S390_lowcore.exit_timer = VTIMER_MAX_SLICE; 530 S390_lowcore.last_update_timer = VTIMER_MAX_SLICE; 531 asm volatile ("SPT %0" : : "m" (S390_lowcore.last_update_timer)); 532 asm volatile ("STCK %0" : "=m" (S390_lowcore.last_update_clock)); 533 __ctl_store(cr0, 0, 0); 534 cr0 |= 0x400; 535 __ctl_load(cr0, 0, 0); 536 537 vt_list = &per_cpu(virt_cpu_timer, smp_processor_id()); 538 INIT_LIST_HEAD(&vt_list->list); 539 spin_lock_init(&vt_list->lock); 540 vt_list->to_expire = 0; 541 vt_list->offset = 0; 542 vt_list->idle = 0; 543 544 } 545 546 static int vtimer_idle_notify(struct notifier_block *self, 547 unsigned long action, void *hcpu) 548 { 549 switch (action) { 550 case CPU_IDLE: 551 stop_cpu_timer(); 552 break; 553 case CPU_NOT_IDLE: 554 start_cpu_timer(); 555 break; 556 } 557 return NOTIFY_OK; 558 } 559 560 static struct notifier_block vtimer_idle_nb = { 561 .notifier_call = vtimer_idle_notify, 562 }; 563 564 void __init vtime_init(void) 565 { 566 /* request the cpu timer external interrupt */ 567 if (register_early_external_interrupt(0x1005, do_cpu_timer_interrupt, 568 &ext_int_info_timer) != 0) 569 panic("Couldn't request external interrupt 0x1005"); 570 571 if (register_idle_notifier(&vtimer_idle_nb)) 572 panic("Couldn't register idle notifier"); 573 574 init_cpu_vtimer(); 575 } 576 577