diff options
| author | Ingo Molnar <mingo@elte.hu> | 2009-02-22 09:15:32 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-02-25 12:38:14 -0500 |
| commit | 80f2257116474ceed5fccab510b4f7245c0f49d7 (patch) | |
| tree | 513775794f865985dedcfc82dedcb1a60e469b76 /kernel | |
| parent | 10dd31a7a17254d6ba793305fc590455393e610e (diff) | |
time: ntp: refactor do_adjtimex()
Impact: cleanup, no functionality changed
do_adjtimex() is currently a monster function with a maze of
branches. Refactor the txc->modes setting aspects of it into
two new helper functions:
process_adj_status()
process_adjtimex_modes()
kernel/time/ntp.o:
text data bss dec hex filename
2512 114 136 2762 aca ntp.o.before
2512 114 136 2762 aca ntp.o.after
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/time/ntp.c | 182 |
1 files changed, 99 insertions, 83 deletions
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index fc08eb10ced4..aded09be98cc 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c | |||
| @@ -332,6 +332,102 @@ static void notify_cmos_timer(void) | |||
| 332 | static inline void notify_cmos_timer(void) { } | 332 | static inline void notify_cmos_timer(void) { } |
| 333 | #endif | 333 | #endif |
| 334 | 334 | ||
| 335 | |||
| 336 | /* | ||
| 337 | * Propagate a new txc->status value into the NTP state: | ||
| 338 | */ | ||
| 339 | static inline void process_adj_status(struct timex *txc, struct timespec *ts) | ||
| 340 | { | ||
| 341 | long now; | ||
| 342 | |||
| 343 | if ((time_status & STA_PLL) && !(txc->status & STA_PLL)) { | ||
| 344 | time_state = TIME_OK; | ||
| 345 | time_status = STA_UNSYNC; | ||
| 346 | } | ||
| 347 | /* only set allowed bits */ | ||
| 348 | time_status &= STA_RONLY; | ||
| 349 | |||
| 350 | /* | ||
| 351 | * If we turn on PLL adjustments then reset the | ||
| 352 | * reference time to current time. | ||
| 353 | */ | ||
| 354 | if (!(time_status & STA_PLL) && (txc->status & STA_PLL)) | ||
| 355 | time_reftime = xtime.tv_sec; | ||
| 356 | |||
| 357 | time_status |= txc->status & ~STA_RONLY; | ||
| 358 | |||
| 359 | switch (time_state) { | ||
| 360 | case TIME_OK: | ||
| 361 | start_timer: | ||
| 362 | now = ts->tv_sec; | ||
| 363 | if (time_status & STA_INS) { | ||
| 364 | time_state = TIME_INS; | ||
| 365 | now += 86400 - now % 86400; | ||
| 366 | hrtimer_start(&leap_timer, ktime_set(now, 0), HRTIMER_MODE_ABS); | ||
| 367 | } else if (time_status & STA_DEL) { | ||
| 368 | time_state = TIME_DEL; | ||
| 369 | now += 86400 - (now + 1) % 86400; | ||
| 370 | hrtimer_start(&leap_timer, ktime_set(now, 0), HRTIMER_MODE_ABS); | ||
| 371 | } | ||
| 372 | break; | ||
| 373 | case TIME_INS: | ||
| 374 | case TIME_DEL: | ||
| 375 | time_state = TIME_OK; | ||
| 376 | goto start_timer; | ||
| 377 | case TIME_WAIT: | ||
| 378 | if (!(time_status & (STA_INS | STA_DEL))) | ||
| 379 | time_state = TIME_OK; | ||
| 380 | break; | ||
| 381 | case TIME_OOP: | ||
| 382 | hrtimer_restart(&leap_timer); | ||
| 383 | break; | ||
| 384 | } | ||
| 385 | } | ||
| 386 | /* | ||
| 387 | * Called with the xtime lock held, so we can access and modify | ||
| 388 | * all the global NTP state: | ||
| 389 | */ | ||
| 390 | static inline void process_adjtimex_modes(struct timex *txc, struct timespec *ts) | ||
| 391 | { | ||
| 392 | if (txc->modes & ADJ_STATUS) | ||
| 393 | process_adj_status(txc, ts); | ||
| 394 | |||
| 395 | if (txc->modes & ADJ_NANO) | ||
| 396 | time_status |= STA_NANO; | ||
| 397 | if (txc->modes & ADJ_MICRO) | ||
| 398 | time_status &= ~STA_NANO; | ||
| 399 | |||
| 400 | if (txc->modes & ADJ_FREQUENCY) { | ||
| 401 | time_freq = (s64)txc->freq * PPM_SCALE; | ||
| 402 | time_freq = min(time_freq, MAXFREQ_SCALED); | ||
| 403 | time_freq = max(time_freq, -MAXFREQ_SCALED); | ||
| 404 | } | ||
| 405 | |||
| 406 | if (txc->modes & ADJ_MAXERROR) | ||
| 407 | time_maxerror = txc->maxerror; | ||
| 408 | if (txc->modes & ADJ_ESTERROR) | ||
| 409 | time_esterror = txc->esterror; | ||
| 410 | |||
| 411 | if (txc->modes & ADJ_TIMECONST) { | ||
| 412 | time_constant = txc->constant; | ||
| 413 | if (!(time_status & STA_NANO)) | ||
| 414 | time_constant += 4; | ||
| 415 | time_constant = min(time_constant, (long)MAXTC); | ||
| 416 | time_constant = max(time_constant, 0l); | ||
| 417 | } | ||
| 418 | |||
| 419 | if (txc->modes & ADJ_TAI && txc->constant > 0) | ||
| 420 | time_tai = txc->constant; | ||
| 421 | |||
| 422 | if (txc->modes & ADJ_OFFSET) | ||
| 423 | ntp_update_offset(txc->offset); | ||
| 424 | if (txc->modes & ADJ_TICK) | ||
| 425 | tick_usec = txc->tick; | ||
| 426 | |||
| 427 | if (txc->modes & (ADJ_TICK|ADJ_FREQUENCY|ADJ_OFFSET)) | ||
| 428 | ntp_update_frequency(); | ||
| 429 | } | ||
| 430 | |||
| 335 | /* | 431 | /* |
| 336 | * adjtimex mainly allows reading (and writing, if superuser) of | 432 | * adjtimex mainly allows reading (and writing, if superuser) of |
| 337 | * kernel time-keeping variables. used by xntpd. | 433 | * kernel time-keeping variables. used by xntpd. |
| @@ -383,90 +479,10 @@ int do_adjtimex(struct timex *txc) | |||
| 383 | txc->offset = save_adjust; | 479 | txc->offset = save_adjust; |
| 384 | goto adj_done; | 480 | goto adj_done; |
| 385 | } | 481 | } |
| 386 | if (txc->modes) { | ||
| 387 | long sec; | ||
| 388 | |||
| 389 | if (txc->modes & ADJ_STATUS) { | ||
| 390 | if ((time_status & STA_PLL) && | ||
| 391 | !(txc->status & STA_PLL)) { | ||
| 392 | time_state = TIME_OK; | ||
| 393 | time_status = STA_UNSYNC; | ||
| 394 | } | ||
| 395 | /* only set allowed bits */ | ||
| 396 | time_status &= STA_RONLY; | ||
| 397 | /* | ||
| 398 | * If we turn on PLL adjustments then reset the | ||
| 399 | * reference time to current time. | ||
| 400 | */ | ||
| 401 | if (!(time_status & STA_PLL) && (txc->status & STA_PLL)) | ||
| 402 | time_reftime = xtime.tv_sec; | ||
| 403 | |||
| 404 | time_status |= txc->status & ~STA_RONLY; | ||
| 405 | |||
| 406 | switch (time_state) { | ||
| 407 | case TIME_OK: | ||
| 408 | start_timer: | ||
| 409 | sec = ts.tv_sec; | ||
| 410 | if (time_status & STA_INS) { | ||
| 411 | time_state = TIME_INS; | ||
| 412 | sec += 86400 - sec % 86400; | ||
| 413 | hrtimer_start(&leap_timer, ktime_set(sec, 0), HRTIMER_MODE_ABS); | ||
| 414 | } else if (time_status & STA_DEL) { | ||
| 415 | time_state = TIME_DEL; | ||
| 416 | sec += 86400 - (sec + 1) % 86400; | ||
| 417 | hrtimer_start(&leap_timer, ktime_set(sec, 0), HRTIMER_MODE_ABS); | ||
| 418 | } | ||
| 419 | break; | ||
| 420 | case TIME_INS: | ||
| 421 | case TIME_DEL: | ||
| 422 | time_state = TIME_OK; | ||
| 423 | goto start_timer; | ||
| 424 | break; | ||
| 425 | case TIME_WAIT: | ||
| 426 | if (!(time_status & (STA_INS | STA_DEL))) | ||
| 427 | time_state = TIME_OK; | ||
| 428 | break; | ||
| 429 | case TIME_OOP: | ||
| 430 | hrtimer_restart(&leap_timer); | ||
| 431 | break; | ||
| 432 | } | ||
| 433 | } | ||
| 434 | |||
| 435 | if (txc->modes & ADJ_NANO) | ||
| 436 | time_status |= STA_NANO; | ||
| 437 | if (txc->modes & ADJ_MICRO) | ||
| 438 | time_status &= ~STA_NANO; | ||
| 439 | 482 | ||
| 440 | if (txc->modes & ADJ_FREQUENCY) { | 483 | /* If there are input parameters, then process them: */ |
| 441 | time_freq = (s64)txc->freq * PPM_SCALE; | 484 | if (txc->modes) |
| 442 | time_freq = min(time_freq, MAXFREQ_SCALED); | 485 | process_adjtimex_modes(txc, &ts); |
| 443 | time_freq = max(time_freq, -MAXFREQ_SCALED); | ||
| 444 | } | ||
| 445 | |||
| 446 | if (txc->modes & ADJ_MAXERROR) | ||
| 447 | time_maxerror = txc->maxerror; | ||
| 448 | if (txc->modes & ADJ_ESTERROR) | ||
| 449 | time_esterror = txc->esterror; | ||
| 450 | |||
| 451 | if (txc->modes & ADJ_TIMECONST) { | ||
| 452 | time_constant = txc->constant; | ||
| 453 | if (!(time_status & STA_NANO)) | ||
| 454 | time_constant += 4; | ||
| 455 | time_constant = min(time_constant, (long)MAXTC); | ||
| 456 | time_constant = max(time_constant, 0l); | ||
| 457 | } | ||
| 458 | |||
| 459 | if (txc->modes & ADJ_TAI && txc->constant > 0) | ||
| 460 | time_tai = txc->constant; | ||
| 461 | |||
| 462 | if (txc->modes & ADJ_OFFSET) | ||
| 463 | ntp_update_offset(txc->offset); | ||
| 464 | if (txc->modes & ADJ_TICK) | ||
| 465 | tick_usec = txc->tick; | ||
| 466 | |||
| 467 | if (txc->modes & (ADJ_TICK|ADJ_FREQUENCY|ADJ_OFFSET)) | ||
| 468 | ntp_update_frequency(); | ||
| 469 | } | ||
| 470 | 486 | ||
| 471 | txc->offset = shift_right(time_offset * NTP_INTERVAL_FREQ, | 487 | txc->offset = shift_right(time_offset * NTP_INTERVAL_FREQ, |
| 472 | NTP_SCALE_SHIFT); | 488 | NTP_SCALE_SHIFT); |
