tools/testing/selftests/drivers/net/so_txtime.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/drivers/net/so_txtime.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/drivers/net/so_txtime.c
Extension
.c
Size
12557 bytes
Lines
539
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct timed_send {
	char	data;
	int64_t	delay_us;
};

#define MAX_NUM_PKT	8
static struct timed_send cfg_buf[MAX_NUM_PKT];
static int cfg_num_pkt;

static int cfg_errq_level;
static int cfg_errq_type;

static struct sockaddr_storage cfg_dst_addr;
static struct sockaddr_storage cfg_src_addr;
static socklen_t cfg_alen;

static uint64_t gettime_ns(clockid_t clock)
{
	struct timespec ts;

	if (clock_gettime(clock, &ts))
		error(1, errno, "gettime");

	return ts.tv_sec * (1000ULL * 1000 * 1000) + ts.tv_nsec;
}

static void do_send_one(int fdt, struct timed_send *ts)
{
	char control[CMSG_SPACE(sizeof(uint64_t))];
	struct msghdr msg = {0};
	struct iovec iov = {0};
	struct cmsghdr *cm;
	uint64_t tdeliver;
	int ret;

	iov.iov_base = &ts->data;
	iov.iov_len = 1;

	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;
	msg.msg_name = (struct sockaddr *)&cfg_dst_addr;
	msg.msg_namelen = cfg_alen;

	if (ts->delay_us >= 0) {
		memset(control, 0, sizeof(control));
		msg.msg_control = &control;
		msg.msg_controllen = sizeof(control);

		tdeliver = glob_tstart + ts->delay_us * 1000;
		tdeliver_max = tdeliver_max > tdeliver ?
			       tdeliver_max : tdeliver;

		cm = CMSG_FIRSTHDR(&msg);
		cm->cmsg_level = SOL_SOCKET;
		cm->cmsg_type = SCM_TXTIME;
		cm->cmsg_len = CMSG_LEN(sizeof(tdeliver));
		memcpy(CMSG_DATA(cm), &tdeliver, sizeof(tdeliver));
	}

	ret = sendmsg(fdt, &msg, 0);
	if (ret == -1)
		error(1, errno, "write");
	if (ret == 0)
		error(1, 0, "write: 0B");

}

static void do_recv_one(int fdr, struct timed_send *ts)
{
	int64_t tstop, texpect;
	char rbuf[2];
	int ret;

	ret = recv(fdr, rbuf, sizeof(rbuf), 0);
	if (ret == -1 && errno == EAGAIN)
		error(1, EAGAIN, "recv: timeout");
	if (ret == -1)
		error(1, errno, "read");
	if (ret != 1)
		error(1, 0, "read: %dB", ret);

	tstop = (gettime_ns(cfg_clockid) - glob_tstart) / 1000;
	texpect = ts->delay_us >= 0 ? ts->delay_us : 0;

	fprintf(stderr, "payload:%c delay:%lld expected:%lld (us)\n",
			rbuf[0], (long long)tstop, (long long)texpect);

	if (rbuf[0] != ts->data) {
		fprintf(stderr, "payload mismatch. expected %c\n", ts->data);
		errors++;

Annotation

Implementation Notes