Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ioctl: Split latency outputs from debugging feature to show command #764

Closed
wants to merge 5 commits into from

Conversation

ikegami-t
Copy link
Contributor

No description provided.

Output only latency since not a debugging purpose but for performance.

Signed-off-by: Tokunori Ikegami <[email protected]>
src/nvme/ioctl.c Outdated
(end.tv_sec - start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec));
}

const char *nvme_admin_to_string(__u8 opcode)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would these functions be useful to export from libnvme?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your comments. Yes the code basically copied from nvme-cli: nvme_cmd_to_string() and duplicated so I will do merge the functionality to export from libnmve.

src/nvme/ioctl.c Outdated
Comment on lines 175 to 178
break;
}

return NULL;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just return NULL instead of break?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my understandig for the coding manner better to use the default case. By the way how about the following implementation instead? Or just I thought also to define the opcode strings as a table to use instead of the function using the switch case statements.

	char *ret = NULL;

	switch (opcode) {
	case nvme_admin_delete_sq:
		ret = "Delete I/O Submission Queue";
		break;
...
	default:
		break;
	}

	return ret;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is terser and easier to follow to just return from the switch case, but doesn't really matter. A simple lookup table could definitely be faster. It might take up more memory unless you only stored entries up to the largest defined opcode.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see so will do try to use the table later.

src/nvme/ioctl.c Outdated
}

if (nvme_get_debug())
nvme_show_command(cmd, err);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pre-existing, but curious why the 64-bit ioctls (nvme_submit_passthru64()) don't do this logging. Is it not useful for them? Does it just require more work to implement than it's worth?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes will do implement as same for the 64-bit ioctls also.

To use by nvme-cli since duplicated the function in nvme-cli.

Signed-off-by: Tokunori Ikegami <[email protected]>
Also move the functions into util from ioctl.

Signed-off-by: Tokunori Ikegami <[email protected]>
src/nvme/ioctl.c Outdated
{
const char *cmd_name;

if (req == NVME_IOCTL_ADMIN_CMD || req == NVME_IOCTL_ADMIN64_CMD)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use nvme_ioctl_cmd_admin()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do.

src/nvme/ioctl.c Outdated
Comment on lines 63 to 76
{
bool ioctl_cmd_admin = false;

switch (req) {
case NVME_IOCTL_ADMIN_CMD:
fallthrough;
case NVME_IOCTL_ADMIN64_CMD:
ioctl_cmd_admin = true;
break;
default:
break;
}

return ioctl_cmd_admin;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just return req == NVME_IOCTL_ADMIN_CMD || req == NVME_IOCTL_ADMIN64_CMD?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay right.

src/nvme/ioctl.c Outdated
Comment on lines 265 to 248
if (nvme_get_debug())
nvme_show_command(cmd, err);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could probably also be done in the 64-bit case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Will change as cmd will be handled for both the 32-bit and 64-bit cases.

{
bool ioctl_cmd = false;

switch (req) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you really need to use fallthrough? Why not just:

	switch (req) {
	case NVME_IOCTL_ADMIN_CMD:
	case NVME_IOCTL_IO_CMD:
	case NVME_IOCTL_ADMIN64_CMD:
	case NVME_IOCTL_IO64_CMD:
		ioctl_cmd = true;
		break;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The checkpatch.pl tool checks fallthrough and the tool is used by the PR check I think. Also usually used it in Kernel code I think also.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/scripts/checkpatch.pl#n7302

src/nvme/ioctl.c Outdated

static bool nvme_ioctl_cmd_64(unsigned long req)
{
if (req == NVME_IOCTL_ADMIN64_CMD || req == NVME_IOCTL_IO64_CMD)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be simplified to a single line:

return req == NVME_IOCTL_ADMIN64_CMD || req == NVME_IOCTL_IO64_CMD;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes looks good. Thank you.

return NULL;
}

const char *nvme_ioctl_to_string(unsigned long req)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be simplified as follows:

const char *nvme_ioctl_to_string(unsigned long req)
{
	switch (req) {
	case NVME_IOCTL_ID:
		return "ID";
	case NVME_IOCTL_RESET:
		return "Reset";
	case NVME_IOCTL_SUBSYS_RESET:
		return "Subsystem reset";
	case NVME_IOCTL_RESCAN:
		return "Rescan";
	case NVME_IOCTL_ADMIN_CMD:
		return "Admin command";
	case NVME_IOCTL_IO_CMD:
		return "IO command";
	case NVME_IOCTL_ADMIN64_CMD:
		return "Admin64 command";
	case NVME_IOCTL_IO64_CMD:
		return "IO64 command";
	default:
		break;
	}

	return NULL;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was mentioned by the comment #764 (comment) so changed as the current code. Is there any comment about this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry just I could understand your mention so fixed as suggested.

Note: The latency logging enabled for other nvme ioctl requests also.

Signed-off-by: Tokunori Ikegami <[email protected]>
Only result variable is different between nvme_passthru_cmd and cmd64.

Signed-off-by: Tokunori Ikegami <[email protected]>
@igaw
Copy link
Collaborator

igaw commented Jan 18, 2024

I don't like the whole approach. This is adding debugging code to the library. The commit 17429f7 didn't even consider all the ioctl interfaces (64bit version) and prints just to stdout. I think we should remove it.

Why not just use existing syscall tracers instead?

Simple syscall latencies can be traced with strace and you can go fancy with bpftrace. E.g something like:

#!/usr/bin/bpftrace
#include <sys/ioctl.h>

struct nvme_passthru_cmd {
	__u8	opcode;
	__u8	flags;
	__u16	rsvd1;
	__u32	nsid;
	__u32	cdw2;
	__u32	cdw3;
	__u64	metadata;
	__u64	addr;
	__u32	metadata_len;
	__u32	data_len;
	__u32	cdw10;
	__u32	cdw11;
	__u32	cdw12;
	__u32	cdw13;
	__u32	cdw14;
	__u32	cdw15;
	__u32	timeout_ms;
	__u32	result;
};

/* remember our own pid, so that we can filter it out from the handlers */
BEGIN { }

tracepoint:syscalls:sys_enter_ioctl /comm == "nvme" && args->__syscall_nr == 16/ {
       $cmd = (struct nvme_passthru_cmd *)args->arg;

       printf("opcode %d\n",$cmd->opcode);
       printf("cdw10 %x\n", $cmd->cdw10)
}

END { }

@igaw
Copy link
Collaborator

igaw commented Mar 7, 2024

With the recent refactoring in logging/debugging the annotation and measuring is done inside application. No need to clutter the library with debugging code.

@igaw igaw closed this Mar 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants