arch/um/kernel/time.c

Source file repositories/reference/linux-study-clean/arch/um/kernel/time.c

File Facts

System
Linux kernel
Corpus path
arch/um/kernel/time.c
Extension
.c
Size
29574 bytes
Lines
1093
Domain
Architecture Layer
Bucket
arch/um
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

while (os_poll(1, &time_travel_ext_fd) != 0) {
			/* nothing */
		}
	}

	if (unlikely(mode == TTMH_READ_START_ACK)) {
		int fd[UM_TIMETRAVEL_SHARED_MAX_FDS];

		ret = os_rcv_fd_msg(time_travel_ext_fd, fd,
				    ARRAY_SIZE(fd), msg, sizeof(*msg));
		if (ret == sizeof(*msg)) {
			time_travel_setup_shm(fd[UM_TIMETRAVEL_SHARED_MEMFD],
					      msg->time & UM_TIMETRAVEL_START_ACK_ID);
			/* we don't use the logging for now */
			os_close_file(fd[UM_TIMETRAVEL_SHARED_LOGFD]);
		}
	} else {
		ret = os_read_file(time_travel_ext_fd, msg, sizeof(*msg));
	}

	if (ret == 0)
		panic("time-travel external link is broken\n");
	if (ret != sizeof(*msg))
		panic("invalid time-travel message - %d bytes\n", ret);

	switch (msg->op) {
	default:
		WARN_ONCE(1, "time-travel: unexpected message %lld\n",
			  (unsigned long long)msg->op);
		break;
	case UM_TIMETRAVEL_ACK:
		return;
	case UM_TIMETRAVEL_RUN:
		time_travel_set_time(msg->time);
		if (time_travel_shm) {
			/* no request right now since we're running */
			time_travel_shm_client->flags &=
				~UM_TIMETRAVEL_SCHEDSHM_FLAGS_REQ_RUN;
			/* no ack for shared memory RUN */
			return;
		}
		break;
	case UM_TIMETRAVEL_FREE_UNTIL:
		/* not supposed to get this with shm, but ignore it */
		if (time_travel_shm)
			break;
		time_travel_ext_free_until = &_time_travel_ext_free_until;
		_time_travel_ext_free_until = msg->time;
		break;
	case UM_TIMETRAVEL_BROADCAST:
		bc_message = msg->time;
		time_travel_should_print_bc_msg = 1;
		break;
	}

	resp.seq = msg->seq;
	os_write_file(time_travel_ext_fd, &resp, sizeof(resp));
}

static u64 time_travel_ext_req(u32 op, u64 time)
{
	static int seq;
	int mseq = ++seq;
	struct um_timetravel_msg msg = {
		.op = op,
		.time = time,
		.seq = mseq,
	};

	/*
	 * We need to block even the timetravel handlers of SIGIO here and
	 * only restore their use when we got the ACK - otherwise we may
	 * (will) get interrupted by that, try to queue the IRQ for future
	 * processing and thus send another request while we're still waiting
	 * for an ACK, but the peer doesn't know we got interrupted and will
	 * send the ACKs in the same order as the message, but we'd need to
	 * see them in the opposite order ...
	 *
	 * This wouldn't matter *too* much, but some ACKs carry the
	 * current time (for UM_TIMETRAVEL_GET) and getting another
	 * ACK without a time would confuse us a lot!
	 *
	 * The sequence number assignment that happens here lets us
	 * debug such message handling issues more easily.
	 */
	block_signals_hard();
	os_write_file(time_travel_ext_fd, &msg, sizeof(msg));

	/* no ACK expected for WAIT in shared memory mode */
	if (msg.op == UM_TIMETRAVEL_WAIT && time_travel_shm)

Annotation

Implementation Notes