lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Thu, 17 Dec 2015 06:53:04 +0000
From:	kan.liang@...el.com
To:	netdev@...r.kernel.org, davem@...emloft.net, bwh@...nel.org
Cc:	jesse.brandeburg@...el.com, andi@...stfloor.org,
	f.fainelli@...il.com, alexander.duyck@...il.com,
	jeffrey.t.kirsher@...el.com, shannon.nelson@...el.com,
	carolyn.wyborny@...el.com, donald.c.skidmore@...el.com,
	mitch.a.williams@...el.com, ogerlitz@...lanox.com,
	edumazet@...gle.com, jiri@...lanox.com, sfeldma@...il.com,
	gospo@...ulusnetworks.com, sasha.levin@...cle.com,
	dsahern@...il.com, tj@...nel.org, cascardo@...hat.com,
	corbet@....net, ben@...adent.org.uk,
	Kan Liang <kan.liang@...el.com>
Subject: [RFC 3/5] ethtool: introduce new ioctl for per queue setting

From: Kan Liang <kan.liang@...el.com>

Introduce a new ioctl for per queue parameters setting.
Users can apply commands to specific queues by setting SUB_COMMAND and
queue_mask as following command.

 ethtool --set-perqueue-command DEVNAME [queue_mask %x] SUB_COMMAND

If queue_mask is not set, the SUB_COMMAND will be applied to all queues.

The following patches will enable SUB_COMMANDs for per queue setting.

Signed-off-by: Kan Liang <kan.liang@...el.com>
---
 ethtool-copy.h | 18 +++++++++++
 ethtool.c      | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 internal.h     |  2 ++
 3 files changed, 114 insertions(+)

diff --git a/ethtool-copy.h b/ethtool-copy.h
index d23ffc4..a76c1dc 100644
--- a/ethtool-copy.h
+++ b/ethtool-copy.h
@@ -1108,6 +1108,22 @@ enum ethtool_sfeatures_retval_bits {
 #define ETHTOOL_F_WISH          (1 << ETHTOOL_F_WISH__BIT)
 #define ETHTOOL_F_COMPAT        (1 << ETHTOOL_F_COMPAT__BIT)
 
+#define MAX_QUEUE		4096
+#define MAX_QUEUE_MASK		(MAX_QUEUE / 64)
+
+/**
+ * struct ethtool_per_queue_op - apply sub command to the queues in mask.
+ * @cmd: ETHTOOL_PERQUEUE
+ * @queue_mask: Mask the queues which sub command apply to
+ * @sub_command: the sub command
+ * @data: parameters of the command
+ */
+struct ethtool_per_queue_op {
+	__u32	cmd;
+	__u64	queue_mask[MAX_QUEUE_MASK];
+	__u32	sub_command;
+	char	data[];
+};
 
 /* CMDs currently supported */
 #define ETHTOOL_GSET		0x00000001 /* Get settings. */
@@ -1190,6 +1206,8 @@ enum ethtool_sfeatures_retval_bits {
 #define ETHTOOL_GTUNABLE	0x00000048 /* Get tunable configuration */
 #define ETHTOOL_STUNABLE	0x00000049 /* Set tunable configuration */
 
+#define ETHTOOL_PERQUEUE	0x0000004a /* Set per queue options */
+
 /* compatibility with older code */
 #define SPARC_ETH_GSET		ETHTOOL_GSET
 #define SPARC_ETH_SSET		ETHTOOL_SSET
diff --git a/ethtool.c b/ethtool.c
index cb9e630..ea88c85 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -3989,6 +3989,8 @@ static int do_seee(struct cmd_context *ctx)
 	return 0;
 }
 
+static int do_perqueue(struct cmd_context *ctx);
+
 #ifndef TEST_ETHTOOL
 int send_ioctl(struct cmd_context *ctx, void *cmd)
 {
@@ -4146,6 +4148,8 @@ static const struct option {
 	  "		[ advertise %x ]\n"
 	  "		[ tx-lpi on|off ]\n"
 	  "		[ tx-timer %d ]\n"},
+	{ "--set-perqueue-command", 1, do_perqueue, "Set per queue command",
+	  "		[queue_mask %x] SUB_COMMAND\n"},
 	{ "-h|--help", 0, show_usage, "Show this help" },
 	{ "--version", 0, do_version, "Show version number" },
 	{}
@@ -4197,6 +4201,96 @@ static int find_option(int argc, char **argp)
 	return -1;
 }
 
+static int set_queue_mask(u64 *queue_mask, char *str)
+{
+	int len = strlen(str);
+	int index = BITS_TO_U64((len * 4));
+	char tmp[17];
+	char *end = str + len;
+	int i, num;
+
+	if (len > MAX_QUEUE)
+		return -EINVAL;
+
+	for (i = 0; i < index; i++) {
+		num = end - str;
+		if (num >= 16) {
+			end -= 16;
+			num = 16;
+		} else {
+			end = str;
+		}
+		strncpy(tmp, end, num);
+		tmp[num] = '\0';
+
+		queue_mask[i] = strtoull(tmp, NULL, 16);
+	}
+
+	return 0;
+}
+
+#define MAX(x, y) (x > y ? x : y)
+
+static int find_max_queue_num(struct cmd_context *ctx)
+{
+	struct ethtool_channels echannels;
+
+	echannels.cmd = ETHTOOL_GCHANNELS;
+	if (send_ioctl(ctx, &echannels))
+		return -1;
+
+	return MAX(MAX(echannels.rx_count, echannels.tx_count), echannels.combined_count);
+}
+
+static int do_perqueue(struct cmd_context *ctx)
+{
+	__u64 queue_mask[MAX_QUEUE_MASK] = {0};
+	__u64 mask;
+	int i, queue_num = 0;
+
+	if (ctx->argc == 0)
+		exit_bad_args();
+
+	/* All queues will be applied if no queue_mask set */
+	if (strncmp(*ctx->argp, "queue_mask", 10)) {
+		queue_num = find_max_queue_num(ctx);
+		if (queue_num < 0) {
+			perror("Cannot get queue number");
+			return -EFAULT;
+		}
+		for (i = 0; i < queue_num / 64; i++)
+			queue_mask[i] = ~0;
+		queue_mask[i] = (1ULL << (queue_num - i * 64)) - 1;
+	} else {
+		ctx->argc--;
+		ctx->argp++;
+		if (set_queue_mask(queue_mask, *ctx->argp)) {
+			perror("Invalid queue mask");
+			return -EINVAL;
+		}
+		ctx->argc--;
+		ctx->argp++;
+
+		/* Get the masked queue number */
+		for (i = 0; i < MAX_QUEUE_MASK; i++) {
+			mask = queue_mask[i];
+			while (mask > 0) {
+				if (mask & 0x1)
+					queue_num++;
+				mask = mask >> 1;
+			}
+		}
+	}
+
+	i = find_option(ctx->argc, ctx->argp);
+	if (i < 0)
+		exit_bad_args();
+
+	/* no sub_command support yet */
+
+	return 0;
+}
+
 int main(int argc, char **argp)
 {
 	int (*func)(struct cmd_context *);
diff --git a/internal.h b/internal.h
index b5ef646..6690d40 100644
--- a/internal.h
+++ b/internal.h
@@ -65,8 +65,10 @@ static inline u64 cpu_to_be64(u64 value)
 
 #define BITS_PER_BYTE		8
 #define BITS_PER_LONG		(BITS_PER_BYTE * sizeof(long))
+#define BITS_PER_LONG_LONG	(BITS_PER_BYTE * sizeof(unsigned long long))
 #define DIV_ROUND_UP(n, d)	(((n) + (d) - 1) / (d))
 #define BITS_TO_LONGS(nr)	DIV_ROUND_UP(nr, BITS_PER_LONG)
+#define BITS_TO_U64(nr)		DIV_ROUND_UP(nr, BITS_PER_LONG_LONG)
 
 static inline void set_bit(unsigned int nr, unsigned long *addr)
 {
-- 
1.7.11.7

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ