Guest User

Untitled

a guest
May 24th, 2018
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 27.09 KB | None | 0 0
  1. From e5e403e2cc772dac3e0472f1d6d81f777d6df36f Mon Sep 17 00:00:00 2001
  2. From: OZAWA Tsuyoshi <ozawa+bsd@t-oza.net>
  3. Date: Tue, 4 May 2010 21:19:32 +0900
  4. Subject: [PATCH] add i386 & amd64 support
  5.  
  6. Signed-off-by: OZAWA Tsuyoshi <ozawa+bsd@t-oza.net>
  7. ---
  8. sys/amd64/amd64/apic_vector.S | 2 +-
  9. sys/amd64/amd64/local_apic.c | 123 +++++++++++++++++++++++++++++++++++++++++
  10. sys/amd64/isa/clock.c | 13 ++++-
  11. sys/amd64/isa/dynticks.c | 81 +++++++++++++++++++++++++++
  12. sys/conf/files.amd64 | 1 +
  13. sys/conf/files.i386 | 1 +
  14. sys/i386/i386/apic_vector.s | 2 +-
  15. sys/i386/i386/local_apic.c | 120 ++++++++++++++++++++++++++++++++++++++++
  16. sys/i386/isa/clock.c | 18 +++++-
  17. sys/i386/isa/dynticks.c | 120 ++++++++++++++++++++++++++++++++++++++++
  18. sys/kern/kern_clock.c | 27 +++++++++
  19. sys/kern/kern_timeout.c | 28 +++++++++
  20. sys/kern/sched_4bsd.c | 3 +
  21. sys/kern/sched_ule.c | 3 +
  22. sys/sys/dynticks.h | 49 ++++++++++++++++
  23. sys/sys/systm.h | 1 +
  24. 16 files changed, 587 insertions(+), 5 deletions(-)
  25. create mode 100644 sys/amd64/isa/dynticks.c
  26. create mode 100644 sys/i386/isa/dynticks.c
  27. create mode 100644 sys/sys/dynticks.h
  28.  
  29. diff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S
  30. index 7aa2891..7609ae4 100644
  31. --- a/sys/amd64/amd64/apic_vector.S
  32. +++ b/sys/amd64/amd64/apic_vector.S
  33. @@ -100,7 +100,7 @@ IDTVEC(timerint)
  34. PUSH_FRAME
  35. FAKE_MCOUNT(TF_RIP(%rsp))
  36. movq %rsp, %rdi
  37. - call lapic_handle_timer
  38. + call timer_intr_handler
  39. MEXITCOUNT
  40. jmp doreti
  41.  
  42. diff --git a/sys/amd64/amd64/local_apic.c b/sys/amd64/amd64/local_apic.c
  43. index 79be51e..3ba823d 100644
  44. --- a/sys/amd64/amd64/local_apic.c
  45. +++ b/sys/amd64/amd64/local_apic.c
  46. @@ -66,6 +66,8 @@ __FBSDID("$FreeBSD: src/sys/amd64/amd64/local_apic.c,v 1.42.2.7.2.1 2010/02/10 0
  47. #include <ddb/ddb.h>
  48. #endif
  49.  
  50. +#include <sys/dynticks.h>
  51. +
  52. #ifdef KDTRACE_HOOKS
  53. #include <sys/dtrace_bsd.h>
  54. cyclic_clock_func_t lapic_cyclic_clock_func[MAXCPU];
  55. @@ -109,6 +111,9 @@ struct lapic {
  56. u_long la_hard_ticks;
  57. u_long la_stat_ticks;
  58. u_long la_prof_ticks;
  59. + u_long la_last_tick;
  60. + u_long la_cur_skip;
  61. + u_long la_skip;
  62. } static lapics[MAX_APIC_ID + 1];
  63.  
  64. /* XXX: should thermal be an NMI? */
  65. @@ -142,6 +147,7 @@ static u_int32_t lapic_timer_divisors[] = {
  66. APIC_TDCR_32, APIC_TDCR_64, APIC_TDCR_128
  67. };
  68.  
  69. +
  70. extern inthand_t IDTVEC(rsvd);
  71.  
  72. volatile lapic_t *lapic;
  73. @@ -156,6 +162,9 @@ static void lapic_timer_periodic(u_int count);
  74. static void lapic_timer_set_divisor(u_int divisor);
  75. static uint32_t lvt_mode(struct lapic *la, u_int pin, uint32_t value);
  76.  
  77. +static struct timer_ops lapic_ops;
  78. +static void lapic_handle_timer_dynamically(struct trapframe *frame);
  79. +
  80. struct pic lapic_pic = { .pic_resume = lapic_resume };
  81.  
  82. static uint32_t
  83. @@ -488,6 +497,8 @@ lapic_setup_clock(void)
  84. profhz = lapic_timer_hz;
  85. lapic_timer_period = value / lapic_timer_hz;
  86.  
  87. + register_timer_intr_handlers(&lapic_ops);
  88. +
  89. /*
  90. * Start up the timer on the BSP. The APs will kick off their
  91. * timer during lapic_setup().
  92. @@ -799,6 +810,10 @@ lapic_handle_timer(struct trapframe *frame)
  93. if (profprocs != 0)
  94. profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
  95. }
  96. +
  97. + la->la_cur_skip = 0;
  98. + la->la_skip = 1;
  99. +
  100. critical_exit();
  101. }
  102.  
  103. @@ -1325,3 +1340,111 @@ lapic_ipi_vectored(u_int vector, int dest)
  104. #endif /* DETECT_DEADLOCK */
  105. }
  106. #endif /* SMP */
  107. +
  108. +
  109. +
  110. +static void lapic_set_next_timer_intr(void)
  111. +{
  112. + struct lapic *la;
  113. + int skip;
  114. + u_long cnt_to_skip;
  115. +
  116. + la = &lapics[PCPU_GET(apic_id)];
  117. + (*la->la_timer_count)++;
  118. +
  119. + skip = callout_get_next_event();
  120. + cnt_to_skip = lapic_timer_period * skip ;
  121. + lapic_timer_oneshot(cnt_to_skip);
  122. + la->la_skip = skip;
  123. + la->la_cur_skip = 0;
  124. +
  125. + return;
  126. +}
  127. +
  128. +static void lapic_set_timer_periodic(void)
  129. +{
  130. + lapic_timer_periodic(lapic_timer_period);
  131. +}
  132. +
  133. +static void
  134. +lapic_handle_timer_dynamically(struct trapframe *frame)
  135. +{
  136. + struct lapic *la;
  137. + int skip;
  138. + int i;
  139. +
  140. + /* Send EOI first thing. */
  141. + lapic_eoi();
  142. +
  143. +#if defined(SMP) && !defined(SCHED_ULE)
  144. + /*
  145. + * Don't do any accounting for the disabled HTT cores, since it
  146. + * will provide misleading numbers for the userland.
  147. + *
  148. + * No locking is necessary here, since even if we loose the race
  149. + * when hlt_cpus_mask changes it is not a big deal, really.
  150. + *
  151. + * Don't do that for ULE, since ULE doesn't consider hlt_cpus_mask
  152. + * and unlike other schedulers it actually schedules threads to
  153. + * those CPUs.
  154. + */
  155. + if ((hlt_cpus_mask & (1 << PCPU_GET(cpuid))) != 0)
  156. + return;
  157. +#endif
  158. +
  159. + /* Look up our local APIC structure for the tick counters. */
  160. + la = &lapics[PCPU_GET(apic_id)];
  161. + (*la->la_timer_count)++;
  162. + critical_enter();
  163. +
  164. +#ifdef KDTRACE_HOOKS
  165. + /*
  166. + * If the DTrace hooks are configured and a callback function
  167. + * has been registered, then call it to process the high speed
  168. + * timers.
  169. + */
  170. + int cpu = PCPU_GET(cpuid);
  171. + /* i dont know this works well? */
  172. + if (lapic_cyclic_clock_func[cpu] != NULL)
  173. + (*lapic_cyclic_clock_func[cpu])(frame);
  174. +#endif
  175. + /* Fire hardclock at hz. */
  176. + skip = la->la_skip;
  177. + for(i = 0; i < skip; i++){
  178. + la->la_hard_ticks += hz;
  179. + if (la->la_hard_ticks >= lapic_timer_hz) {
  180. + la->la_hard_ticks -= lapic_timer_hz;
  181. + if (PCPU_GET(cpuid) == 0)
  182. + hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
  183. + else
  184. + hardclock_cpu(TRAPF_USERMODE(frame));
  185. + }
  186. +
  187. + /* Fire statclock at stathz. */
  188. + la->la_stat_ticks += stathz;
  189. + if (la->la_stat_ticks >= lapic_timer_hz) {
  190. + la->la_stat_ticks -= lapic_timer_hz;
  191. + statclock(TRAPF_USERMODE(frame));
  192. + }
  193. +
  194. + /* Fire profclock at profhz, but only when needed. */
  195. + la->la_prof_ticks += profhz;
  196. + if (la->la_prof_ticks >= lapic_timer_hz) {
  197. + if (profprocs != 0){
  198. + la->la_prof_ticks -= lapic_timer_hz;
  199. + profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
  200. + }
  201. + }
  202. + }
  203. +
  204. + lapic_set_next_timer_intr();
  205. + critical_exit();
  206. +}
  207. +
  208. +
  209. +static struct timer_ops lapic_ops = {
  210. + .perticks_handler = lapic_handle_timer,
  211. + .dynticks_handler = lapic_handle_timer_dynamically,
  212. + .set_timer_periodic = lapic_set_timer_periodic,
  213. + .set_next_timer_intr = lapic_set_next_timer_intr,
  214. +};
  215. diff --git a/sys/amd64/isa/clock.c b/sys/amd64/isa/clock.c
  216. index d8b48d2..4aaf2c8 100644
  217. --- a/sys/amd64/isa/clock.c
  218. +++ b/sys/amd64/isa/clock.c
  219. @@ -69,6 +69,7 @@ __FBSDID("$FreeBSD: src/sys/amd64/isa/clock.c,v 1.234.2.2.6.1 2010/02/10 00:26:2
  220. #include <sys/sysctl.h>
  221. #include <sys/cons.h>
  222. #include <sys/power.h>
  223. +#include <sys/dynticks.h>
  224.  
  225. #include <machine/clock.h>
  226. #include <machine/cpu.h>
  227. @@ -134,6 +135,8 @@ static unsigned i8254_get_timecount(struct timecounter *tc);
  228. static unsigned i8254_simple_get_timecount(struct timecounter *tc);
  229. static void set_timer_freq(u_int freq, int intr_freq);
  230.  
  231. +static struct timer_ops clk_ops;
  232. +
  233. static struct timecounter i8254_timecounter = {
  234. i8254_get_timecount, /* get_timecount */
  235. 0, /* no poll_pps */
  236. @@ -765,7 +768,8 @@ cpu_initclocks()
  237. * timecounter to user a simpler algorithm.
  238. */
  239. if (!using_lapic_timer) {
  240. - intr_add_handler("clk", 0, (driver_filter_t *)clkintr, NULL, NULL,
  241. + register_timer_intr_handlers(&clk_ops);
  242. + intr_add_handler("clk", 0, (driver_filter_t *)timer_intr_handler, NULL, NULL,
  243. INTR_TYPE_CLK, NULL);
  244. i8254_intsrc = intr_lookup_source(0);
  245. if (i8254_intsrc != NULL)
  246. @@ -935,4 +939,11 @@ static devclass_t attimer_devclass;
  247. DRIVER_MODULE(attimer, isa, attimer_driver, attimer_devclass, 0, 0);
  248. DRIVER_MODULE(attimer, acpi, attimer_driver, attimer_devclass, 0, 0);
  249.  
  250. +static struct timer_ops clk_ops = {
  251. + .ext_perticks_handler = clkintr,
  252. + .ext_dynticks_handler = NULL,
  253. + .set_next_timer_intr = NULL,
  254. + .set_timer_periodic = NULL,
  255. +};
  256. +
  257. #endif /* DEV_ISA */
  258. diff --git a/sys/amd64/isa/dynticks.c b/sys/amd64/isa/dynticks.c
  259. new file mode 100644
  260. index 0000000..7ae8f8b
  261. --- /dev/null
  262. +++ b/sys/amd64/isa/dynticks.c
  263. @@ -0,0 +1,81 @@
  264. +/*-
  265. + * Copyright (c) 2003 OZAWA Tsuyoshi <ozawa@t-oza.net>
  266. + * All rights reserved.
  267. + *
  268. + * Redistribution and use in source and binary forms, with or without
  269. + * modification, are permitted provided that the following conditions
  270. + * are met:
  271. + * 1. Redistributions of source code must retain the above copyright
  272. + * notice, this list of conditions and the following disclaimer.
  273. + * 2. Redistributions in binary form must reproduce the above copyright
  274. + * notice, this list of conditions and the following disclaimer in the
  275. + * documentation and/or other materials provided with the distribution.
  276. + * 3. Neither the name of the author nor the names of any co-contributors
  277. + * may be used to endorse or promote products derived from this software
  278. + * without specific prior written permission.
  279. + *
  280. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  281. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  282. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  283. + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  284. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  285. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  286. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  287. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  288. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  289. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  290. + * SUCH DAMAGE.
  291. + */
  292. +
  293. +#include <sys/cdefs.h>
  294. +__FBSDID("$FreeBSD: src/sys/amd64/isa/dynticks.c,v 0.1.0 2010/05/02 16:26:20 OZAWATsusyohi Exp $");
  295. +
  296. +#include <sys/dynticks.h>
  297. +#include <sys/systm.h>
  298. +
  299. +static int enable_dynticks = 0;
  300. +static void (*cur_handler)(struct trapframe *frame);
  301. +
  302. +static struct timer_ops *tops;
  303. +
  304. +void timer_intr_handler(struct trapframe *frame)
  305. +{
  306. + cur_handler(frame);
  307. +}
  308. +
  309. +void register_timer_intr_handlers(struct timer_ops *ops)
  310. +{
  311. + tops = ops;
  312. + cur_handler = ops->perticks_handler;
  313. +
  314. + if ( tops->perticks_handler && tops->dynticks_handler) {
  315. + enable_dynticks = 1;
  316. + }
  317. +}
  318. +
  319. +void switch_to_dynticks(void)
  320. +{
  321. + if(!enable_dynticks)
  322. + return;
  323. +
  324. + critical_enter();
  325. + cur_handler = tops->dynticks_handler;
  326. + tops->set_next_timer_intr();
  327. + critical_exit();
  328. +}
  329. +
  330. +void switch_to_perticks(void)
  331. +{
  332. + if(!enable_dynticks)
  333. + return;
  334. +
  335. + if(!tops->perticks_handler){
  336. + panic("NULL perticks handler!\n");
  337. + return;
  338. + }
  339. +
  340. + critical_enter();
  341. + cur_handler = tops->perticks_handler;
  342. + tops->set_timer_periodic();
  343. + critical_exit();
  344. +}
  345. diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64
  346. index 44732e8..d20dc77 100644
  347. --- a/sys/conf/files.amd64
  348. +++ b/sys/conf/files.amd64
  349. @@ -123,6 +123,7 @@ amd64/amd64/vm_machdep.c standard
  350. amd64/isa/atpic.c optional atpic isa
  351. #amd64/isa/atpic_vector.S optional atpic isa
  352. amd64/isa/clock.c standard
  353. +amd64/isa/dynticks.c standard
  354. amd64/isa/elcr.c standard
  355. amd64/isa/isa.c standard
  356. amd64/isa/isa_dma.c standard
  357. diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
  358. index 033999c..ad3c916 100644
  359. --- a/sys/conf/files.i386
  360. +++ b/sys/conf/files.i386
  361. @@ -330,6 +330,7 @@ i386/ibcs2/imgact_coff.c optional ibcs2
  362. i386/isa/atpic.c standard
  363. #i386/isa/atpic_vector.s standard
  364. i386/isa/clock.c standard
  365. +i386/isa/dynticks.c standard
  366. i386/isa/dpms.c optional dpms
  367. i386/isa/elcr.c standard
  368. i386/isa/elink.c optional ep | ie
  369. diff --git a/sys/i386/i386/apic_vector.s b/sys/i386/i386/apic_vector.s
  370. index c2f5aca..722678c 100644
  371. --- a/sys/i386/i386/apic_vector.s
  372. +++ b/sys/i386/i386/apic_vector.s
  373. @@ -105,7 +105,7 @@ IDTVEC(timerint)
  374. SET_KERNEL_SREGS
  375. FAKE_MCOUNT(TF_EIP(%esp))
  376. pushl %esp
  377. - call lapic_handle_timer
  378. + call timer_intr_handler
  379. add $4, %esp
  380. MEXITCOUNT
  381. jmp doreti
  382. diff --git a/sys/i386/i386/local_apic.c b/sys/i386/i386/local_apic.c
  383. index 0151030..19f3853 100644
  384. --- a/sys/i386/i386/local_apic.c
  385. +++ b/sys/i386/i386/local_apic.c
  386. @@ -66,6 +66,8 @@ __FBSDID("$FreeBSD: src/sys/i386/i386/local_apic.c,v 1.44.2.6.2.1 2010/02/10 00:
  387. #include <ddb/ddb.h>
  388. #endif
  389.  
  390. +#include <sys/dynticks.h>
  391. +
  392. #ifdef KDTRACE_HOOKS
  393. #include <sys/dtrace_bsd.h>
  394. cyclic_clock_func_t lapic_cyclic_clock_func[MAXCPU];
  395. @@ -109,6 +111,9 @@ struct lapic {
  396. u_long la_hard_ticks;
  397. u_long la_stat_ticks;
  398. u_long la_prof_ticks;
  399. + u_long la_last_tick;
  400. + u_long la_cur_skip;
  401. + u_long la_skip;
  402. } static lapics[MAX_APIC_ID + 1];
  403.  
  404. /* XXX: should thermal be an NMI? */
  405. @@ -142,6 +147,7 @@ static u_int32_t lapic_timer_divisors[] = {
  406. APIC_TDCR_32, APIC_TDCR_64, APIC_TDCR_128
  407. };
  408.  
  409. +
  410. extern inthand_t IDTVEC(rsvd);
  411.  
  412. volatile lapic_t *lapic;
  413. @@ -156,6 +162,9 @@ static void lapic_timer_periodic(u_int count);
  414. static void lapic_timer_set_divisor(u_int divisor);
  415. static uint32_t lvt_mode(struct lapic *la, u_int pin, uint32_t value);
  416.  
  417. +static struct timer_ops lapic_ops;
  418. +static void lapic_handle_timer_dynamically(struct trapframe *frame);
  419. +
  420. struct pic lapic_pic = { .pic_resume = lapic_resume };
  421.  
  422. static uint32_t
  423. @@ -490,6 +499,8 @@ lapic_setup_clock(void)
  424. profhz = lapic_timer_hz;
  425. lapic_timer_period = value / lapic_timer_hz;
  426.  
  427. + register_timer_intr_handlers(&lapic_ops);
  428. +
  429. /*
  430. * Start up the timer on the BSP. The APs will kick off their
  431. * timer during lapic_setup().
  432. @@ -801,6 +812,10 @@ lapic_handle_timer(struct trapframe *frame)
  433. if (profprocs != 0)
  434. profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
  435. }
  436. +
  437. + la->la_cur_skip = 0;
  438. + la->la_skip = 1;
  439. +
  440. critical_exit();
  441. }
  442.  
  443. @@ -1332,3 +1347,108 @@ lapic_ipi_vectored(u_int vector, int dest)
  444. #endif /* DETECT_DEADLOCK */
  445. }
  446. #endif /* SMP */
  447. +
  448. +static void lapic_set_next_timer_intr(void)
  449. +{
  450. + struct lapic *la;
  451. + int skip;
  452. + u_long cnt_to_skip;
  453. +
  454. + la = &lapics[PCPU_GET(apic_id)];
  455. + (*la->la_timer_count)++;
  456. +
  457. + skip = callout_get_next_event();
  458. + cnt_to_skip = lapic_timer_period * skip ;
  459. + lapic_timer_oneshot(cnt_to_skip);
  460. + la->la_skip = skip;
  461. + la->la_cur_skip = 0;
  462. +
  463. + return;
  464. +}
  465. +
  466. +static void lapic_set_timer_periodic(void)
  467. +{
  468. + lapic_timer_periodic(lapic_timer_period);
  469. +}
  470. +
  471. +static void
  472. +lapic_handle_timer_dynamically(struct trapframe *frame)
  473. +{
  474. + struct lapic *la;
  475. + int skip;
  476. + int i;
  477. +
  478. + /* Send EOI first thing. */
  479. + lapic_eoi();
  480. +
  481. +#if defined(SMP) && !defined(SCHED_ULE)
  482. + /*
  483. + * Don't do any accounting for the disabled HTT cores, since it
  484. + * will provide misleading numbers for the userland.
  485. + *
  486. + * No locking is necessary here, since even if we loose the race
  487. + * when hlt_cpus_mask changes it is not a big deal, really.
  488. + *
  489. + * Don't do that for ULE, since ULE doesn't consider hlt_cpus_mask
  490. + * and unlike other schedulers it actually schedules threads to
  491. + * those CPUs.
  492. + */
  493. + if ((hlt_cpus_mask & (1 << PCPU_GET(cpuid))) != 0)
  494. + return;
  495. +#endif
  496. +
  497. + /* Look up our local APIC structure for the tick counters. */
  498. + la = &lapics[PCPU_GET(apic_id)];
  499. + (*la->la_timer_count)++;
  500. + critical_enter();
  501. +
  502. +#ifdef KDTRACE_HOOKS
  503. + /*
  504. + * If the DTrace hooks are configured and a callback function
  505. + * has been registered, then call it to process the high speed
  506. + * timers.
  507. + */
  508. + int cpu = PCPU_GET(cpuid);
  509. + /* i dont know this works well? */
  510. + if (lapic_cyclic_clock_func[cpu] != NULL)
  511. + (*lapic_cyclic_clock_func[cpu])(frame);
  512. +#endif
  513. + /* Fire hardclock at hz. */
  514. + skip = la->la_skip;
  515. + for(i = 0; i < skip; i++){
  516. + la->la_hard_ticks += hz;
  517. + if (la->la_hard_ticks >= lapic_timer_hz) {
  518. + la->la_hard_ticks -= lapic_timer_hz;
  519. + if (PCPU_GET(cpuid) == 0)
  520. + hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
  521. + else
  522. + hardclock_cpu(TRAPF_USERMODE(frame));
  523. + }
  524. +
  525. + /* Fire statclock at stathz. */
  526. + la->la_stat_ticks += stathz;
  527. + if (la->la_stat_ticks >= lapic_timer_hz) {
  528. + la->la_stat_ticks -= lapic_timer_hz;
  529. + statclock(TRAPF_USERMODE(frame));
  530. + }
  531. +
  532. + /* Fire profclock at profhz, but only when needed. */
  533. + la->la_prof_ticks += profhz;
  534. + if (la->la_prof_ticks >= lapic_timer_hz) {
  535. + if (profprocs != 0){
  536. + la->la_prof_ticks -= lapic_timer_hz;
  537. + profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
  538. + }
  539. + }
  540. + }
  541. +
  542. + lapic_set_next_timer_intr();
  543. + critical_exit();
  544. +}
  545. +
  546. +static struct timer_ops lapic_ops = {
  547. + .perticks_handler = lapic_handle_timer,
  548. + .dynticks_handler = lapic_handle_timer_dynamically,
  549. + .set_timer_periodic = lapic_set_timer_periodic,
  550. + .set_next_timer_intr = lapic_set_next_timer_intr,
  551. +};
  552. diff --git a/sys/i386/isa/clock.c b/sys/i386/isa/clock.c
  553. index 0b6b42b..3d53dd5 100644
  554. --- a/sys/i386/isa/clock.c
  555. +++ b/sys/i386/isa/clock.c
  556. @@ -72,6 +72,7 @@ __FBSDID("$FreeBSD: src/sys/i386/isa/clock.c,v 1.239.2.2.6.1 2010/02/10 00:26:20
  557. #include <sys/sysctl.h>
  558. #include <sys/cons.h>
  559. #include <sys/power.h>
  560. +#include <sys/dynticks.h>
  561.  
  562. #include <machine/clock.h>
  563. #include <machine/cpu.h>
  564. @@ -136,6 +137,8 @@ static unsigned i8254_get_timecount(struct timecounter *tc);
  565. static unsigned i8254_simple_get_timecount(struct timecounter *tc);
  566. static void set_timer_freq(u_int freq, int intr_freq);
  567.  
  568. +static struct timer_ops clk_ops;
  569. +
  570. static struct timecounter i8254_timecounter = {
  571. i8254_get_timecount, /* get_timecount */
  572. 0, /* no poll_pps */
  573. @@ -769,8 +772,9 @@ cpu_initclocks()
  574. * timecounter to user a simpler algorithm.
  575. */
  576. if (!using_lapic_timer) {
  577. - intr_add_handler("clk", 0, (driver_filter_t *)clkintr, NULL,
  578. - NULL, INTR_TYPE_CLK, NULL);
  579. + register_ext_timer_intr_handlers(&clk_ops);
  580. + intr_add_handler("clk", 0, (driver_filter_t *)ext_timer_intr_handler, NULL,
  581. + NULL, INTR_TYPE_CLK, NULL);
  582. i8254_intsrc = intr_lookup_source(0);
  583. if (i8254_intsrc != NULL)
  584. i8254_pending =
  585. @@ -939,4 +943,14 @@ static devclass_t attimer_devclass;
  586. DRIVER_MODULE(attimer, isa, attimer_driver, attimer_devclass, 0, 0);
  587. DRIVER_MODULE(attimer, acpi, attimer_driver, attimer_devclass, 0, 0);
  588.  
  589. +#if 1
  590. +static struct timer_ops clk_ops = {
  591. + .ext_perticks_handler = clkintr,
  592. + .ext_dynticks_handler = NULL,
  593. + .set_next_timer_intr = NULL,
  594. + .set_timer_periodic = NULL,
  595. +};
  596. +#endif
  597. +
  598. +
  599. #endif /* DEV_ISA */
  600. diff --git a/sys/i386/isa/dynticks.c b/sys/i386/isa/dynticks.c
  601. new file mode 100644
  602. index 0000000..bf5033f
  603. --- /dev/null
  604. +++ b/sys/i386/isa/dynticks.c
  605. @@ -0,0 +1,120 @@
  606. +/*-
  607. + * Copyright (c) 2003 OZAWA Tsuyoshi <ozawa@t-oza.net>
  608. + * All rights reserved.
  609. + *
  610. + * Redistribution and use in source and binary forms, with or without
  611. + * modification, are permitted provided that the following conditions
  612. + * are met:
  613. + * 1. Redistributions of source code must retain the above copyright
  614. + * notice, this list of conditions and the following disclaimer.
  615. + * 2. Redistributions in binary form must reproduce the above copyright
  616. + * notice, this list of conditions and the following disclaimer in the
  617. + * documentation and/or other materials provided with the distribution.
  618. + * 3. Neither the name of the author nor the names of any co-contributors
  619. + * may be used to endorse or promote products derived from this software
  620. + * without specific prior written permission.
  621. + *
  622. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  623. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  624. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  625. + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  626. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  627. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  628. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  629. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  630. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  631. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  632. + * SUCH DAMAGE.
  633. + */
  634. +
  635. +#include <sys/cdefs.h>
  636. +__FBSDID("$FreeBSD: src/sys/amd64/isa/dynticks.c,v 0.1.0 2010/05/02 16:26:20 OZAWATsusyohi Exp $");
  637. +
  638. +#include <sys/dynticks.h>
  639. +#include <sys/systm.h>
  640. +
  641. +static int enable_dynticks = 0;
  642. +static int use_ext_clksrc = 0;
  643. +static void (*cur_handler)(struct trapframe *frame);
  644. +static int (*cur_ext_handler)(struct trapframe *frame);
  645. +
  646. +static struct timer_ops *tops;
  647. +
  648. +void timer_intr_handler(struct trapframe *frame)
  649. +{
  650. + if(!cur_handler)
  651. + panic("cur_handler is NULL!\n");
  652. +
  653. + cur_handler(frame);
  654. +}
  655. +
  656. +int ext_timer_intr_handler(struct trapframe *frame)
  657. +{
  658. + if(!cur_ext_handler)
  659. + panic("cur_ext_handler is NULL!\n");
  660. +
  661. + return cur_ext_handler(frame);
  662. +}
  663. +
  664. +void register_timer_intr_handlers(struct timer_ops *ops)
  665. +{
  666. + tops = ops;
  667. +
  668. + if (ops->perticks_handler) {
  669. + cur_handler = ops->perticks_handler;
  670. + use_ext_clksrc = 0;
  671. + }
  672. +
  673. + if ( tops->perticks_handler && tops->dynticks_handler) {
  674. + enable_dynticks = 1;
  675. + }
  676. +}
  677. +
  678. +void register_ext_timer_intr_handlers(struct timer_ops *ops)
  679. +{
  680. + tops = ops;
  681. +
  682. + if (tops->ext_perticks_handler) {
  683. + cur_ext_handler = ops->ext_perticks_handler;
  684. + use_ext_clksrc = 1;
  685. + }
  686. +
  687. + if (tops->ext_perticks_handler && tops->ext_dynticks_handler) {
  688. + enable_dynticks = 1;
  689. + }
  690. +}
  691. +
  692. +void switch_to_dynticks(void)
  693. +{
  694. + if(!enable_dynticks)
  695. + return;
  696. +
  697. + /* TODO: swtich external clock handler */
  698. + if(use_ext_clksrc)
  699. + return;
  700. +
  701. + critical_enter();
  702. + cur_handler = tops->dynticks_handler;
  703. + tops->set_next_timer_intr();
  704. + critical_exit();
  705. +}
  706. +
  707. +void switch_to_perticks(void)
  708. +{
  709. + if(!enable_dynticks)
  710. + return;
  711. +
  712. + /* TODO: swtich external clock handler */
  713. + if(use_ext_clksrc)
  714. + return;
  715. +
  716. + if(!tops->perticks_handler){
  717. + panic("NULL perticks handler!\n");
  718. + return;
  719. + }
  720. +
  721. + critical_enter();
  722. + cur_handler = tops->perticks_handler;
  723. + tops->set_timer_periodic();
  724. + critical_exit();
  725. +}
  726. diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c
  727. index d2faa52..82ab8eb 100644
  728. --- a/sys/kern/kern_clock.c
  729. +++ b/sys/kern/kern_clock.c
  730. @@ -344,6 +344,33 @@ hardclock(int usermode, uintfptr_t pc)
  731. #endif /* SW_WATCHDOG */
  732. }
  733.  
  734. +void
  735. +hardclock_dynticks(int usermode, uintfptr_t pc,int skip)
  736. +{
  737. + //int i;
  738. +
  739. + //atomic_add_int((volatile int *)&ticks, skip); // FIXME
  740. + atomic_add_int((volatile int *)&ticks, 1);
  741. + hardclock_cpu(usermode);
  742. + tc_ticktock();
  743. + /*
  744. + * If no separate statistics clock is available, run it from here.
  745. + *
  746. + * XXX: this only works for UP
  747. + */
  748. + if (stathz == 0) {
  749. + profclock(usermode, pc);
  750. + statclock(usermode);
  751. + }
  752. +#ifdef DEVICE_POLLING
  753. + hardclock_device_poll(); /* this is very short and quick */
  754. +#endif /* DEVICE_POLLING */
  755. +#ifdef SW_WATCHDOG
  756. + if (watchdog_enabled > 0 && (watchdog_ticks -= skip ) <= 0)
  757. + watchdog_fire();
  758. +#endif /* SW_WATCHDOG */
  759. +}
  760. +
  761. /*
  762. * Compute number of ticks in the specified amount of time.
  763. */
  764. diff --git a/sys/kern/kern_timeout.c b/sys/kern/kern_timeout.c
  765. index 658dcc3..f982a77 100644
  766. --- a/sys/kern/kern_timeout.c
  767. +++ b/sys/kern/kern_timeout.c
  768. @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD: src/sys/kern/kern_timeout.c,v 1.106.2.1.4.1 2010/02/10 00:26
  769. #include <sys/proc.h>
  770. #include <sys/sleepqueue.h>
  771. #include <sys/sysctl.h>
  772. +#include <sys/dynticks.h>
  773.  
  774. static int avg_depth;
  775. SYSCTL_INT(_debug, OID_AUTO, to_avg_depth, CTLFLAG_RD, &avg_depth, 0,
  776. @@ -704,3 +705,30 @@ adjust_timeout_calltodo(time_change)
  777. return;
  778. }
  779. #endif /* APM_FIXUP_CALLTODO */
  780. +
  781. +int
  782. +callout_get_next_event(void)
  783. +{
  784. + struct callout *c;
  785. + struct callout_tailq *sc;
  786. + int curticks;
  787. + int skip = 1;
  788. +
  789. + curticks = softticks;
  790. +
  791. + while( skip < ncallout ) {
  792. + sc = &callwheel[ (curticks+skip) & callwheelmask ];
  793. + /* scan callout queue to get next timer event */
  794. + TAILQ_FOREACH( c, sc, c_links.tqe ){
  795. + if( c && c->c_time <= curticks + ncallout ){
  796. + if( c->c_time > 0 ){
  797. + goto out;
  798. + }
  799. + }
  800. + }
  801. + skip++;
  802. + }
  803. +
  804. +out:
  805. + return skip;
  806. +}
  807. diff --git a/sys/kern/sched_4bsd.c b/sys/kern/sched_4bsd.c
  808. index b9871b8..e12d45b 100644
  809. --- a/sys/kern/sched_4bsd.c
  810. +++ b/sys/kern/sched_4bsd.c
  811. @@ -54,6 +54,7 @@ __FBSDID("$FreeBSD: src/sys/kern/sched_4bsd.c,v 1.106.2.9.2.1 2010/02/10 00:26:2
  812. #include <sys/sx.h>
  813. #include <sys/turnstile.h>
  814. #include <sys/umtx.h>
  815. +#include <sys/dynticks.h>
  816. #include <machine/pcb.h>
  817. #include <machine/smp.h>
  818.  
  819. @@ -1430,8 +1431,10 @@ sched_idletd(void *dummy)
  820. for (;;) {
  821. mtx_assert(&Giant, MA_NOTOWNED);
  822.  
  823. + switch_to_dynticks();
  824. while (sched_runnable() == 0)
  825. cpu_idle();
  826. + switch_to_perticks();
  827.  
  828. mtx_lock_spin(&sched_lock);
  829. mi_switch(SW_VOL, NULL);
  830. diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c
  831. index 7943bb2..1bf9e31 100644
  832. --- a/sys/kern/sched_ule.c
  833. +++ b/sys/kern/sched_ule.c
  834. @@ -61,6 +61,7 @@ __FBSDID("$FreeBSD: src/sys/kern/sched_ule.c,v 1.214.2.12.2.1 2010/02/10 00:26:2
  835. #include <sys/umtx.h>
  836. #include <sys/vmmeter.h>
  837. #include <sys/cpuset.h>
  838. +#include <sys/dynticks.h>
  839. #ifdef KTRACE
  840. #include <sys/uio.h>
  841. #include <sys/ktrace.h>
  842. @@ -2670,12 +2671,14 @@ sched_idletd(void *dummy)
  843. mtx_assert(&Giant, MA_NOTOWNED);
  844. /* ULE relies on preemption for idle interruption. */
  845. for (;;) {
  846. + switch_to_dynticks();
  847. #ifdef SMP
  848. if (tdq_idled(tdq))
  849. cpu_idle();
  850. #else
  851. cpu_idle();
  852. #endif
  853. + switch_to_perticks();
  854. }
  855. }
  856.  
  857. diff --git a/sys/sys/dynticks.h b/sys/sys/dynticks.h
  858. new file mode 100644
  859. index 0000000..5b268cd
  860. --- /dev/null
  861. +++ b/sys/sys/dynticks.h
  862. @@ -0,0 +1,49 @@
  863. +#ifndef _SYS_DYNTICKS_H_
  864. +#define _SYS_DYNTICKS_H_
  865. +
  866. +/*-
  867. + * Copyright (c) 2010 Tsuyoshi OZAWA
  868. + * All rights reserved.
  869. + *
  870. + * Redistribution and use in source and binary forms, with or without
  871. + * modification, are permitted provided that the following conditions
  872. + * are met:
  873. + * 1. Redistributions of source code must retain the above copyright
  874. + * notice, this list of conditions and the following disclaimer.
  875. + * 2. Redistributions in binary form must reproduce the above copyright
  876. + * notice, this list of conditions and the following disclaimer in the
  877. + * documentation and/or other materials provided with the distribution.
  878. + *
  879. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  880. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  881. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  882. + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  883. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  884. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  885. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  886. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  887. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  888. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  889. + * SUCH DAMAGE.
  890. + *
  891. + */
  892. +#include <sys/types.h>
  893. +#include <machine/frame.h>
  894. +
  895. +struct timer_ops {
  896. + void (*perticks_handler)(struct trapframe *frame);
  897. + int (*ext_perticks_handler)(struct trapframe *frame);
  898. + void (*dynticks_handler)(struct trapframe *frame);
  899. + int (*ext_dynticks_handler)(struct trapframe *frame);
  900. + void (*set_timer_periodic)(void);
  901. + void (*set_next_timer_intr)(void);
  902. +};
  903. +
  904. +void timer_intr_handler(struct trapframe *frame);
  905. +int ext_timer_intr_handler(struct trapframe *frame);
  906. +int callout_get_next_event(void);
  907. +void register_timer_intr_handlers(struct timer_ops *ops);
  908. +void register_ext_timer_intr_handlers(struct timer_ops *ops);
  909. +void switch_to_dynticks(void);
  910. +void switch_to_perticks(void);
  911. +#endif /* _SYS_DYNTICKS_H_ */
  912. diff --git a/sys/sys/systm.h b/sys/sys/systm.h
  913. index 45969b3..9d6525d 100644
  914. --- a/sys/sys/systm.h
  915. +++ b/sys/sys/systm.h
  916. @@ -232,6 +232,7 @@ u_long casuword(volatile u_long *p, u_long oldval, u_long newval);
  917. void realitexpire(void *);
  918.  
  919. void hardclock(int usermode, uintfptr_t pc);
  920. +void hardclock_dynticks(int usermode, uintfptr_t pc,int skip);
  921. void hardclock_cpu(int usermode);
  922. void softclock(void *);
  923. void statclock(int usermode);
  924. --
  925. 1.7.0.1
Add Comment
Please, Sign In to add comment