Lines Matching +full:always +full:- +full:wait +full:- +full:for +full:- +full:ack
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2015 Anton Ivanov (aivanov@{brocade.com,kot-begemot.co.uk})
5 * Copyright (C) 2012-2014 Cisco Systems
6 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
23 #include <linux/time-internal.h>
42 static int time_travel_ext_fd = -1;
56 return (unsigned long long)(jiffies - INITIAL_JIFFIES + in sched_clock()
64 panic("time-travel: time goes backwards %lld -> %lld\n", in time_travel_set_time()
85 printk(KERN_INFO "time-travel: received broadcast 0x%llx\n", bc_message); in _time_travel_print_bc_msg()
97 len = time_travel_shm->len; in time_travel_setup_shm()
99 if (time_travel_shm->version != UM_TIMETRAVEL_SCHEDSHM_VERSION || in time_travel_setup_shm()
112 time_travel_shm_offset = time_travel_shm->current_time; in time_travel_setup_shm()
113 time_travel_shm_client = &time_travel_shm->clients[id]; in time_travel_setup_shm()
114 time_travel_shm_client->capa |= UM_TIMETRAVEL_SCHEDSHM_CAP_TIME_SHARE; in time_travel_setup_shm()
116 /* always look at that free_until from now on */ in time_travel_setup_shm()
117 time_travel_ext_free_until = &time_travel_shm->free_until; in time_travel_setup_shm()
149 msg->time & UM_TIMETRAVEL_START_ACK_ID); in time_travel_handle_message()
150 /* we don't use the logging for now */ in time_travel_handle_message()
158 panic("time-travel external link is broken\n"); in time_travel_handle_message()
160 panic("invalid time-travel message - %d bytes\n", ret); in time_travel_handle_message()
162 switch (msg->op) { in time_travel_handle_message()
164 WARN_ONCE(1, "time-travel: unexpected message %lld\n", in time_travel_handle_message()
165 (unsigned long long)msg->op); in time_travel_handle_message()
170 time_travel_set_time(msg->time); in time_travel_handle_message()
173 time_travel_shm_client->flags &= in time_travel_handle_message()
175 /* no ack for shared memory RUN */ in time_travel_handle_message()
184 _time_travel_ext_free_until = msg->time; in time_travel_handle_message()
187 bc_message = msg->time; in time_travel_handle_message()
192 resp.seq = msg->seq; in time_travel_handle_message()
208 * only restore their use when we got the ACK - otherwise we may in time_travel_ext_req()
209 * (will) get interrupted by that, try to queue the IRQ for future in time_travel_ext_req()
211 * for an ACK, but the peer doesn't know we got interrupted and will in time_travel_ext_req()
216 * current time (for UM_TIMETRAVEL_GET) and getting another in time_travel_ext_req()
217 * ACK without a time would confuse us a lot! in time_travel_ext_req()
225 /* no ACK expected for WAIT in shared memory mode */ in time_travel_ext_req()
236 panic("time-travel: ACK message has different seqno! op=%d, seq=%d != %d time=%lld\n", in time_travel_ext_req()
269 /* asked for exactly this time previously */ in time_travel_ext_update_request()
278 * Note for shm we ignore FREE_UNTIL messages and leave the pointer in time_travel_ext_update_request()
279 * to shared memory, and for non-shm the offset is 0. in time_travel_ext_update_request()
282 time < (*time_travel_ext_free_until - time_travel_shm_offset)) in time_travel_ext_update_request()
291 running = &time_travel_shm->clients[time_travel_shm->running_id]; in time_travel_ext_update_request()
293 if (running->capa & UM_TIMETRAVEL_SCHEDSHM_CAP_TIME_SHARE) { in time_travel_ext_update_request()
294 time_travel_shm_client->flags |= in time_travel_ext_update_request()
297 time_travel_shm_client->req_time = time; in time_travel_ext_update_request()
298 if (time < time_travel_shm->free_until) in time_travel_ext_update_request()
299 time_travel_shm->free_until = time; in time_travel_ext_update_request()
312 if (time_travel_shm->running_id != time_travel_shm_id) in __time_travel_propagate_time()
313 panic("time-travel: setting time while not running\n"); in __time_travel_propagate_time()
314 time_travel_shm->current_time = time_travel_time + in __time_travel_propagate_time()
327 /* returns true if we must do a wait to the simtime device */
332 * don't have to request/wait for anything until then, unless in time_travel_ext_request()
335 * Note for shm we ignore FREE_UNTIL messages and leave the pointer in time_travel_ext_request()
336 * to shared memory, and for non-shm the offset is 0. in time_travel_ext_request()
339 time < (*time_travel_ext_free_until - time_travel_shm_offset)) in time_travel_ext_request()
357 time_travel_ext_req(UM_TIMETRAVEL_WAIT, -1); in time_travel_ext_wait()
369 time_travel_ext_waiting--; in time_travel_ext_wait()
371 /* we might request more stuff while polling - reset when we run */ in time_travel_ext_wait()
378 time_travel_set_time(time_travel_shm->current_time - in time_travel_ext_get_time()
381 time_travel_ext_req(UM_TIMETRAVEL_GET, -1); in time_travel_ext_get_time()
406 if (e->pending) in __time_travel_add_event()
409 e->pending = true; in __time_travel_add_event()
410 e->time = time; in __time_travel_add_event()
421 if ((tmp->time > e->time) || in __time_travel_add_event()
422 (tmp->time == e->time && tmp->onstack && e->onstack)) { in __time_travel_add_event()
423 list_add_tail(&e->list, &tmp->list); in __time_travel_add_event()
430 list_add_tail(&e->list, &time_travel_events); in __time_travel_add_event()
433 time_travel_ext_update_request(tmp->time); in __time_travel_add_event()
434 time_travel_next_event = tmp->time; in __time_travel_add_event()
441 if (WARN_ON(!e->fn)) in time_travel_add_event()
460 tt_extra_sched_jiffies -= 1; in time_travel_periodic_timer()
471 * Don't do anything for most cases. Note that because here we have in deliver_time_travel_irqs()
472 * to disable IRQs (and re-enable later) we'll actually recurse at in deliver_time_travel_irqs()
483 list_del(&e->list); in deliver_time_travel_irqs()
484 e->pending = false; in deliver_time_travel_irqs()
485 e->fn(e); in deliver_time_travel_irqs()
498 e->fn(e); in time_travel_deliver_event()
500 list_add_tail(&e->list, &time_travel_irqs); in time_travel_deliver_event()
506 e->pending = true; in time_travel_deliver_event()
512 e->fn(e); in time_travel_deliver_event()
522 if (!e->pending) in time_travel_del_event()
525 list_del(&e->list); in time_travel_del_event()
526 e->pending = false; in time_travel_del_event()
539 /* add it without a handler - we deal with that specifically below */ in time_travel_update_time()
546 __time_travel_update_time(e->time, idle); in time_travel_update_time()
551 BUG_ON(time_travel_time != e->time); in time_travel_update_time()
556 if (e->onstack) in time_travel_update_time()
557 panic("On-stack event dequeued outside of the stack! time=%lld, event time=%lld, event=%pS\n", in time_travel_update_time()
558 time_travel_time, e->time, e); in time_travel_update_time()
565 time_travel_ext_update_request(e->time); in time_travel_update_time()
603 * We could model interrupt latency here, for now just in time_travel_add_irq_event()
615 tt_extra_sched_jiffies -= 1; in time_travel_oneshot_timer()
623 * Wait "forever" (using S64_MAX because there are some potential in time_travel_sleep()
638 * This is somewhat wrong - we should get the first in time_travel_sleep()
643 os_timer_one_shot(time_travel_timer_event.time - next); in time_travel_sleep()
668 unsigned long long id = (unsigned long long)-1; in time_travel_connect_external()
673 if (sep - socket > sizeof(buf) - 1) in time_travel_connect_external()
676 memcpy(buf, socket, sep - socket); in time_travel_connect_external()
679 panic("time-travel: invalid external ID in string '%s'\n", in time_travel_connect_external()
681 return -EINVAL; in time_travel_connect_external()
689 panic("time-travel: failed to connect to external socket %s\n", in time_travel_connect_external()
708 time_travel_start = time_travel_ext_req(UM_TIMETRAVEL_GET_TOD, -1); in time_travel_set_start()
711 time_travel_start -= time_travel_time; in time_travel_set_start()
756 /* externally not usable - redefine here so we can */
766 * In basic time-travel mode we still get real interrupts in timer_handler()
770 * This is not the case in inf-cpu mode, since there we in timer_handler()
839 .name = "posix-timer",
852 ….min_delta_ticks = TIMER_MIN_DELTA, // microsecond resolution should be enough for anyone, same as…
859 if (get_current()->mm != NULL) in um_timer()
861 /* userspace - relay signal, results in correct userspace timers */ in um_timer()
862 os_alarm_process(get_current()->mm->context.id.pid); in um_timer()
881 * even more waiting, and that's not good - it messes up the in timer_read()
908 printk(KERN_ERR "register_timer : request_irq failed - " in um_timer_setup()
909 "errno = %d\n", -err); in um_timer_setup()
913 printk(KERN_ERR "creation of timer failed - errno = %d\n", -err); in um_timer_setup()
957 if (strcmp(str, "=inf-cpu") == 0) { in setup_time_travel()
959 timer_clockevent.name = "time-travel-timer-infcpu"; in setup_time_travel()
960 timer_clocksource.name = "time-travel-clock"; in setup_time_travel()
966 timer_clockevent.name = "time-travel-timer-external"; in setup_time_travel()
967 timer_clocksource.name = "time-travel-clock-external"; in setup_time_travel()
973 timer_clockevent.name = "time-travel-timer"; in setup_time_travel()
974 timer_clocksource.name = "time-travel-clock"; in setup_time_travel()
978 return -EINVAL; in setup_time_travel()
981 __setup("time-travel", setup_time_travel);
983 "time-travel\n"
986 "waiting for real time to elapse. However, instance CPU speed is limited by\n"
987 "the real CPU speed, so e.g. a 10ms timer will always fire after ~10ms wall\n"
990 "time-travel=inf-cpu\n"
992 "are no wall clock timers, and any CPU processing happens - as seen from the\n"
993 "guest - instantly. This can be useful for accurate simulation regardless of\n"
997 "time-travel=ext:[ID:]/path/to/socket\n"
998 "This enables time travel mode similar to =inf-cpu, except the system will\n"
1003 "The optional ID is a 64-bit integer that's sent to the central scheduler.\n");
1017 __setup("time-travel-start=", setup_time_travel_start);
1019 "time-travel-start=<nanoseconds>\n"
1045 static struct kobj_attribute bc_attribute = __ATTR(bc-message, 0660, bc_show, bc_store);
1052 bc_time_kobject = kobject_create_and_add("um-ext-time", kernel_kobj); in um_bc_start()