* [PATCH v5 19/26] app/testpmd: add item raw to flow command
From: Adrien Mazarguil @ 2016-12-21 14:51 UTC (permalink / raw)
To: dev
In-Reply-To: <cover.1482331076.git.adrien.mazarguil@6wind.com>
Matches arbitrary byte strings with properties:
- relative: look for pattern after the previous item.
- search: search pattern from offset (see also limit).
- offset: absolute or relative offset for pattern.
- limit: search area limit for start of pattern.
- length: pattern length.
- pattern: byte string to look for.
Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Olga Shern <olgas@mellanox.com>
---
app/test-pmd/cmdline_flow.c | 208 +++++++++++++++++++++++++++++++++++++++
1 file changed, 208 insertions(+)
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 0592969..c52a8f7 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -57,6 +57,8 @@ enum index {
INTEGER,
UNSIGNED,
PREFIX,
+ BOOLEAN,
+ STRING,
RULE_ID,
PORT_ID,
GROUP_ID,
@@ -106,6 +108,12 @@ enum index {
ITEM_VF_ID,
ITEM_PORT,
ITEM_PORT_INDEX,
+ ITEM_RAW,
+ ITEM_RAW_RELATIVE,
+ ITEM_RAW_SEARCH,
+ ITEM_RAW_OFFSET,
+ ITEM_RAW_LIMIT,
+ ITEM_RAW_PATTERN,
/* Validate/create actions. */
ACTIONS,
@@ -115,6 +123,13 @@ enum index {
ACTION_PASSTHRU,
};
+/** Size of pattern[] field in struct rte_flow_item_raw. */
+#define ITEM_RAW_PATTERN_SIZE 36
+
+/** Storage size for struct rte_flow_item_raw including pattern. */
+#define ITEM_RAW_SIZE \
+ (offsetof(struct rte_flow_item_raw, pattern) + ITEM_RAW_PATTERN_SIZE)
+
/** Maximum number of subsequent tokens and arguments on the stack. */
#define CTX_STACK_SIZE 16
@@ -216,6 +231,13 @@ struct token {
.size = sizeof(*((s *)0)->f), \
})
+/** Static initializer for ARGS() with arbitrary size. */
+#define ARGS_ENTRY_USZ(s, f, sz) \
+ (&(const struct arg){ \
+ .offset = offsetof(s, f), \
+ .size = (sz), \
+ })
+
/** Parser output buffer layout expected by cmd_flow_parsed(). */
struct buffer {
enum index command; /**< Flow command. */
@@ -306,6 +328,7 @@ static const enum index next_item[] = {
ITEM_PF,
ITEM_VF,
ITEM_PORT,
+ ITEM_RAW,
ZERO,
};
@@ -327,6 +350,16 @@ static const enum index item_port[] = {
ZERO,
};
+static const enum index item_raw[] = {
+ ITEM_RAW_RELATIVE,
+ ITEM_RAW_SEARCH,
+ ITEM_RAW_OFFSET,
+ ITEM_RAW_LIMIT,
+ ITEM_RAW_PATTERN,
+ ITEM_NEXT,
+ ZERO,
+};
+
static const enum index next_action[] = {
ACTION_END,
ACTION_VOID,
@@ -363,11 +396,19 @@ static int parse_int(struct context *, const struct token *,
static int parse_prefix(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
+static int parse_boolean(struct context *, const struct token *,
+ const char *, unsigned int,
+ void *, unsigned int);
+static int parse_string(struct context *, const struct token *,
+ const char *, unsigned int,
+ void *, unsigned int);
static int parse_port(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
static int comp_none(struct context *, const struct token *,
unsigned int, char *, unsigned int);
+static int comp_boolean(struct context *, const struct token *,
+ unsigned int, char *, unsigned int);
static int comp_action(struct context *, const struct token *,
unsigned int, char *, unsigned int);
static int comp_port(struct context *, const struct token *,
@@ -410,6 +451,20 @@ static const struct token token_list[] = {
.call = parse_prefix,
.comp = comp_none,
},
+ [BOOLEAN] = {
+ .name = "{boolean}",
+ .type = "BOOLEAN",
+ .help = "any boolean value",
+ .call = parse_boolean,
+ .comp = comp_boolean,
+ },
+ [STRING] = {
+ .name = "{string}",
+ .type = "STRING",
+ .help = "fixed string",
+ .call = parse_string,
+ .comp = comp_none,
+ },
[RULE_ID] = {
.name = "{rule id}",
.type = "RULE ID",
@@ -654,6 +709,52 @@ static const struct token token_list[] = {
.next = NEXT(item_port, NEXT_ENTRY(UNSIGNED), item_param),
.args = ARGS(ARGS_ENTRY(struct rte_flow_item_port, index)),
},
+ [ITEM_RAW] = {
+ .name = "raw",
+ .help = "match an arbitrary byte string",
+ .priv = PRIV_ITEM(RAW, ITEM_RAW_SIZE),
+ .next = NEXT(item_raw),
+ .call = parse_vc,
+ },
+ [ITEM_RAW_RELATIVE] = {
+ .name = "relative",
+ .help = "look for pattern after the previous item",
+ .next = NEXT(item_raw, NEXT_ENTRY(BOOLEAN), item_param),
+ .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw,
+ relative, 1)),
+ },
+ [ITEM_RAW_SEARCH] = {
+ .name = "search",
+ .help = "search pattern from offset (see also limit)",
+ .next = NEXT(item_raw, NEXT_ENTRY(BOOLEAN), item_param),
+ .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw,
+ search, 1)),
+ },
+ [ITEM_RAW_OFFSET] = {
+ .name = "offset",
+ .help = "absolute or relative offset for pattern",
+ .next = NEXT(item_raw, NEXT_ENTRY(INTEGER), item_param),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, offset)),
+ },
+ [ITEM_RAW_LIMIT] = {
+ .name = "limit",
+ .help = "search area limit for start of pattern",
+ .next = NEXT(item_raw, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, limit)),
+ },
+ [ITEM_RAW_PATTERN] = {
+ .name = "pattern",
+ .help = "byte string to look for",
+ .next = NEXT(item_raw,
+ NEXT_ENTRY(STRING),
+ NEXT_ENTRY(ITEM_PARAM_IS,
+ ITEM_PARAM_SPEC,
+ ITEM_PARAM_MASK)),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, length),
+ ARGS_ENTRY_USZ(struct rte_flow_item_raw,
+ pattern,
+ ITEM_RAW_PATTERN_SIZE)),
+ },
/* Validate/create actions. */
[ACTIONS] = {
.name = "actions",
@@ -1246,6 +1347,96 @@ parse_int(struct context *ctx, const struct token *token,
return -1;
}
+/**
+ * Parse a string.
+ *
+ * Two arguments (ctx->args) are retrieved from the stack to store data and
+ * its length (in that order).
+ */
+static int
+parse_string(struct context *ctx, const struct token *token,
+ const char *str, unsigned int len,
+ void *buf, unsigned int size)
+{
+ const struct arg *arg_data = pop_args(ctx);
+ const struct arg *arg_len = pop_args(ctx);
+ char tmp[16]; /* Ought to be enough. */
+ int ret;
+
+ /* Arguments are expected. */
+ if (!arg_data)
+ return -1;
+ if (!arg_len) {
+ push_args(ctx, arg_data);
+ return -1;
+ }
+ size = arg_data->size;
+ /* Bit-mask fill is not supported. */
+ if (arg_data->mask || size < len)
+ goto error;
+ if (!ctx->object)
+ return len;
+ /* Let parse_int() fill length information first. */
+ ret = snprintf(tmp, sizeof(tmp), "%u", len);
+ if (ret < 0)
+ goto error;
+ push_args(ctx, arg_len);
+ ret = parse_int(ctx, token, tmp, ret, NULL, 0);
+ if (ret < 0) {
+ pop_args(ctx);
+ goto error;
+ }
+ buf = (uint8_t *)ctx->object + arg_data->offset;
+ /* Output buffer is not necessarily NUL-terminated. */
+ memcpy(buf, str, len);
+ memset((uint8_t *)buf + len, 0x55, size - len);
+ if (ctx->objmask)
+ memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len);
+ return len;
+error:
+ push_args(ctx, arg_len);
+ push_args(ctx, arg_data);
+ return -1;
+}
+
+/** Boolean values (even indices stand for false). */
+static const char *const boolean_name[] = {
+ "0", "1",
+ "false", "true",
+ "no", "yes",
+ "N", "Y",
+ NULL,
+};
+
+/**
+ * Parse a boolean value.
+ *
+ * Last argument (ctx->args) is retrieved to determine storage size and
+ * location.
+ */
+static int
+parse_boolean(struct context *ctx, const struct token *token,
+ const char *str, unsigned int len,
+ void *buf, unsigned int size)
+{
+ const struct arg *arg = pop_args(ctx);
+ unsigned int i;
+ int ret;
+
+ /* Argument is expected. */
+ if (!arg)
+ return -1;
+ for (i = 0; boolean_name[i]; ++i)
+ if (!strncmp(str, boolean_name[i], len))
+ break;
+ /* Process token as integer. */
+ if (boolean_name[i])
+ str = i & 1 ? "1" : "0";
+ push_args(ctx, arg);
+ ret = parse_int(ctx, token, str, strlen(str), buf, size);
+ return ret > 0 ? (int)len : ret;
+}
+
/** Parse port and update context. */
static int
parse_port(struct context *ctx, const struct token *token,
@@ -1284,6 +1475,23 @@ comp_none(struct context *ctx, const struct token *token,
return 0;
}
+/** Complete boolean values. */
+static int
+comp_boolean(struct context *ctx, const struct token *token,
+ unsigned int ent, char *buf, unsigned int size)
+{
+ unsigned int i;
+
+ (void)ctx;
+ (void)token;
+ for (i = 0; boolean_name[i]; ++i)
+ if (buf && i == ent)
+ return snprintf(buf, size, "%s", boolean_name[i]);
+ if (buf)
+ return -1;
+ return i;
+}
+
/** Complete action names. */
static int
comp_action(struct context *ctx, const struct token *token,
--
2.1.4
^ permalink raw reply related
* [PATCH v5 20/26] app/testpmd: add items eth/vlan to flow command
From: Adrien Mazarguil @ 2016-12-21 14:51 UTC (permalink / raw)
To: dev
In-Reply-To: <cover.1482331076.git.adrien.mazarguil@6wind.com>
These pattern items match basic Ethernet headers (source, destination and
type) and related 802.1Q/ad VLAN headers.
Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Olga Shern <olgas@mellanox.com>
---
app/test-pmd/cmdline_flow.c | 126 +++++++++++++++++++++++++++++++++++++++
1 file changed, 126 insertions(+)
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index c52a8f7..e22e0c2 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -43,6 +43,7 @@
#include <rte_ethdev.h>
#include <rte_byteorder.h>
#include <cmdline_parse.h>
+#include <cmdline_parse_etheraddr.h>
#include <rte_flow.h>
#include "testpmd.h"
@@ -59,6 +60,7 @@ enum index {
PREFIX,
BOOLEAN,
STRING,
+ MAC_ADDR,
RULE_ID,
PORT_ID,
GROUP_ID,
@@ -114,6 +116,13 @@ enum index {
ITEM_RAW_OFFSET,
ITEM_RAW_LIMIT,
ITEM_RAW_PATTERN,
+ ITEM_ETH,
+ ITEM_ETH_DST,
+ ITEM_ETH_SRC,
+ ITEM_ETH_TYPE,
+ ITEM_VLAN,
+ ITEM_VLAN_TPID,
+ ITEM_VLAN_TCI,
/* Validate/create actions. */
ACTIONS,
@@ -238,6 +247,14 @@ struct token {
.size = (sz), \
})
+/** Same as ARGS_ENTRY() using network byte ordering. */
+#define ARGS_ENTRY_HTON(s, f) \
+ (&(const struct arg){ \
+ .hton = 1, \
+ .offset = offsetof(s, f), \
+ .size = sizeof(((s *)0)->f), \
+ })
+
/** Parser output buffer layout expected by cmd_flow_parsed(). */
struct buffer {
enum index command; /**< Flow command. */
@@ -329,6 +346,8 @@ static const enum index next_item[] = {
ITEM_VF,
ITEM_PORT,
ITEM_RAW,
+ ITEM_ETH,
+ ITEM_VLAN,
ZERO,
};
@@ -360,6 +379,21 @@ static const enum index item_raw[] = {
ZERO,
};
+static const enum index item_eth[] = {
+ ITEM_ETH_DST,
+ ITEM_ETH_SRC,
+ ITEM_ETH_TYPE,
+ ITEM_NEXT,
+ ZERO,
+};
+
+static const enum index item_vlan[] = {
+ ITEM_VLAN_TPID,
+ ITEM_VLAN_TCI,
+ ITEM_NEXT,
+ ZERO,
+};
+
static const enum index next_action[] = {
ACTION_END,
ACTION_VOID,
@@ -402,6 +436,9 @@ static int parse_boolean(struct context *, const struct token *,
static int parse_string(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
+static int parse_mac_addr(struct context *, const struct token *,
+ const char *, unsigned int,
+ void *, unsigned int);
static int parse_port(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
@@ -465,6 +502,13 @@ static const struct token token_list[] = {
.call = parse_string,
.comp = comp_none,
},
+ [MAC_ADDR] = {
+ .name = "{MAC address}",
+ .type = "MAC-48",
+ .help = "standard MAC address notation",
+ .call = parse_mac_addr,
+ .comp = comp_none,
+ },
[RULE_ID] = {
.name = "{rule id}",
.type = "RULE ID",
@@ -755,6 +799,50 @@ static const struct token token_list[] = {
pattern,
ITEM_RAW_PATTERN_SIZE)),
},
+ [ITEM_ETH] = {
+ .name = "eth",
+ .help = "match Ethernet header",
+ .priv = PRIV_ITEM(ETH, sizeof(struct rte_flow_item_eth)),
+ .next = NEXT(item_eth),
+ .call = parse_vc,
+ },
+ [ITEM_ETH_DST] = {
+ .name = "dst",
+ .help = "destination MAC",
+ .next = NEXT(item_eth, NEXT_ENTRY(MAC_ADDR), item_param),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_item_eth, dst)),
+ },
+ [ITEM_ETH_SRC] = {
+ .name = "src",
+ .help = "source MAC",
+ .next = NEXT(item_eth, NEXT_ENTRY(MAC_ADDR), item_param),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_item_eth, src)),
+ },
+ [ITEM_ETH_TYPE] = {
+ .name = "type",
+ .help = "EtherType",
+ .next = NEXT(item_eth, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, type)),
+ },
+ [ITEM_VLAN] = {
+ .name = "vlan",
+ .help = "match 802.1Q/ad VLAN tag",
+ .priv = PRIV_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)),
+ .next = NEXT(item_vlan),
+ .call = parse_vc,
+ },
+ [ITEM_VLAN_TPID] = {
+ .name = "tpid",
+ .help = "tag protocol identifier",
+ .next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, tpid)),
+ },
+ [ITEM_VLAN_TCI] = {
+ .name = "tci",
+ .help = "tag control information",
+ .next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, tci)),
+ },
/* Validate/create actions. */
[ACTIONS] = {
.name = "actions",
@@ -1399,6 +1487,44 @@ parse_string(struct context *ctx, const struct token *token,
return -1;
}
+/**
+ * Parse a MAC address.
+ *
+ * Last argument (ctx->args) is retrieved to determine storage size and
+ * location.
+ */
+static int
+parse_mac_addr(struct context *ctx, const struct token *token,
+ const char *str, unsigned int len,
+ void *buf, unsigned int size)
+{
+ const struct arg *arg = pop_args(ctx);
+ struct ether_addr tmp;
+ int ret;
+
+ (void)token;
+ /* Argument is expected. */
+ if (!arg)
+ return -1;
+ size = arg->size;
+ /* Bit-mask fill is not supported. */
+ if (arg->mask || size != sizeof(tmp))
+ goto error;
+ ret = cmdline_parse_etheraddr(NULL, str, &tmp, size);
+ if (ret < 0 || (unsigned int)ret != len)
+ goto error;
+ if (!ctx->object)
+ return len;
+ buf = (uint8_t *)ctx->object + arg->offset;
+ memcpy(buf, &tmp, size);
+ if (ctx->objmask)
+ memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size);
+ return len;
+error:
+ push_args(ctx, arg);
+ return -1;
+}
+
/** Boolean values (even indices stand for false). */
static const char *const boolean_name[] = {
"0", "1",
--
2.1.4
^ permalink raw reply related
* [PATCH v5 21/26] app/testpmd: add items ipv4/ipv6 to flow command
From: Adrien Mazarguil @ 2016-12-21 14:51 UTC (permalink / raw)
To: dev
In-Reply-To: <cover.1482331076.git.adrien.mazarguil@6wind.com>
Add the ability to match basic fields from IPv4 and IPv6 headers (source
and destination addresses only).
Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Olga Shern <olgas@mellanox.com>
---
app/test-pmd/cmdline_flow.c | 177 +++++++++++++++++++++++++++++++++++++++
1 file changed, 177 insertions(+)
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index e22e0c2..1f6a5a0 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -38,6 +38,7 @@
#include <errno.h>
#include <ctype.h>
#include <string.h>
+#include <arpa/inet.h>
#include <rte_common.h>
#include <rte_ethdev.h>
@@ -61,6 +62,8 @@ enum index {
BOOLEAN,
STRING,
MAC_ADDR,
+ IPV4_ADDR,
+ IPV6_ADDR,
RULE_ID,
PORT_ID,
GROUP_ID,
@@ -123,6 +126,12 @@ enum index {
ITEM_VLAN,
ITEM_VLAN_TPID,
ITEM_VLAN_TCI,
+ ITEM_IPV4,
+ ITEM_IPV4_SRC,
+ ITEM_IPV4_DST,
+ ITEM_IPV6,
+ ITEM_IPV6_SRC,
+ ITEM_IPV6_DST,
/* Validate/create actions. */
ACTIONS,
@@ -348,6 +357,8 @@ static const enum index next_item[] = {
ITEM_RAW,
ITEM_ETH,
ITEM_VLAN,
+ ITEM_IPV4,
+ ITEM_IPV6,
ZERO,
};
@@ -394,6 +405,20 @@ static const enum index item_vlan[] = {
ZERO,
};
+static const enum index item_ipv4[] = {
+ ITEM_IPV4_SRC,
+ ITEM_IPV4_DST,
+ ITEM_NEXT,
+ ZERO,
+};
+
+static const enum index item_ipv6[] = {
+ ITEM_IPV6_SRC,
+ ITEM_IPV6_DST,
+ ITEM_NEXT,
+ ZERO,
+};
+
static const enum index next_action[] = {
ACTION_END,
ACTION_VOID,
@@ -439,6 +464,12 @@ static int parse_string(struct context *, const struct token *,
static int parse_mac_addr(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
+static int parse_ipv4_addr(struct context *, const struct token *,
+ const char *, unsigned int,
+ void *, unsigned int);
+static int parse_ipv6_addr(struct context *, const struct token *,
+ const char *, unsigned int,
+ void *, unsigned int);
static int parse_port(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
@@ -509,6 +540,20 @@ static const struct token token_list[] = {
.call = parse_mac_addr,
.comp = comp_none,
},
+ [IPV4_ADDR] = {
+ .name = "{IPv4 address}",
+ .type = "IPV4 ADDRESS",
+ .help = "standard IPv4 address notation",
+ .call = parse_ipv4_addr,
+ .comp = comp_none,
+ },
+ [IPV6_ADDR] = {
+ .name = "{IPv6 address}",
+ .type = "IPV6 ADDRESS",
+ .help = "standard IPv6 address notation",
+ .call = parse_ipv6_addr,
+ .comp = comp_none,
+ },
[RULE_ID] = {
.name = "{rule id}",
.type = "RULE ID",
@@ -843,6 +888,48 @@ static const struct token token_list[] = {
.next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, tci)),
},
+ [ITEM_IPV4] = {
+ .name = "ipv4",
+ .help = "match IPv4 header",
+ .priv = PRIV_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)),
+ .next = NEXT(item_ipv4),
+ .call = parse_vc,
+ },
+ [ITEM_IPV4_SRC] = {
+ .name = "src",
+ .help = "source address",
+ .next = NEXT(item_ipv4, NEXT_ENTRY(IPV4_ADDR), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
+ hdr.src_addr)),
+ },
+ [ITEM_IPV4_DST] = {
+ .name = "dst",
+ .help = "destination address",
+ .next = NEXT(item_ipv4, NEXT_ENTRY(IPV4_ADDR), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
+ hdr.dst_addr)),
+ },
+ [ITEM_IPV6] = {
+ .name = "ipv6",
+ .help = "match IPv6 header",
+ .priv = PRIV_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)),
+ .next = NEXT(item_ipv6),
+ .call = parse_vc,
+ },
+ [ITEM_IPV6_SRC] = {
+ .name = "src",
+ .help = "source address",
+ .next = NEXT(item_ipv6, NEXT_ENTRY(IPV6_ADDR), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
+ hdr.src_addr)),
+ },
+ [ITEM_IPV6_DST] = {
+ .name = "dst",
+ .help = "destination address",
+ .next = NEXT(item_ipv6, NEXT_ENTRY(IPV6_ADDR), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
+ hdr.dst_addr)),
+ },
/* Validate/create actions. */
[ACTIONS] = {
.name = "actions",
@@ -1525,6 +1612,96 @@ parse_mac_addr(struct context *ctx, const struct token *token,
return -1;
}
+/**
+ * Parse an IPv4 address.
+ *
+ * Last argument (ctx->args) is retrieved to determine storage size and
+ * location.
+ */
+static int
+parse_ipv4_addr(struct context *ctx, const struct token *token,
+ const char *str, unsigned int len,
+ void *buf, unsigned int size)
+{
+ const struct arg *arg = pop_args(ctx);
+ char str2[len + 1];
+ struct in_addr tmp;
+ int ret;
+
+ /* Argument is expected. */
+ if (!arg)
+ return -1;
+ size = arg->size;
+ /* Bit-mask fill is not supported. */
+ if (arg->mask || size != sizeof(tmp))
+ goto error;
+ /* Only network endian is supported. */
+ if (!arg->hton)
+ goto error;
+ memcpy(str2, str, len);
+ str2[len] = '\0';
+ ret = inet_pton(AF_INET, str2, &tmp);
+ if (ret != 1) {
+ /* Attempt integer parsing. */
+ push_args(ctx, arg);
+ return parse_int(ctx, token, str, len, buf, size);
+ }
+ if (!ctx->object)
+ return len;
+ buf = (uint8_t *)ctx->object + arg->offset;
+ memcpy(buf, &tmp, size);
+ if (ctx->objmask)
+ memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size);
+ return len;
+error:
+ push_args(ctx, arg);
+ return -1;
+}
+
+/**
+ * Parse an IPv6 address.
+ *
+ * Last argument (ctx->args) is retrieved to determine storage size and
+ * location.
+ */
+static int
+parse_ipv6_addr(struct context *ctx, const struct token *token,
+ const char *str, unsigned int len,
+ void *buf, unsigned int size)
+{
+ const struct arg *arg = pop_args(ctx);
+ char str2[len + 1];
+ struct in6_addr tmp;
+ int ret;
+
+ (void)token;
+ /* Argument is expected. */
+ if (!arg)
+ return -1;
+ size = arg->size;
+ /* Bit-mask fill is not supported. */
+ if (arg->mask || size != sizeof(tmp))
+ goto error;
+ /* Only network endian is supported. */
+ if (!arg->hton)
+ goto error;
+ memcpy(str2, str, len);
+ str2[len] = '\0';
+ ret = inet_pton(AF_INET6, str2, &tmp);
+ if (ret != 1)
+ goto error;
+ if (!ctx->object)
+ return len;
+ buf = (uint8_t *)ctx->object + arg->offset;
+ memcpy(buf, &tmp, size);
+ if (ctx->objmask)
+ memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size);
+ return len;
+error:
+ push_args(ctx, arg);
+ return -1;
+}
+
/** Boolean values (even indices stand for false). */
static const char *const boolean_name[] = {
"0", "1",
--
2.1.4
^ permalink raw reply related
* [PATCH v5 22/26] app/testpmd: add L4 items to flow command
From: Adrien Mazarguil @ 2016-12-21 14:51 UTC (permalink / raw)
To: dev
In-Reply-To: <cover.1482331076.git.adrien.mazarguil@6wind.com>
Add the ability to match a few properties of common L4[.5] protocol
headers:
- ICMP: type and code.
- UDP: source and destination ports.
- TCP: source and destination ports.
- SCTP: source and destination ports.
- VXLAN: network identifier.
Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Olga Shern <olgas@mellanox.com>
---
app/test-pmd/cmdline_flow.c | 163 +++++++++++++++++++++++++++++++++++++++
1 file changed, 163 insertions(+)
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 1f6a5a0..259e9eb 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -132,6 +132,20 @@ enum index {
ITEM_IPV6,
ITEM_IPV6_SRC,
ITEM_IPV6_DST,
+ ITEM_ICMP,
+ ITEM_ICMP_TYPE,
+ ITEM_ICMP_CODE,
+ ITEM_UDP,
+ ITEM_UDP_SRC,
+ ITEM_UDP_DST,
+ ITEM_TCP,
+ ITEM_TCP_SRC,
+ ITEM_TCP_DST,
+ ITEM_SCTP,
+ ITEM_SCTP_SRC,
+ ITEM_SCTP_DST,
+ ITEM_VXLAN,
+ ITEM_VXLAN_VNI,
/* Validate/create actions. */
ACTIONS,
@@ -359,6 +373,11 @@ static const enum index next_item[] = {
ITEM_VLAN,
ITEM_IPV4,
ITEM_IPV6,
+ ITEM_ICMP,
+ ITEM_UDP,
+ ITEM_TCP,
+ ITEM_SCTP,
+ ITEM_VXLAN,
ZERO,
};
@@ -419,6 +438,40 @@ static const enum index item_ipv6[] = {
ZERO,
};
+static const enum index item_icmp[] = {
+ ITEM_ICMP_TYPE,
+ ITEM_ICMP_CODE,
+ ITEM_NEXT,
+ ZERO,
+};
+
+static const enum index item_udp[] = {
+ ITEM_UDP_SRC,
+ ITEM_UDP_DST,
+ ITEM_NEXT,
+ ZERO,
+};
+
+static const enum index item_tcp[] = {
+ ITEM_TCP_SRC,
+ ITEM_TCP_DST,
+ ITEM_NEXT,
+ ZERO,
+};
+
+static const enum index item_sctp[] = {
+ ITEM_SCTP_SRC,
+ ITEM_SCTP_DST,
+ ITEM_NEXT,
+ ZERO,
+};
+
+static const enum index item_vxlan[] = {
+ ITEM_VXLAN_VNI,
+ ITEM_NEXT,
+ ZERO,
+};
+
static const enum index next_action[] = {
ACTION_END,
ACTION_VOID,
@@ -930,6 +983,103 @@ static const struct token token_list[] = {
.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
hdr.dst_addr)),
},
+ [ITEM_ICMP] = {
+ .name = "icmp",
+ .help = "match ICMP header",
+ .priv = PRIV_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)),
+ .next = NEXT(item_icmp),
+ .call = parse_vc,
+ },
+ [ITEM_ICMP_TYPE] = {
+ .name = "type",
+ .help = "ICMP packet type",
+ .next = NEXT(item_icmp, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp,
+ hdr.icmp_type)),
+ },
+ [ITEM_ICMP_CODE] = {
+ .name = "code",
+ .help = "ICMP packet code",
+ .next = NEXT(item_icmp, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp,
+ hdr.icmp_code)),
+ },
+ [ITEM_UDP] = {
+ .name = "udp",
+ .help = "match UDP header",
+ .priv = PRIV_ITEM(UDP, sizeof(struct rte_flow_item_udp)),
+ .next = NEXT(item_udp),
+ .call = parse_vc,
+ },
+ [ITEM_UDP_SRC] = {
+ .name = "src",
+ .help = "UDP source port",
+ .next = NEXT(item_udp, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp,
+ hdr.src_port)),
+ },
+ [ITEM_UDP_DST] = {
+ .name = "dst",
+ .help = "UDP destination port",
+ .next = NEXT(item_udp, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp,
+ hdr.dst_port)),
+ },
+ [ITEM_TCP] = {
+ .name = "tcp",
+ .help = "match TCP header",
+ .priv = PRIV_ITEM(TCP, sizeof(struct rte_flow_item_tcp)),
+ .next = NEXT(item_tcp),
+ .call = parse_vc,
+ },
+ [ITEM_TCP_SRC] = {
+ .name = "src",
+ .help = "TCP source port",
+ .next = NEXT(item_tcp, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp,
+ hdr.src_port)),
+ },
+ [ITEM_TCP_DST] = {
+ .name = "dst",
+ .help = "TCP destination port",
+ .next = NEXT(item_tcp, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp,
+ hdr.dst_port)),
+ },
+ [ITEM_SCTP] = {
+ .name = "sctp",
+ .help = "match SCTP header",
+ .priv = PRIV_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)),
+ .next = NEXT(item_sctp),
+ .call = parse_vc,
+ },
+ [ITEM_SCTP_SRC] = {
+ .name = "src",
+ .help = "SCTP source port",
+ .next = NEXT(item_sctp, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
+ hdr.src_port)),
+ },
+ [ITEM_SCTP_DST] = {
+ .name = "dst",
+ .help = "SCTP destination port",
+ .next = NEXT(item_sctp, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
+ hdr.dst_port)),
+ },
+ [ITEM_VXLAN] = {
+ .name = "vxlan",
+ .help = "match VXLAN header",
+ .priv = PRIV_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)),
+ .next = NEXT(item_vxlan),
+ .call = parse_vc,
+ },
+ [ITEM_VXLAN_VNI] = {
+ .name = "vni",
+ .help = "VXLAN identifier",
+ .next = NEXT(item_vxlan, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, vni)),
+ },
/* Validate/create actions. */
[ACTIONS] = {
.name = "actions",
@@ -1502,6 +1652,19 @@ parse_int(struct context *ctx, const struct token *token,
case sizeof(uint16_t):
*(uint16_t *)buf = arg->hton ? rte_cpu_to_be_16(u) : u;
break;
+ case sizeof(uint8_t [3]):
+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+ if (!arg->hton) {
+ ((uint8_t *)buf)[0] = u;
+ ((uint8_t *)buf)[1] = u >> 8;
+ ((uint8_t *)buf)[2] = u >> 16;
+ break;
+ }
+#endif
+ ((uint8_t *)buf)[0] = u >> 16;
+ ((uint8_t *)buf)[1] = u >> 8;
+ ((uint8_t *)buf)[2] = u;
+ break;
case sizeof(uint32_t):
*(uint32_t *)buf = arg->hton ? rte_cpu_to_be_32(u) : u;
break;
--
2.1.4
^ permalink raw reply related
* [PATCH v5 23/26] app/testpmd: add various actions to flow command
From: Adrien Mazarguil @ 2016-12-21 14:51 UTC (permalink / raw)
To: dev
In-Reply-To: <cover.1482331076.git.adrien.mazarguil@6wind.com>
- MARK: attach 32 bit value to packets.
- FLAG: flag packets.
- DROP: drop packets.
- COUNT: enable counters for a rule.
- PF: redirect packets to physical device function.
- VF: redirect packets to virtual device function.
Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Olga Shern <olgas@mellanox.com>
---
app/test-pmd/cmdline_flow.c | 121 +++++++++++++++++++++++++++++++++++++++
1 file changed, 121 insertions(+)
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 259e9eb..a4e8ebe 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -153,6 +153,15 @@ enum index {
ACTION_END,
ACTION_VOID,
ACTION_PASSTHRU,
+ ACTION_MARK,
+ ACTION_MARK_ID,
+ ACTION_FLAG,
+ ACTION_DROP,
+ ACTION_COUNT,
+ ACTION_PF,
+ ACTION_VF,
+ ACTION_VF_ORIGINAL,
+ ACTION_VF_ID,
};
/** Size of pattern[] field in struct rte_flow_item_raw. */
@@ -476,6 +485,25 @@ static const enum index next_action[] = {
ACTION_END,
ACTION_VOID,
ACTION_PASSTHRU,
+ ACTION_MARK,
+ ACTION_FLAG,
+ ACTION_DROP,
+ ACTION_COUNT,
+ ACTION_PF,
+ ACTION_VF,
+ ZERO,
+};
+
+static const enum index action_mark[] = {
+ ACTION_MARK_ID,
+ ACTION_NEXT,
+ ZERO,
+};
+
+static const enum index action_vf[] = {
+ ACTION_VF_ORIGINAL,
+ ACTION_VF_ID,
+ ACTION_NEXT,
ZERO,
};
@@ -487,6 +515,8 @@ static int parse_vc(struct context *, const struct token *,
void *, unsigned int);
static int parse_vc_spec(struct context *, const struct token *,
const char *, unsigned int, void *, unsigned int);
+static int parse_vc_conf(struct context *, const struct token *,
+ const char *, unsigned int, void *, unsigned int);
static int parse_destroy(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
@@ -1112,6 +1142,70 @@ static const struct token token_list[] = {
.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
.call = parse_vc,
},
+ [ACTION_MARK] = {
+ .name = "mark",
+ .help = "attach 32 bit value to packets",
+ .priv = PRIV_ACTION(MARK, sizeof(struct rte_flow_action_mark)),
+ .next = NEXT(action_mark),
+ .call = parse_vc,
+ },
+ [ACTION_MARK_ID] = {
+ .name = "id",
+ .help = "32 bit value to return with packets",
+ .next = NEXT(action_mark, NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_action_mark, id)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_FLAG] = {
+ .name = "flag",
+ .help = "flag packets",
+ .priv = PRIV_ACTION(FLAG, 0),
+ .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
+ .call = parse_vc,
+ },
+ [ACTION_DROP] = {
+ .name = "drop",
+ .help = "drop packets (note: passthru has priority)",
+ .priv = PRIV_ACTION(DROP, 0),
+ .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
+ .call = parse_vc,
+ },
+ [ACTION_COUNT] = {
+ .name = "count",
+ .help = "enable counters for this rule",
+ .priv = PRIV_ACTION(COUNT, 0),
+ .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
+ .call = parse_vc,
+ },
+ [ACTION_PF] = {
+ .name = "pf",
+ .help = "redirect packets to physical device function",
+ .priv = PRIV_ACTION(PF, 0),
+ .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
+ .call = parse_vc,
+ },
+ [ACTION_VF] = {
+ .name = "vf",
+ .help = "redirect packets to virtual device function",
+ .priv = PRIV_ACTION(VF, sizeof(struct rte_flow_action_vf)),
+ .next = NEXT(action_vf),
+ .call = parse_vc,
+ },
+ [ACTION_VF_ORIGINAL] = {
+ .name = "original",
+ .help = "use original VF ID if possible",
+ .next = NEXT(action_vf, NEXT_ENTRY(BOOLEAN)),
+ .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_vf,
+ original, 1)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_VF_ID] = {
+ .name = "id",
+ .help = "VF ID to redirect packets to",
+ .next = NEXT(action_vf, NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_action_vf, id)),
+ .call = parse_vc_conf,
+ },
};
/** Remove and return last entry from argument stack. */
@@ -1446,6 +1540,33 @@ parse_vc_spec(struct context *ctx, const struct token *token,
return len;
}
+/** Parse action configuration field. */
+static int
+parse_vc_conf(struct context *ctx, const struct token *token,
+ const char *str, unsigned int len,
+ void *buf, unsigned int size)
+{
+ struct buffer *out = buf;
+ struct rte_flow_action *action;
+
+ (void)size;
+ /* Token name must match. */
+ if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+ return -1;
+ /* Nothing else to do if there is no buffer. */
+ if (!out)
+ return len;
+ if (!out->args.vc.actions_n)
+ return -1;
+ action = &out->args.vc.actions[out->args.vc.actions_n - 1];
+ /* Point to selected object. */
+ ctx->object = out->args.vc.data;
+ ctx->objmask = NULL;
+ /* Update configuration pointer. */
+ action->conf = ctx->object;
+ return len;
+}
+
/** Parse tokens for destroy command. */
static int
parse_destroy(struct context *ctx, const struct token *token,
--
2.1.4
^ permalink raw reply related
* [PATCH v5 24/26] app/testpmd: add queue actions to flow command
From: Adrien Mazarguil @ 2016-12-21 14:51 UTC (permalink / raw)
To: dev
In-Reply-To: <cover.1482331076.git.adrien.mazarguil@6wind.com>
- QUEUE: assign packets to a given queue index.
- DUP: duplicate packets to a given queue index.
- RSS: spread packets among several queues.
Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Olga Shern <olgas@mellanox.com>
---
app/test-pmd/cmdline_flow.c | 152 +++++++++++++++++++++++++++++++++++++++
1 file changed, 152 insertions(+)
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index a4e8ebe..db680c6 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -156,8 +156,15 @@ enum index {
ACTION_MARK,
ACTION_MARK_ID,
ACTION_FLAG,
+ ACTION_QUEUE,
+ ACTION_QUEUE_INDEX,
ACTION_DROP,
ACTION_COUNT,
+ ACTION_DUP,
+ ACTION_DUP_INDEX,
+ ACTION_RSS,
+ ACTION_RSS_QUEUES,
+ ACTION_RSS_QUEUE,
ACTION_PF,
ACTION_VF,
ACTION_VF_ORIGINAL,
@@ -171,6 +178,14 @@ enum index {
#define ITEM_RAW_SIZE \
(offsetof(struct rte_flow_item_raw, pattern) + ITEM_RAW_PATTERN_SIZE)
+/** Number of queue[] entries in struct rte_flow_action_rss. */
+#define ACTION_RSS_NUM 32
+
+/** Storage size for struct rte_flow_action_rss including queues. */
+#define ACTION_RSS_SIZE \
+ (offsetof(struct rte_flow_action_rss, queue) + \
+ sizeof(*((struct rte_flow_action_rss *)0)->queue) * ACTION_RSS_NUM)
+
/** Maximum number of subsequent tokens and arguments on the stack. */
#define CTX_STACK_SIZE 16
@@ -487,8 +502,11 @@ static const enum index next_action[] = {
ACTION_PASSTHRU,
ACTION_MARK,
ACTION_FLAG,
+ ACTION_QUEUE,
ACTION_DROP,
ACTION_COUNT,
+ ACTION_DUP,
+ ACTION_RSS,
ACTION_PF,
ACTION_VF,
ZERO,
@@ -500,6 +518,24 @@ static const enum index action_mark[] = {
ZERO,
};
+static const enum index action_queue[] = {
+ ACTION_QUEUE_INDEX,
+ ACTION_NEXT,
+ ZERO,
+};
+
+static const enum index action_dup[] = {
+ ACTION_DUP_INDEX,
+ ACTION_NEXT,
+ ZERO,
+};
+
+static const enum index action_rss[] = {
+ ACTION_RSS_QUEUES,
+ ACTION_NEXT,
+ ZERO,
+};
+
static const enum index action_vf[] = {
ACTION_VF_ORIGINAL,
ACTION_VF_ID,
@@ -517,6 +553,9 @@ static int parse_vc_spec(struct context *, const struct token *,
const char *, unsigned int, void *, unsigned int);
static int parse_vc_conf(struct context *, const struct token *,
const char *, unsigned int, void *, unsigned int);
+static int parse_vc_action_rss_queue(struct context *, const struct token *,
+ const char *, unsigned int, void *,
+ unsigned int);
static int parse_destroy(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
@@ -566,6 +605,8 @@ static int comp_port(struct context *, const struct token *,
unsigned int, char *, unsigned int);
static int comp_rule_id(struct context *, const struct token *,
unsigned int, char *, unsigned int);
+static int comp_vc_action_rss_queue(struct context *, const struct token *,
+ unsigned int, char *, unsigned int);
/** Token definitions. */
static const struct token token_list[] = {
@@ -1163,6 +1204,21 @@ static const struct token token_list[] = {
.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
.call = parse_vc,
},
+ [ACTION_QUEUE] = {
+ .name = "queue",
+ .help = "assign packets to a given queue index",
+ .priv = PRIV_ACTION(QUEUE,
+ sizeof(struct rte_flow_action_queue)),
+ .next = NEXT(action_queue),
+ .call = parse_vc,
+ },
+ [ACTION_QUEUE_INDEX] = {
+ .name = "index",
+ .help = "queue index to use",
+ .next = NEXT(action_queue, NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_action_queue, index)),
+ .call = parse_vc_conf,
+ },
[ACTION_DROP] = {
.name = "drop",
.help = "drop packets (note: passthru has priority)",
@@ -1177,6 +1233,39 @@ static const struct token token_list[] = {
.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
.call = parse_vc,
},
+ [ACTION_DUP] = {
+ .name = "dup",
+ .help = "duplicate packets to a given queue index",
+ .priv = PRIV_ACTION(DUP, sizeof(struct rte_flow_action_dup)),
+ .next = NEXT(action_dup),
+ .call = parse_vc,
+ },
+ [ACTION_DUP_INDEX] = {
+ .name = "index",
+ .help = "queue index to duplicate packets to",
+ .next = NEXT(action_dup, NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY(struct rte_flow_action_dup, index)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_RSS] = {
+ .name = "rss",
+ .help = "spread packets among several queues",
+ .priv = PRIV_ACTION(RSS, ACTION_RSS_SIZE),
+ .next = NEXT(action_rss),
+ .call = parse_vc,
+ },
+ [ACTION_RSS_QUEUES] = {
+ .name = "queues",
+ .help = "queue indices to use",
+ .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_QUEUE)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_RSS_QUEUE] = {
+ .name = "{queue}",
+ .help = "queue index",
+ .call = parse_vc_action_rss_queue,
+ .comp = comp_vc_action_rss_queue,
+ },
[ACTION_PF] = {
.name = "pf",
.help = "redirect packets to physical device function",
@@ -1567,6 +1656,51 @@ parse_vc_conf(struct context *ctx, const struct token *token,
return len;
}
+/**
+ * Parse queue field for RSS action.
+ *
+ * Valid tokens are queue indices and the "end" token.
+ */
+static int
+parse_vc_action_rss_queue(struct context *ctx, const struct token *token,
+ const char *str, unsigned int len,
+ void *buf, unsigned int size)
+{
+ static const enum index next[] = NEXT_ENTRY(ACTION_RSS_QUEUE);
+ int ret;
+ int i;
+
+ (void)token;
+ (void)buf;
+ (void)size;
+ if (ctx->curr != ACTION_RSS_QUEUE)
+ return -1;
+ i = ctx->objdata >> 16;
+ if (!strncmp(str, "end", len)) {
+ ctx->objdata &= 0xffff;
+ return len;
+ }
+ if (i >= ACTION_RSS_NUM)
+ return -1;
+ if (push_args(ctx, ARGS_ENTRY(struct rte_flow_action_rss, queue[i])))
+ return -1;
+ ret = parse_int(ctx, token, str, len, NULL, 0);
+ if (ret < 0) {
+ pop_args(ctx);
+ return -1;
+ }
+ ++i;
+ ctx->objdata = i << 16 | (ctx->objdata & 0xffff);
+ /* Repeat token. */
+ if (ctx->next_num == RTE_DIM(ctx->next))
+ return -1;
+ ctx->next[ctx->next_num++] = next;
+ if (!ctx->object)
+ return len;
+ ((struct rte_flow_action_rss *)ctx->object)->num = i;
+ return len;
+}
+
/** Parse tokens for destroy command. */
static int
parse_destroy(struct context *ctx, const struct token *token,
@@ -2141,6 +2275,24 @@ comp_rule_id(struct context *ctx, const struct token *token,
return i;
}
+/** Complete queue field for RSS action. */
+static int
+comp_vc_action_rss_queue(struct context *ctx, const struct token *token,
+ unsigned int ent, char *buf, unsigned int size)
+{
+ static const char *const str[] = { "", "end", NULL };
+ unsigned int i;
+
+ (void)ctx;
+ (void)token;
+ for (i = 0; str[i] != NULL; ++i)
+ if (buf && i == ent)
+ return snprintf(buf, size, "%s", str[i]);
+ if (buf)
+ return -1;
+ return i;
+}
+
/** Internal context. */
static struct context cmd_flow_context;
--
2.1.4
^ permalink raw reply related
* [PATCH v5 25/26] doc: describe testpmd flow command
From: Adrien Mazarguil @ 2016-12-21 14:51 UTC (permalink / raw)
To: dev
In-Reply-To: <cover.1482331076.git.adrien.mazarguil@6wind.com>
Document syntax, interaction with rte_flow and provide usage examples.
Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Olga Shern <olgas@mellanox.com>
Acked-by: John McNamara <john.mcnamara@intel.com>
---
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 612 +++++++++++++++++++++++
1 file changed, 612 insertions(+)
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index f1c269a..03b6fa9 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1631,6 +1631,9 @@ Filter Functions
This section details the available filter functions that are available.
+Note these functions interface the deprecated legacy filtering framework,
+superseded by *rte_flow*. See `Flow rules management`_.
+
ethertype_filter
~~~~~~~~~~~~~~~~~~~~
@@ -2041,3 +2044,612 @@ Set different GRE key length for input set::
For example to set GRE key length for input set to 4 bytes on port 0::
testpmd> global_config 0 gre-key-len 4
+
+
+.. _testpmd_rte_flow:
+
+Flow rules management
+---------------------
+
+Control of the generic flow API (*rte_flow*) is fully exposed through the
+``flow`` command (validation, creation, destruction and queries).
+
+Considering *rte_flow* overlaps with all `Filter Functions`_, using both
+features simultaneously may cause undefined side-effects and is therefore
+not recommended.
+
+``flow`` syntax
+~~~~~~~~~~~~~~~
+
+Because the ``flow`` command uses dynamic tokens to handle the large number
+of possible flow rules combinations, its behavior differs slightly from
+other commands, in particular:
+
+- Pressing *?* or the *<tab>* key displays contextual help for the current
+ token, not that of the entire command.
+
+- Optional and repeated parameters are supported (provided they are listed
+ in the contextual help).
+
+The first parameter stands for the operation mode. Possible operations and
+their general syntax are described below. They are covered in detail in the
+following sections.
+
+- Check whether a flow rule can be created::
+
+ flow validate {port_id}
+ [group {group_id}] [priority {level}] [ingress] [egress]
+ pattern {item} [/ {item} [...]] / end
+ actions {action} [/ {action} [...]] / end
+
+- Create a flow rule::
+
+ flow create {port_id}
+ [group {group_id}] [priority {level}] [ingress] [egress]
+ pattern {item} [/ {item} [...]] / end
+ actions {action} [/ {action} [...]] / end
+
+- Destroy specific flow rules::
+
+ flow destroy {port_id} rule {rule_id} [...]
+
+- Destroy all flow rules::
+
+ flow flush {port_id}
+
+- Query an existing flow rule::
+
+ flow query {port_id} {rule_id} {action}
+
+- List existing flow rules sorted by priority, filtered by group
+ identifiers::
+
+ flow list {port_id} [group {group_id}] [...]
+
+Validating flow rules
+~~~~~~~~~~~~~~~~~~~~~
+
+``flow validate`` reports whether a flow rule would be accepted by the
+underlying device in its current state but stops short of creating it. It is
+bound to ``rte_flow_validate()``::
+
+ flow validate {port_id}
+ [group {group_id}] [priority {level}] [ingress] [egress]
+ pattern {item} [/ {item} [...]] / end
+ actions {action} [/ {action} [...]] / end
+
+If successful, it will show::
+
+ Flow rule validated
+
+Otherwise it will show an error message of the form::
+
+ Caught error type [...] ([...]): [...]
+
+This command uses the same parameters as ``flow create``, their format is
+described in `Creating flow rules`_.
+
+Check whether redirecting any Ethernet packet received on port 0 to RX queue
+index 6 is supported::
+
+ testpmd> flow validate 0 ingress pattern eth / end
+ actions queue index 6 / end
+ Flow rule validated
+ testpmd>
+
+Port 0 does not support TCPv6 rules::
+
+ testpmd> flow validate 0 ingress pattern eth / ipv6 / tcp / end
+ actions drop / end
+ Caught error type 9 (specific pattern item): Invalid argument
+ testpmd>
+
+Creating flow rules
+~~~~~~~~~~~~~~~~~~~
+
+``flow create`` validates and creates the specified flow rule. It is bound
+to ``rte_flow_create()``::
+
+ flow create {port_id}
+ [group {group_id}] [priority {level}] [ingress] [egress]
+ pattern {item} [/ {item} [...]] / end
+ actions {action} [/ {action} [...]] / end
+
+If successful, it will return a flow rule ID usable with other commands::
+
+ Flow rule #[...] created
+
+Otherwise it will show an error message of the form::
+
+ Caught error type [...] ([...]): [...]
+
+Parameters describe in the following order:
+
+- Attributes (*group*, *priority*, *ingress*, *egress* tokens).
+- A matching pattern, starting with the *pattern* token and terminated by an
+ *end* pattern item.
+- Actions, starting with the *actions* token and terminated by an *end*
+ action.
+
+These translate directly to *rte_flow* objects provided as-is to the
+underlying functions.
+
+The shortest valid definition only comprises mandatory tokens::
+
+ testpmd> flow create 0 pattern end actions end
+
+Note that PMDs may refuse rules that essentially do nothing such as this
+one.
+
+**All unspecified object values are automatically initialized to 0.**
+
+Attributes
+^^^^^^^^^^
+
+These tokens affect flow rule attributes (``struct rte_flow_attr``) and are
+specified before the ``pattern`` token.
+
+- ``group {group id}``: priority group.
+- ``priority {level}``: priority level within group.
+- ``ingress``: rule applies to ingress traffic.
+- ``egress``: rule applies to egress traffic.
+
+Each instance of an attribute specified several times overrides the previous
+value as shown below (group 4 is used)::
+
+ testpmd> flow create 0 group 42 group 24 group 4 [...]
+
+Note that once enabled, ``ingress`` and ``egress`` cannot be disabled.
+
+While not specifying a direction is an error, some rules may allow both
+simultaneously.
+
+Most rules affect RX therefore contain the ``ingress`` token::
+
+ testpmd> flow create 0 ingress pattern [...]
+
+Matching pattern
+^^^^^^^^^^^^^^^^
+
+A matching pattern starts after the ``pattern`` token. It is made of pattern
+items and is terminated by a mandatory ``end`` item.
+
+Items are named after their type (*RTE_FLOW_ITEM_TYPE_* from ``enum
+rte_flow_item_type``).
+
+The ``/`` token is used as a separator between pattern items as shown
+below::
+
+ testpmd> flow create 0 ingress pattern eth / ipv4 / udp / end [...]
+
+Note that protocol items like these must be stacked from lowest to highest
+layer to make sense. For instance, the following rule is either invalid or
+unlikely to match any packet::
+
+ testpmd> flow create 0 ingress pattern eth / udp / ipv4 / end [...]
+
+More information on these restrictions can be found in the *rte_flow*
+documentation.
+
+Several items support additional specification structures, for example
+``ipv4`` allows specifying source and destination addresses as follows::
+
+ testpmd> flow create 0 ingress pattern eth / ipv4 src is 10.1.1.1
+ dst is 10.2.0.0 / end [...]
+
+This rule matches all IPv4 traffic with the specified properties.
+
+In this example, ``src`` and ``dst`` are field names of the underlying
+``struct rte_flow_item_ipv4`` object. All item properties can be specified
+in a similar fashion.
+
+The ``is`` token means that the subsequent value must be matched exactly,
+and assigns ``spec`` and ``mask`` fields in ``struct rte_flow_item``
+accordingly. Possible assignment tokens are:
+
+- ``is``: match value perfectly (with full bit-mask).
+- ``spec``: match value according to configured bit-mask.
+- ``last``: specify upper bound to establish a range.
+- ``mask``: specify bit-mask with relevant bits set to one.
+- ``prefix``: generate bit-mask from a prefix length.
+
+These yield identical results::
+
+ ipv4 src is 10.1.1.1
+
+::
+
+ ipv4 src spec 10.1.1.1 src mask 255.255.255.255
+
+::
+
+ ipv4 src spec 10.1.1.1 src prefix 32
+
+::
+
+ ipv4 src is 10.1.1.1 src last 10.1.1.1 # range with a single value
+
+::
+
+ ipv4 src is 10.1.1.1 src last 0 # 0 disables range
+
+Inclusive ranges can be defined with ``last``::
+
+ ipv4 src is 10.1.1.1 src last 10.2.3.4 # 10.1.1.1 to 10.2.3.4
+
+Note that ``mask`` affects both ``spec`` and ``last``::
+
+ ipv4 src is 10.1.1.1 src last 10.2.3.4 src mask 255.255.0.0
+ # matches 10.1.0.0 to 10.2.255.255
+
+Properties can be modified multiple times::
+
+ ipv4 src is 10.1.1.1 src is 10.1.2.3 src is 10.2.3.4 # matches 10.2.3.4
+
+::
+
+ ipv4 src is 10.1.1.1 src prefix 24 src prefix 16 # matches 10.1.0.0/16
+
+Pattern items
+^^^^^^^^^^^^^
+
+This section lists supported pattern items and their attributes, if any.
+
+- ``end``: end list of pattern items.
+
+- ``void``: no-op pattern item.
+
+- ``invert``: perform actions when pattern does not match.
+
+- ``any``: match any protocol for the current layer.
+
+ - ``num {unsigned}``: number of layers covered.
+
+- ``pf``: match packets addressed to the physical function.
+
+- ``vf``: match packets addressed to a virtual function ID.
+
+ - ``id {unsigned}``: destination VF ID.
+
+- ``port``: device-specific physical port index to use.
+
+ - ``index {unsigned}``: physical port index.
+
+- ``raw``: match an arbitrary byte string.
+
+ - ``relative {boolean}``: look for pattern after the previous item.
+ - ``search {boolean}``: search pattern from offset (see also limit).
+ - ``offset {integer}``: absolute or relative offset for pattern.
+ - ``limit {unsigned}``: search area limit for start of pattern.
+ - ``pattern {string}``: byte string to look for.
+
+- ``eth``: match Ethernet header.
+
+ - ``dst {MAC-48}``: destination MAC.
+ - ``src {MAC-48}``: source MAC.
+ - ``type {unsigned}``: EtherType.
+
+- ``vlan``: match 802.1Q/ad VLAN tag.
+
+ - ``tpid {unsigned}``: tag protocol identifier.
+ - ``tci {unsigned}``: tag control information.
+
+- ``ipv4``: match IPv4 header.
+
+ - ``src {ipv4 address}``: source address.
+ - ``dst {ipv4 address}``: destination address.
+
+- ``ipv6``: match IPv6 header.
+
+ - ``src {ipv6 address}``: source address.
+ - ``dst {ipv6 address}``: destination address.
+
+- ``icmp``: match ICMP header.
+
+ - ``type {unsigned}``: ICMP packet type.
+ - ``code {unsigned}``: ICMP packet code.
+
+- ``udp``: match UDP header.
+
+ - ``src {unsigned}``: UDP source port.
+ - ``dst {unsigned}``: UDP destination port.
+
+- ``tcp``: match TCP header.
+
+ - ``src {unsigned}``: TCP source port.
+ - ``dst {unsigned}``: TCP destination port.
+
+- ``sctp``: match SCTP header.
+
+ - ``src {unsigned}``: SCTP source port.
+ - ``dst {unsigned}``: SCTP destination port.
+
+- ``vxlan``: match VXLAN header.
+
+ - ``vni {unsigned}``: VXLAN identifier.
+
+Actions list
+^^^^^^^^^^^^
+
+A list of actions starts after the ``actions`` token in the same fashion as
+`Matching pattern`_; actions are separated by ``/`` tokens and the list is
+terminated by a mandatory ``end`` action.
+
+Actions are named after their type (*RTE_FLOW_ACTION_TYPE_* from ``enum
+rte_flow_action_type``).
+
+Dropping all incoming UDPv4 packets can be expressed as follows::
+
+ testpmd> flow create 0 ingress pattern eth / ipv4 / udp / end
+ actions drop / end
+
+Several actions have configurable properties which must be specified when
+there is no valid default value. For example, ``queue`` requires a target
+queue index.
+
+This rule redirects incoming UDPv4 traffic to queue index 6::
+
+ testpmd> flow create 0 ingress pattern eth / ipv4 / udp / end
+ actions queue index 6 / end
+
+While this one could be rejected by PMDs (unspecified queue index)::
+
+ testpmd> flow create 0 ingress pattern eth / ipv4 / udp / end
+ actions queue / end
+
+As defined by *rte_flow*, the list is not ordered, all actions of a given
+rule are performed simultaneously. These are equivalent::
+
+ queue index 6 / void / mark id 42 / end
+
+::
+
+ void / mark id 42 / queue index 6 / end
+
+All actions in a list should have different types, otherwise only the last
+action of a given type is taken into account::
+
+ queue index 4 / queue index 5 / queue index 6 / end # will use queue 6
+
+::
+
+ drop / drop / drop / end # drop is performed only once
+
+::
+
+ mark id 42 / queue index 3 / mark id 24 / end # mark will be 24
+
+Considering they are performed simultaneously, opposite and overlapping
+actions can sometimes be combined when the end result is unambiguous::
+
+ drop / queue index 6 / end # drop has no effect
+
+::
+
+ drop / dup index 6 / end # same as above
+
+::
+
+ queue index 6 / rss queues 6 7 8 / end # queue has no effect
+
+::
+
+ drop / passthru / end # drop has no effect
+
+Note that PMDs may still refuse such combinations.
+
+Actions
+^^^^^^^
+
+This section lists supported actions and their attributes, if any.
+
+- ``end``: end list of actions.
+
+- ``void``: no-op action.
+
+- ``passthru``: let subsequent rule process matched packets.
+
+- ``mark``: attach 32 bit value to packets.
+
+ - ``id {unsigned}``: 32 bit value to return with packets.
+
+- ``flag``: flag packets.
+
+- ``queue``: assign packets to a given queue index.
+
+ - ``index {unsigned}``: queue index to use.
+
+- ``drop``: drop packets (note: passthru has priority).
+
+- ``count``: enable counters for this rule.
+
+- ``dup``: duplicate packets to a given queue index.
+
+ - ``index {unsigned}``: queue index to duplicate packets to.
+
+- ``rss``: spread packets among several queues.
+
+ - ``queues [{unsigned} [...]] end``: queue indices to use.
+
+- ``pf``: redirect packets to physical device function.
+
+- ``vf``: redirect packets to virtual device function.
+
+ - ``original {boolean}``: use original VF ID if possible.
+ - ``id {unsigned}``: VF ID to redirect packets to.
+
+Destroying flow rules
+~~~~~~~~~~~~~~~~~~~~~
+
+``flow destroy`` destroys one or more rules from their rule ID (as returned
+by ``flow create``), this command calls ``rte_flow_destroy()`` as many
+times as necessary::
+
+ flow destroy {port_id} rule {rule_id} [...]
+
+If successful, it will show::
+
+ Flow rule #[...] destroyed
+
+It does not report anything for rule IDs that do not exist. The usual error
+message is shown when a rule cannot be destroyed::
+
+ Caught error type [...] ([...]): [...]
+
+``flow flush`` destroys all rules on a device and does not take extra
+arguments. It is bound to ``rte_flow_flush()``::
+
+ flow flush {port_id}
+
+Any errors are reported as above.
+
+Creating several rules and destroying them::
+
+ testpmd> flow create 0 ingress pattern eth / ipv6 / end
+ actions queue index 2 / end
+ Flow rule #0 created
+ testpmd> flow create 0 ingress pattern eth / ipv4 / end
+ actions queue index 3 / end
+ Flow rule #1 created
+ testpmd> flow destroy 0 rule 0 rule 1
+ Flow rule #1 destroyed
+ Flow rule #0 destroyed
+ testpmd>
+
+The same result can be achieved using ``flow flush``::
+
+ testpmd> flow create 0 ingress pattern eth / ipv6 / end
+ actions queue index 2 / end
+ Flow rule #0 created
+ testpmd> flow create 0 ingress pattern eth / ipv4 / end
+ actions queue index 3 / end
+ Flow rule #1 created
+ testpmd> flow flush 0
+ testpmd>
+
+Non-existent rule IDs are ignored::
+
+ testpmd> flow create 0 ingress pattern eth / ipv6 / end
+ actions queue index 2 / end
+ Flow rule #0 created
+ testpmd> flow create 0 ingress pattern eth / ipv4 / end
+ actions queue index 3 / end
+ Flow rule #1 created
+ testpmd> flow destroy 0 rule 42 rule 10 rule 2
+ testpmd>
+ testpmd> flow destroy 0 rule 0
+ Flow rule #0 destroyed
+ testpmd>
+
+Querying flow rules
+~~~~~~~~~~~~~~~~~~~
+
+``flow query`` queries a specific action of a flow rule having that
+ability. Such actions collect information that can be reported using this
+command. It is bound to ``rte_flow_query()``::
+
+ flow query {port_id} {rule_id} {action}
+
+If successful, it will display either the retrieved data for known actions
+or the following message::
+
+ Cannot display result for action type [...] ([...])
+
+Otherwise, it will complain either that the rule does not exist or that some
+error occurred::
+
+ Flow rule #[...] not found
+
+::
+
+ Caught error type [...] ([...]): [...]
+
+Currently only the ``count`` action is supported. This action reports the
+number of packets that hit the flow rule and the total number of bytes. Its
+output has the following format::
+
+ count:
+ hits_set: [...] # whether "hits" contains a valid value
+ bytes_set: [...] # whether "bytes" contains a valid value
+ hits: [...] # number of packets
+ bytes: [...] # number of bytes
+
+Querying counters for TCPv6 packets redirected to queue 6::
+
+ testpmd> flow create 0 ingress pattern eth / ipv6 / tcp / end
+ actions queue index 6 / count / end
+ Flow rule #4 created
+ testpmd> flow query 0 4 count
+ count:
+ hits_set: 1
+ bytes_set: 0
+ hits: 386446
+ bytes: 0
+ testpmd>
+
+Listing flow rules
+~~~~~~~~~~~~~~~~~~
+
+``flow list`` lists existing flow rules sorted by priority and optionally
+filtered by group identifiers::
+
+ flow list {port_id} [group {group_id}] [...]
+
+This command only fails with the following message if the device does not
+exist::
+
+ Invalid port [...]
+
+Output consists of a header line followed by a short description of each
+flow rule, one per line. There is no output at all when no flow rules are
+configured on the device::
+
+ ID Group Prio Attr Rule
+ [...] [...] [...] [...] [...]
+
+``Attr`` column flags:
+
+- ``i`` for ``ingress``.
+- ``e`` for ``egress``.
+
+Creating several flow rules and listing them::
+
+ testpmd> flow create 0 ingress pattern eth / ipv4 / end
+ actions queue index 6 / end
+ Flow rule #0 created
+ testpmd> flow create 0 ingress pattern eth / ipv6 / end
+ actions queue index 2 / end
+ Flow rule #1 created
+ testpmd> flow create 0 priority 5 ingress pattern eth / ipv4 / udp / end
+ actions rss queues 6 7 8 end / end
+ Flow rule #2 created
+ testpmd> flow list 0
+ ID Group Prio Attr Rule
+ 0 0 0 i- ETH IPV4 => QUEUE
+ 1 0 0 i- ETH IPV6 => QUEUE
+ 2 0 5 i- ETH IPV4 UDP => RSS
+ testpmd>
+
+Rules are sorted by priority (i.e. group ID first, then priority level)::
+
+ testpmd> flow list 1
+ ID Group Prio Attr Rule
+ 0 0 0 i- ETH => COUNT
+ 6 0 500 i- ETH IPV6 TCP => DROP COUNT
+ 5 0 1000 i- ETH IPV6 ICMP => QUEUE
+ 1 24 0 i- ETH IPV4 UDP => QUEUE
+ 4 24 10 i- ETH IPV4 TCP => DROP
+ 3 24 20 i- ETH IPV4 => DROP
+ 2 24 42 i- ETH IPV4 UDP => QUEUE
+ 7 63 0 i- ETH IPV6 UDP VXLAN => MARK QUEUE
+ testpmd>
+
+Output can be limited to specific groups::
+
+ testpmd> flow list 1 group 0 group 63
+ ID Group Prio Attr Rule
+ 0 0 0 i- ETH => COUNT
+ 6 0 500 i- ETH IPV6 TCP => DROP COUNT
+ 5 0 1000 i- ETH IPV6 ICMP => QUEUE
+ 7 63 0 i- ETH IPV6 UDP VXLAN => MARK QUEUE
+ testpmd>
--
2.1.4
^ permalink raw reply related
* [PATCH v5 26/26] app/testpmd: add protocol fields to flow command
From: Adrien Mazarguil @ 2016-12-21 14:51 UTC (permalink / raw)
To: dev; +Cc: Xing, Beilei, Pei, Yulong, Nelio Laranjeiro
In-Reply-To: <cover.1482331076.git.adrien.mazarguil@6wind.com>
This commit exposes the following item fields through the flow command:
- VLAN priority code point, drop eligible indicator and VLAN identifier
(all part of TCI).
- IPv4 type of service, time to live and protocol.
- IPv6 traffic class, flow label, next header and hop limit.
- SCTP tag and checksum.
Cc: Xing, Beilei <beilei.xing@intel.com>
Cc: Pei, Yulong <yulong.pei@intel.com>
Signed-off-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
app/test-pmd/cmdline_flow.c | 127 +++++++++++++++++++++++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 12 +++
2 files changed, 139 insertions(+)
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index db680c6..7760c2d 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -126,10 +126,20 @@ enum index {
ITEM_VLAN,
ITEM_VLAN_TPID,
ITEM_VLAN_TCI,
+ ITEM_VLAN_PCP,
+ ITEM_VLAN_DEI,
+ ITEM_VLAN_VID,
ITEM_IPV4,
+ ITEM_IPV4_TOS,
+ ITEM_IPV4_TTL,
+ ITEM_IPV4_PROTO,
ITEM_IPV4_SRC,
ITEM_IPV4_DST,
ITEM_IPV6,
+ ITEM_IPV6_TC,
+ ITEM_IPV6_FLOW,
+ ITEM_IPV6_PROTO,
+ ITEM_IPV6_HOP,
ITEM_IPV6_SRC,
ITEM_IPV6_DST,
ITEM_ICMP,
@@ -144,6 +154,8 @@ enum index {
ITEM_SCTP,
ITEM_SCTP_SRC,
ITEM_SCTP_DST,
+ ITEM_SCTP_TAG,
+ ITEM_SCTP_CKSUM,
ITEM_VXLAN,
ITEM_VXLAN_VNI,
@@ -281,6 +293,23 @@ struct token {
.mask = (const void *)&(const s){ .f = (1 << (b)) - 1 }, \
})
+/** Static initializer for ARGS() to target an arbitrary bit-mask. */
+#define ARGS_ENTRY_MASK(s, f, m) \
+ (&(const struct arg){ \
+ .offset = offsetof(s, f), \
+ .size = sizeof(((s *)0)->f), \
+ .mask = (const void *)(m), \
+ })
+
+/** Same as ARGS_ENTRY_MASK() using network byte ordering for the value. */
+#define ARGS_ENTRY_MASK_HTON(s, f, m) \
+ (&(const struct arg){ \
+ .hton = 1, \
+ .offset = offsetof(s, f), \
+ .size = sizeof(((s *)0)->f), \
+ .mask = (const void *)(m), \
+ })
+
/** Static initializer for ARGS() to target a pointer. */
#define ARGS_ENTRY_PTR(s, f) \
(&(const struct arg){ \
@@ -444,11 +473,17 @@ static const enum index item_eth[] = {
static const enum index item_vlan[] = {
ITEM_VLAN_TPID,
ITEM_VLAN_TCI,
+ ITEM_VLAN_PCP,
+ ITEM_VLAN_DEI,
+ ITEM_VLAN_VID,
ITEM_NEXT,
ZERO,
};
static const enum index item_ipv4[] = {
+ ITEM_IPV4_TOS,
+ ITEM_IPV4_TTL,
+ ITEM_IPV4_PROTO,
ITEM_IPV4_SRC,
ITEM_IPV4_DST,
ITEM_NEXT,
@@ -456,6 +491,10 @@ static const enum index item_ipv4[] = {
};
static const enum index item_ipv6[] = {
+ ITEM_IPV6_TC,
+ ITEM_IPV6_FLOW,
+ ITEM_IPV6_PROTO,
+ ITEM_IPV6_HOP,
ITEM_IPV6_SRC,
ITEM_IPV6_DST,
ITEM_NEXT,
@@ -486,6 +525,8 @@ static const enum index item_tcp[] = {
static const enum index item_sctp[] = {
ITEM_SCTP_SRC,
ITEM_SCTP_DST,
+ ITEM_SCTP_TAG,
+ ITEM_SCTP_CKSUM,
ITEM_NEXT,
ZERO,
};
@@ -1012,6 +1053,27 @@ static const struct token token_list[] = {
.next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, tci)),
},
+ [ITEM_VLAN_PCP] = {
+ .name = "pcp",
+ .help = "priority code point",
+ .next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan,
+ tci, "\xe0\x00")),
+ },
+ [ITEM_VLAN_DEI] = {
+ .name = "dei",
+ .help = "drop eligible indicator",
+ .next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan,
+ tci, "\x10\x00")),
+ },
+ [ITEM_VLAN_VID] = {
+ .name = "vid",
+ .help = "VLAN identifier",
+ .next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan,
+ tci, "\x0f\xff")),
+ },
[ITEM_IPV4] = {
.name = "ipv4",
.help = "match IPv4 header",
@@ -1019,6 +1081,27 @@ static const struct token token_list[] = {
.next = NEXT(item_ipv4),
.call = parse_vc,
},
+ [ITEM_IPV4_TOS] = {
+ .name = "tos",
+ .help = "type of service",
+ .next = NEXT(item_ipv4, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
+ hdr.type_of_service)),
+ },
+ [ITEM_IPV4_TTL] = {
+ .name = "ttl",
+ .help = "time to live",
+ .next = NEXT(item_ipv4, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
+ hdr.time_to_live)),
+ },
+ [ITEM_IPV4_PROTO] = {
+ .name = "proto",
+ .help = "next protocol ID",
+ .next = NEXT(item_ipv4, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
+ hdr.next_proto_id)),
+ },
[ITEM_IPV4_SRC] = {
.name = "src",
.help = "source address",
@@ -1040,6 +1123,36 @@ static const struct token token_list[] = {
.next = NEXT(item_ipv6),
.call = parse_vc,
},
+ [ITEM_IPV6_TC] = {
+ .name = "tc",
+ .help = "traffic class",
+ .next = NEXT(item_ipv6, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6,
+ hdr.vtc_flow,
+ "\x0f\xf0\x00\x00")),
+ },
+ [ITEM_IPV6_FLOW] = {
+ .name = "flow",
+ .help = "flow label",
+ .next = NEXT(item_ipv6, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6,
+ hdr.vtc_flow,
+ "\x00\x0f\xff\xff")),
+ },
+ [ITEM_IPV6_PROTO] = {
+ .name = "proto",
+ .help = "protocol (next header)",
+ .next = NEXT(item_ipv6, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
+ hdr.proto)),
+ },
+ [ITEM_IPV6_HOP] = {
+ .name = "hop",
+ .help = "hop limit",
+ .next = NEXT(item_ipv6, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
+ hdr.hop_limits)),
+ },
[ITEM_IPV6_SRC] = {
.name = "src",
.help = "source address",
@@ -1138,6 +1251,20 @@ static const struct token token_list[] = {
.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
hdr.dst_port)),
},
+ [ITEM_SCTP_TAG] = {
+ .name = "tag",
+ .help = "validation tag",
+ .next = NEXT(item_sctp, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
+ hdr.tag)),
+ },
+ [ITEM_SCTP_CKSUM] = {
+ .name = "cksum",
+ .help = "checksum",
+ .next = NEXT(item_sctp, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp,
+ hdr.cksum)),
+ },
[ITEM_VXLAN] = {
.name = "vxlan",
.help = "match VXLAN header",
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 03b6fa9..cacdef1 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -2333,14 +2333,24 @@ This section lists supported pattern items and their attributes, if any.
- ``tpid {unsigned}``: tag protocol identifier.
- ``tci {unsigned}``: tag control information.
+ - ``pcp {unsigned}``: priority code point.
+ - ``dei {unsigned}``: drop eligible indicator.
+ - ``vid {unsigned}``: VLAN identifier.
- ``ipv4``: match IPv4 header.
+ - ``tos {unsigned}``: type of service.
+ - ``ttl {unsigned}``: time to live.
+ - ``proto {unsigned}``: next protocol ID.
- ``src {ipv4 address}``: source address.
- ``dst {ipv4 address}``: destination address.
- ``ipv6``: match IPv6 header.
+ - ``tc {unsigned}``: traffic class.
+ - ``flow {unsigned}``: flow label.
+ - ``proto {unsigned}``: protocol (next header).
+ - ``hop {unsigned}``: hop limit.
- ``src {ipv6 address}``: source address.
- ``dst {ipv6 address}``: destination address.
@@ -2363,6 +2373,8 @@ This section lists supported pattern items and their attributes, if any.
- ``src {unsigned}``: SCTP source port.
- ``dst {unsigned}``: SCTP destination port.
+ - ``tag {unsigned}``: validation tag.
+ - ``cksum {unsigned}``: checksum.
- ``vxlan``: match VXLAN header.
--
2.1.4
^ permalink raw reply related
* Re: [PATCH v2 06/12] crypto/armv8: add PMD optimized for ARMv8 processors
From: De Lara Guarch, Pablo @ 2016-12-21 14:55 UTC (permalink / raw)
To: zbigniew.bodek@caviumnetworks.com, jerin.jacob@caviumnetworks.com
Cc: dev@dpdk.org
In-Reply-To: <1481077985-4224-7-git-send-email-zbigniew.bodek@caviumnetworks.com>
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of
> zbigniew.bodek@caviumnetworks.com
> Sent: Wednesday, December 07, 2016 2:33 AM
> To: De Lara Guarch, Pablo; jerin.jacob@caviumnetworks.com
> Cc: dev@dpdk.org; Zbigniew Bodek
> Subject: [dpdk-dev] [PATCH v2 06/12] crypto/armv8: add PMD optimized
> for ARMv8 processors
>
> From: Zbigniew Bodek <zbigniew.bodek@caviumnetworks.com>
>
> This patch introduces crypto poll mode driver
> using ARMv8 cryptographic extensions.
> CPU compatibility with this driver is detected in
> run-time and virtual crypto device will not be
> created if CPU doesn't provide:
> AES, SHA1, SHA2 and NEON.
>
> This PMD is optimized to provide performance boost
> for chained crypto operations processing,
> such as encryption + HMAC generation,
> decryption + HMAC validation. In particular,
> cipher only or hash only operations are
> not provided.
>
> The driver currently supports AES-128-CBC
> in combination with:
> SHA256 MAC, SHA256 HMAC and SHA1 HMAC and relies
> on the low-level assembly code.
>
> This patch adds driver's code only and does
> not include it in the build system.
>
> Signed-off-by: Zbigniew Bodek <zbigniew.bodek@caviumnetworks.com>
> ---
> drivers/crypto/armv8/Makefile | 72 ++
> drivers/crypto/armv8/asm/include/rte_armv8_defs.h | 80 ++
> drivers/crypto/armv8/rte_armv8_pmd.c | 915
> ++++++++++++++++++++++
> drivers/crypto/armv8/rte_armv8_pmd_ops.c | 390 +++++++++
> drivers/crypto/armv8/rte_armv8_pmd_private.h | 210 +++++
> drivers/crypto/armv8/rte_armv8_pmd_version.map | 3 +
> 6 files changed, 1670 insertions(+)
> create mode 100644 drivers/crypto/armv8/Makefile
> create mode 100644
> drivers/crypto/armv8/asm/include/rte_armv8_defs.h
> create mode 100644 drivers/crypto/armv8/rte_armv8_pmd.c
> create mode 100644 drivers/crypto/armv8/rte_armv8_pmd_ops.c
> create mode 100644 drivers/crypto/armv8/rte_armv8_pmd_private.h
> create mode 100644 drivers/crypto/armv8/rte_armv8_pmd_version.map
>
...
> diff --git a/drivers/crypto/armv8/asm/include/rte_armv8_defs.h
> b/drivers/crypto/armv8/asm/include/rte_armv8_defs.h
> new file mode 100644
> index 0000000..ea05495
> --- /dev/null
> +++ b/drivers/crypto/armv8/asm/include/rte_armv8_defs.h
> @@ -0,0 +1,80 @@
...
> +
> +#ifndef _RTE_ARMV8_DEFS_H_
> +#define _RTE_ARMV8_DEFS_H_
> +
> +struct crypto_arg {
> + struct {
> + uint8_t *key;
> + uint8_t *iv;
> + } cipher;
Remove unnecessary tab above.
> + struct {
> + struct {
> + uint8_t *key;
> + uint8_t *i_key_pad;
> + uint8_t *o_key_pad;
> + } hmac;
> + } digest;
> +};
...
> diff --git a/drivers/crypto/armv8/rte_armv8_pmd.c
> b/drivers/crypto/armv8/rte_armv8_pmd.c
> new file mode 100644
> index 0000000..0410bb0
> --- /dev/null
> +++ b/drivers/crypto/armv8/rte_armv8_pmd.c
> + * 3D array type for ARM Combined Mode crypto functions pointers.
> + * CRYPTO_CIPHER_MAX: max cipher ID number
> + * CRYPTO_AUTH_MAX: max auth ID number
> + * CRYPTO_CIPHER_KEYLEN_MAX: max key length ID number
> + */
> +typedef const crypto_func_t
> +crypto_func_tbl_t[CRYPTO_CIPHER_MAX][CRYPTO_AUTH_MAX][CRYPTO_
> CIPHER_KEYLEN_MAX];
> +
> +/* Evaluate to key length definition */
> +#define KEYL(keyl) (ARMV8_CRYPTO_CIPHER_KEYLEN_
> ## keyl)
I don't think a tab is necessary here after define (happens on other parts)
> +
> +/* Local aliases for supported ciphers */
> +#define CIPH_AES_CBC RTE_CRYPTO_CIPHER_AES_CBC
> +/* Local aliases for supported hashes */
> +#define AUTH_SHA1_HMAC
> RTE_CRYPTO_AUTH_SHA1_HMAC
> +#define AUTH_SHA256 RTE_CRYPTO_AUTH_SHA256
> +#define AUTH_SHA256_HMAC RTE_CRYPTO_AUTH_SHA256_HMAC
...
> diff --git a/drivers/crypto/armv8/rte_armv8_pmd_ops.c
> b/drivers/crypto/armv8/rte_armv8_pmd_ops.c
> new file mode 100644
> index 0000000..0f768f4
> --- /dev/null
> +++ b/drivers/crypto/armv8/rte_armv8_pmd_ops.c
...
> + { /* AES CBC */
> + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
> + {.sym = {
> + .xform_type =
> RTE_CRYPTO_SYM_XFORM_CIPHER,
> + {.cipher = {
> + .algo =
> RTE_CRYPTO_CIPHER_AES_CBC,
> + .block_size = 16,
> + .key_size = {
> + .min = 16,
> + .max = 32,
> + .increment = 8
>From what I read, this PMD only supports AES-128-CBC.
If that's right, then key_size should be .min = 16, .max = 16, .increment = 0.
^ permalink raw reply
* Re: [PATCH v2 08/12] mk/crypto/armv8: add PMD to the build system
From: De Lara Guarch, Pablo @ 2016-12-21 15:01 UTC (permalink / raw)
To: zbigniew.bodek@caviumnetworks.com, jerin.jacob@caviumnetworks.com
Cc: dev@dpdk.org
In-Reply-To: <1481077985-4224-9-git-send-email-zbigniew.bodek@caviumnetworks.com>
> -----Original Message-----
> From: zbigniew.bodek@caviumnetworks.com
> [mailto:zbigniew.bodek@caviumnetworks.com]
> Sent: Wednesday, December 07, 2016 2:33 AM
> To: De Lara Guarch, Pablo; jerin.jacob@caviumnetworks.com
> Cc: dev@dpdk.org; Zbigniew Bodek
> Subject: [PATCH v2 08/12] mk/crypto/armv8: add PMD to the build system
>
> From: Zbigniew Bodek <zbigniew.bodek@caviumnetworks.com>
>
> Build ARMv8 crypto PMD if compiling for ARM64
> and CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO option
> is enable in the configuration file.
>
> Signed-off-by: Zbigniew Bodek <zbigniew.bodek@caviumnetworks.com>
> ---
> drivers/crypto/Makefile | 3 +++
> mk/rte.app.mk | 3 +++
> 2 files changed, 6 insertions(+)
>
> diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
> index 745c614..a5de944 100644
> --- a/drivers/crypto/Makefile
> +++ b/drivers/crypto/Makefile
> @@ -33,6 +33,9 @@ include $(RTE_SDK)/mk/rte.vars.mk
>
> DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += aesni_gcm
> DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += aesni_mb
> +ifeq ($(CONFIG_RTE_ARCH_ARM64),y)
> +DIRS-$(CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO) += armv8
> +endif
Is this extra conditional necessary (ARM64)? I would think enabling ARMV8_CRYPTO would be sufficient.
^ permalink raw reply
* [PATCH v4 0/3] app: make python apps python2/3 compliant
From: John McNamara @ 2016-12-21 15:03 UTC (permalink / raw)
To: dev; +Cc: mkletzan, nhorman, John McNamara
In-Reply-To: <1481212265-10229-1-git-send-email-john.mcnamara@intel.com>
These patches refactor the DPDK Python applications to make them Python 2/3
compatible.
In order to do this the patchset starts by making the apps PEP8 compliant in
accordance with the DPDK Coding guidelines:
http://dpdk.org/doc/guides/contributing/coding_style.html#python-code
Implementing PEP8 and Python 2/3 compliance means that we can check all future
Python patches for consistency. Python 2/3 support also makes downstream
packaging easier as more distros move to Python 3 as the system python.
See the previous discussion about Python2/3 compatibilty here:
http://dpdk.org/ml/archives/dev/2016-December/051683.html
V4: * Rebase to latest HEAD.
V3: * Squash shebang patch into Python 3 patch.
* Only add /usr/bin/env shebang line to code that is executable.
V2: * Fix broken rebase.
John McNamara (3):
app: make python apps pep8 compliant
app: make python apps python2/3 compliant
doc: add required python versions to docs
app/cmdline_test/cmdline_test.py | 87 ++-
app/cmdline_test/cmdline_test_data.py | 403 +++++-----
app/test/autotest.py | 46 +-
app/test/autotest_data.py | 831 ++++++++++-----------
app/test/autotest_runner.py | 740 +++++++++---------
app/test/autotest_test_funcs.py | 481 ++++++------
doc/guides/conf.py | 9 +-
doc/guides/contributing/coding_style.rst | 3 +-
doc/guides/linux_gsg/sys_reqs.rst | 2 +-
examples/ip_pipeline/config/diagram-generator.py | 13 +-
.../ip_pipeline/config/pipeline-to-core-mapping.py | 11 +-
tools/cpu_layout.py | 79 +-
tools/dpdk-devbind.py | 25 +-
tools/dpdk-pmdinfo.py | 75 +-
14 files changed, 1405 insertions(+), 1400 deletions(-)
--
2.7.4
^ permalink raw reply
* [PATCH v4 1/3] app: make python apps pep8 compliant
From: John McNamara @ 2016-12-21 15:03 UTC (permalink / raw)
To: dev; +Cc: mkletzan, nhorman, John McNamara
In-Reply-To: <1481212265-10229-1-git-send-email-john.mcnamara@intel.com>
Make all DPDK python application compliant with the PEP8 standard
to allow for consistency checking of patches and to allow further
refactoring.
Signed-off-by: John McNamara <john.mcnamara@intel.com>
---
app/cmdline_test/cmdline_test.py | 81 +-
app/cmdline_test/cmdline_test_data.py | 401 +++++-----
app/test/autotest.py | 40 +-
app/test/autotest_data.py | 831 +++++++++++----------
app/test/autotest_runner.py | 739 +++++++++---------
app/test/autotest_test_funcs.py | 479 ++++++------
doc/guides/conf.py | 9 +-
examples/ip_pipeline/config/diagram-generator.py | 13 +-
.../ip_pipeline/config/pipeline-to-core-mapping.py | 11 +-
tools/cpu_layout.py | 55 +-
tools/dpdk-devbind.py | 23 +-
tools/dpdk-pmdinfo.py | 61 +-
12 files changed, 1376 insertions(+), 1367 deletions(-)
diff --git a/app/cmdline_test/cmdline_test.py b/app/cmdline_test/cmdline_test.py
index 8efc5ea..4729987 100755
--- a/app/cmdline_test/cmdline_test.py
+++ b/app/cmdline_test/cmdline_test.py
@@ -33,16 +33,21 @@
# Script that runs cmdline_test app and feeds keystrokes into it.
-import sys, pexpect, string, os, cmdline_test_data
+import cmdline_test_data
+import os
+import pexpect
+import sys
+
#
# function to run test
#
-def runTest(child,test):
- child.send(test["Sequence"])
- if test["Result"] == None:
- return 0
- child.expect(test["Result"],1)
+def runTest(child, test):
+ child.send(test["Sequence"])
+ if test["Result"] is None:
+ return 0
+ child.expect(test["Result"], 1)
+
#
# history test is a special case
@@ -57,57 +62,57 @@ def runTest(child,test):
# This is a self-contained test, it needs only a pexpect child
#
def runHistoryTest(child):
- # find out history size
- child.sendline(cmdline_test_data.CMD_GET_BUFSIZE)
- child.expect("History buffer size: \\d+", timeout=1)
- history_size = int(child.after[len(cmdline_test_data.BUFSIZE_TEMPLATE):])
- i = 0
+ # find out history size
+ child.sendline(cmdline_test_data.CMD_GET_BUFSIZE)
+ child.expect("History buffer size: \\d+", timeout=1)
+ history_size = int(child.after[len(cmdline_test_data.BUFSIZE_TEMPLATE):])
+ i = 0
- # fill the history with numbers
- while i < history_size / 10:
- # add 1 to prevent from parsing as octals
- child.send("1" + str(i).zfill(8) + cmdline_test_data.ENTER)
- # the app will simply print out the number
- child.expect(str(i + 100000000), timeout=1)
- i += 1
- # scroll back history
- child.send(cmdline_test_data.UP * (i + 2) + cmdline_test_data.ENTER)
- child.expect("100000000", timeout=1)
+ # fill the history with numbers
+ while i < history_size / 10:
+ # add 1 to prevent from parsing as octals
+ child.send("1" + str(i).zfill(8) + cmdline_test_data.ENTER)
+ # the app will simply print out the number
+ child.expect(str(i + 100000000), timeout=1)
+ i += 1
+ # scroll back history
+ child.send(cmdline_test_data.UP * (i + 2) + cmdline_test_data.ENTER)
+ child.expect("100000000", timeout=1)
# the path to cmdline_test executable is supplied via command-line.
if len(sys.argv) < 2:
- print "Error: please supply cmdline_test app path"
- sys.exit(1)
+ print "Error: please supply cmdline_test app path"
+ sys.exit(1)
test_app_path = sys.argv[1]
if not os.path.exists(test_app_path):
- print "Error: please supply cmdline_test app path"
- sys.exit(1)
+ print "Error: please supply cmdline_test app path"
+ sys.exit(1)
child = pexpect.spawn(test_app_path)
print "Running command-line tests..."
for test in cmdline_test_data.tests:
- print (test["Name"] + ":").ljust(30),
- try:
- runTest(child,test)
- print "PASS"
- except:
- print "FAIL"
- print child
- sys.exit(1)
+ print (test["Name"] + ":").ljust(30),
+ try:
+ runTest(child, test)
+ print "PASS"
+ except:
+ print "FAIL"
+ print child
+ sys.exit(1)
# since last test quits the app, run new instance
child = pexpect.spawn(test_app_path)
print ("History fill test:").ljust(30),
try:
- runHistoryTest(child)
- print "PASS"
+ runHistoryTest(child)
+ print "PASS"
except:
- print "FAIL"
- print child
- sys.exit(1)
+ print "FAIL"
+ print child
+ sys.exit(1)
child.close()
sys.exit(0)
diff --git a/app/cmdline_test/cmdline_test_data.py b/app/cmdline_test/cmdline_test_data.py
index b1945a5..3ce6cbc 100644
--- a/app/cmdline_test/cmdline_test_data.py
+++ b/app/cmdline_test/cmdline_test_data.py
@@ -33,8 +33,6 @@
# collection of static data
-import sys
-
# keycode constants
CTRL_A = chr(1)
CTRL_B = chr(2)
@@ -95,217 +93,220 @@
# and expected output (if any).
tests = [
-# test basic commands
- {"Name" : "command test 1",
- "Sequence" : "ambiguous first" + ENTER,
- "Result" : CMD1},
- {"Name" : "command test 2",
- "Sequence" : "ambiguous second" + ENTER,
- "Result" : CMD2},
- {"Name" : "command test 3",
- "Sequence" : "ambiguous ambiguous" + ENTER,
- "Result" : AMBIG},
- {"Name" : "command test 4",
- "Sequence" : "ambiguous ambiguous2" + ENTER,
- "Result" : AMBIG},
+ # test basic commands
+ {"Name": "command test 1",
+ "Sequence": "ambiguous first" + ENTER,
+ "Result": CMD1},
+ {"Name": "command test 2",
+ "Sequence": "ambiguous second" + ENTER,
+ "Result": CMD2},
+ {"Name": "command test 3",
+ "Sequence": "ambiguous ambiguous" + ENTER,
+ "Result": AMBIG},
+ {"Name": "command test 4",
+ "Sequence": "ambiguous ambiguous2" + ENTER,
+ "Result": AMBIG},
- {"Name" : "invalid command test 1",
- "Sequence" : "ambiguous invalid" + ENTER,
- "Result" : BAD_ARG},
-# test invalid commands
- {"Name" : "invalid command test 2",
- "Sequence" : "invalid" + ENTER,
- "Result" : NOT_FOUND},
- {"Name" : "invalid command test 3",
- "Sequence" : "ambiguousinvalid" + ENTER2,
- "Result" : NOT_FOUND},
+ {"Name": "invalid command test 1",
+ "Sequence": "ambiguous invalid" + ENTER,
+ "Result": BAD_ARG},
+ # test invalid commands
+ {"Name": "invalid command test 2",
+ "Sequence": "invalid" + ENTER,
+ "Result": NOT_FOUND},
+ {"Name": "invalid command test 3",
+ "Sequence": "ambiguousinvalid" + ENTER2,
+ "Result": NOT_FOUND},
-# test arrows and deletes
- {"Name" : "arrows & delete test 1",
- "Sequence" : "singlebad" + LEFT*2 + CTRL_B + DEL*3 + ENTER,
- "Result" : SINGLE},
- {"Name" : "arrows & delete test 2",
- "Sequence" : "singlebad" + LEFT*5 + RIGHT + CTRL_F + DEL*3 + ENTER,
- "Result" : SINGLE},
+ # test arrows and deletes
+ {"Name": "arrows & delete test 1",
+ "Sequence": "singlebad" + LEFT*2 + CTRL_B + DEL*3 + ENTER,
+ "Result": SINGLE},
+ {"Name": "arrows & delete test 2",
+ "Sequence": "singlebad" + LEFT*5 + RIGHT + CTRL_F + DEL*3 + ENTER,
+ "Result": SINGLE},
-# test backspace
- {"Name" : "backspace test",
- "Sequence" : "singlebad" + BKSPACE*3 + ENTER,
- "Result" : SINGLE},
+ # test backspace
+ {"Name": "backspace test",
+ "Sequence": "singlebad" + BKSPACE*3 + ENTER,
+ "Result": SINGLE},
-# test goto left and goto right
- {"Name" : "goto left test",
- "Sequence" : "biguous first" + CTRL_A + "am" + ENTER,
- "Result" : CMD1},
- {"Name" : "goto right test",
- "Sequence" : "biguous fir" + CTRL_A + "am" + CTRL_E + "st" + ENTER,
- "Result" : CMD1},
+ # test goto left and goto right
+ {"Name": "goto left test",
+ "Sequence": "biguous first" + CTRL_A + "am" + ENTER,
+ "Result": CMD1},
+ {"Name": "goto right test",
+ "Sequence": "biguous fir" + CTRL_A + "am" + CTRL_E + "st" + ENTER,
+ "Result": CMD1},
-# test goto words
- {"Name" : "goto left word test",
- "Sequence" : "ambiguous st" + ALT_B + "fir" + ENTER,
- "Result" : CMD1},
- {"Name" : "goto right word test",
- "Sequence" : "ambig first" + CTRL_A + ALT_F + "uous" + ENTER,
- "Result" : CMD1},
+ # test goto words
+ {"Name": "goto left word test",
+ "Sequence": "ambiguous st" + ALT_B + "fir" + ENTER,
+ "Result": CMD1},
+ {"Name": "goto right word test",
+ "Sequence": "ambig first" + CTRL_A + ALT_F + "uous" + ENTER,
+ "Result": CMD1},
-# test removing words
- {"Name" : "remove left word 1",
- "Sequence" : "single invalid" + CTRL_W + ENTER,
- "Result" : SINGLE},
- {"Name" : "remove left word 2",
- "Sequence" : "single invalid" + ALT_BKSPACE + ENTER,
- "Result" : SINGLE},
- {"Name" : "remove right word",
- "Sequence" : "single invalid" + ALT_B + ALT_D + ENTER,
- "Result" : SINGLE},
+ # test removing words
+ {"Name": "remove left word 1",
+ "Sequence": "single invalid" + CTRL_W + ENTER,
+ "Result": SINGLE},
+ {"Name": "remove left word 2",
+ "Sequence": "single invalid" + ALT_BKSPACE + ENTER,
+ "Result": SINGLE},
+ {"Name": "remove right word",
+ "Sequence": "single invalid" + ALT_B + ALT_D + ENTER,
+ "Result": SINGLE},
-# test kill buffer (copy and paste)
- {"Name" : "killbuffer test 1",
- "Sequence" : "ambiguous" + CTRL_A + CTRL_K + " first" + CTRL_A + CTRL_Y + ENTER,
- "Result" : CMD1},
- {"Name" : "killbuffer test 2",
- "Sequence" : "ambiguous" + CTRL_A + CTRL_K + CTRL_Y*26 + ENTER,
- "Result" : NOT_FOUND},
+ # test kill buffer (copy and paste)
+ {"Name": "killbuffer test 1",
+ "Sequence": "ambiguous" + CTRL_A + CTRL_K + " first" + CTRL_A +
+ CTRL_Y + ENTER,
+ "Result": CMD1},
+ {"Name": "killbuffer test 2",
+ "Sequence": "ambiguous" + CTRL_A + CTRL_K + CTRL_Y*26 + ENTER,
+ "Result": NOT_FOUND},
-# test newline
- {"Name" : "newline test",
- "Sequence" : "invalid" + CTRL_C + "single" + ENTER,
- "Result" : SINGLE},
+ # test newline
+ {"Name": "newline test",
+ "Sequence": "invalid" + CTRL_C + "single" + ENTER,
+ "Result": SINGLE},
-# test redisplay (nothing should really happen)
- {"Name" : "redisplay test",
- "Sequence" : "single" + CTRL_L + ENTER,
- "Result" : SINGLE},
+ # test redisplay (nothing should really happen)
+ {"Name": "redisplay test",
+ "Sequence": "single" + CTRL_L + ENTER,
+ "Result": SINGLE},
-# test autocomplete
- {"Name" : "autocomplete test 1",
- "Sequence" : "si" + TAB + ENTER,
- "Result" : SINGLE},
- {"Name" : "autocomplete test 2",
- "Sequence" : "si" + TAB + "_" + TAB + ENTER,
- "Result" : SINGLE_LONG},
- {"Name" : "autocomplete test 3",
- "Sequence" : "in" + TAB + ENTER,
- "Result" : NOT_FOUND},
- {"Name" : "autocomplete test 4",
- "Sequence" : "am" + TAB + ENTER,
- "Result" : BAD_ARG},
- {"Name" : "autocomplete test 5",
- "Sequence" : "am" + TAB + "fir" + TAB + ENTER,
- "Result" : CMD1},
- {"Name" : "autocomplete test 6",
- "Sequence" : "am" + TAB + "fir" + TAB + TAB + ENTER,
- "Result" : CMD1},
- {"Name" : "autocomplete test 7",
- "Sequence" : "am" + TAB + "fir" + TAB + " " + TAB + ENTER,
- "Result" : CMD1},
- {"Name" : "autocomplete test 8",
- "Sequence" : "am" + TAB + " am" + TAB + " " + ENTER,
- "Result" : AMBIG},
- {"Name" : "autocomplete test 9",
- "Sequence" : "am" + TAB + "inv" + TAB + ENTER,
- "Result" : BAD_ARG},
- {"Name" : "autocomplete test 10",
- "Sequence" : "au" + TAB + ENTER,
- "Result" : NOT_FOUND},
- {"Name" : "autocomplete test 11",
- "Sequence" : "au" + TAB + "1" + ENTER,
- "Result" : AUTO1},
- {"Name" : "autocomplete test 12",
- "Sequence" : "au" + TAB + "2" + ENTER,
- "Result" : AUTO2},
- {"Name" : "autocomplete test 13",
- "Sequence" : "au" + TAB + "2" + TAB + ENTER,
- "Result" : AUTO2},
- {"Name" : "autocomplete test 14",
- "Sequence" : "au" + TAB + "2 " + TAB + ENTER,
- "Result" : AUTO2},
- {"Name" : "autocomplete test 15",
- "Sequence" : "24" + TAB + ENTER,
- "Result" : "24"},
+ # test autocomplete
+ {"Name": "autocomplete test 1",
+ "Sequence": "si" + TAB + ENTER,
+ "Result": SINGLE},
+ {"Name": "autocomplete test 2",
+ "Sequence": "si" + TAB + "_" + TAB + ENTER,
+ "Result": SINGLE_LONG},
+ {"Name": "autocomplete test 3",
+ "Sequence": "in" + TAB + ENTER,
+ "Result": NOT_FOUND},
+ {"Name": "autocomplete test 4",
+ "Sequence": "am" + TAB + ENTER,
+ "Result": BAD_ARG},
+ {"Name": "autocomplete test 5",
+ "Sequence": "am" + TAB + "fir" + TAB + ENTER,
+ "Result": CMD1},
+ {"Name": "autocomplete test 6",
+ "Sequence": "am" + TAB + "fir" + TAB + TAB + ENTER,
+ "Result": CMD1},
+ {"Name": "autocomplete test 7",
+ "Sequence": "am" + TAB + "fir" + TAB + " " + TAB + ENTER,
+ "Result": CMD1},
+ {"Name": "autocomplete test 8",
+ "Sequence": "am" + TAB + " am" + TAB + " " + ENTER,
+ "Result": AMBIG},
+ {"Name": "autocomplete test 9",
+ "Sequence": "am" + TAB + "inv" + TAB + ENTER,
+ "Result": BAD_ARG},
+ {"Name": "autocomplete test 10",
+ "Sequence": "au" + TAB + ENTER,
+ "Result": NOT_FOUND},
+ {"Name": "autocomplete test 11",
+ "Sequence": "au" + TAB + "1" + ENTER,
+ "Result": AUTO1},
+ {"Name": "autocomplete test 12",
+ "Sequence": "au" + TAB + "2" + ENTER,
+ "Result": AUTO2},
+ {"Name": "autocomplete test 13",
+ "Sequence": "au" + TAB + "2" + TAB + ENTER,
+ "Result": AUTO2},
+ {"Name": "autocomplete test 14",
+ "Sequence": "au" + TAB + "2 " + TAB + ENTER,
+ "Result": AUTO2},
+ {"Name": "autocomplete test 15",
+ "Sequence": "24" + TAB + ENTER,
+ "Result": "24"},
-# test history
- {"Name" : "history test 1",
- "Sequence" : "invalid" + ENTER + "single" + ENTER + "invalid" + ENTER + UP + CTRL_P + ENTER,
- "Result" : SINGLE},
- {"Name" : "history test 2",
- "Sequence" : "invalid" + ENTER + "ambiguous first" + ENTER + "invalid" + ENTER + "single" + ENTER + UP * 3 + CTRL_N + DOWN + ENTER,
- "Result" : SINGLE},
+ # test history
+ {"Name": "history test 1",
+ "Sequence": "invalid" + ENTER + "single" + ENTER + "invalid" +
+ ENTER + UP + CTRL_P + ENTER,
+ "Result": SINGLE},
+ {"Name": "history test 2",
+ "Sequence": "invalid" + ENTER + "ambiguous first" + ENTER + "invalid" +
+ ENTER + "single" + ENTER + UP * 3 + CTRL_N + DOWN + ENTER,
+ "Result": SINGLE},
-#
-# tests that improve coverage
-#
+ #
+ # tests that improve coverage
+ #
-# empty space tests
- {"Name" : "empty space test 1",
- "Sequence" : RIGHT + LEFT + CTRL_B + CTRL_F + ENTER,
- "Result" : PROMPT},
- {"Name" : "empty space test 2",
- "Sequence" : BKSPACE + ENTER,
- "Result" : PROMPT},
- {"Name" : "empty space test 3",
- "Sequence" : CTRL_E*2 + CTRL_A*2 + ENTER,
- "Result" : PROMPT},
- {"Name" : "empty space test 4",
- "Sequence" : ALT_F*2 + ALT_B*2 + ENTER,
- "Result" : PROMPT},
- {"Name" : "empty space test 5",
- "Sequence" : " " + CTRL_E*2 + CTRL_A*2 + ENTER,
- "Result" : PROMPT},
- {"Name" : "empty space test 6",
- "Sequence" : " " + CTRL_A + ALT_F*2 + ALT_B*2 + ENTER,
- "Result" : PROMPT},
- {"Name" : "empty space test 7",
- "Sequence" : " " + CTRL_A + CTRL_D + CTRL_E + CTRL_D + ENTER,
- "Result" : PROMPT},
- {"Name" : "empty space test 8",
- "Sequence" : " space" + CTRL_W*2 + ENTER,
- "Result" : PROMPT},
- {"Name" : "empty space test 9",
- "Sequence" : " space" + ALT_BKSPACE*2 + ENTER,
- "Result" : PROMPT},
- {"Name" : "empty space test 10",
- "Sequence" : " space " + CTRL_A + ALT_D*3 + ENTER,
- "Result" : PROMPT},
+ # empty space tests
+ {"Name": "empty space test 1",
+ "Sequence": RIGHT + LEFT + CTRL_B + CTRL_F + ENTER,
+ "Result": PROMPT},
+ {"Name": "empty space test 2",
+ "Sequence": BKSPACE + ENTER,
+ "Result": PROMPT},
+ {"Name": "empty space test 3",
+ "Sequence": CTRL_E*2 + CTRL_A*2 + ENTER,
+ "Result": PROMPT},
+ {"Name": "empty space test 4",
+ "Sequence": ALT_F*2 + ALT_B*2 + ENTER,
+ "Result": PROMPT},
+ {"Name": "empty space test 5",
+ "Sequence": " " + CTRL_E*2 + CTRL_A*2 + ENTER,
+ "Result": PROMPT},
+ {"Name": "empty space test 6",
+ "Sequence": " " + CTRL_A + ALT_F*2 + ALT_B*2 + ENTER,
+ "Result": PROMPT},
+ {"Name": "empty space test 7",
+ "Sequence": " " + CTRL_A + CTRL_D + CTRL_E + CTRL_D + ENTER,
+ "Result": PROMPT},
+ {"Name": "empty space test 8",
+ "Sequence": " space" + CTRL_W*2 + ENTER,
+ "Result": PROMPT},
+ {"Name": "empty space test 9",
+ "Sequence": " space" + ALT_BKSPACE*2 + ENTER,
+ "Result": PROMPT},
+ {"Name": "empty space test 10",
+ "Sequence": " space " + CTRL_A + ALT_D*3 + ENTER,
+ "Result": PROMPT},
-# non-printable char tests
- {"Name" : "non-printable test 1",
- "Sequence" : chr(27) + chr(47) + ENTER,
- "Result" : PROMPT},
- {"Name" : "non-printable test 2",
- "Sequence" : chr(27) + chr(128) + ENTER*7,
- "Result" : PROMPT},
- {"Name" : "non-printable test 3",
- "Sequence" : chr(27) + chr(91) + chr(127) + ENTER*6,
- "Result" : PROMPT},
+ # non-printable char tests
+ {"Name": "non-printable test 1",
+ "Sequence": chr(27) + chr(47) + ENTER,
+ "Result": PROMPT},
+ {"Name": "non-printable test 2",
+ "Sequence": chr(27) + chr(128) + ENTER*7,
+ "Result": PROMPT},
+ {"Name": "non-printable test 3",
+ "Sequence": chr(27) + chr(91) + chr(127) + ENTER*6,
+ "Result": PROMPT},
-# miscellaneous tests
- {"Name" : "misc test 1",
- "Sequence" : ENTER,
- "Result" : PROMPT},
- {"Name" : "misc test 2",
- "Sequence" : "single #comment" + ENTER,
- "Result" : SINGLE},
- {"Name" : "misc test 3",
- "Sequence" : "#empty line" + ENTER,
- "Result" : PROMPT},
- {"Name" : "misc test 4",
- "Sequence" : " single " + ENTER,
- "Result" : SINGLE},
- {"Name" : "misc test 5",
- "Sequence" : "single#" + ENTER,
- "Result" : SINGLE},
- {"Name" : "misc test 6",
- "Sequence" : 'a' * 257 + ENTER,
- "Result" : NOT_FOUND},
- {"Name" : "misc test 7",
- "Sequence" : "clear_history" + UP*5 + DOWN*5 + ENTER,
- "Result" : PROMPT},
- {"Name" : "misc test 8",
- "Sequence" : "a" + HELP + CTRL_C,
- "Result" : PROMPT},
- {"Name" : "misc test 9",
- "Sequence" : CTRL_D*3,
- "Result" : None},
+ # miscellaneous tests
+ {"Name": "misc test 1",
+ "Sequence": ENTER,
+ "Result": PROMPT},
+ {"Name": "misc test 2",
+ "Sequence": "single #comment" + ENTER,
+ "Result": SINGLE},
+ {"Name": "misc test 3",
+ "Sequence": "#empty line" + ENTER,
+ "Result": PROMPT},
+ {"Name": "misc test 4",
+ "Sequence": " single " + ENTER,
+ "Result": SINGLE},
+ {"Name": "misc test 5",
+ "Sequence": "single#" + ENTER,
+ "Result": SINGLE},
+ {"Name": "misc test 6",
+ "Sequence": 'a' * 257 + ENTER,
+ "Result": NOT_FOUND},
+ {"Name": "misc test 7",
+ "Sequence": "clear_history" + UP*5 + DOWN*5 + ENTER,
+ "Result": PROMPT},
+ {"Name": "misc test 8",
+ "Sequence": "a" + HELP + CTRL_C,
+ "Result": PROMPT},
+ {"Name": "misc test 9",
+ "Sequence": CTRL_D*3,
+ "Result": None},
]
diff --git a/app/test/autotest.py b/app/test/autotest.py
index b9fd6b6..3a00538 100644
--- a/app/test/autotest.py
+++ b/app/test/autotest.py
@@ -33,44 +33,46 @@
# Script that uses either test app or qemu controlled by python-pexpect
-import sys, autotest_data, autotest_runner
-
+import autotest_data
+import autotest_runner
+import sys
def usage():
- print"Usage: autotest.py [test app|test iso image]",
- print "[target] [whitelist|-blacklist]"
+ print"Usage: autotest.py [test app|test iso image]",
+ print "[target] [whitelist|-blacklist]"
if len(sys.argv) < 3:
- usage()
- sys.exit(1)
+ usage()
+ sys.exit(1)
target = sys.argv[2]
-test_whitelist=None
-test_blacklist=None
+test_whitelist = None
+test_blacklist = None
# get blacklist/whitelist
if len(sys.argv) > 3:
- testlist = sys.argv[3].split(',')
- testlist = [test.lower() for test in testlist]
- if testlist[0].startswith('-'):
- testlist[0] = testlist[0].lstrip('-')
- test_blacklist = testlist
- else:
- test_whitelist = testlist
+ testlist = sys.argv[3].split(',')
+ testlist = [test.lower() for test in testlist]
+ if testlist[0].startswith('-'):
+ testlist[0] = testlist[0].lstrip('-')
+ test_blacklist = testlist
+ else:
+ test_whitelist = testlist
-cmdline = "%s -c f -n 4"%(sys.argv[1])
+cmdline = "%s -c f -n 4" % (sys.argv[1])
print cmdline
-runner = autotest_runner.AutotestRunner(cmdline, target, test_blacklist, test_whitelist)
+runner = autotest_runner.AutotestRunner(cmdline, target, test_blacklist,
+ test_whitelist)
for test_group in autotest_data.parallel_test_group_list:
- runner.add_parallel_test_group(test_group)
+ runner.add_parallel_test_group(test_group)
for test_group in autotest_data.non_parallel_test_group_list:
- runner.add_non_parallel_test_group(test_group)
+ runner.add_non_parallel_test_group(test_group)
num_fails = runner.run_all_tests()
diff --git a/app/test/autotest_data.py b/app/test/autotest_data.py
index 9e8fd94..0cf4cfd 100644
--- a/app/test/autotest_data.py
+++ b/app/test/autotest_data.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
# BSD LICENSE
#
@@ -36,12 +36,14 @@
from glob import glob
from autotest_test_funcs import *
+
# quick and dirty function to find out number of sockets
def num_sockets():
- result = len(glob("/sys/devices/system/node/node*"))
- if result == 0:
- return 1
- return result
+ result = len(glob("/sys/devices/system/node/node*"))
+ if result == 0:
+ return 1
+ return result
+
# Assign given number to each socket
# e.g. 32 becomes 32,32 or 32,32,32,32
@@ -51,420 +53,419 @@ def per_sockets(num):
# groups of tests that can be run in parallel
# the grouping has been found largely empirically
parallel_test_group_list = [
-
-{
- "Prefix": "group_1",
- "Memory" : per_sockets(8),
- "Tests" :
- [
- {
- "Name" : "Cycles autotest",
- "Command" : "cycles_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" : "Timer autotest",
- "Command" : "timer_autotest",
- "Func" : timer_autotest,
- "Report" : None,
- },
- {
- "Name" : "Debug autotest",
- "Command" : "debug_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" : "Errno autotest",
- "Command" : "errno_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" : "Meter autotest",
- "Command" : "meter_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" : "Common autotest",
- "Command" : "common_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" : "Resource autotest",
- "Command" : "resource_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- ]
-},
-{
- "Prefix": "group_2",
- "Memory" : "16",
- "Tests" :
- [
- {
- "Name" : "Memory autotest",
- "Command" : "memory_autotest",
- "Func" : memory_autotest,
- "Report" : None,
- },
- {
- "Name" : "Read/write lock autotest",
- "Command" : "rwlock_autotest",
- "Func" : rwlock_autotest,
- "Report" : None,
- },
- {
- "Name" : "Logs autotest",
- "Command" : "logs_autotest",
- "Func" : logs_autotest,
- "Report" : None,
- },
- {
- "Name" : "CPU flags autotest",
- "Command" : "cpuflags_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" : "Version autotest",
- "Command" : "version_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" : "EAL filesystem autotest",
- "Command" : "eal_fs_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" : "EAL flags autotest",
- "Command" : "eal_flags_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" : "Hash autotest",
- "Command" : "hash_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- ],
-},
-{
- "Prefix": "group_3",
- "Memory" : per_sockets(512),
- "Tests" :
- [
- {
- "Name" : "LPM autotest",
- "Command" : "lpm_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" : "LPM6 autotest",
- "Command" : "lpm6_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" : "Memcpy autotest",
- "Command" : "memcpy_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" : "Memzone autotest",
- "Command" : "memzone_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" : "String autotest",
- "Command" : "string_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" : "Alarm autotest",
- "Command" : "alarm_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- ]
-},
-{
- "Prefix": "group_4",
- "Memory" : per_sockets(128),
- "Tests" :
- [
- {
- "Name" : "PCI autotest",
- "Command" : "pci_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" : "Malloc autotest",
- "Command" : "malloc_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" : "Multi-process autotest",
- "Command" : "multiprocess_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" : "Mbuf autotest",
- "Command" : "mbuf_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" : "Per-lcore autotest",
- "Command" : "per_lcore_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" : "Ring autotest",
- "Command" : "ring_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- ]
-},
-{
- "Prefix": "group_5",
- "Memory" : "32",
- "Tests" :
- [
- {
- "Name" : "Spinlock autotest",
- "Command" : "spinlock_autotest",
- "Func" : spinlock_autotest,
- "Report" : None,
- },
- {
- "Name" : "Byte order autotest",
- "Command" : "byteorder_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" : "TAILQ autotest",
- "Command" : "tailq_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" : "Command-line autotest",
- "Command" : "cmdline_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" : "Interrupts autotest",
- "Command" : "interrupt_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- ]
-},
-{
- "Prefix": "group_6",
- "Memory" : per_sockets(512),
- "Tests" :
- [
- {
- "Name" : "Function reentrancy autotest",
- "Command" : "func_reentrancy_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" : "Mempool autotest",
- "Command" : "mempool_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" : "Atomics autotest",
- "Command" : "atomic_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" : "Prefetch autotest",
- "Command" : "prefetch_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" :"Red autotest",
- "Command" : "red_autotest",
- "Func" :default_autotest,
- "Report" :None,
- },
- ]
-},
-{
- "Prefix" : "group_7",
- "Memory" : "64",
- "Tests" :
- [
- {
- "Name" : "PMD ring autotest",
- "Command" : "ring_pmd_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" : "Access list control autotest",
- "Command" : "acl_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- {
- "Name" :"Sched autotest",
- "Command" : "sched_autotest",
- "Func" :default_autotest,
- "Report" :None,
- },
- ]
-},
+ {
+ "Prefix": "group_1",
+ "Memory": per_sockets(8),
+ "Tests":
+ [
+ {
+ "Name": "Cycles autotest",
+ "Command": "cycles_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Timer autotest",
+ "Command": "timer_autotest",
+ "Func": timer_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Debug autotest",
+ "Command": "debug_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Errno autotest",
+ "Command": "errno_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Meter autotest",
+ "Command": "meter_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Common autotest",
+ "Command": "common_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Resource autotest",
+ "Command": "resource_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ ]
+ },
+ {
+ "Prefix": "group_2",
+ "Memory": "16",
+ "Tests":
+ [
+ {
+ "Name": "Memory autotest",
+ "Command": "memory_autotest",
+ "Func": memory_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Read/write lock autotest",
+ "Command": "rwlock_autotest",
+ "Func": rwlock_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Logs autotest",
+ "Command": "logs_autotest",
+ "Func": logs_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "CPU flags autotest",
+ "Command": "cpuflags_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Version autotest",
+ "Command": "version_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "EAL filesystem autotest",
+ "Command": "eal_fs_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "EAL flags autotest",
+ "Command": "eal_flags_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Hash autotest",
+ "Command": "hash_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ ],
+ },
+ {
+ "Prefix": "group_3",
+ "Memory": per_sockets(512),
+ "Tests":
+ [
+ {
+ "Name": "LPM autotest",
+ "Command": "lpm_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "LPM6 autotest",
+ "Command": "lpm6_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Memcpy autotest",
+ "Command": "memcpy_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Memzone autotest",
+ "Command": "memzone_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "String autotest",
+ "Command": "string_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Alarm autotest",
+ "Command": "alarm_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ ]
+ },
+ {
+ "Prefix": "group_4",
+ "Memory": per_sockets(128),
+ "Tests":
+ [
+ {
+ "Name": "PCI autotest",
+ "Command": "pci_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Malloc autotest",
+ "Command": "malloc_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Multi-process autotest",
+ "Command": "multiprocess_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Mbuf autotest",
+ "Command": "mbuf_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Per-lcore autotest",
+ "Command": "per_lcore_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Ring autotest",
+ "Command": "ring_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ ]
+ },
+ {
+ "Prefix": "group_5",
+ "Memory": "32",
+ "Tests":
+ [
+ {
+ "Name": "Spinlock autotest",
+ "Command": "spinlock_autotest",
+ "Func": spinlock_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Byte order autotest",
+ "Command": "byteorder_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "TAILQ autotest",
+ "Command": "tailq_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Command-line autotest",
+ "Command": "cmdline_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Interrupts autotest",
+ "Command": "interrupt_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ ]
+ },
+ {
+ "Prefix": "group_6",
+ "Memory": per_sockets(512),
+ "Tests":
+ [
+ {
+ "Name": "Function reentrancy autotest",
+ "Command": "func_reentrancy_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Mempool autotest",
+ "Command": "mempool_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Atomics autotest",
+ "Command": "atomic_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Prefetch autotest",
+ "Command": "prefetch_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Red autotest",
+ "Command": "red_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ ]
+ },
+ {
+ "Prefix": "group_7",
+ "Memory": "64",
+ "Tests":
+ [
+ {
+ "Name": "PMD ring autotest",
+ "Command": "ring_pmd_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Access list control autotest",
+ "Command": "acl_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ {
+ "Name": "Sched autotest",
+ "Command": "sched_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ ]
+ },
]
# tests that should not be run when any other tests are running
non_parallel_test_group_list = [
-{
- "Prefix" : "kni",
- "Memory" : "512",
- "Tests" :
- [
- {
- "Name" : "KNI autotest",
- "Command" : "kni_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- ]
-},
-{
- "Prefix": "mempool_perf",
- "Memory" : per_sockets(256),
- "Tests" :
- [
- {
- "Name" : "Mempool performance autotest",
- "Command" : "mempool_perf_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- ]
-},
-{
- "Prefix": "memcpy_perf",
- "Memory" : per_sockets(512),
- "Tests" :
- [
- {
- "Name" : "Memcpy performance autotest",
- "Command" : "memcpy_perf_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- ]
-},
-{
- "Prefix": "hash_perf",
- "Memory" : per_sockets(512),
- "Tests" :
- [
- {
- "Name" : "Hash performance autotest",
- "Command" : "hash_perf_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- ]
-},
-{
- "Prefix" : "power",
- "Memory" : "16",
- "Tests" :
- [
- {
- "Name" : "Power autotest",
- "Command" : "power_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- ]
-},
-{
- "Prefix" : "power_acpi_cpufreq",
- "Memory" : "16",
- "Tests" :
- [
- {
- "Name" : "Power ACPI cpufreq autotest",
- "Command" : "power_acpi_cpufreq_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- ]
-},
-{
- "Prefix" : "power_kvm_vm",
- "Memory" : "16",
- "Tests" :
- [
- {
- "Name" : "Power KVM VM autotest",
- "Command" : "power_kvm_vm_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- ]
-},
-{
- "Prefix": "timer_perf",
- "Memory" : per_sockets(512),
- "Tests" :
- [
- {
- "Name" : "Timer performance autotest",
- "Command" : "timer_perf_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- ]
-},
+ {
+ "Prefix": "kni",
+ "Memory": "512",
+ "Tests":
+ [
+ {
+ "Name": "KNI autotest",
+ "Command": "kni_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ ]
+ },
+ {
+ "Prefix": "mempool_perf",
+ "Memory": per_sockets(256),
+ "Tests":
+ [
+ {
+ "Name": "Mempool performance autotest",
+ "Command": "mempool_perf_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ ]
+ },
+ {
+ "Prefix": "memcpy_perf",
+ "Memory": per_sockets(512),
+ "Tests":
+ [
+ {
+ "Name": "Memcpy performance autotest",
+ "Command": "memcpy_perf_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ ]
+ },
+ {
+ "Prefix": "hash_perf",
+ "Memory": per_sockets(512),
+ "Tests":
+ [
+ {
+ "Name": "Hash performance autotest",
+ "Command": "hash_perf_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ ]
+ },
+ {
+ "Prefix": "power",
+ "Memory": "16",
+ "Tests":
+ [
+ {
+ "Name": "Power autotest",
+ "Command": "power_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ ]
+ },
+ {
+ "Prefix": "power_acpi_cpufreq",
+ "Memory": "16",
+ "Tests":
+ [
+ {
+ "Name": "Power ACPI cpufreq autotest",
+ "Command": "power_acpi_cpufreq_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ ]
+ },
+ {
+ "Prefix": "power_kvm_vm",
+ "Memory": "16",
+ "Tests":
+ [
+ {
+ "Name": "Power KVM VM autotest",
+ "Command": "power_kvm_vm_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ ]
+ },
+ {
+ "Prefix": "timer_perf",
+ "Memory": per_sockets(512),
+ "Tests":
+ [
+ {
+ "Name": "Timer performance autotest",
+ "Command": "timer_perf_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ ]
+ },
-#
-# Please always make sure that ring_perf is the last test!
-#
-{
- "Prefix": "ring_perf",
- "Memory" : per_sockets(512),
- "Tests" :
- [
- {
- "Name" : "Ring performance autotest",
- "Command" : "ring_perf_autotest",
- "Func" : default_autotest,
- "Report" : None,
- },
- ]
-},
+ #
+ # Please always make sure that ring_perf is the last test!
+ #
+ {
+ "Prefix": "ring_perf",
+ "Memory": per_sockets(512),
+ "Tests":
+ [
+ {
+ "Name": "Ring performance autotest",
+ "Command": "ring_perf_autotest",
+ "Func": default_autotest,
+ "Report": None,
+ },
+ ]
+ },
]
diff --git a/app/test/autotest_runner.py b/app/test/autotest_runner.py
index 21d3be2..55b63a8 100644
--- a/app/test/autotest_runner.py
+++ b/app/test/autotest_runner.py
@@ -33,20 +33,29 @@
# The main logic behind running autotests in parallel
-import multiprocessing, subprocess, sys, pexpect, re, time, os, StringIO, csv
+import StringIO
+import csv
+import multiprocessing
+import pexpect
+import re
+import subprocess
+import sys
+import time
# wait for prompt
+
+
def wait_prompt(child):
- try:
- child.sendline()
- result = child.expect(["RTE>>", pexpect.TIMEOUT, pexpect.EOF],
- timeout = 120)
- except:
- return False
- if result == 0:
- return True
- else:
- return False
+ try:
+ child.sendline()
+ result = child.expect(["RTE>>", pexpect.TIMEOUT, pexpect.EOF],
+ timeout=120)
+ except:
+ return False
+ if result == 0:
+ return True
+ else:
+ return False
# run a test group
# each result tuple in results list consists of:
@@ -60,363 +69,363 @@ def wait_prompt(child):
# this function needs to be outside AutotestRunner class
# because otherwise Pool won't work (or rather it will require
# quite a bit of effort to make it work).
-def run_test_group(cmdline, test_group):
- results = []
- child = None
- start_time = time.time()
- startuplog = None
-
- # run test app
- try:
- # prepare logging of init
- startuplog = StringIO.StringIO()
-
- print >>startuplog, "\n%s %s\n" % ("="*20, test_group["Prefix"])
- print >>startuplog, "\ncmdline=%s" % cmdline
-
- child = pexpect.spawn(cmdline, logfile=startuplog)
-
- # wait for target to boot
- if not wait_prompt(child):
- child.close()
-
- results.append((-1, "Fail [No prompt]", "Start %s" % test_group["Prefix"],
- time.time() - start_time, startuplog.getvalue(), None))
-
- # mark all tests as failed
- for test in test_group["Tests"]:
- results.append((-1, "Fail [No prompt]", test["Name"],
- time.time() - start_time, "", None))
- # exit test
- return results
-
- except:
- results.append((-1, "Fail [Can't run]", "Start %s" % test_group["Prefix"],
- time.time() - start_time, startuplog.getvalue(), None))
-
- # mark all tests as failed
- for t in test_group["Tests"]:
- results.append((-1, "Fail [Can't run]", t["Name"],
- time.time() - start_time, "", None))
- # exit test
- return results
-
- # startup was successful
- results.append((0, "Success", "Start %s" % test_group["Prefix"],
- time.time() - start_time, startuplog.getvalue(), None))
-
- # parse the binary for available test commands
- binary = cmdline.split()[0]
- stripped = 'not stripped' not in subprocess.check_output(['file', binary])
- if not stripped:
- symbols = subprocess.check_output(['nm', binary]).decode('utf-8')
- avail_cmds = re.findall('test_register_(\w+)', symbols)
-
- # run all tests in test group
- for test in test_group["Tests"]:
-
- # create log buffer for each test
- # in multiprocessing environment, the logging would be
- # interleaved and will create a mess, hence the buffering
- logfile = StringIO.StringIO()
- child.logfile = logfile
-
- result = ()
-
- # make a note when the test started
- start_time = time.time()
-
- try:
- # print test name to log buffer
- print >>logfile, "\n%s %s\n" % ("-"*20, test["Name"])
-
- # run test function associated with the test
- if stripped or test["Command"] in avail_cmds:
- result = test["Func"](child, test["Command"])
- else:
- result = (0, "Skipped [Not Available]")
-
- # make a note when the test was finished
- end_time = time.time()
-
- # append test data to the result tuple
- result += (test["Name"], end_time - start_time,
- logfile.getvalue())
-
- # call report function, if any defined, and supply it with
- # target and complete log for test run
- if test["Report"]:
- report = test["Report"](self.target, log)
-
- # append report to results tuple
- result += (report,)
- else:
- # report is None
- result += (None,)
- except:
- # make a note when the test crashed
- end_time = time.time()
-
- # mark test as failed
- result = (-1, "Fail [Crash]", test["Name"],
- end_time - start_time, logfile.getvalue(), None)
- finally:
- # append the results to the results list
- results.append(result)
-
- # regardless of whether test has crashed, try quitting it
- try:
- child.sendline("quit")
- child.close()
- # if the test crashed, just do nothing instead
- except:
- # nop
- pass
-
- # return test results
- return results
-
+def run_test_group(cmdline, test_group):
+ results = []
+ child = None
+ start_time = time.time()
+ startuplog = None
+
+ # run test app
+ try:
+ # prepare logging of init
+ startuplog = StringIO.StringIO()
+
+ print >>startuplog, "\n%s %s\n" % ("=" * 20, test_group["Prefix"])
+ print >>startuplog, "\ncmdline=%s" % cmdline
+
+ child = pexpect.spawn(cmdline, logfile=startuplog)
+
+ # wait for target to boot
+ if not wait_prompt(child):
+ child.close()
+
+ results.append((-1,
+ "Fail [No prompt]",
+ "Start %s" % test_group["Prefix"],
+ time.time() - start_time,
+ startuplog.getvalue(),
+ None))
+
+ # mark all tests as failed
+ for test in test_group["Tests"]:
+ results.append((-1, "Fail [No prompt]", test["Name"],
+ time.time() - start_time, "", None))
+ # exit test
+ return results
+
+ except:
+ results.append((-1,
+ "Fail [Can't run]",
+ "Start %s" % test_group["Prefix"],
+ time.time() - start_time,
+ startuplog.getvalue(),
+ None))
+
+ # mark all tests as failed
+ for t in test_group["Tests"]:
+ results.append((-1, "Fail [Can't run]", t["Name"],
+ time.time() - start_time, "", None))
+ # exit test
+ return results
+
+ # startup was successful
+ results.append((0, "Success", "Start %s" % test_group["Prefix"],
+ time.time() - start_time, startuplog.getvalue(), None))
+
+ # parse the binary for available test commands
+ binary = cmdline.split()[0]
+ stripped = 'not stripped' not in subprocess.check_output(['file', binary])
+ if not stripped:
+ symbols = subprocess.check_output(['nm', binary]).decode('utf-8')
+ avail_cmds = re.findall('test_register_(\w+)', symbols)
+
+ # run all tests in test group
+ for test in test_group["Tests"]:
+
+ # create log buffer for each test
+ # in multiprocessing environment, the logging would be
+ # interleaved and will create a mess, hence the buffering
+ logfile = StringIO.StringIO()
+ child.logfile = logfile
+
+ result = ()
+
+ # make a note when the test started
+ start_time = time.time()
+
+ try:
+ # print test name to log buffer
+ print >>logfile, "\n%s %s\n" % ("-" * 20, test["Name"])
+
+ # run test function associated with the test
+ if stripped or test["Command"] in avail_cmds:
+ result = test["Func"](child, test["Command"])
+ else:
+ result = (0, "Skipped [Not Available]")
+
+ # make a note when the test was finished
+ end_time = time.time()
+
+ # append test data to the result tuple
+ result += (test["Name"], end_time - start_time,
+ logfile.getvalue())
+
+ # call report function, if any defined, and supply it with
+ # target and complete log for test run
+ if test["Report"]:
+ report = test["Report"](self.target, log)
+
+ # append report to results tuple
+ result += (report,)
+ else:
+ # report is None
+ result += (None,)
+ except:
+ # make a note when the test crashed
+ end_time = time.time()
+
+ # mark test as failed
+ result = (-1, "Fail [Crash]", test["Name"],
+ end_time - start_time, logfile.getvalue(), None)
+ finally:
+ # append the results to the results list
+ results.append(result)
+
+ # regardless of whether test has crashed, try quitting it
+ try:
+ child.sendline("quit")
+ child.close()
+ # if the test crashed, just do nothing instead
+ except:
+ # nop
+ pass
+
+ # return test results
+ return results
# class representing an instance of autotests run
class AutotestRunner:
- cmdline = ""
- parallel_test_groups = []
- non_parallel_test_groups = []
- logfile = None
- csvwriter = None
- target = ""
- start = None
- n_tests = 0
- fails = 0
- log_buffers = []
- blacklist = []
- whitelist = []
-
-
- def __init__(self, cmdline, target, blacklist, whitelist):
- self.cmdline = cmdline
- self.target = target
- self.blacklist = blacklist
- self.whitelist = whitelist
-
- # log file filename
- logfile = "%s.log" % target
- csvfile = "%s.csv" % target
-
- self.logfile = open(logfile, "w")
- csvfile = open(csvfile, "w")
- self.csvwriter = csv.writer(csvfile)
-
- # prepare results table
- self.csvwriter.writerow(["test_name","test_result","result_str"])
-
-
-
- # set up cmdline string
- def __get_cmdline(self, test):
- cmdline = self.cmdline
-
- # append memory limitations for each test
- # otherwise tests won't run in parallel
- if not "i686" in self.target:
- cmdline += " --socket-mem=%s"% test["Memory"]
- else:
- # affinitize startup so that tests don't fail on i686
- cmdline = "taskset 1 " + cmdline
- cmdline += " -m " + str(sum(map(int,test["Memory"].split(","))))
-
- # set group prefix for autotest group
- # otherwise they won't run in parallel
- cmdline += " --file-prefix=%s"% test["Prefix"]
-
- return cmdline
-
-
-
- def add_parallel_test_group(self,test_group):
- self.parallel_test_groups.append(test_group)
-
- def add_non_parallel_test_group(self,test_group):
- self.non_parallel_test_groups.append(test_group)
-
-
- def __process_results(self, results):
- # this iterates over individual test results
- for i, result in enumerate(results):
-
- # increase total number of tests that were run
- # do not include "start" test
- if i > 0:
- self.n_tests += 1
-
- # unpack result tuple
- test_result, result_str, test_name, \
- test_time, log, report = result
-
- # get total run time
- cur_time = time.time()
- total_time = int(cur_time - self.start)
-
- # print results, test run time and total time since start
- print ("%s:" % test_name).ljust(30),
- print result_str.ljust(29),
- print "[%02dm %02ds]" % (test_time / 60, test_time % 60),
-
- # don't print out total time every line, it's the same anyway
- if i == len(results) - 1:
- print "[%02dm %02ds]" % (total_time / 60, total_time % 60)
- else:
- print ""
-
- # if test failed and it wasn't a "start" test
- if test_result < 0 and not i == 0:
- self.fails += 1
-
- # collect logs
- self.log_buffers.append(log)
-
- # create report if it exists
- if report:
- try:
- f = open("%s_%s_report.rst" % (self.target,test_name), "w")
- except IOError:
- print "Report for %s could not be created!" % test_name
- else:
- with f:
- f.write(report)
-
- # write test result to CSV file
- if i != 0:
- self.csvwriter.writerow([test_name, test_result, result_str])
-
-
-
-
- # this function iterates over test groups and removes each
- # test that is not in whitelist/blacklist
- def __filter_groups(self, test_groups):
- groups_to_remove = []
-
- # filter out tests from parallel test groups
- for i, test_group in enumerate(test_groups):
-
- # iterate over a copy so that we could safely delete individual tests
- for test in test_group["Tests"][:]:
- test_id = test["Command"]
-
- # dump tests are specified in full e.g. "Dump_mempool"
- if "_autotest" in test_id:
- test_id = test_id[:-len("_autotest")]
-
- # filter out blacklisted/whitelisted tests
- if self.blacklist and test_id in self.blacklist:
- test_group["Tests"].remove(test)
- continue
- if self.whitelist and test_id not in self.whitelist:
- test_group["Tests"].remove(test)
- continue
-
- # modify or remove original group
- if len(test_group["Tests"]) > 0:
- test_groups[i] = test_group
- else:
- # remember which groups should be deleted
- # put the numbers backwards so that we start
- # deleting from the end, not from the beginning
- groups_to_remove.insert(0, i)
-
- # remove test groups that need to be removed
- for i in groups_to_remove:
- del test_groups[i]
-
- return test_groups
-
-
-
- # iterate over test groups and run tests associated with them
- def run_all_tests(self):
- # filter groups
- self.parallel_test_groups = \
- self.__filter_groups(self.parallel_test_groups)
- self.non_parallel_test_groups = \
- self.__filter_groups(self.non_parallel_test_groups)
-
- # create a pool of worker threads
- pool = multiprocessing.Pool(processes=1)
-
- results = []
-
- # whatever happens, try to save as much logs as possible
- try:
-
- # create table header
- print ""
- print "Test name".ljust(30),
- print "Test result".ljust(29),
- print "Test".center(9),
- print "Total".center(9)
- print "=" * 80
-
- # make a note of tests start time
- self.start = time.time()
-
- # assign worker threads to run test groups
- for test_group in self.parallel_test_groups:
- result = pool.apply_async(run_test_group,
- [self.__get_cmdline(test_group), test_group])
- results.append(result)
-
- # iterate while we have group execution results to get
- while len(results) > 0:
-
- # iterate over a copy to be able to safely delete results
- # this iterates over a list of group results
- for group_result in results[:]:
-
- # if the thread hasn't finished yet, continue
- if not group_result.ready():
- continue
-
- res = group_result.get()
-
- self.__process_results(res)
-
- # remove result from results list once we're done with it
- results.remove(group_result)
-
- # run non_parallel tests. they are run one by one, synchronously
- for test_group in self.non_parallel_test_groups:
- group_result = run_test_group(self.__get_cmdline(test_group), test_group)
-
- self.__process_results(group_result)
-
- # get total run time
- cur_time = time.time()
- total_time = int(cur_time - self.start)
-
- # print out summary
- print "=" * 80
- print "Total run time: %02dm %02ds" % (total_time / 60, total_time % 60)
- if self.fails != 0:
- print "Number of failed tests: %s" % str(self.fails)
-
- # write summary to logfile
- self.logfile.write("Summary\n")
- self.logfile.write("Target: ".ljust(15) + "%s\n" % self.target)
- self.logfile.write("Tests: ".ljust(15) + "%i\n" % self.n_tests)
- self.logfile.write("Failed tests: ".ljust(15) + "%i\n" % self.fails)
- except:
- print "Exception occured"
- print sys.exc_info()
- self.fails = 1
-
- # drop logs from all executions to a logfile
- for buf in self.log_buffers:
- self.logfile.write(buf.replace("\r",""))
-
- log_buffers = []
-
- return self.fails
+ cmdline = ""
+ parallel_test_groups = []
+ non_parallel_test_groups = []
+ logfile = None
+ csvwriter = None
+ target = ""
+ start = None
+ n_tests = 0
+ fails = 0
+ log_buffers = []
+ blacklist = []
+ whitelist = []
+
+ def __init__(self, cmdline, target, blacklist, whitelist):
+ self.cmdline = cmdline
+ self.target = target
+ self.blacklist = blacklist
+ self.whitelist = whitelist
+
+ # log file filename
+ logfile = "%s.log" % target
+ csvfile = "%s.csv" % target
+
+ self.logfile = open(logfile, "w")
+ csvfile = open(csvfile, "w")
+ self.csvwriter = csv.writer(csvfile)
+
+ # prepare results table
+ self.csvwriter.writerow(["test_name", "test_result", "result_str"])
+
+ # set up cmdline string
+ def __get_cmdline(self, test):
+ cmdline = self.cmdline
+
+ # append memory limitations for each test
+ # otherwise tests won't run in parallel
+ if "i686" not in self.target:
+ cmdline += " --socket-mem=%s" % test["Memory"]
+ else:
+ # affinitize startup so that tests don't fail on i686
+ cmdline = "taskset 1 " + cmdline
+ cmdline += " -m " + str(sum(map(int, test["Memory"].split(","))))
+
+ # set group prefix for autotest group
+ # otherwise they won't run in parallel
+ cmdline += " --file-prefix=%s" % test["Prefix"]
+
+ return cmdline
+
+ def add_parallel_test_group(self, test_group):
+ self.parallel_test_groups.append(test_group)
+
+ def add_non_parallel_test_group(self, test_group):
+ self.non_parallel_test_groups.append(test_group)
+
+ def __process_results(self, results):
+ # this iterates over individual test results
+ for i, result in enumerate(results):
+
+ # increase total number of tests that were run
+ # do not include "start" test
+ if i > 0:
+ self.n_tests += 1
+
+ # unpack result tuple
+ test_result, result_str, test_name, \
+ test_time, log, report = result
+
+ # get total run time
+ cur_time = time.time()
+ total_time = int(cur_time - self.start)
+
+ # print results, test run time and total time since start
+ print ("%s:" % test_name).ljust(30),
+ print result_str.ljust(29),
+ print "[%02dm %02ds]" % (test_time / 60, test_time % 60),
+
+ # don't print out total time every line, it's the same anyway
+ if i == len(results) - 1:
+ print "[%02dm %02ds]" % (total_time / 60, total_time % 60)
+ else:
+ print ""
+
+ # if test failed and it wasn't a "start" test
+ if test_result < 0 and not i == 0:
+ self.fails += 1
+
+ # collect logs
+ self.log_buffers.append(log)
+
+ # create report if it exists
+ if report:
+ try:
+ f = open("%s_%s_report.rst" %
+ (self.target, test_name), "w")
+ except IOError:
+ print "Report for %s could not be created!" % test_name
+ else:
+ with f:
+ f.write(report)
+
+ # write test result to CSV file
+ if i != 0:
+ self.csvwriter.writerow([test_name, test_result, result_str])
+
+ # this function iterates over test groups and removes each
+ # test that is not in whitelist/blacklist
+ def __filter_groups(self, test_groups):
+ groups_to_remove = []
+
+ # filter out tests from parallel test groups
+ for i, test_group in enumerate(test_groups):
+
+ # iterate over a copy so that we could safely delete individual
+ # tests
+ for test in test_group["Tests"][:]:
+ test_id = test["Command"]
+
+ # dump tests are specified in full e.g. "Dump_mempool"
+ if "_autotest" in test_id:
+ test_id = test_id[:-len("_autotest")]
+
+ # filter out blacklisted/whitelisted tests
+ if self.blacklist and test_id in self.blacklist:
+ test_group["Tests"].remove(test)
+ continue
+ if self.whitelist and test_id not in self.whitelist:
+ test_group["Tests"].remove(test)
+ continue
+
+ # modify or remove original group
+ if len(test_group["Tests"]) > 0:
+ test_groups[i] = test_group
+ else:
+ # remember which groups should be deleted
+ # put the numbers backwards so that we start
+ # deleting from the end, not from the beginning
+ groups_to_remove.insert(0, i)
+
+ # remove test groups that need to be removed
+ for i in groups_to_remove:
+ del test_groups[i]
+
+ return test_groups
+
+ # iterate over test groups and run tests associated with them
+ def run_all_tests(self):
+ # filter groups
+ self.parallel_test_groups = \
+ self.__filter_groups(self.parallel_test_groups)
+ self.non_parallel_test_groups = \
+ self.__filter_groups(self.non_parallel_test_groups)
+
+ # create a pool of worker threads
+ pool = multiprocessing.Pool(processes=1)
+
+ results = []
+
+ # whatever happens, try to save as much logs as possible
+ try:
+
+ # create table header
+ print ""
+ print "Test name".ljust(30),
+ print "Test result".ljust(29),
+ print "Test".center(9),
+ print "Total".center(9)
+ print "=" * 80
+
+ # make a note of tests start time
+ self.start = time.time()
+
+ # assign worker threads to run test groups
+ for test_group in self.parallel_test_groups:
+ result = pool.apply_async(run_test_group,
+ [self.__get_cmdline(test_group),
+ test_group])
+ results.append(result)
+
+ # iterate while we have group execution results to get
+ while len(results) > 0:
+
+ # iterate over a copy to be able to safely delete results
+ # this iterates over a list of group results
+ for group_result in results[:]:
+
+ # if the thread hasn't finished yet, continue
+ if not group_result.ready():
+ continue
+
+ res = group_result.get()
+
+ self.__process_results(res)
+
+ # remove result from results list once we're done with it
+ results.remove(group_result)
+
+ # run non_parallel tests. they are run one by one, synchronously
+ for test_group in self.non_parallel_test_groups:
+ group_result = run_test_group(
+ self.__get_cmdline(test_group), test_group)
+
+ self.__process_results(group_result)
+
+ # get total run time
+ cur_time = time.time()
+ total_time = int(cur_time - self.start)
+
+ # print out summary
+ print "=" * 80
+ print "Total run time: %02dm %02ds" % (total_time / 60,
+ total_time % 60)
+ if self.fails != 0:
+ print "Number of failed tests: %s" % str(self.fails)
+
+ # write summary to logfile
+ self.logfile.write("Summary\n")
+ self.logfile.write("Target: ".ljust(15) + "%s\n" % self.target)
+ self.logfile.write("Tests: ".ljust(15) + "%i\n" % self.n_tests)
+ self.logfile.write("Failed tests: ".ljust(
+ 15) + "%i\n" % self.fails)
+ except:
+ print "Exception occurred"
+ print sys.exc_info()
+ self.fails = 1
+
+ # drop logs from all executions to a logfile
+ for buf in self.log_buffers:
+ self.logfile.write(buf.replace("\r", ""))
+
+ return self.fails
diff --git a/app/test/autotest_test_funcs.py b/app/test/autotest_test_funcs.py
index 14cffd0..c482ea8 100644
--- a/app/test/autotest_test_funcs.py
+++ b/app/test/autotest_test_funcs.py
@@ -33,257 +33,272 @@
# Test functions
-import sys, pexpect, time, os, re
+import pexpect
# default autotest, used to run most tests
# waits for "Test OK"
+
+
def default_autotest(child, test_name):
- child.sendline(test_name)
- result = child.expect(["Test OK", "Test Failed",
- "Command not found", pexpect.TIMEOUT], timeout = 900)
- if result == 1:
- return -1, "Fail"
- elif result == 2:
- return -1, "Fail [Not found]"
- elif result == 3:
- return -1, "Fail [Timeout]"
- return 0, "Success"
+ child.sendline(test_name)
+ result = child.expect(["Test OK", "Test Failed",
+ "Command not found", pexpect.TIMEOUT], timeout=900)
+ if result == 1:
+ return -1, "Fail"
+ elif result == 2:
+ return -1, "Fail [Not found]"
+ elif result == 3:
+ return -1, "Fail [Timeout]"
+ return 0, "Success"
# autotest used to run dump commands
# just fires the command
+
+
def dump_autotest(child, test_name):
- child.sendline(test_name)
- return 0, "Success"
+ child.sendline(test_name)
+ return 0, "Success"
# memory autotest
# reads output and waits for Test OK
+
+
def memory_autotest(child, test_name):
- child.sendline(test_name)
- regexp = "phys:0x[0-9a-f]*, len:([0-9]*), virt:0x[0-9a-f]*, socket_id:[0-9]*"
- index = child.expect([regexp, pexpect.TIMEOUT], timeout = 180)
- if index != 0:
- return -1, "Fail [Timeout]"
- size = int(child.match.groups()[0], 16)
- if size <= 0:
- return -1, "Fail [Bad size]"
- index = child.expect(["Test OK", "Test Failed",
- pexpect.TIMEOUT], timeout = 10)
- if index == 1:
- return -1, "Fail"
- elif index == 2:
- return -1, "Fail [Timeout]"
- return 0, "Success"
+ child.sendline(test_name)
+ regexp = "phys:0x[0-9a-f]*, len:([0-9]*), virt:0x[0-9a-f]*, " \
+ "socket_id:[0-9]*"
+ index = child.expect([regexp, pexpect.TIMEOUT], timeout=180)
+ if index != 0:
+ return -1, "Fail [Timeout]"
+ size = int(child.match.groups()[0], 16)
+ if size <= 0:
+ return -1, "Fail [Bad size]"
+ index = child.expect(["Test OK", "Test Failed",
+ pexpect.TIMEOUT], timeout=10)
+ if index == 1:
+ return -1, "Fail"
+ elif index == 2:
+ return -1, "Fail [Timeout]"
+ return 0, "Success"
+
def spinlock_autotest(child, test_name):
- i = 0
- ir = 0
- child.sendline(test_name)
- while True:
- index = child.expect(["Test OK",
- "Test Failed",
- "Hello from core ([0-9]*) !",
- "Hello from within recursive locks from ([0-9]*) !",
- pexpect.TIMEOUT], timeout = 5)
- # ok
- if index == 0:
- break
-
- # message, check ordering
- elif index == 2:
- if int(child.match.groups()[0]) < i:
- return -1, "Fail [Bad order]"
- i = int(child.match.groups()[0])
- elif index == 3:
- if int(child.match.groups()[0]) < ir:
- return -1, "Fail [Bad order]"
- ir = int(child.match.groups()[0])
-
- # fail
- elif index == 4:
- return -1, "Fail [Timeout]"
- elif index == 1:
- return -1, "Fail"
-
- return 0, "Success"
+ i = 0
+ ir = 0
+ child.sendline(test_name)
+ while True:
+ index = child.expect(["Test OK",
+ "Test Failed",
+ "Hello from core ([0-9]*) !",
+ "Hello from within recursive locks "
+ "from ([0-9]*) !",
+ pexpect.TIMEOUT], timeout=5)
+ # ok
+ if index == 0:
+ break
+
+ # message, check ordering
+ elif index == 2:
+ if int(child.match.groups()[0]) < i:
+ return -1, "Fail [Bad order]"
+ i = int(child.match.groups()[0])
+ elif index == 3:
+ if int(child.match.groups()[0]) < ir:
+ return -1, "Fail [Bad order]"
+ ir = int(child.match.groups()[0])
+
+ # fail
+ elif index == 4:
+ return -1, "Fail [Timeout]"
+ elif index == 1:
+ return -1, "Fail"
+
+ return 0, "Success"
+
def rwlock_autotest(child, test_name):
- i = 0
- child.sendline(test_name)
- while True:
- index = child.expect(["Test OK",
- "Test Failed",
- "Hello from core ([0-9]*) !",
- "Global write lock taken on master core ([0-9]*)",
- pexpect.TIMEOUT], timeout = 10)
- # ok
- if index == 0:
- if i != 0xffff:
- return -1, "Fail [Message is missing]"
- break
-
- # message, check ordering
- elif index == 2:
- if int(child.match.groups()[0]) < i:
- return -1, "Fail [Bad order]"
- i = int(child.match.groups()[0])
-
- # must be the last message, check ordering
- elif index == 3:
- i = 0xffff
-
- elif index == 4:
- return -1, "Fail [Timeout]"
-
- # fail
- else:
- return -1, "Fail"
-
- return 0, "Success"
+ i = 0
+ child.sendline(test_name)
+ while True:
+ index = child.expect(["Test OK",
+ "Test Failed",
+ "Hello from core ([0-9]*) !",
+ "Global write lock taken on master "
+ "core ([0-9]*)",
+ pexpect.TIMEOUT], timeout=10)
+ # ok
+ if index == 0:
+ if i != 0xffff:
+ return -1, "Fail [Message is missing]"
+ break
+
+ # message, check ordering
+ elif index == 2:
+ if int(child.match.groups()[0]) < i:
+ return -1, "Fail [Bad order]"
+ i = int(child.match.groups()[0])
+
+ # must be the last message, check ordering
+ elif index == 3:
+ i = 0xffff
+
+ elif index == 4:
+ return -1, "Fail [Timeout]"
+
+ # fail
+ else:
+ return -1, "Fail"
+
+ return 0, "Success"
+
def logs_autotest(child, test_name):
- i = 0
- child.sendline(test_name)
-
- log_list = [
- "TESTAPP1: error message",
- "TESTAPP1: critical message",
- "TESTAPP2: critical message",
- "TESTAPP1: error message",
- ]
-
- for log_msg in log_list:
- index = child.expect([log_msg,
- "Test OK",
- "Test Failed",
- pexpect.TIMEOUT], timeout = 10)
-
- if index == 3:
- return -1, "Fail [Timeout]"
- # not ok
- elif index != 0:
- return -1, "Fail"
-
- index = child.expect(["Test OK",
- "Test Failed",
- pexpect.TIMEOUT], timeout = 10)
-
- return 0, "Success"
+ child.sendline(test_name)
+
+ log_list = [
+ "TESTAPP1: error message",
+ "TESTAPP1: critical message",
+ "TESTAPP2: critical message",
+ "TESTAPP1: error message",
+ ]
+
+ for log_msg in log_list:
+ index = child.expect([log_msg,
+ "Test OK",
+ "Test Failed",
+ pexpect.TIMEOUT], timeout=10)
+
+ if index == 3:
+ return -1, "Fail [Timeout]"
+ # not ok
+ elif index != 0:
+ return -1, "Fail"
+
+ index = child.expect(["Test OK",
+ "Test Failed",
+ pexpect.TIMEOUT], timeout=10)
+
+ return 0, "Success"
+
def timer_autotest(child, test_name):
- i = 0
- child.sendline(test_name)
-
- index = child.expect(["Start timer stress tests",
- "Test Failed",
- pexpect.TIMEOUT], timeout = 5)
-
- if index == 1:
- return -1, "Fail"
- elif index == 2:
- return -1, "Fail [Timeout]"
-
- index = child.expect(["Start timer stress tests 2",
- "Test Failed",
- pexpect.TIMEOUT], timeout = 5)
-
- if index == 1:
- return -1, "Fail"
- elif index == 2:
- return -1, "Fail [Timeout]"
-
- index = child.expect(["Start timer basic tests",
- "Test Failed",
- pexpect.TIMEOUT], timeout = 5)
-
- if index == 1:
- return -1, "Fail"
- elif index == 2:
- return -1, "Fail [Timeout]"
-
- prev_lcore_timer1 = -1
-
- lcore_tim0 = -1
- lcore_tim1 = -1
- lcore_tim2 = -1
- lcore_tim3 = -1
-
- while True:
- index = child.expect(["TESTTIMER: ([0-9]*): callback id=([0-9]*) count=([0-9]*) on core ([0-9]*)",
- "Test OK",
- "Test Failed",
- pexpect.TIMEOUT], timeout = 10)
-
- if index == 1:
- break
-
- if index == 2:
- return -1, "Fail"
- elif index == 3:
- return -1, "Fail [Timeout]"
-
- try:
- t = int(child.match.groups()[0])
- id = int(child.match.groups()[1])
- cnt = int(child.match.groups()[2])
- lcore = int(child.match.groups()[3])
- except:
- return -1, "Fail [Cannot parse]"
-
- # timer0 always expires on the same core when cnt < 20
- if id == 0:
- if lcore_tim0 == -1:
- lcore_tim0 = lcore
- elif lcore != lcore_tim0 and cnt < 20:
- return -1, "Fail [lcore != lcore_tim0 (%d, %d)]"%(lcore, lcore_tim0)
- if cnt > 21:
- return -1, "Fail [tim0 cnt > 21]"
-
- # timer1 each time expires on a different core
- if id == 1:
- if lcore == lcore_tim1:
- return -1, "Fail [lcore == lcore_tim1 (%d, %d)]"%(lcore, lcore_tim1)
- lcore_tim1 = lcore
- if cnt > 10:
- return -1, "Fail [tim1 cnt > 30]"
-
- # timer0 always expires on the same core
- if id == 2:
- if lcore_tim2 == -1:
- lcore_tim2 = lcore
- elif lcore != lcore_tim2:
- return -1, "Fail [lcore != lcore_tim2 (%d, %d)]"%(lcore, lcore_tim2)
- if cnt > 30:
- return -1, "Fail [tim2 cnt > 30]"
-
- # timer0 always expires on the same core
- if id == 3:
- if lcore_tim3 == -1:
- lcore_tim3 = lcore
- elif lcore != lcore_tim3:
- return -1, "Fail [lcore_tim3 changed (%d -> %d)]"%(lcore, lcore_tim3)
- if cnt > 30:
- return -1, "Fail [tim3 cnt > 30]"
-
- # must be 2 different cores
- if lcore_tim0 == lcore_tim3:
- return -1, "Fail [lcore_tim0 (%d) == lcore_tim3 (%d)]"%(lcore_tim0, lcore_tim3)
-
- return 0, "Success"
+ child.sendline(test_name)
+
+ index = child.expect(["Start timer stress tests",
+ "Test Failed",
+ pexpect.TIMEOUT], timeout=5)
+
+ if index == 1:
+ return -1, "Fail"
+ elif index == 2:
+ return -1, "Fail [Timeout]"
+
+ index = child.expect(["Start timer stress tests 2",
+ "Test Failed",
+ pexpect.TIMEOUT], timeout=5)
+
+ if index == 1:
+ return -1, "Fail"
+ elif index == 2:
+ return -1, "Fail [Timeout]"
+
+ index = child.expect(["Start timer basic tests",
+ "Test Failed",
+ pexpect.TIMEOUT], timeout=5)
+
+ if index == 1:
+ return -1, "Fail"
+ elif index == 2:
+ return -1, "Fail [Timeout]"
+
+ lcore_tim0 = -1
+ lcore_tim1 = -1
+ lcore_tim2 = -1
+ lcore_tim3 = -1
+
+ while True:
+ index = child.expect(["TESTTIMER: ([0-9]*): callback id=([0-9]*) "
+ "count=([0-9]*) on core ([0-9]*)",
+ "Test OK",
+ "Test Failed",
+ pexpect.TIMEOUT], timeout=10)
+
+ if index == 1:
+ break
+
+ if index == 2:
+ return -1, "Fail"
+ elif index == 3:
+ return -1, "Fail [Timeout]"
+
+ try:
+ id = int(child.match.groups()[1])
+ cnt = int(child.match.groups()[2])
+ lcore = int(child.match.groups()[3])
+ except:
+ return -1, "Fail [Cannot parse]"
+
+ # timer0 always expires on the same core when cnt < 20
+ if id == 0:
+ if lcore_tim0 == -1:
+ lcore_tim0 = lcore
+ elif lcore != lcore_tim0 and cnt < 20:
+ return -1, "Fail [lcore != lcore_tim0 (%d, %d)]" \
+ % (lcore, lcore_tim0)
+ if cnt > 21:
+ return -1, "Fail [tim0 cnt > 21]"
+
+ # timer1 each time expires on a different core
+ if id == 1:
+ if lcore == lcore_tim1:
+ return -1, "Fail [lcore == lcore_tim1 (%d, %d)]" \
+ % (lcore, lcore_tim1)
+ lcore_tim1 = lcore
+ if cnt > 10:
+ return -1, "Fail [tim1 cnt > 30]"
+
+ # timer0 always expires on the same core
+ if id == 2:
+ if lcore_tim2 == -1:
+ lcore_tim2 = lcore
+ elif lcore != lcore_tim2:
+ return -1, "Fail [lcore != lcore_tim2 (%d, %d)]" \
+ % (lcore, lcore_tim2)
+ if cnt > 30:
+ return -1, "Fail [tim2 cnt > 30]"
+
+ # timer0 always expires on the same core
+ if id == 3:
+ if lcore_tim3 == -1:
+ lcore_tim3 = lcore
+ elif lcore != lcore_tim3:
+ return -1, "Fail [lcore_tim3 changed (%d -> %d)]" \
+ % (lcore, lcore_tim3)
+ if cnt > 30:
+ return -1, "Fail [tim3 cnt > 30]"
+
+ # must be 2 different cores
+ if lcore_tim0 == lcore_tim3:
+ return -1, "Fail [lcore_tim0 (%d) == lcore_tim3 (%d)]" \
+ % (lcore_tim0, lcore_tim3)
+
+ return 0, "Success"
+
def ring_autotest(child, test_name):
- child.sendline(test_name)
- index = child.expect(["Test OK", "Test Failed",
- pexpect.TIMEOUT], timeout = 2)
- if index == 1:
- return -1, "Fail"
- elif index == 2:
- return -1, "Fail [Timeout]"
-
- child.sendline("set_watermark test 100")
- child.sendline("dump_ring test")
- index = child.expect([" watermark=100",
- pexpect.TIMEOUT], timeout = 1)
- if index != 0:
- return -1, "Fail [Bad watermark]"
-
- return 0, "Success"
+ child.sendline(test_name)
+ index = child.expect(["Test OK", "Test Failed",
+ pexpect.TIMEOUT], timeout=2)
+ if index == 1:
+ return -1, "Fail"
+ elif index == 2:
+ return -1, "Fail [Timeout]"
+
+ child.sendline("set_watermark test 100")
+ child.sendline("dump_ring test")
+ index = child.expect([" watermark=100",
+ pexpect.TIMEOUT], timeout=1)
+ if index != 0:
+ return -1, "Fail [Bad watermark]"
+
+ return 0, "Success"
diff --git a/doc/guides/conf.py b/doc/guides/conf.py
index 29e8efb..34c62de 100644
--- a/doc/guides/conf.py
+++ b/doc/guides/conf.py
@@ -58,7 +58,8 @@
html_show_copyright = False
highlight_language = 'none'
-version = subprocess.check_output(['make', '-sRrC', '../../', 'showversion']).decode('utf-8').rstrip()
+version = subprocess.check_output(['make', '-sRrC', '../../', 'showversion'])
+version = version.decode('utf-8').rstrip()
release = version
master_doc = 'index'
@@ -94,6 +95,7 @@
'preamble': latex_preamble
}
+
# Override the default Latex formatter in order to modify the
# code/verbatim blocks.
class CustomLatexFormatter(LatexFormatter):
@@ -117,12 +119,12 @@ def __init__(self, **options):
("tools/devbind", "dpdk-devbind",
"check device status and bind/unbind them from drivers", "", 8)]
-######## :numref: fallback ########
+
+# ####### :numref: fallback ########
# The following hook functions add some simple handling for the :numref:
# directive for Sphinx versions prior to 1.3.1. The functions replace the
# :numref: reference with a link to the target (for all Sphinx doc types).
# It doesn't try to label figures/tables.
-
def numref_role(reftype, rawtext, text, lineno, inliner):
"""
Add a Sphinx role to handle numref references. Note, we can't convert
@@ -136,6 +138,7 @@ def numref_role(reftype, rawtext, text, lineno, inliner):
internal=True)
return [newnode], []
+
def process_numref(app, doctree, from_docname):
"""
Process the numref nodes once the doctree has been built and prior to
diff --git a/examples/ip_pipeline/config/diagram-generator.py b/examples/ip_pipeline/config/diagram-generator.py
index 6b7170b..1748833 100755
--- a/examples/ip_pipeline/config/diagram-generator.py
+++ b/examples/ip_pipeline/config/diagram-generator.py
@@ -36,7 +36,8 @@
# the DPDK ip_pipeline application.
#
# The input configuration file is translated to an output file in DOT syntax,
-# which is then used to create the image file using graphviz (www.graphviz.org).
+# which is then used to create the image file using graphviz
+# (www.graphviz.org).
#
from __future__ import print_function
@@ -94,6 +95,7 @@
# SOURCEx | SOURCEx | SOURCEx | PIPELINEy | SOURCEx
# SINKx | SINKx | PIPELINEy | SINKx | SINKx
+
#
# Parse the input configuration file to detect the graph nodes and edges
#
@@ -321,16 +323,17 @@ def process_config_file(cfgfile):
#
print('Creating image file "%s" ...' % imgfile)
if os.system('which dot > /dev/null'):
- print('Error: Unable to locate "dot" executable.' \
- 'Please install the "graphviz" package (www.graphviz.org).')
+ print('Error: Unable to locate "dot" executable.'
+ 'Please install the "graphviz" package (www.graphviz.org).')
return
os.system(dot_cmd)
if __name__ == '__main__':
- parser = argparse.ArgumentParser(description=\
- 'Create diagram for IP pipeline configuration file.')
+ parser = argparse.ArgumentParser(description='Create diagram for IP '
+ 'pipeline configuration '
+ 'file.')
parser.add_argument(
'-f',
diff --git a/examples/ip_pipeline/config/pipeline-to-core-mapping.py b/examples/ip_pipeline/config/pipeline-to-core-mapping.py
index c2050b8..7a4eaa2 100755
--- a/examples/ip_pipeline/config/pipeline-to-core-mapping.py
+++ b/examples/ip_pipeline/config/pipeline-to-core-mapping.py
@@ -39,15 +39,14 @@
#
from __future__ import print_function
-import sys
-import errno
-import os
-import re
+from collections import namedtuple
+import argparse
import array
+import errno
import itertools
+import os
import re
-import argparse
-from collections import namedtuple
+import sys
# default values
enable_stage0_traceout = 1
diff --git a/tools/cpu_layout.py b/tools/cpu_layout.py
index d38d0b5..ccc22ec 100755
--- a/tools/cpu_layout.py
+++ b/tools/cpu_layout.py
@@ -38,40 +38,40 @@
cores = []
core_map = {}
-fd=open("/proc/cpuinfo")
+fd = open("/proc/cpuinfo")
lines = fd.readlines()
fd.close()
core_details = []
core_lines = {}
for line in lines:
- if len(line.strip()) != 0:
- name, value = line.split(":", 1)
- core_lines[name.strip()] = value.strip()
- else:
- core_details.append(core_lines)
- core_lines = {}
+ if len(line.strip()) != 0:
+ name, value = line.split(":", 1)
+ core_lines[name.strip()] = value.strip()
+ else:
+ core_details.append(core_lines)
+ core_lines = {}
for core in core_details:
- for field in ["processor", "core id", "physical id"]:
- if field not in core:
- print "Error getting '%s' value from /proc/cpuinfo" % field
- sys.exit(1)
- core[field] = int(core[field])
+ for field in ["processor", "core id", "physical id"]:
+ if field not in core:
+ print "Error getting '%s' value from /proc/cpuinfo" % field
+ sys.exit(1)
+ core[field] = int(core[field])
- if core["core id"] not in cores:
- cores.append(core["core id"])
- if core["physical id"] not in sockets:
- sockets.append(core["physical id"])
- key = (core["physical id"], core["core id"])
- if key not in core_map:
- core_map[key] = []
- core_map[key].append(core["processor"])
+ if core["core id"] not in cores:
+ cores.append(core["core id"])
+ if core["physical id"] not in sockets:
+ sockets.append(core["physical id"])
+ key = (core["physical id"], core["core id"])
+ if key not in core_map:
+ core_map[key] = []
+ core_map[key].append(core["processor"])
print "============================================================"
print "Core and Socket Information (as reported by '/proc/cpuinfo')"
print "============================================================\n"
-print "cores = ",cores
+print "cores = ", cores
print "sockets = ", sockets
print ""
@@ -81,15 +81,16 @@
print " ".ljust(max_core_id_len + len('Core ')),
for s in sockets:
- print "Socket %s" % str(s).ljust(max_core_map_len - len('Socket ')),
+ print "Socket %s" % str(s).ljust(max_core_map_len - len('Socket ')),
print ""
+
print " ".ljust(max_core_id_len + len('Core ')),
for s in sockets:
- print "--------".ljust(max_core_map_len),
+ print "--------".ljust(max_core_map_len),
print ""
for c in cores:
- print "Core %s" % str(c).ljust(max_core_id_len),
- for s in sockets:
- print str(core_map[(s,c)]).ljust(max_core_map_len),
- print ""
+ print "Core %s" % str(c).ljust(max_core_id_len),
+ for s in sockets:
+ print str(core_map[(s, c)]).ljust(max_core_map_len),
+ print ""
diff --git a/tools/dpdk-devbind.py b/tools/dpdk-devbind.py
index f1d374d..4f51a4b 100755
--- a/tools/dpdk-devbind.py
+++ b/tools/dpdk-devbind.py
@@ -93,10 +93,10 @@ def usage():
Unbind a device (Equivalent to \"-b none\")
--force:
- By default, network devices which are used by Linux - as indicated by having
- routes in the routing table - cannot be modified. Using the --force
- flag overrides this behavior, allowing active links to be forcibly
- unbound.
+ By default, network devices which are used by Linux - as indicated by
+ having routes in the routing table - cannot be modified. Using the
+ --force flag overrides this behavior, allowing active links to be
+ forcibly unbound.
WARNING: This can lead to loss of network connection and should be used
with caution.
@@ -151,7 +151,7 @@ def find_module(mod):
# check for a copy based off current path
tools_dir = dirname(abspath(sys.argv[0]))
- if (tools_dir.endswith("tools")):
+ if tools_dir.endswith("tools"):
base_dir = dirname(tools_dir)
find_out = check_output(["find", base_dir, "-name", mod + ".ko"])
if len(find_out) > 0: # something matched
@@ -249,7 +249,7 @@ def get_nic_details():
dev = {}
dev_lines = check_output(["lspci", "-Dvmmn"]).splitlines()
for dev_line in dev_lines:
- if (len(dev_line) == 0):
+ if len(dev_line) == 0:
if dev["Class"][0:2] == NETWORK_BASE_CLASS:
# convert device and vendor ids to numbers, then add to global
dev["Vendor"] = int(dev["Vendor"], 16)
@@ -315,8 +315,8 @@ def get_crypto_details():
dev = {}
dev_lines = check_output(["lspci", "-Dvmmn"]).splitlines()
for dev_line in dev_lines:
- if (len(dev_line) == 0):
- if (dev["Class"][0:2] == CRYPTO_BASE_CLASS):
+ if len(dev_line) == 0:
+ if dev["Class"][0:2] == CRYPTO_BASE_CLASS:
# convert device and vendor ids to numbers, then add to global
dev["Vendor"] = int(dev["Vendor"], 16)
dev["Device"] = int(dev["Device"], 16)
@@ -513,7 +513,8 @@ def display_devices(title, dev_list, extra_params=None):
for dev in dev_list:
if extra_params is not None:
strings.append("%s '%s' %s" % (dev["Slot"],
- dev["Device_str"], extra_params % dev))
+ dev["Device_str"],
+ extra_params % dev))
else:
strings.append("%s '%s'" % (dev["Slot"], dev["Device_str"]))
# sort before printing, so that the entries appear in PCI order
@@ -532,7 +533,7 @@ def show_status():
# split our list of network devices into the three categories above
for d in devices.keys():
- if (NETWORK_BASE_CLASS in devices[d]["Class"]):
+ if NETWORK_BASE_CLASS in devices[d]["Class"]:
if not has_driver(d):
no_drv.append(devices[d])
continue
@@ -555,7 +556,7 @@ def show_status():
no_drv = []
for d in devices.keys():
- if (CRYPTO_BASE_CLASS in devices[d]["Class"]):
+ if CRYPTO_BASE_CLASS in devices[d]["Class"]:
if not has_driver(d):
no_drv.append(devices[d])
continue
diff --git a/tools/dpdk-pmdinfo.py b/tools/dpdk-pmdinfo.py
index 3db9819..3d3ad7d 100755
--- a/tools/dpdk-pmdinfo.py
+++ b/tools/dpdk-pmdinfo.py
@@ -4,52 +4,20 @@
# Utility to dump PMD_INFO_STRING support from an object file
#
# -------------------------------------------------------------------------
+import json
import os
+import platform
+import string
import sys
+from elftools.common.exceptions import ELFError
+from elftools.common.py3compat import (byte2int, bytes2str, str2bytes)
+from elftools.elf.elffile import ELFFile
from optparse import OptionParser
-import string
-import json
-import platform
# For running from development directory. It should take precedence over the
# installed pyelftools.
sys.path.insert(0, '.')
-
-from elftools import __version__
-from elftools.common.exceptions import ELFError
-from elftools.common.py3compat import (
- ifilter, byte2int, bytes2str, itervalues, str2bytes)
-from elftools.elf.elffile import ELFFile
-from elftools.elf.dynamic import DynamicSection, DynamicSegment
-from elftools.elf.enums import ENUM_D_TAG
-from elftools.elf.segments import InterpSegment
-from elftools.elf.sections import SymbolTableSection
-from elftools.elf.gnuversions import (
- GNUVerSymSection, GNUVerDefSection,
- GNUVerNeedSection,
-)
-from elftools.elf.relocation import RelocationSection
-from elftools.elf.descriptions import (
- describe_ei_class, describe_ei_data, describe_ei_version,
- describe_ei_osabi, describe_e_type, describe_e_machine,
- describe_e_version_numeric, describe_p_type, describe_p_flags,
- describe_sh_type, describe_sh_flags,
- describe_symbol_type, describe_symbol_bind, describe_symbol_visibility,
- describe_symbol_shndx, describe_reloc_type, describe_dyn_tag,
- describe_ver_flags,
-)
-from elftools.elf.constants import E_FLAGS
-from elftools.dwarf.dwarfinfo import DWARFInfo
-from elftools.dwarf.descriptions import (
- describe_reg_name, describe_attr_value, set_global_machine_arch,
- describe_CFI_instructions, describe_CFI_register_rule,
- describe_CFI_CFA_rule,
-)
-from elftools.dwarf.constants import (
- DW_LNS_copy, DW_LNS_set_file, DW_LNE_define_file)
-from elftools.dwarf.callframe import CIE, FDE
-
raw_output = False
pcidb = None
@@ -326,7 +294,7 @@ def parse_pmd_info_string(self, mystring):
for i in optional_pmd_info:
try:
print("%s: %s" % (i['tag'], pmdinfo[i['id']]))
- except KeyError as e:
+ except KeyError:
continue
if (len(pmdinfo["pci_ids"]) != 0):
@@ -475,7 +443,7 @@ def process_dt_needed_entries(self):
with open(library, 'rb') as file:
try:
libelf = ReadElf(file, sys.stdout)
- except ELFError as e:
+ except ELFError:
print("%s is no an ELF file" % library)
continue
libelf.process_dt_needed_entries()
@@ -491,7 +459,7 @@ def scan_autoload_path(autoload_path):
try:
dirs = os.listdir(autoload_path)
- except OSError as e:
+ except OSError:
# Couldn't read the directory, give up
return
@@ -503,10 +471,10 @@ def scan_autoload_path(autoload_path):
try:
file = open(dpath, 'rb')
readelf = ReadElf(file, sys.stdout)
- except ELFError as e:
+ except ELFError:
# this is likely not an elf file, skip it
continue
- except IOError as e:
+ except IOError:
# No permission to read the file, skip it
continue
@@ -531,7 +499,7 @@ def scan_for_autoload_pmds(dpdk_path):
file = open(dpdk_path, 'rb')
try:
readelf = ReadElf(file, sys.stdout)
- except ElfError as e:
+ except ElfError:
if raw_output is False:
print("Unable to parse %s" % file)
return
@@ -557,7 +525,7 @@ def main(stream=None):
global raw_output
global pcidb
- pcifile_default = "./pci.ids" # for unknown OS's assume local file
+ pcifile_default = "./pci.ids" # For unknown OS's assume local file
if platform.system() == 'Linux':
pcifile_default = "/usr/share/hwdata/pci.ids"
elif platform.system() == 'FreeBSD':
@@ -577,7 +545,8 @@ def main(stream=None):
"to get vendor names from",
default=pcifile_default, metavar="FILE")
optparser.add_option("-t", "--table", dest="tblout",
- help="output information on hw support as a hex table",
+ help="output information on hw support as a "
+ "hex table",
action='store_true')
optparser.add_option("-p", "--plugindir", dest="pdir",
help="scan dpdk for autoload plugins",
--
2.7.4
^ permalink raw reply related
* [PATCH v4 2/3] app: make python apps python2/3 compliant
From: John McNamara @ 2016-12-21 15:03 UTC (permalink / raw)
To: dev; +Cc: mkletzan, nhorman, John McNamara
In-Reply-To: <1481212265-10229-1-git-send-email-john.mcnamara@intel.com>
Make all the DPDK Python apps work with Python 2 or 3 to
allow them to work with whatever is the system default.
Signed-off-by: John McNamara <john.mcnamara@intel.com>
---
app/cmdline_test/cmdline_test.py | 26 ++++++++++++------------
app/cmdline_test/cmdline_test_data.py | 2 --
app/test/autotest.py | 10 ++++-----
app/test/autotest_data.py | 2 --
app/test/autotest_runner.py | 37 ++++++++++++++++------------------
app/test/autotest_test_funcs.py | 2 --
tools/cpu_layout.py | 38 ++++++++++++++++++-----------------
tools/dpdk-devbind.py | 2 +-
tools/dpdk-pmdinfo.py | 14 +++++++------
9 files changed, 64 insertions(+), 69 deletions(-)
diff --git a/app/cmdline_test/cmdline_test.py b/app/cmdline_test/cmdline_test.py
index 4729987..229f71f 100755
--- a/app/cmdline_test/cmdline_test.py
+++ b/app/cmdline_test/cmdline_test.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
# BSD LICENSE
#
@@ -32,7 +32,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# Script that runs cmdline_test app and feeds keystrokes into it.
-
+from __future__ import print_function
import cmdline_test_data
import os
import pexpect
@@ -81,38 +81,38 @@ def runHistoryTest(child):
# the path to cmdline_test executable is supplied via command-line.
if len(sys.argv) < 2:
- print "Error: please supply cmdline_test app path"
+ print("Error: please supply cmdline_test app path")
sys.exit(1)
test_app_path = sys.argv[1]
if not os.path.exists(test_app_path):
- print "Error: please supply cmdline_test app path"
+ print("Error: please supply cmdline_test app path")
sys.exit(1)
child = pexpect.spawn(test_app_path)
-print "Running command-line tests..."
+print("Running command-line tests...")
for test in cmdline_test_data.tests:
- print (test["Name"] + ":").ljust(30),
+ testname = (test["Name"] + ":").ljust(30)
try:
runTest(child, test)
- print "PASS"
+ print(testname, "PASS")
except:
- print "FAIL"
- print child
+ print(testname, "FAIL")
+ print(child)
sys.exit(1)
# since last test quits the app, run new instance
child = pexpect.spawn(test_app_path)
-print ("History fill test:").ljust(30),
+testname = ("History fill test:").ljust(30)
try:
runHistoryTest(child)
- print "PASS"
+ print(testname, "PASS")
except:
- print "FAIL"
- print child
+ print(testname, "FAIL")
+ print(child)
sys.exit(1)
child.close()
sys.exit(0)
diff --git a/app/cmdline_test/cmdline_test_data.py b/app/cmdline_test/cmdline_test_data.py
index 3ce6cbc..28dfefe 100644
--- a/app/cmdline_test/cmdline_test_data.py
+++ b/app/cmdline_test/cmdline_test_data.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
# BSD LICENSE
#
# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
diff --git a/app/test/autotest.py b/app/test/autotest.py
index 3a00538..5c19a02 100644
--- a/app/test/autotest.py
+++ b/app/test/autotest.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
# BSD LICENSE
#
@@ -32,15 +32,15 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# Script that uses either test app or qemu controlled by python-pexpect
-
+from __future__ import print_function
import autotest_data
import autotest_runner
import sys
def usage():
- print"Usage: autotest.py [test app|test iso image]",
- print "[target] [whitelist|-blacklist]"
+ print("Usage: autotest.py [test app|test iso image] ",
+ "[target] [whitelist|-blacklist]")
if len(sys.argv) < 3:
usage()
@@ -63,7 +63,7 @@ def usage():
cmdline = "%s -c f -n 4" % (sys.argv[1])
-print cmdline
+print(cmdline)
runner = autotest_runner.AutotestRunner(cmdline, target, test_blacklist,
test_whitelist)
diff --git a/app/test/autotest_data.py b/app/test/autotest_data.py
index 0cf4cfd..0cd598b 100644
--- a/app/test/autotest_data.py
+++ b/app/test/autotest_data.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-
# BSD LICENSE
#
# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
diff --git a/app/test/autotest_runner.py b/app/test/autotest_runner.py
index 55b63a8..fc882ec 100644
--- a/app/test/autotest_runner.py
+++ b/app/test/autotest_runner.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
# BSD LICENSE
#
# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
@@ -271,15 +269,16 @@ def __process_results(self, results):
total_time = int(cur_time - self.start)
# print results, test run time and total time since start
- print ("%s:" % test_name).ljust(30),
- print result_str.ljust(29),
- print "[%02dm %02ds]" % (test_time / 60, test_time % 60),
+ result = ("%s:" % test_name).ljust(30)
+ result += result_str.ljust(29)
+ result += "[%02dm %02ds]" % (test_time / 60, test_time % 60)
# don't print out total time every line, it's the same anyway
if i == len(results) - 1:
- print "[%02dm %02ds]" % (total_time / 60, total_time % 60)
+ print(result,
+ "[%02dm %02ds]" % (total_time / 60, total_time % 60))
else:
- print ""
+ print(result)
# if test failed and it wasn't a "start" test
if test_result < 0 and not i == 0:
@@ -294,7 +293,7 @@ def __process_results(self, results):
f = open("%s_%s_report.rst" %
(self.target, test_name), "w")
except IOError:
- print "Report for %s could not be created!" % test_name
+ print("Report for %s could not be created!" % test_name)
else:
with f:
f.write(report)
@@ -360,12 +359,10 @@ def run_all_tests(self):
try:
# create table header
- print ""
- print "Test name".ljust(30),
- print "Test result".ljust(29),
- print "Test".center(9),
- print "Total".center(9)
- print "=" * 80
+ print("")
+ print("Test name".ljust(30), "Test result".ljust(29),
+ "Test".center(9), "Total".center(9))
+ print("=" * 80)
# make a note of tests start time
self.start = time.time()
@@ -407,11 +404,11 @@ def run_all_tests(self):
total_time = int(cur_time - self.start)
# print out summary
- print "=" * 80
- print "Total run time: %02dm %02ds" % (total_time / 60,
- total_time % 60)
+ print("=" * 80)
+ print("Total run time: %02dm %02ds" % (total_time / 60,
+ total_time % 60))
if self.fails != 0:
- print "Number of failed tests: %s" % str(self.fails)
+ print("Number of failed tests: %s" % str(self.fails))
# write summary to logfile
self.logfile.write("Summary\n")
@@ -420,8 +417,8 @@ def run_all_tests(self):
self.logfile.write("Failed tests: ".ljust(
15) + "%i\n" % self.fails)
except:
- print "Exception occurred"
- print sys.exc_info()
+ print("Exception occurred")
+ print(sys.exc_info())
self.fails = 1
# drop logs from all executions to a logfile
diff --git a/app/test/autotest_test_funcs.py b/app/test/autotest_test_funcs.py
index c482ea8..1c5f390 100644
--- a/app/test/autotest_test_funcs.py
+++ b/app/test/autotest_test_funcs.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
# BSD LICENSE
#
# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
diff --git a/tools/cpu_layout.py b/tools/cpu_layout.py
index ccc22ec..0e049a6 100755
--- a/tools/cpu_layout.py
+++ b/tools/cpu_layout.py
@@ -1,4 +1,5 @@
-#! /usr/bin/python
+#!/usr/bin/env python
+
#
# BSD LICENSE
#
@@ -31,7 +32,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
-
+from __future__ import print_function
import sys
sockets = []
@@ -55,7 +56,7 @@
for core in core_details:
for field in ["processor", "core id", "physical id"]:
if field not in core:
- print "Error getting '%s' value from /proc/cpuinfo" % field
+ print("Error getting '%s' value from /proc/cpuinfo" % field)
sys.exit(1)
core[field] = int(core[field])
@@ -68,29 +69,30 @@
core_map[key] = []
core_map[key].append(core["processor"])
-print "============================================================"
-print "Core and Socket Information (as reported by '/proc/cpuinfo')"
-print "============================================================\n"
-print "cores = ", cores
-print "sockets = ", sockets
-print ""
+print("============================================================")
+print("Core and Socket Information (as reported by '/proc/cpuinfo')")
+print("============================================================\n")
+print("cores = ", cores)
+print("sockets = ", sockets)
+print("")
max_processor_len = len(str(len(cores) * len(sockets) * 2 - 1))
max_core_map_len = max_processor_len * 2 + len('[, ]') + len('Socket ')
max_core_id_len = len(str(max(cores)))
-print " ".ljust(max_core_id_len + len('Core ')),
+output = " ".ljust(max_core_id_len + len('Core '))
for s in sockets:
- print "Socket %s" % str(s).ljust(max_core_map_len - len('Socket ')),
-print ""
+ output += " Socket %s" % str(s).ljust(max_core_map_len - len('Socket '))
+print(output)
-print " ".ljust(max_core_id_len + len('Core ')),
+output = " ".ljust(max_core_id_len + len('Core '))
for s in sockets:
- print "--------".ljust(max_core_map_len),
-print ""
+ output += " --------".ljust(max_core_map_len)
+ output += " "
+print(output)
for c in cores:
- print "Core %s" % str(c).ljust(max_core_id_len),
+ output = "Core %s" % str(c).ljust(max_core_id_len)
for s in sockets:
- print str(core_map[(s, c)]).ljust(max_core_map_len),
- print ""
+ output += " " + str(core_map[(s, c)]).ljust(max_core_map_len)
+ print(output)
diff --git a/tools/dpdk-devbind.py b/tools/dpdk-devbind.py
index 4f51a4b..e057b87 100755
--- a/tools/dpdk-devbind.py
+++ b/tools/dpdk-devbind.py
@@ -1,4 +1,4 @@
-#! /usr/bin/python
+#! /usr/bin/env python
#
# BSD LICENSE
#
diff --git a/tools/dpdk-pmdinfo.py b/tools/dpdk-pmdinfo.py
index 3d3ad7d..d4e51aa 100755
--- a/tools/dpdk-pmdinfo.py
+++ b/tools/dpdk-pmdinfo.py
@@ -1,9 +1,11 @@
#!/usr/bin/env python
+
# -------------------------------------------------------------------------
#
# Utility to dump PMD_INFO_STRING support from an object file
#
# -------------------------------------------------------------------------
+from __future__ import print_function
import json
import os
import platform
@@ -54,7 +56,7 @@ def addDevice(self, deviceStr):
self.devices[devID] = Device(deviceStr)
def report(self):
- print self.ID, self.name
+ print(self.ID, self.name)
for id, dev in self.devices.items():
dev.report()
@@ -80,7 +82,7 @@ def __init__(self, deviceStr):
self.subdevices = {}
def report(self):
- print "\t%s\t%s" % (self.ID, self.name)
+ print("\t%s\t%s" % (self.ID, self.name))
for subID, subdev in self.subdevices.items():
subdev.report()
@@ -126,7 +128,7 @@ def __init__(self, vendor, device, name):
self.name = name
def report(self):
- print "\t\t%s\t%s\t%s" % (self.vendorID, self.deviceID, self.name)
+ print("\t\t%s\t%s\t%s" % (self.vendorID, self.deviceID, self.name))
class PCIIds:
@@ -154,7 +156,7 @@ def reportVendors(self):
"""Reports the vendors
"""
for vid, v in self.vendors.items():
- print v.ID, v.name
+ print(v.ID, v.name)
def report(self, vendor=None):
"""
@@ -185,7 +187,7 @@ def findDate(self, content):
def parse(self):
if len(self.contents) < 1:
- print "data/%s-pci.ids not found" % self.date
+ print("data/%s-pci.ids not found" % self.date)
else:
vendorID = ""
deviceID = ""
@@ -432,7 +434,7 @@ def process_dt_needed_entries(self):
for tag in dynsec.iter_tags():
if tag.entry.d_tag == 'DT_NEEDED':
- rc = tag.needed.find("librte_pmd")
+ rc = tag.needed.find(b"librte_pmd")
if (rc != -1):
library = search_file(tag.needed,
runpath + ":" + ldlibpath +
--
2.7.4
^ permalink raw reply related
* [PATCH v4 3/3] doc: add required python versions to docs
From: John McNamara @ 2016-12-21 15:03 UTC (permalink / raw)
To: dev; +Cc: mkletzan, nhorman, John McNamara
In-Reply-To: <1481212265-10229-1-git-send-email-john.mcnamara@intel.com>
Add a requirement to support both Python 2 and 3 to the
DPDK Python Coding Standards and Getting started Guide.
Signed-off-by: John McNamara <john.mcnamara@intel.com>
---
doc/guides/contributing/coding_style.rst | 3 ++-
doc/guides/linux_gsg/sys_reqs.rst | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/doc/guides/contributing/coding_style.rst b/doc/guides/contributing/coding_style.rst
index 1eb67f3..4163960 100644
--- a/doc/guides/contributing/coding_style.rst
+++ b/doc/guides/contributing/coding_style.rst
@@ -690,6 +690,7 @@ Control Statements
Python Code
-----------
-All python code should be compliant with `PEP8 (Style Guide for Python Code) <https://www.python.org/dev/peps/pep-0008/>`_.
+All Python code should work with Python 2.7+ and 3.2+ and be compliant with
+`PEP8 (Style Guide for Python Code) <https://www.python.org/dev/peps/pep-0008/>`_.
The ``pep8`` tool can be used for testing compliance with the guidelines.
diff --git a/doc/guides/linux_gsg/sys_reqs.rst b/doc/guides/linux_gsg/sys_reqs.rst
index 76d82e6..61222c6 100644
--- a/doc/guides/linux_gsg/sys_reqs.rst
+++ b/doc/guides/linux_gsg/sys_reqs.rst
@@ -84,7 +84,7 @@ Compilation of the DPDK
x86_x32 ABI is currently supported with distribution packages only on Ubuntu
higher than 13.10 or recent Debian distribution. The only supported compiler is gcc 4.9+.
-* Python, version 2.6 or 2.7, to use various helper scripts included in the DPDK package.
+* Python, version 2.7+ or 3.2+, to use various helper scripts included in the DPDK package.
**Optional Tools:**
--
2.7.4
^ permalink raw reply related
* Re: Example(Load_balancer) Tx Flush Bug(This bug DPDK each version)
From: Thomas Monjalon @ 2016-12-21 15:08 UTC (permalink / raw)
To: Maple; +Cc: dev, 李非, 施展
In-Reply-To: <2016122122394164225248@raisecom.com>
Hi,
Thanks for trying to send a patch.
Below are some comments to help you sending a proper patch.
2016-12-21 22:39, Maple:
> From 94f2eaed51e6e5402e8c03b80e0999a4fd420390 Mon Sep 17 00:00:00 2001
> From: root <root@liujian@raisecom.com>
Here we should have your real name, not "root".
> To: <dev@dpdk.org>
> Cc: <thomas.monjalon@6wind.com>, <lifei@raisecom.com>,<shizhan@raisecom.com>
> Date: Wed, 21 Dec 2016 22:31:29 +0800
> Subject: [PATCH] load_balancer Tx Flush Bug
>
> We found a bug in use load_balancer example,and,This bug DPDK each version.
> In IO tx flush, only flush port 0.
> So,If I enable more than the Port,then,In addition to 0 port won't flush.
>
> Signed-off-by: root <root@liujian@raisecom.com>
Here alse we should have your real name.
See ~/.gitconfig
> ---
> a/examples/load_balancer/runtime.c | 667 ++++++++++++++++++++++++++++++++++++
> b/examples/load_balancer/runtime.c | 669 +++++++++++++++++++++++++++++++++++++
You are sending the whole file instead of the diff.
Are you using git?
It should be as simple as "git clone git://dpdk.org/dpdk", then
modify the file, then "git commit -as", then send patch with
"git send-email -1 --to dev@dpdk.org".
As it will be your second version, you should add these options:
-v2 --in-reply-to '<2016122122394164225248@raisecom.com>'
Thanks
^ permalink raw reply
* Re: [PATCH v5 02/26] doc: add rte_flow prog guide
From: Mcnamara, John @ 2016-12-21 15:09 UTC (permalink / raw)
To: Adrien Mazarguil, dev@dpdk.org
In-Reply-To: <e7d83f890bf2bd53c2333475b8d1213cfc796413.1482331076.git.adrien.mazarguil@6wind.com>
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Adrien Mazarguil
> Sent: Wednesday, December 21, 2016 2:51 PM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v5 02/26] doc: add rte_flow prog guide
>
> This documentation is based on the latest RFC submission, subsequently
> updated according to feedback from the community.
>
> Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
> Acked-by: Olga Shern <olgas@mellanox.com>
Acked-by: John McNamara <john.mcnamara@intel.com>
^ permalink raw reply
* [PATCH v4 00/23] Decouple ethdev from PCI device
From: Jan Blunck @ 2016-12-21 15:09 UTC (permalink / raw)
To: dev; +Cc: shreyansh.jain, david.marchand, stephen
This is a partial merge of Stephens and my patches to make the rte_eth_dev
independent of the rte_pci_device.
Changes between v4 and v3:
- broken out refactorings of drivers similar to Stephens example
- use inline function instead of macro
- fix build issues with bnx2x and mlx4/5
Changes between v3 and v2:
- converted PCI device users I've missed in previous version
Jan Blunck (17):
eal: define container_of macro
eal: Allow passing const rte_intr_handle
virtio: Don't fill dev_info->driver_name
virtio: Add vtpci_intr_handle() helper to get rte_intr_handle
virtio: Don't depend on struct rte_eth_dev's pci_dev
bnx2x: localize mapping from eth_dev to pci
fm10k: localize mapping from eth_dev to pci
qede: localize mapping of eth_dev to pci
szedata2: localize handling of pci resources
nfp: localize rte_pci_device handling
vmxnet3: use eth_dev->data->drv_name instead of pci_drv name
ethdev: Helper to map to struct rte_pci_device
drivers: Replace per-PMD macros with rte_eth_dev_to_pci() helper
drivers: Use rte_eth_dev_to_pci() helper
ethdev: Move filling of rte_eth_dev_info->pci_dev to dev_infos_get()
ethdev: Decouple interrupt handling from PCI device
ethdev: Decouple struct rte_eth_dev from struct rte_pci_device
Stephen Hemminger (6):
rte_device: make driver pointer const
pmd: remove useless reset of dev_info->dev_pci
e1000: localize mapping from eth_dev to pci
ixgbe: localize mapping from eth_dev to pci_device
i40e: localize mapping of eth_dev to pci
broadcom: localize mapping from eth_dev to pci
app/test/virtual_pmd.c | 5 +-
drivers/net/af_packet/rte_eth_af_packet.c | 1 -
drivers/net/bnx2x/bnx2x_ethdev.c | 15 +--
drivers/net/bnxt/bnxt_ethdev.c | 24 +++--
drivers/net/bnxt/bnxt_ring.c | 16 ++--
drivers/net/bonding/rte_eth_bond_args.c | 12 ++-
drivers/net/bonding/rte_eth_bond_pmd.c | 1 -
drivers/net/cxgbe/cxgbe_ethdev.c | 4 +-
drivers/net/cxgbe/cxgbe_main.c | 4 +-
drivers/net/e1000/em_ethdev.c | 50 +++++-----
drivers/net/e1000/igb_ethdev.c | 100 +++++++++++---------
drivers/net/e1000/igb_pf.c | 4 +-
drivers/net/ena/ena_ethdev.c | 4 +-
drivers/net/enic/enic_ethdev.c | 3 +-
drivers/net/fm10k/fm10k_ethdev.c | 84 +++++++++--------
drivers/net/i40e/i40e_ethdev.c | 78 ++++++++++------
drivers/net/i40e/i40e_ethdev_vf.c | 59 +++++++-----
drivers/net/ixgbe/ixgbe_ethdev.c | 122 ++++++++++++++-----------
drivers/net/ixgbe/ixgbe_pf.c | 4 +-
drivers/net/mlx4/mlx4.c | 4 +-
drivers/net/mlx5/mlx5.c | 2 +-
drivers/net/mlx5/mlx5_ethdev.c | 2 +
drivers/net/nfp/nfp_net.c | 19 ++--
drivers/net/null/rte_eth_null.c | 1 -
drivers/net/pcap/rte_eth_pcap.c | 1 -
drivers/net/qede/qede_ethdev.c | 19 ++--
drivers/net/ring/rte_eth_ring.c | 1 -
drivers/net/szedata2/rte_eth_szedata2.c | 73 +++++++++------
drivers/net/szedata2/rte_eth_szedata2.h | 58 +++++-------
drivers/net/thunderx/nicvf_ethdev.c | 7 +-
drivers/net/virtio/virtio_ethdev.c | 41 ++++-----
drivers/net/virtio/virtio_pci.h | 6 ++
drivers/net/virtio/virtio_user_ethdev.c | 1 -
drivers/net/vmxnet3/vmxnet3_ethdev.c | 8 +-
drivers/net/xenvirt/rte_eth_xenvirt.c | 1 -
lib/librte_eal/common/include/rte_common.h | 20 ++++
lib/librte_eal/common/include/rte_dev.h | 2 +-
lib/librte_eal/common/include/rte_interrupts.h | 8 +-
lib/librte_eal/common/include/rte_pci.h | 6 ++
lib/librte_eal/linuxapp/eal/eal_interrupts.c | 62 +++++++++----
lib/librte_ether/rte_ethdev.c | 25 +++--
lib/librte_ether/rte_ethdev.h | 13 ++-
42 files changed, 577 insertions(+), 393 deletions(-)
--
2.7.4
^ permalink raw reply
* [PATCH v4 01/23] eal: define container_of macro
From: Jan Blunck @ 2016-12-21 15:09 UTC (permalink / raw)
To: dev; +Cc: shreyansh.jain, david.marchand, stephen, Jan Viktorin
In-Reply-To: <1482332986-7599-1-git-send-email-jblunck@infradead.org>
This macro is based on Jan Viktorin's original patch but also checks the
type of the passed pointer against the type of the member.
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
[jblunck@infradead.org: add type checking and __extension__]
Signed-off-by: Jan Blunck <jblunck@infradead.org>
---
lib/librte_eal/common/include/rte_common.h | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/lib/librte_eal/common/include/rte_common.h b/lib/librte_eal/common/include/rte_common.h
index db5ac91..8dda3e2 100644
--- a/lib/librte_eal/common/include/rte_common.h
+++ b/lib/librte_eal/common/include/rte_common.h
@@ -331,6 +331,26 @@ rte_bsf32(uint32_t v)
#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
#endif
+/**
+ * Return pointer to the wrapping struct instance.
+ *
+ * Example:
+ *
+ * struct wrapper {
+ * ...
+ * struct child c;
+ * ...
+ * };
+ *
+ * struct child *x = obtain(...);
+ * struct wrapper *w = container_of(x, struct wrapper, c);
+ */
+#ifndef container_of
+#define container_of(ptr, type, member) __extension__ ({ \
+ typeof(((type *)0)->member) *_ptr = (ptr); \
+ (type *)(((char *)_ptr) - offsetof(type, member)); })
+#endif
+
#define _RTE_STR(x) #x
/** Take a macro value and get a string version of it */
#define RTE_STR(x) _RTE_STR(x)
--
2.7.4
^ permalink raw reply related
* [PATCH v4 02/23] eal: Allow passing const rte_intr_handle
From: Jan Blunck @ 2016-12-21 15:09 UTC (permalink / raw)
To: dev; +Cc: shreyansh.jain, david.marchand, stephen
In-Reply-To: <1482332986-7599-1-git-send-email-jblunck@infradead.org>
Both register/unregister and enable/disable don't necessarily require the
rte_intr_handle to be modifiable. Therefore lets constify it.
Signed-off-by: Jan Blunck <jblunck@infradead.org>
---
lib/librte_eal/common/include/rte_interrupts.h | 8 ++--
lib/librte_eal/linuxapp/eal/eal_interrupts.c | 62 ++++++++++++++++++--------
2 files changed, 47 insertions(+), 23 deletions(-)
diff --git a/lib/librte_eal/common/include/rte_interrupts.h b/lib/librte_eal/common/include/rte_interrupts.h
index fd3c6ef..6cade01 100644
--- a/lib/librte_eal/common/include/rte_interrupts.h
+++ b/lib/librte_eal/common/include/rte_interrupts.h
@@ -70,7 +70,7 @@ typedef void (*rte_intr_callback_fn)(struct rte_intr_handle *intr_handle,
* - On success, zero.
* - On failure, a negative value.
*/
-int rte_intr_callback_register(struct rte_intr_handle *intr_handle,
+int rte_intr_callback_register(const struct rte_intr_handle *intr_handle,
rte_intr_callback_fn cb, void *cb_arg);
/**
@@ -88,7 +88,7 @@ int rte_intr_callback_register(struct rte_intr_handle *intr_handle,
* - On success, return the number of callback entities removed.
* - On failure, a negative value.
*/
-int rte_intr_callback_unregister(struct rte_intr_handle *intr_handle,
+int rte_intr_callback_unregister(const struct rte_intr_handle *intr_handle,
rte_intr_callback_fn cb, void *cb_arg);
/**
@@ -101,7 +101,7 @@ int rte_intr_callback_unregister(struct rte_intr_handle *intr_handle,
* - On success, zero.
* - On failure, a negative value.
*/
-int rte_intr_enable(struct rte_intr_handle *intr_handle);
+int rte_intr_enable(const struct rte_intr_handle *intr_handle);
/**
* It disables the interrupt for the specified handle.
@@ -113,7 +113,7 @@ int rte_intr_enable(struct rte_intr_handle *intr_handle);
* - On success, zero.
* - On failure, a negative value.
*/
-int rte_intr_disable(struct rte_intr_handle *intr_handle);
+int rte_intr_disable(const struct rte_intr_handle *intr_handle);
#ifdef __cplusplus
}
diff --git a/lib/librte_eal/linuxapp/eal/eal_interrupts.c b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
index 47a3b20..cb55751 100644
--- a/lib/librte_eal/linuxapp/eal/eal_interrupts.c
+++ b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
@@ -136,7 +136,7 @@ static pthread_t intr_thread;
/* enable legacy (INTx) interrupts */
static int
-vfio_enable_intx(struct rte_intr_handle *intr_handle) {
+vfio_enable_intx(const struct rte_intr_handle *intr_handle) {
struct vfio_irq_set *irq_set;
char irq_set_buf[IRQ_SET_BUF_LEN];
int len, ret;
@@ -183,7 +183,7 @@ vfio_enable_intx(struct rte_intr_handle *intr_handle) {
/* disable legacy (INTx) interrupts */
static int
-vfio_disable_intx(struct rte_intr_handle *intr_handle) {
+vfio_disable_intx(const struct rte_intr_handle *intr_handle) {
struct vfio_irq_set *irq_set;
char irq_set_buf[IRQ_SET_BUF_LEN];
int len, ret;
@@ -226,7 +226,7 @@ vfio_disable_intx(struct rte_intr_handle *intr_handle) {
/* enable MSI interrupts */
static int
-vfio_enable_msi(struct rte_intr_handle *intr_handle) {
+vfio_enable_msi(const struct rte_intr_handle *intr_handle) {
int len, ret;
char irq_set_buf[IRQ_SET_BUF_LEN];
struct vfio_irq_set *irq_set;
@@ -255,7 +255,7 @@ vfio_enable_msi(struct rte_intr_handle *intr_handle) {
/* disable MSI interrupts */
static int
-vfio_disable_msi(struct rte_intr_handle *intr_handle) {
+vfio_disable_msi(const struct rte_intr_handle *intr_handle) {
struct vfio_irq_set *irq_set;
char irq_set_buf[IRQ_SET_BUF_LEN];
int len, ret;
@@ -278,9 +278,30 @@ vfio_disable_msi(struct rte_intr_handle *intr_handle) {
return ret;
}
+static int
+get_max_intr(const struct rte_intr_handle *intr_handle)
+{
+ struct rte_intr_source *src;
+
+ TAILQ_FOREACH(src, &intr_sources, next) {
+ if (src->intr_handle.fd != intr_handle->fd)
+ continue;
+
+ if (!src->intr_handle.max_intr)
+ src->intr_handle.max_intr = 1;
+ else if (src->intr_handle.max_intr > RTE_MAX_RXTX_INTR_VEC_ID)
+ src->intr_handle.max_intr
+ = RTE_MAX_RXTX_INTR_VEC_ID + 1;
+
+ return src->intr_handle.max_intr;
+ }
+
+ return -1;
+}
+
/* enable MSI-X interrupts */
static int
-vfio_enable_msix(struct rte_intr_handle *intr_handle) {
+vfio_enable_msix(const struct rte_intr_handle *intr_handle) {
int len, ret;
char irq_set_buf[MSIX_IRQ_SET_BUF_LEN];
struct vfio_irq_set *irq_set;
@@ -290,12 +311,15 @@ vfio_enable_msix(struct rte_intr_handle *intr_handle) {
irq_set = (struct vfio_irq_set *) irq_set_buf;
irq_set->argsz = len;
- if (!intr_handle->max_intr)
- intr_handle->max_intr = 1;
- else if (intr_handle->max_intr > RTE_MAX_RXTX_INTR_VEC_ID)
- intr_handle->max_intr = RTE_MAX_RXTX_INTR_VEC_ID + 1;
- irq_set->count = intr_handle->max_intr;
+ ret = get_max_intr(intr_handle);
+ if (ret < 0) {
+ RTE_LOG(ERR, EAL, "Invalid number of MSI-X irqs for fd %d\n",
+ intr_handle->fd);
+ return -1;
+ }
+
+ irq_set->count = ret;
irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER;
irq_set->index = VFIO_PCI_MSIX_IRQ_INDEX;
irq_set->start = 0;
@@ -318,7 +342,7 @@ vfio_enable_msix(struct rte_intr_handle *intr_handle) {
/* disable MSI-X interrupts */
static int
-vfio_disable_msix(struct rte_intr_handle *intr_handle) {
+vfio_disable_msix(const struct rte_intr_handle *intr_handle) {
struct vfio_irq_set *irq_set;
char irq_set_buf[MSIX_IRQ_SET_BUF_LEN];
int len, ret;
@@ -343,7 +367,7 @@ vfio_disable_msix(struct rte_intr_handle *intr_handle) {
#endif
static int
-uio_intx_intr_disable(struct rte_intr_handle *intr_handle)
+uio_intx_intr_disable(const struct rte_intr_handle *intr_handle)
{
unsigned char command_high;
@@ -367,7 +391,7 @@ uio_intx_intr_disable(struct rte_intr_handle *intr_handle)
}
static int
-uio_intx_intr_enable(struct rte_intr_handle *intr_handle)
+uio_intx_intr_enable(const struct rte_intr_handle *intr_handle)
{
unsigned char command_high;
@@ -391,7 +415,7 @@ uio_intx_intr_enable(struct rte_intr_handle *intr_handle)
}
static int
-uio_intr_disable(struct rte_intr_handle *intr_handle)
+uio_intr_disable(const struct rte_intr_handle *intr_handle)
{
const int value = 0;
@@ -405,7 +429,7 @@ uio_intr_disable(struct rte_intr_handle *intr_handle)
}
static int
-uio_intr_enable(struct rte_intr_handle *intr_handle)
+uio_intr_enable(const struct rte_intr_handle *intr_handle)
{
const int value = 1;
@@ -419,7 +443,7 @@ uio_intr_enable(struct rte_intr_handle *intr_handle)
}
int
-rte_intr_callback_register(struct rte_intr_handle *intr_handle,
+rte_intr_callback_register(const struct rte_intr_handle *intr_handle,
rte_intr_callback_fn cb, void *cb_arg)
{
int ret, wake_thread;
@@ -491,7 +515,7 @@ rte_intr_callback_register(struct rte_intr_handle *intr_handle,
}
int
-rte_intr_callback_unregister(struct rte_intr_handle *intr_handle,
+rte_intr_callback_unregister(const struct rte_intr_handle *intr_handle,
rte_intr_callback_fn cb_fn, void *cb_arg)
{
int ret;
@@ -555,7 +579,7 @@ rte_intr_callback_unregister(struct rte_intr_handle *intr_handle,
}
int
-rte_intr_enable(struct rte_intr_handle *intr_handle)
+rte_intr_enable(const struct rte_intr_handle *intr_handle)
{
if (!intr_handle || intr_handle->fd < 0 || intr_handle->uio_cfg_fd < 0)
return -1;
@@ -599,7 +623,7 @@ rte_intr_enable(struct rte_intr_handle *intr_handle)
}
int
-rte_intr_disable(struct rte_intr_handle *intr_handle)
+rte_intr_disable(const struct rte_intr_handle *intr_handle)
{
if (!intr_handle || intr_handle->fd < 0 || intr_handle->uio_cfg_fd < 0)
return -1;
--
2.7.4
^ permalink raw reply related
* [PATCH v4 03/23] rte_device: make driver pointer const
From: Jan Blunck @ 2016-12-21 15:09 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, shreyansh.jain, david.marchand
In-Reply-To: <1482332986-7599-1-git-send-email-jblunck@infradead.org>
From: Stephen Hemminger <stephen@networkplumber.org>
The info in rte_device about driver is immutable and
shouldn't change.
Acked-by: Jan Blunck <jblunck@infradead.org>
Acked-by: Jan Blunck <jblunck@infradead.org>
---
lib/librte_eal/common/include/rte_dev.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 8840380..e5471a2 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -122,7 +122,7 @@ struct rte_driver;
*/
struct rte_device {
TAILQ_ENTRY(rte_device) next; /**< Next device */
- struct rte_driver *driver; /**< Associated driver */
+ const struct rte_driver *driver;/**< Associated driver */
int numa_node; /**< NUMA node connection */
struct rte_devargs *devargs; /**< Device user arguments */
};
--
2.7.4
^ permalink raw reply related
* [PATCH v4 04/23] pmd: remove useless reset of dev_info->dev_pci
From: Jan Blunck @ 2016-12-21 15:09 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, shreyansh.jain, david.marchand,
Stephen Hemminger
In-Reply-To: <1482332986-7599-1-git-send-email-jblunck@infradead.org>
From: Stephen Hemminger <stephen@networkplumber.org>
Since rte_eth_dev_info_get does memset() on dev_info before
calling device specific code, the explicit assignment of NULL
in all these virtual drivers has no effect.
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
Acked-by: Jan Blunck <jblunck@infradead.org>
---
app/test/virtual_pmd.c | 1 -
drivers/net/af_packet/rte_eth_af_packet.c | 1 -
drivers/net/bonding/rte_eth_bond_pmd.c | 1 -
drivers/net/null/rte_eth_null.c | 1 -
drivers/net/pcap/rte_eth_pcap.c | 1 -
drivers/net/ring/rte_eth_ring.c | 1 -
drivers/net/xenvirt/rte_eth_xenvirt.c | 1 -
7 files changed, 7 deletions(-)
diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index 65b44c6..e0447fd 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -117,7 +117,6 @@ virtual_ethdev_info_get(struct rte_eth_dev *dev __rte_unused,
dev_info->max_tx_queues = (uint16_t)512;
dev_info->min_rx_bufsize = 0;
- dev_info->pci_dev = NULL;
}
static int
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index ff45068..2951f86 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -287,7 +287,6 @@ eth_dev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
dev_info->max_rx_queues = (uint16_t)internals->nb_queues;
dev_info->max_tx_queues = (uint16_t)internals->nb_queues;
dev_info->min_rx_bufsize = 0;
- dev_info->pci_dev = NULL;
}
static void
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index a80b6fa..74af658 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -1675,7 +1675,6 @@ bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
dev_info->max_tx_queues = (uint16_t)512;
dev_info->min_rx_bufsize = 0;
- dev_info->pci_dev = NULL;
dev_info->rx_offload_capa = internals->rx_offload_capa;
dev_info->tx_offload_capa = internals->tx_offload_capa;
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 836d982..b4f253a 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -301,7 +301,6 @@ eth_dev_info(struct rte_eth_dev *dev,
dev_info->max_rx_queues = RTE_DIM(internals->rx_null_queues);
dev_info->max_tx_queues = RTE_DIM(internals->tx_null_queues);
dev_info->min_rx_bufsize = 0;
- dev_info->pci_dev = NULL;
dev_info->reta_size = internals->reta_size;
dev_info->flow_type_rss_offloads = internals->flow_type_rss_offloads;
}
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index 0162f44..7253b9a 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c
@@ -559,7 +559,6 @@ eth_dev_info(struct rte_eth_dev *dev,
dev_info->max_rx_queues = dev->data->nb_rx_queues;
dev_info->max_tx_queues = dev->data->nb_tx_queues;
dev_info->min_rx_bufsize = 0;
- dev_info->pci_dev = NULL;
}
static void
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index c1767c4..dc99a1f 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -179,7 +179,6 @@ eth_dev_info(struct rte_eth_dev *dev,
dev_info->max_rx_queues = (uint16_t)internals->max_rx_queues;
dev_info->max_tx_queues = (uint16_t)internals->max_tx_queues;
dev_info->min_rx_bufsize = 0;
- dev_info->pci_dev = NULL;
}
static void
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
index c08a056..609824b 100644
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
@@ -337,7 +337,6 @@ eth_dev_info(struct rte_eth_dev *dev,
dev_info->max_rx_queues = (uint16_t)1;
dev_info->max_tx_queues = (uint16_t)1;
dev_info->min_rx_bufsize = 0;
- dev_info->pci_dev = NULL;
}
static void
--
2.7.4
^ permalink raw reply related
* [PATCH v4 05/23] e1000: localize mapping from eth_dev to pci
From: Jan Blunck @ 2016-12-21 15:09 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, shreyansh.jain, david.marchand
In-Reply-To: <1482332986-7599-1-git-send-email-jblunck@infradead.org>
From: Stephen Hemminger <stephen@networkplumber.org>
Create one macro for where PCI device information is extracted
from ethernet device. Makes later changes easier to review, and test.
Acked-by: Jan Blunck <jblunck@infradead.org>
---
drivers/net/e1000/e1000_ethdev.h | 2 +
drivers/net/e1000/em_ethdev.c | 50 +++++++++++---------
drivers/net/e1000/igb_ethdev.c | 99 ++++++++++++++++++++++------------------
drivers/net/e1000/igb_pf.c | 4 +-
4 files changed, 87 insertions(+), 68 deletions(-)
diff --git a/drivers/net/e1000/e1000_ethdev.h b/drivers/net/e1000/e1000_ethdev.h
index 6c25c8d..134f8b9 100644
--- a/drivers/net/e1000/e1000_ethdev.h
+++ b/drivers/net/e1000/e1000_ethdev.h
@@ -286,6 +286,8 @@ struct e1000_adapter {
#define E1000_DEV_PRIVATE_TO_FILTER_INFO(adapter) \
(&((struct e1000_adapter *)adapter)->filter)
+#define E1000_DEV_TO_PCI(eth_dev) \
+ (eth_dev->pci_dev)
/*
* RX/TX IGB function prototypes
*/
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index aee3d34..014e575 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -83,7 +83,8 @@ static int eth_em_flow_ctrl_set(struct rte_eth_dev *dev,
static int eth_em_interrupt_setup(struct rte_eth_dev *dev);
static int eth_em_rxq_interrupt_setup(struct rte_eth_dev *dev);
static int eth_em_interrupt_get_status(struct rte_eth_dev *dev);
-static int eth_em_interrupt_action(struct rte_eth_dev *dev);
+static int eth_em_interrupt_action(struct rte_eth_dev *dev,
+ struct rte_intr_handle *handle);
static void eth_em_interrupt_handler(struct rte_intr_handle *handle,
void *param);
@@ -287,7 +288,8 @@ eth_em_dev_is_ich8(struct e1000_hw *hw)
static int
eth_em_dev_init(struct rte_eth_dev *eth_dev)
{
- struct rte_pci_device *pci_dev;
+ struct rte_pci_device *pci_dev = E1000_DEV_TO_PCI(eth_dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
struct e1000_adapter *adapter =
E1000_DEV_PRIVATE(eth_dev->data->dev_private);
struct e1000_hw *hw =
@@ -295,8 +297,6 @@ eth_em_dev_init(struct rte_eth_dev *eth_dev)
struct e1000_vfta * shadow_vfta =
E1000_DEV_PRIVATE_TO_VFTA(eth_dev->data->dev_private);
- pci_dev = eth_dev->pci_dev;
-
eth_dev->dev_ops = ð_em_ops;
eth_dev->rx_pkt_burst = (eth_rx_burst_t)ð_em_recv_pkts;
eth_dev->tx_pkt_burst = (eth_tx_burst_t)ð_em_xmit_pkts;
@@ -351,8 +351,8 @@ eth_em_dev_init(struct rte_eth_dev *eth_dev)
eth_dev->data->port_id, pci_dev->id.vendor_id,
pci_dev->id.device_id);
- rte_intr_callback_register(&(pci_dev->intr_handle),
- eth_em_interrupt_handler, (void *)eth_dev);
+ rte_intr_callback_register(intr_handle,
+ eth_em_interrupt_handler, eth_dev);
return 0;
}
@@ -360,17 +360,16 @@ eth_em_dev_init(struct rte_eth_dev *eth_dev)
static int
eth_em_dev_uninit(struct rte_eth_dev *eth_dev)
{
- struct rte_pci_device *pci_dev;
+ struct rte_pci_device *pci_dev = E1000_DEV_TO_PCI(eth_dev);
struct e1000_adapter *adapter =
E1000_DEV_PRIVATE(eth_dev->data->dev_private);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
PMD_INIT_FUNC_TRACE();
if (rte_eal_process_type() != RTE_PROC_PRIMARY)
return -EPERM;
- pci_dev = eth_dev->pci_dev;
-
if (adapter->stopped == 0)
eth_em_close(eth_dev);
@@ -382,9 +381,9 @@ eth_em_dev_uninit(struct rte_eth_dev *eth_dev)
eth_dev->data->mac_addrs = NULL;
/* disable uio intr before callback unregister */
- rte_intr_disable(&(pci_dev->intr_handle));
- rte_intr_callback_unregister(&(pci_dev->intr_handle),
- eth_em_interrupt_handler, (void *)eth_dev);
+ rte_intr_disable(intr_handle);
+ rte_intr_callback_unregister(intr_handle,
+ eth_em_interrupt_handler, eth_dev);
return 0;
}
@@ -556,7 +555,9 @@ eth_em_start(struct rte_eth_dev *dev)
E1000_DEV_PRIVATE(dev->data->dev_private);
struct e1000_hw *hw =
E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev =
+ E1000_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
int ret, mask;
uint32_t intr_vector = 0;
uint32_t *speeds;
@@ -738,7 +739,8 @@ eth_em_stop(struct rte_eth_dev *dev)
{
struct rte_eth_link link;
struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = E1000_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
em_rxq_intr_disable(hw);
em_lsc_intr_disable(hw);
@@ -999,9 +1001,11 @@ static int
eth_em_rx_queue_intr_enable(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id)
{
struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct rte_pci_device *pci_dev = E1000_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
em_rxq_intr_enable(hw);
- rte_intr_enable(&dev->pci_dev->intr_handle);
+ rte_intr_enable(intr_handle);
return 0;
}
@@ -1536,8 +1540,10 @@ eth_em_interrupt_get_status(struct rte_eth_dev *dev)
* - On failure, a negative value.
*/
static int
-eth_em_interrupt_action(struct rte_eth_dev *dev)
+eth_em_interrupt_action(struct rte_eth_dev *dev,
+ struct rte_intr_handle *intr_handle)
{
+ struct rte_pci_device *pci_dev = E1000_DEV_TO_PCI(dev);
struct e1000_hw *hw =
E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct e1000_interrupt *intr =
@@ -1550,7 +1556,7 @@ eth_em_interrupt_action(struct rte_eth_dev *dev)
return -1;
intr->flags &= ~E1000_FLAG_NEED_LINK_UPDATE;
- rte_intr_enable(&(dev->pci_dev->intr_handle));
+ rte_intr_enable(intr_handle);
/* set get_link_status to check register later */
hw->mac.get_link_status = 1;
@@ -1571,8 +1577,8 @@ eth_em_interrupt_action(struct rte_eth_dev *dev)
PMD_INIT_LOG(INFO, " Port %d: Link Down", dev->data->port_id);
}
PMD_INIT_LOG(DEBUG, "PCI Address: %04d:%02d:%02d:%d",
- dev->pci_dev->addr.domain, dev->pci_dev->addr.bus,
- dev->pci_dev->addr.devid, dev->pci_dev->addr.function);
+ pci_dev->addr.domain, pci_dev->addr.bus,
+ pci_dev->addr.devid, pci_dev->addr.function);
tctl = E1000_READ_REG(hw, E1000_TCTL);
rctl = E1000_READ_REG(hw, E1000_RCTL);
@@ -1604,13 +1610,13 @@ eth_em_interrupt_action(struct rte_eth_dev *dev)
* void
*/
static void
-eth_em_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
- void *param)
+eth_em_interrupt_handler(struct rte_intr_handle *handle,
+ void *param)
{
struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
eth_em_interrupt_get_status(dev);
- eth_em_interrupt_action(dev);
+ eth_em_interrupt_action(dev, handle);
_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 2fddf0c..e0115ea 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -132,7 +132,8 @@ static int eth_igb_flow_ctrl_set(struct rte_eth_dev *dev,
static int eth_igb_lsc_interrupt_setup(struct rte_eth_dev *dev);
static int eth_igb_rxq_interrupt_setup(struct rte_eth_dev *dev);
static int eth_igb_interrupt_get_status(struct rte_eth_dev *dev);
-static int eth_igb_interrupt_action(struct rte_eth_dev *dev);
+static int eth_igb_interrupt_action(struct rte_eth_dev *dev,
+ struct rte_intr_handle *handle);
static void eth_igb_interrupt_handler(struct rte_intr_handle *handle,
void *param);
static int igb_hardware_init(struct e1000_hw *hw);
@@ -668,15 +669,16 @@ igb_pf_reset_hw(struct e1000_hw *hw)
}
static void
-igb_identify_hardware(struct rte_eth_dev *dev)
+igb_identify_hardware(struct rte_eth_dev *dev, struct rte_pci_device *pci_dev)
{
struct e1000_hw *hw =
E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- hw->vendor_id = dev->pci_dev->id.vendor_id;
- hw->device_id = dev->pci_dev->id.device_id;
- hw->subsystem_vendor_id = dev->pci_dev->id.subsystem_vendor_id;
- hw->subsystem_device_id = dev->pci_dev->id.subsystem_device_id;
+
+ hw->vendor_id = pci_dev->id.vendor_id;
+ hw->device_id = pci_dev->id.device_id;
+ hw->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id;
+ hw->subsystem_device_id = pci_dev->id.subsystem_device_id;
e1000_set_mac_type(hw);
@@ -743,7 +745,7 @@ static int
eth_igb_dev_init(struct rte_eth_dev *eth_dev)
{
int error = 0;
- struct rte_pci_device *pci_dev;
+ struct rte_pci_device *pci_dev = E1000_DEV_TO_PCI(eth_dev);
struct e1000_hw *hw =
E1000_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
struct e1000_vfta * shadow_vfta =
@@ -755,8 +757,6 @@ eth_igb_dev_init(struct rte_eth_dev *eth_dev)
uint32_t ctrl_ext;
- pci_dev = eth_dev->pci_dev;
-
eth_dev->dev_ops = ð_igb_ops;
eth_dev->rx_pkt_burst = ð_igb_recv_pkts;
eth_dev->tx_pkt_burst = ð_igb_xmit_pkts;
@@ -774,7 +774,7 @@ eth_igb_dev_init(struct rte_eth_dev *eth_dev)
hw->hw_addr= (void *)pci_dev->mem_resource[0].addr;
- igb_identify_hardware(eth_dev);
+ igb_identify_hardware(eth_dev, pci_dev);
if (e1000_setup_init_funcs(hw, FALSE) != E1000_SUCCESS) {
error = -EIO;
goto err_late;
@@ -908,6 +908,7 @@ static int
eth_igb_dev_uninit(struct rte_eth_dev *eth_dev)
{
struct rte_pci_device *pci_dev;
+ struct rte_intr_handle *intr_handle;
struct e1000_hw *hw;
struct e1000_adapter *adapter =
E1000_DEV_PRIVATE(eth_dev->data->dev_private);
@@ -918,7 +919,8 @@ eth_igb_dev_uninit(struct rte_eth_dev *eth_dev)
return -EPERM;
hw = E1000_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
- pci_dev = eth_dev->pci_dev;
+ pci_dev = E1000_DEV_TO_PCI(eth_dev);
+ intr_handle = &pci_dev->intr_handle;
if (adapter->stopped == 0)
eth_igb_close(eth_dev);
@@ -937,9 +939,9 @@ eth_igb_dev_uninit(struct rte_eth_dev *eth_dev)
igb_pf_host_uninit(eth_dev);
/* disable uio intr before callback unregister */
- rte_intr_disable(&(pci_dev->intr_handle));
- rte_intr_callback_unregister(&(pci_dev->intr_handle),
- eth_igb_interrupt_handler, (void *)eth_dev);
+ rte_intr_disable(intr_handle);
+ rte_intr_callback_unregister(intr_handle,
+ eth_igb_interrupt_handler, eth_dev);
return 0;
}
@@ -951,6 +953,7 @@ static int
eth_igbvf_dev_init(struct rte_eth_dev *eth_dev)
{
struct rte_pci_device *pci_dev;
+ struct rte_intr_handle *intr_handle;
struct e1000_adapter *adapter =
E1000_DEV_PRIVATE(eth_dev->data->dev_private);
struct e1000_hw *hw =
@@ -973,8 +976,7 @@ eth_igbvf_dev_init(struct rte_eth_dev *eth_dev)
return 0;
}
- pci_dev = eth_dev->pci_dev;
-
+ pci_dev = E1000_DEV_TO_PCI(eth_dev);
rte_eth_copy_pci_info(eth_dev, pci_dev);
hw->device_id = pci_dev->id.device_id;
@@ -1038,9 +1040,9 @@ eth_igbvf_dev_init(struct rte_eth_dev *eth_dev)
eth_dev->data->port_id, pci_dev->id.vendor_id,
pci_dev->id.device_id, "igb_mac_82576_vf");
- rte_intr_callback_register(&pci_dev->intr_handle,
- eth_igbvf_interrupt_handler,
- (void *)eth_dev);
+ intr_handle = &pci_dev->intr_handle;
+ rte_intr_callback_register(intr_handle,
+ eth_igbvf_interrupt_handler, eth_dev);
return 0;
}
@@ -1050,7 +1052,7 @@ eth_igbvf_dev_uninit(struct rte_eth_dev *eth_dev)
{
struct e1000_adapter *adapter =
E1000_DEV_PRIVATE(eth_dev->data->dev_private);
- struct rte_pci_device *pci_dev = eth_dev->pci_dev;
+ struct rte_pci_device *pci_dev = E1000_DEV_TO_PCI(eth_dev);
PMD_INIT_FUNC_TRACE();
@@ -1217,7 +1219,8 @@ eth_igb_start(struct rte_eth_dev *dev)
E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct e1000_adapter *adapter =
E1000_DEV_PRIVATE(dev->data->dev_private);
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = E1000_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
int ret, mask;
uint32_t intr_vector = 0;
uint32_t ctrl_ext;
@@ -1425,11 +1428,12 @@ eth_igb_stop(struct rte_eth_dev *dev)
struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct e1000_filter_info *filter_info =
E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+ struct rte_pci_device *pci_dev = E1000_DEV_TO_PCI(dev);
struct rte_eth_link link;
struct e1000_flex_filter *p_flex;
struct e1000_5tuple_filter *p_5tuple, *p_5tuple_next;
struct e1000_2tuple_filter *p_2tuple, *p_2tuple_next;
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
igb_intr_disable(hw);
@@ -1529,7 +1533,8 @@ eth_igb_close(struct rte_eth_dev *dev)
struct e1000_adapter *adapter =
E1000_DEV_PRIVATE(dev->data->dev_private);
struct rte_eth_link link;
- struct rte_pci_device *pci_dev;
+ struct rte_pci_device *pci_dev = E1000_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
eth_igb_stop(dev);
adapter->stopped = 1;
@@ -1549,10 +1554,9 @@ eth_igb_close(struct rte_eth_dev *dev)
igb_dev_free_queues(dev);
- pci_dev = dev->pci_dev;
- if (pci_dev->intr_handle.intr_vec) {
- rte_free(pci_dev->intr_handle.intr_vec);
- pci_dev->intr_handle.intr_vec = NULL;
+ if (intr_handle->intr_vec) {
+ rte_free(intr_handle->intr_vec);
+ intr_handle->intr_vec = NULL;
}
memset(&link, 0, sizeof(link));
@@ -2633,12 +2637,14 @@ eth_igb_interrupt_get_status(struct rte_eth_dev *dev)
* - On failure, a negative value.
*/
static int
-eth_igb_interrupt_action(struct rte_eth_dev *dev)
+eth_igb_interrupt_action(struct rte_eth_dev *dev,
+ struct rte_intr_handle *intr_handle)
{
struct e1000_hw *hw =
E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct e1000_interrupt *intr =
E1000_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
+ struct rte_pci_device *pci_dev = E1000_DEV_TO_PCI(dev);
uint32_t tctl, rctl;
struct rte_eth_link link;
int ret;
@@ -2649,7 +2655,7 @@ eth_igb_interrupt_action(struct rte_eth_dev *dev)
}
igb_intr_enable(dev);
- rte_intr_enable(&(dev->pci_dev->intr_handle));
+ rte_intr_enable(intr_handle);
if (intr->flags & E1000_FLAG_NEED_LINK_UPDATE) {
intr->flags &= ~E1000_FLAG_NEED_LINK_UPDATE;
@@ -2677,10 +2683,10 @@ eth_igb_interrupt_action(struct rte_eth_dev *dev)
}
PMD_INIT_LOG(DEBUG, "PCI Address: %04d:%02d:%02d:%d",
- dev->pci_dev->addr.domain,
- dev->pci_dev->addr.bus,
- dev->pci_dev->addr.devid,
- dev->pci_dev->addr.function);
+ pci_dev->addr.domain,
+ pci_dev->addr.bus,
+ pci_dev->addr.devid,
+ pci_dev->addr.function);
tctl = E1000_READ_REG(hw, E1000_TCTL);
rctl = E1000_READ_REG(hw, E1000_RCTL);
if (link.link_status) {
@@ -2713,13 +2719,12 @@ eth_igb_interrupt_action(struct rte_eth_dev *dev)
* void
*/
static void
-eth_igb_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
- void *param)
+eth_igb_interrupt_handler(struct rte_intr_handle *handle, void *param)
{
struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
eth_igb_interrupt_get_status(dev);
- eth_igb_interrupt_action(dev);
+ eth_igb_interrupt_action(dev, handle);
}
static int
@@ -2759,7 +2764,7 @@ void igbvf_mbx_process(struct rte_eth_dev *dev)
}
static int
-eth_igbvf_interrupt_action(struct rte_eth_dev *dev)
+eth_igbvf_interrupt_action(struct rte_eth_dev *dev, struct rte_intr_handle *intr_handle)
{
struct e1000_interrupt *intr =
E1000_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
@@ -2770,19 +2775,19 @@ eth_igbvf_interrupt_action(struct rte_eth_dev *dev)
}
igbvf_intr_enable(dev);
- rte_intr_enable(&dev->pci_dev->intr_handle);
+ rte_intr_enable(intr_handle);
return 0;
}
static void
-eth_igbvf_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
+eth_igbvf_interrupt_handler(struct rte_intr_handle *handle,
void *param)
{
struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
eth_igbvf_interrupt_get_status(dev);
- eth_igbvf_interrupt_action(dev);
+ eth_igbvf_interrupt_action(dev, handle);
}
static int
@@ -3055,8 +3060,9 @@ igbvf_dev_start(struct rte_eth_dev *dev)
E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct e1000_adapter *adapter =
E1000_DEV_PRIVATE(dev->data->dev_private);
+ struct rte_pci_device *pci_dev = E1000_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
int ret;
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
uint32_t intr_vector = 0;
PMD_INIT_FUNC_TRACE();
@@ -3110,7 +3116,8 @@ igbvf_dev_start(struct rte_eth_dev *dev)
static void
igbvf_dev_stop(struct rte_eth_dev *dev)
{
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = E1000_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
PMD_INIT_FUNC_TRACE();
@@ -5095,6 +5102,8 @@ eth_igb_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
{
struct e1000_hw *hw =
E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct rte_pci_device *pci_dev = E1000_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
uint32_t mask = 1 << queue_id;
uint32_t regval;
@@ -5102,7 +5111,7 @@ eth_igb_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
E1000_WRITE_REG(hw, E1000_EIMS, regval | mask);
E1000_WRITE_FLUSH(hw);
- rte_intr_enable(&dev->pci_dev->intr_handle);
+ rte_intr_enable(intr_handle);
return 0;
}
@@ -5166,8 +5175,8 @@ eth_igb_configure_msix_intr(struct rte_eth_dev *dev)
uint32_t vec = E1000_MISC_VEC_ID;
uint32_t base = E1000_MISC_VEC_ID;
uint32_t misc_shift = 0;
-
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = E1000_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
/* won't configure msix register if no mapping is done
* between intr vector and event fd
diff --git a/drivers/net/e1000/igb_pf.c b/drivers/net/e1000/igb_pf.c
index 5845bc2..67da3c2 100644
--- a/drivers/net/e1000/igb_pf.c
+++ b/drivers/net/e1000/igb_pf.c
@@ -57,7 +57,9 @@
static inline uint16_t
dev_num_vf(struct rte_eth_dev *eth_dev)
{
- return eth_dev->pci_dev->max_vfs;
+ struct rte_pci_device *pci_dev = E1000_DEV_TO_PCI(eth_dev);
+
+ return pci_dev->max_vfs;
}
static inline
--
2.7.4
^ permalink raw reply related
* [PATCH v4 06/23] ixgbe: localize mapping from eth_dev to pci_device
From: Jan Blunck @ 2016-12-21 15:09 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, shreyansh.jain, david.marchand,
Stephen Hemminger
In-Reply-To: <1482332986-7599-1-git-send-email-jblunck@infradead.org>
From: Stephen Hemminger <stephen@networkplumber.org>
Since later changes will change where PCI information is,
localize mapping in one macro.
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
Acked-by: Jan Blunck <jblunck@infradead.org>
---
drivers/net/ixgbe/ixgbe_ethdev.c | 120 ++++++++++++++++++++++-----------------
drivers/net/ixgbe/ixgbe_ethdev.h | 3 +
drivers/net/ixgbe/ixgbe_pf.c | 4 +-
3 files changed, 74 insertions(+), 53 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index edc9b22..2d05751 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -233,7 +233,8 @@ static void ixgbe_dev_link_status_print(struct rte_eth_dev *dev);
static int ixgbe_dev_lsc_interrupt_setup(struct rte_eth_dev *dev);
static int ixgbe_dev_rxq_interrupt_setup(struct rte_eth_dev *dev);
static int ixgbe_dev_interrupt_get_status(struct rte_eth_dev *dev);
-static int ixgbe_dev_interrupt_action(struct rte_eth_dev *dev);
+static int ixgbe_dev_interrupt_action(struct rte_eth_dev *dev,
+ struct rte_intr_handle *handle);
static void ixgbe_dev_interrupt_handler(struct rte_intr_handle *handle,
void *param);
static void ixgbe_dev_interrupt_delayed_handler(void *param);
@@ -1083,7 +1084,8 @@ ixgbe_swfw_lock_reset(struct ixgbe_hw *hw)
static int
eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev)
{
- struct rte_pci_device *pci_dev;
+ struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(eth_dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
struct ixgbe_hw *hw =
IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
struct ixgbe_vfta *shadow_vfta =
@@ -1127,7 +1129,6 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev)
return 0;
}
- pci_dev = eth_dev->pci_dev;
rte_eth_copy_pci_info(eth_dev, pci_dev);
@@ -1272,12 +1273,11 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev)
eth_dev->data->port_id, pci_dev->id.vendor_id,
pci_dev->id.device_id);
- rte_intr_callback_register(&pci_dev->intr_handle,
- ixgbe_dev_interrupt_handler,
- (void *)eth_dev);
+ rte_intr_callback_register(intr_handle,
+ ixgbe_dev_interrupt_handler, eth_dev);
/* enable uio/vfio intr/eventfd mapping */
- rte_intr_enable(&pci_dev->intr_handle);
+ rte_intr_enable(intr_handle);
/* enable support intr */
ixgbe_enable_intr(eth_dev);
@@ -1293,7 +1293,8 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev)
static int
eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev)
{
- struct rte_pci_device *pci_dev;
+ struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(eth_dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
struct ixgbe_hw *hw;
PMD_INIT_FUNC_TRACE();
@@ -1302,7 +1303,6 @@ eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev)
return -EPERM;
hw = IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
- pci_dev = eth_dev->pci_dev;
if (hw->adapter_stopped == 0)
ixgbe_dev_close(eth_dev);
@@ -1315,9 +1315,9 @@ eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev)
ixgbe_swfw_lock_reset(hw);
/* disable uio intr before callback unregister */
- rte_intr_disable(&(pci_dev->intr_handle));
- rte_intr_callback_unregister(&(pci_dev->intr_handle),
- ixgbe_dev_interrupt_handler, (void *)eth_dev);
+ rte_intr_disable(intr_handle);
+ rte_intr_callback_unregister(intr_handle,
+ ixgbe_dev_interrupt_handler, eth_dev);
/* uninitialize PF if max_vfs not zero */
ixgbe_pf_host_uninit(eth_dev);
@@ -1381,7 +1381,8 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev)
{
int diag;
uint32_t tc, tcs;
- struct rte_pci_device *pci_dev;
+ struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(eth_dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
struct ixgbe_hw *hw =
IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
struct ixgbe_vfta *shadow_vfta =
@@ -1419,8 +1420,6 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev)
return 0;
}
- pci_dev = eth_dev->pci_dev;
-
rte_eth_copy_pci_info(eth_dev, pci_dev);
hw->device_id = pci_dev->id.device_id;
@@ -1513,10 +1512,9 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev)
return -EIO;
}
- rte_intr_callback_register(&pci_dev->intr_handle,
- ixgbevf_dev_interrupt_handler,
- (void *)eth_dev);
- rte_intr_enable(&pci_dev->intr_handle);
+ rte_intr_callback_register(intr_handle,
+ ixgbevf_dev_interrupt_handler, eth_dev);
+ rte_intr_enable(intr_handle);
ixgbevf_intr_enable(hw);
PMD_INIT_LOG(DEBUG, "port %d vendorID=0x%x deviceID=0x%x mac.type=%s",
@@ -1531,8 +1529,9 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev)
static int
eth_ixgbevf_dev_uninit(struct rte_eth_dev *eth_dev)
{
+ struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(eth_dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
struct ixgbe_hw *hw;
- struct rte_pci_device *pci_dev = eth_dev->pci_dev;
PMD_INIT_FUNC_TRACE();
@@ -1554,10 +1553,9 @@ eth_ixgbevf_dev_uninit(struct rte_eth_dev *eth_dev)
rte_free(eth_dev->data->mac_addrs);
eth_dev->data->mac_addrs = NULL;
- rte_intr_disable(&pci_dev->intr_handle);
- rte_intr_callback_unregister(&pci_dev->intr_handle,
- ixgbevf_dev_interrupt_handler,
- (void *)eth_dev);
+ rte_intr_disable(intr_handle);
+ rte_intr_callback_unregister(intr_handle,
+ ixgbevf_dev_interrupt_handler, eth_dev);
return 0;
}
@@ -1947,6 +1945,8 @@ ixgbe_vmdq_vlan_hw_filter_enable(struct rte_eth_dev *dev)
static int
ixgbe_check_vf_rss_rxq_num(struct rte_eth_dev *dev, uint16_t nb_rx_q)
{
+ struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
+
switch (nb_rx_q) {
case 1:
case 2:
@@ -1960,7 +1960,7 @@ ixgbe_check_vf_rss_rxq_num(struct rte_eth_dev *dev, uint16_t nb_rx_q)
}
RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool = nb_rx_q;
- RTE_ETH_DEV_SRIOV(dev).def_pool_q_idx = dev->pci_dev->max_vfs * nb_rx_q;
+ RTE_ETH_DEV_SRIOV(dev).def_pool_q_idx = pci_dev->max_vfs * nb_rx_q;
return 0;
}
@@ -2191,7 +2191,8 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct ixgbe_vf_info *vfinfo =
*IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private);
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
uint32_t intr_vector = 0;
int err, link_up = 0, negotiate = 0;
uint32_t speed = 0;
@@ -2291,7 +2292,7 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
/* Restore vf rate limit */
if (vfinfo != NULL) {
- for (vf = 0; vf < dev->pci_dev->max_vfs; vf++)
+ for (vf = 0; vf < pci_dev->max_vfs; vf++)
for (idx = 0; idx < IXGBE_MAX_QUEUE_NUM_PER_VF; idx++)
if (vfinfo[vf].tx_rate[idx] != 0)
ixgbe_set_vf_rate_limit(dev, vf,
@@ -2368,8 +2369,7 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
ixgbe_dev_lsc_interrupt_setup(dev);
} else {
rte_intr_callback_unregister(intr_handle,
- ixgbe_dev_interrupt_handler,
- (void *)dev);
+ ixgbe_dev_interrupt_handler, dev);
if (dev->data->dev_conf.intr_conf.lsc != 0)
PMD_INIT_LOG(INFO, "lsc won't enable because of"
" no intr multiplex\n");
@@ -2408,7 +2408,8 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)
struct ixgbe_filter_info *filter_info =
IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
struct ixgbe_5tuple_filter *p_5tuple, *p_5tuple_next;
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
int vf;
PMD_INIT_FUNC_TRACE();
@@ -2423,8 +2424,7 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)
/* stop adapter */
ixgbe_stop_adapter(hw);
- for (vf = 0; vfinfo != NULL &&
- vf < dev->pci_dev->max_vfs; vf++)
+ for (vf = 0; vfinfo != NULL && vf < pci_dev->max_vfs; vf++)
vfinfo[vf].clear_to_send = false;
if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper) {
@@ -3031,6 +3031,7 @@ ixgbevf_dev_stats_reset(struct rte_eth_dev *dev)
static void
ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
{
+ struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
@@ -3049,7 +3050,7 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
dev_info->max_rx_pktlen = 15872; /* includes CRC, cf MAXFRS register */
dev_info->max_mac_addrs = hw->mac.num_rar_entries;
dev_info->max_hash_mac_addrs = IXGBE_VMDQ_NUM_UC_MAC;
- dev_info->max_vfs = dev->pci_dev->max_vfs;
+ dev_info->max_vfs = pci_dev->max_vfs;
if (hw->mac.type == ixgbe_mac_82598EB)
dev_info->max_vmdq_pools = ETH_16_POOLS;
else
@@ -3163,6 +3164,7 @@ static void
ixgbevf_dev_info_get(struct rte_eth_dev *dev,
struct rte_eth_dev_info *dev_info)
{
+ struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
dev_info->max_rx_queues = (uint16_t)hw->mac.max_rx_queues;
@@ -3171,7 +3173,7 @@ ixgbevf_dev_info_get(struct rte_eth_dev *dev,
dev_info->max_rx_pktlen = 15872; /* includes CRC, cf MAXFRS reg */
dev_info->max_mac_addrs = hw->mac.num_rar_entries;
dev_info->max_hash_mac_addrs = IXGBE_VMDQ_NUM_UC_MAC;
- dev_info->max_vfs = dev->pci_dev->max_vfs;
+ dev_info->max_vfs = pci_dev->max_vfs;
if (hw->mac.type == ixgbe_mac_82598EB)
dev_info->max_vmdq_pools = ETH_16_POOLS;
else
@@ -3433,6 +3435,7 @@ ixgbe_dev_interrupt_get_status(struct rte_eth_dev *dev)
static void
ixgbe_dev_link_status_print(struct rte_eth_dev *dev)
{
+ struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
struct rte_eth_link link;
memset(&link, 0, sizeof(link));
@@ -3448,10 +3451,10 @@ ixgbe_dev_link_status_print(struct rte_eth_dev *dev)
(int)(dev->data->port_id));
}
PMD_INIT_LOG(DEBUG, "PCI Address: " PCI_PRI_FMT,
- dev->pci_dev->addr.domain,
- dev->pci_dev->addr.bus,
- dev->pci_dev->addr.devid,
- dev->pci_dev->addr.function);
+ pci_dev->addr.domain,
+ pci_dev->addr.bus,
+ pci_dev->addr.devid,
+ pci_dev->addr.function);
}
/*
@@ -3465,7 +3468,8 @@ ixgbe_dev_link_status_print(struct rte_eth_dev *dev)
* - On failure, a negative value.
*/
static int
-ixgbe_dev_interrupt_action(struct rte_eth_dev *dev)
+ixgbe_dev_interrupt_action(struct rte_eth_dev *dev,
+ struct rte_intr_handle *intr_handle)
{
struct ixgbe_interrupt *intr =
IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
@@ -3515,7 +3519,7 @@ ixgbe_dev_interrupt_action(struct rte_eth_dev *dev)
} else {
PMD_DRV_LOG(DEBUG, "enable intr immediately");
ixgbe_enable_intr(dev);
- rte_intr_enable(&(dev->pci_dev->intr_handle));
+ rte_intr_enable(intr_handle);
}
@@ -3540,6 +3544,8 @@ static void
ixgbe_dev_interrupt_delayed_handler(void *param)
{
struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
+ struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
struct ixgbe_interrupt *intr =
IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
struct ixgbe_hw *hw =
@@ -3564,7 +3570,7 @@ ixgbe_dev_interrupt_delayed_handler(void *param)
PMD_DRV_LOG(DEBUG, "enable intr in delayed handler S[%08x]", eicr);
ixgbe_enable_intr(dev);
- rte_intr_enable(&(dev->pci_dev->intr_handle));
+ rte_intr_enable(intr_handle);
}
/**
@@ -3580,13 +3586,13 @@ ixgbe_dev_interrupt_delayed_handler(void *param)
* void
*/
static void
-ixgbe_dev_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
+ixgbe_dev_interrupt_handler(struct rte_intr_handle *handle,
void *param)
{
struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
ixgbe_dev_interrupt_get_status(dev);
- ixgbe_dev_interrupt_action(dev);
+ ixgbe_dev_interrupt_action(dev, handle);
}
static int
@@ -4196,7 +4202,8 @@ ixgbevf_dev_start(struct rte_eth_dev *dev)
struct ixgbe_hw *hw =
IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
uint32_t intr_vector = 0;
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
int err, mask = 0;
@@ -4259,7 +4266,8 @@ static void
ixgbevf_dev_stop(struct rte_eth_dev *dev)
{
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
PMD_INIT_FUNC_TRACE();
@@ -5061,6 +5069,8 @@ ixgbe_mirror_rule_reset(struct rte_eth_dev *dev, uint8_t rule_id)
static int
ixgbevf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
{
+ struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
uint32_t mask;
struct ixgbe_hw *hw =
IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -5070,7 +5080,7 @@ ixgbevf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
RTE_SET_USED(queue_id);
IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask);
- rte_intr_enable(&dev->pci_dev->intr_handle);
+ rte_intr_enable(intr_handle);
return 0;
}
@@ -5093,6 +5103,8 @@ ixgbevf_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
static int
ixgbe_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
{
+ struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
uint32_t mask;
struct ixgbe_hw *hw =
IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -5112,7 +5124,7 @@ ixgbe_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
mask &= (1 << (queue_id - 32));
IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(1), mask);
}
- rte_intr_enable(&dev->pci_dev->intr_handle);
+ rte_intr_enable(intr_handle);
return 0;
}
@@ -5216,7 +5228,8 @@ ixgbe_set_ivar_map(struct ixgbe_hw *hw, int8_t direction,
static void
ixgbevf_configure_msix(struct rte_eth_dev *dev)
{
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
struct ixgbe_hw *hw =
IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
uint32_t q_idx;
@@ -5249,7 +5262,8 @@ ixgbevf_configure_msix(struct rte_eth_dev *dev)
static void
ixgbe_configure_msix(struct rte_eth_dev *dev)
{
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
struct ixgbe_hw *hw =
IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
uint32_t queue_id, base = IXGBE_MISC_VEC_ID;
@@ -5367,6 +5381,7 @@ static int ixgbe_set_queue_rate_limit(struct rte_eth_dev *dev,
static int ixgbe_set_vf_rate_limit(struct rte_eth_dev *dev, uint16_t vf,
uint16_t tx_rate, uint64_t q_msk)
{
+ struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct ixgbe_vf_info *vfinfo =
*(IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private));
@@ -5381,7 +5396,7 @@ static int ixgbe_set_vf_rate_limit(struct rte_eth_dev *dev, uint16_t vf,
return -EINVAL;
if (vfinfo != NULL) {
- for (vf_idx = 0; vf_idx < dev->pci_dev->max_vfs; vf_idx++) {
+ for (vf_idx = 0; vf_idx < pci_dev->max_vfs; vf_idx++) {
if (vf_idx == vf)
continue;
for (idx = 0; idx < RTE_DIM(vfinfo[vf_idx].tx_rate);
@@ -7194,15 +7209,16 @@ ixgbe_e_tag_insertion_en_dis(struct rte_eth_dev *dev,
struct rte_eth_l2_tunnel_conf *l2_tunnel,
bool en)
{
+ struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
int ret = 0;
uint32_t vmtir, vmvir;
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- if (l2_tunnel->vf_id >= dev->pci_dev->max_vfs) {
+ if (l2_tunnel->vf_id >= pci_dev->max_vfs) {
PMD_DRV_LOG(ERR,
"VF id %u should be less than %u",
l2_tunnel->vf_id,
- dev->pci_dev->max_vfs);
+ pci_dev->max_vfs);
return -EINVAL;
}
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index 4ff6338..a0e02aa 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -291,6 +291,9 @@ struct ixgbe_adapter {
struct rte_timecounter tx_tstamp_tc;
};
+#define IXGBE_DEV_TO_PCI(eth_dev) \
+ (eth_dev->pci_dev)
+
#define IXGBE_DEV_PRIVATE_TO_HW(adapter)\
(&((struct ixgbe_adapter *)adapter)->hw)
diff --git a/drivers/net/ixgbe/ixgbe_pf.c b/drivers/net/ixgbe/ixgbe_pf.c
index 26395e4..cb10265 100644
--- a/drivers/net/ixgbe/ixgbe_pf.c
+++ b/drivers/net/ixgbe/ixgbe_pf.c
@@ -61,7 +61,9 @@
static inline uint16_t
dev_num_vf(struct rte_eth_dev *eth_dev)
{
- return eth_dev->pci_dev->max_vfs;
+ struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(eth_dev);
+
+ return pci_dev->max_vfs;
}
static inline
--
2.7.4
^ permalink raw reply related
* [PATCH v4 07/23] i40e: localize mapping of eth_dev to pci
From: Jan Blunck @ 2016-12-21 15:09 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, shreyansh.jain, david.marchand,
Stephen Hemminger
In-Reply-To: <1482332986-7599-1-git-send-email-jblunck@infradead.org>
From: Stephen Hemminger <stephen@networkplumber.org>
Simplify later changes to eth_dev.
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
Acked-by: Jan Blunck <jblunck@infradead.org>
---
drivers/net/i40e/i40e_ethdev.c | 77 ++++++++++++++++++++++++---------------
drivers/net/i40e/i40e_ethdev.h | 3 ++
drivers/net/i40e/i40e_ethdev_vf.c | 58 ++++++++++++++++-------------
3 files changed, 83 insertions(+), 55 deletions(-)
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 67778ba..ba5795e 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -373,8 +373,8 @@ static void i40e_stat_update_48(struct i40e_hw *hw,
uint64_t *offset,
uint64_t *stat);
static void i40e_pf_config_irq0(struct i40e_hw *hw, bool no_queue);
-static void i40e_dev_interrupt_handler(
- __rte_unused struct rte_intr_handle *handle, void *param);
+static void i40e_dev_interrupt_handler(struct rte_intr_handle *handle,
+ void *param);
static int i40e_res_pool_init(struct i40e_res_pool_info *pool,
uint32_t base, uint32_t num);
static void i40e_res_pool_destroy(struct i40e_res_pool_info *pool);
@@ -907,7 +907,7 @@ is_floating_veb_supported(struct rte_devargs *devargs)
static void
config_floating_veb(struct rte_eth_dev *dev)
{
- struct rte_pci_device *pci_dev = dev->pci_dev;
+ struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -931,6 +931,7 @@ static int
eth_i40e_dev_init(struct rte_eth_dev *dev)
{
struct rte_pci_device *pci_dev;
+ struct rte_intr_handle *intr_handle;
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct i40e_vsi *vsi;
@@ -952,7 +953,8 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
i40e_set_tx_function(dev);
return 0;
}
- pci_dev = dev->pci_dev;
+ pci_dev = I40E_DEV_TO_PCI(dev);
+ intr_handle = &pci_dev->intr_handle;
rte_eth_copy_pci_info(dev, pci_dev);
@@ -1148,15 +1150,15 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
i40e_pf_host_init(dev);
/* register callback func to eal lib */
- rte_intr_callback_register(&(pci_dev->intr_handle),
- i40e_dev_interrupt_handler, (void *)dev);
+ rte_intr_callback_register(intr_handle,
+ i40e_dev_interrupt_handler, dev);
/* configure and enable device interrupt */
i40e_pf_config_irq0(hw, TRUE);
i40e_pf_enable_irq0(hw);
/* enable uio intr after callback register */
- rte_intr_enable(&(pci_dev->intr_handle));
+ rte_intr_enable(intr_handle);
/*
* Add an ethertype filter to drop all flow control frames transmitted
* from VSIs. By doing so, we stop VF from sending out PAUSE or PFC
@@ -1204,6 +1206,7 @@ static int
eth_i40e_dev_uninit(struct rte_eth_dev *dev)
{
struct rte_pci_device *pci_dev;
+ struct rte_intr_handle *intr_handle;
struct i40e_hw *hw;
struct i40e_filter_control_settings settings;
int ret;
@@ -1215,7 +1218,8 @@ eth_i40e_dev_uninit(struct rte_eth_dev *dev)
return 0;
hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- pci_dev = dev->pci_dev;
+ pci_dev = I40E_DEV_TO_PCI(dev);
+ intr_handle = &pci_dev->intr_handle;
if (hw->adapter_stopped == 0)
i40e_dev_close(dev);
@@ -1245,11 +1249,11 @@ eth_i40e_dev_uninit(struct rte_eth_dev *dev)
dev->data->mac_addrs = NULL;
/* disable uio intr before callback unregister */
- rte_intr_disable(&(pci_dev->intr_handle));
+ rte_intr_disable(intr_handle);
/* register callback func to eal lib */
- rte_intr_callback_unregister(&(pci_dev->intr_handle),
- i40e_dev_interrupt_handler, (void *)dev);
+ rte_intr_callback_unregister(intr_handle,
+ i40e_dev_interrupt_handler, dev);
return 0;
}
@@ -1335,7 +1339,8 @@ void
i40e_vsi_queues_unbind_intr(struct i40e_vsi *vsi)
{
struct rte_eth_dev *dev = vsi->adapter->eth_dev;
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
uint16_t msix_vect = vsi->msix_intr;
uint16_t i;
@@ -1448,7 +1453,8 @@ void
i40e_vsi_queues_bind_intr(struct i40e_vsi *vsi)
{
struct rte_eth_dev *dev = vsi->adapter->eth_dev;
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
uint16_t msix_vect = vsi->msix_intr;
uint16_t nb_msix = RTE_MIN(vsi->nb_msix, intr_handle->nb_efd);
@@ -1519,7 +1525,8 @@ static void
i40e_vsi_enable_queues_intr(struct i40e_vsi *vsi)
{
struct rte_eth_dev *dev = vsi->adapter->eth_dev;
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
uint16_t interval = i40e_calc_itr_interval(\
RTE_LIBRTE_I40E_ITR_INTERVAL);
@@ -1550,7 +1557,8 @@ static void
i40e_vsi_disable_queues_intr(struct i40e_vsi *vsi)
{
struct rte_eth_dev *dev = vsi->adapter->eth_dev;
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
uint16_t msix_intr, i;
@@ -1675,7 +1683,8 @@ i40e_dev_start(struct rte_eth_dev *dev)
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct i40e_vsi *main_vsi = pf->main_vsi;
int ret, i;
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
uint32_t intr_vector = 0;
hw->adapter_stopped = 0;
@@ -1808,7 +1817,8 @@ i40e_dev_stop(struct rte_eth_dev *dev)
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct i40e_vsi *main_vsi = pf->main_vsi;
struct i40e_mirror_rule *p_mirror;
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
int i;
/* Disable all queues */
@@ -1859,6 +1869,8 @@ i40e_dev_close(struct rte_eth_dev *dev)
{
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
uint32_t reg;
int i;
@@ -1870,7 +1882,7 @@ i40e_dev_close(struct rte_eth_dev *dev)
/* Disable interrupt */
i40e_pf_disable_irq0(hw);
- rte_intr_disable(&(dev->pci_dev->intr_handle));
+ rte_intr_disable(intr_handle);
/* shutdown and destroy the HMC */
i40e_shutdown_lan_hmc(hw);
@@ -2582,13 +2594,14 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct i40e_vsi *vsi = pf->main_vsi;
+ struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
dev_info->max_rx_queues = vsi->nb_qps;
dev_info->max_tx_queues = vsi->nb_qps;
dev_info->min_rx_bufsize = I40E_BUF_SIZE_MIN;
dev_info->max_rx_pktlen = I40E_FRAME_SIZE_MAX;
dev_info->max_mac_addrs = vsi->max_macaddrs;
- dev_info->max_vfs = dev->pci_dev->max_vfs;
+ dev_info->max_vfs = pci_dev->max_vfs;
dev_info->rx_offload_capa =
DEV_RX_OFFLOAD_VLAN_STRIP |
DEV_RX_OFFLOAD_QINQ_STRIP |
@@ -3490,9 +3503,10 @@ i40e_pf_parameter_init(struct rte_eth_dev *dev)
{
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+ struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
uint16_t qp_count = 0, vsi_count = 0;
- if (dev->pci_dev->max_vfs && !hw->func_caps.sr_iov_1_1) {
+ if (pci_dev->max_vfs && !hw->func_caps.sr_iov_1_1) {
PMD_INIT_LOG(ERR, "HW configuration doesn't support SRIOV");
return -EINVAL;
}
@@ -3533,10 +3547,10 @@ i40e_pf_parameter_init(struct rte_eth_dev *dev)
/* VF queue/VSI allocation */
pf->vf_qp_offset = pf->lan_qp_offset + pf->lan_nb_qps;
- if (hw->func_caps.sr_iov_1_1 && dev->pci_dev->max_vfs) {
+ if (hw->func_caps.sr_iov_1_1 && pci_dev->max_vfs) {
pf->flags |= I40E_FLAG_SRIOV;
pf->vf_nb_qps = RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF;
- pf->vf_num = dev->pci_dev->max_vfs;
+ pf->vf_num = pci_dev->max_vfs;
PMD_DRV_LOG(DEBUG, "%u VF VSIs, %u queues per VF VSI, "
"in total %u queues", pf->vf_num, pf->vf_nb_qps,
pf->vf_nb_qps * pf->vf_num);
@@ -5526,7 +5540,7 @@ i40e_dev_handle_aq_msg(struct rte_eth_dev *dev)
* void
*/
static void
-i40e_dev_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
+i40e_dev_interrupt_handler(struct rte_intr_handle *intr_handle,
void *param)
{
struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
@@ -5573,7 +5587,7 @@ i40e_dev_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
done:
/* Enable interrupt */
i40e_pf_enable_irq0(hw);
- rte_intr_enable(&(dev->pci_dev->intr_handle));
+ rte_intr_enable(intr_handle);
}
static int
@@ -8124,10 +8138,11 @@ i40e_dev_filter_ctrl(struct rte_eth_dev *dev,
static void
i40e_enable_extended_tag(struct rte_eth_dev *dev)
{
+ struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
uint32_t buf = 0;
int ret;
- ret = rte_eal_pci_read_config(dev->pci_dev, &buf, sizeof(buf),
+ ret = rte_eal_pci_read_config(pci_dev, &buf, sizeof(buf),
PCI_DEV_CAP_REG);
if (ret < 0) {
PMD_DRV_LOG(ERR, "Failed to read PCI offset 0x%x",
@@ -8140,7 +8155,7 @@ i40e_enable_extended_tag(struct rte_eth_dev *dev)
}
buf = 0;
- ret = rte_eal_pci_read_config(dev->pci_dev, &buf, sizeof(buf),
+ ret = rte_eal_pci_read_config(pci_dev, &buf, sizeof(buf),
PCI_DEV_CTRL_REG);
if (ret < 0) {
PMD_DRV_LOG(ERR, "Failed to read PCI offset 0x%x",
@@ -8152,7 +8167,7 @@ i40e_enable_extended_tag(struct rte_eth_dev *dev)
return;
}
buf |= PCI_DEV_CTRL_EXT_TAG_MASK;
- ret = rte_eal_pci_write_config(dev->pci_dev, &buf, sizeof(buf),
+ ret = rte_eal_pci_write_config(pci_dev, &buf, sizeof(buf),
PCI_DEV_CTRL_REG);
if (ret < 0) {
PMD_DRV_LOG(ERR, "Failed to write PCI offset 0x%x",
@@ -9555,7 +9570,8 @@ i40e_dev_get_dcb_info(struct rte_eth_dev *dev,
static int
i40e_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
{
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
uint16_t interval =
i40e_calc_itr_interval(RTE_LIBRTE_I40E_ITR_INTERVAL);
@@ -9580,7 +9596,7 @@ i40e_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT));
I40E_WRITE_FLUSH(hw);
- rte_intr_enable(&dev->pci_dev->intr_handle);
+ rte_intr_enable(&pci_dev->intr_handle);
return 0;
}
@@ -9588,7 +9604,8 @@ i40e_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
static int
i40e_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
{
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
uint16_t msix_intr;
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 298cef4..da8dd7e 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -617,6 +617,9 @@ void i40e_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
void i40e_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
struct rte_eth_txq_info *qinfo);
+#define I40E_DEV_TO_PCI(eth_dev) \
+ (eth_dev->pci_dev)
+
/* I40E_DEV_PRIVATE_TO */
#define I40E_DEV_PRIVATE_TO_PF(adapter) \
(&((struct i40e_adapter *)adapter)->pf)
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index aa306d6..a4d8a66 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -718,7 +718,8 @@ i40evf_config_irq_map(struct rte_eth_dev *dev)
uint8_t cmd_buffer[sizeof(struct i40e_virtchnl_irq_map_info) + \
sizeof(struct i40e_virtchnl_vector_map)];
struct i40e_virtchnl_irq_map_info *map_info;
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
uint32_t vector_id;
int i, err;
@@ -1401,7 +1402,7 @@ i40evf_handle_aq_msg(struct rte_eth_dev *dev)
* void
*/
static void
-i40evf_dev_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
+i40evf_dev_interrupt_handler(struct rte_intr_handle *intr_handle,
void *param)
{
struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
@@ -1431,15 +1432,15 @@ i40evf_dev_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
done:
i40evf_enable_irq0(hw);
- rte_intr_enable(&dev->pci_dev->intr_handle);
+ rte_intr_enable(intr_handle);
}
static int
i40evf_dev_init(struct rte_eth_dev *eth_dev)
{
- struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(\
- eth_dev->data->dev_private);
- struct rte_pci_device *pci_dev = eth_dev->pci_dev;
+ struct i40e_hw *hw
+ = I40E_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
+ struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(eth_dev);
PMD_INIT_FUNC_TRACE();
@@ -1458,15 +1459,15 @@ i40evf_dev_init(struct rte_eth_dev *eth_dev)
return 0;
}
- rte_eth_copy_pci_info(eth_dev, eth_dev->pci_dev);
+ rte_eth_copy_pci_info(eth_dev, pci_dev);
- hw->vendor_id = eth_dev->pci_dev->id.vendor_id;
- hw->device_id = eth_dev->pci_dev->id.device_id;
- hw->subsystem_vendor_id = eth_dev->pci_dev->id.subsystem_vendor_id;
- hw->subsystem_device_id = eth_dev->pci_dev->id.subsystem_device_id;
- hw->bus.device = eth_dev->pci_dev->addr.devid;
- hw->bus.func = eth_dev->pci_dev->addr.function;
- hw->hw_addr = (void *)eth_dev->pci_dev->mem_resource[0].addr;
+ hw->vendor_id = pci_dev->id.vendor_id;
+ hw->device_id = pci_dev->id.device_id;
+ hw->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id;
+ hw->subsystem_device_id = pci_dev->id.subsystem_device_id;
+ hw->bus.device = pci_dev->addr.devid;
+ hw->bus.func = pci_dev->addr.function;
+ hw->hw_addr = (void *)pci_dev->mem_resource[0].addr;
hw->adapter_stopped = 0;
if(i40evf_init_vf(eth_dev) != 0) {
@@ -1853,7 +1854,8 @@ i40evf_enable_queues_intr(struct rte_eth_dev *dev)
{
struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
if (!rte_intr_allow_others(intr_handle)) {
I40E_WRITE_REG(hw,
@@ -1885,7 +1887,8 @@ i40evf_disable_queues_intr(struct rte_eth_dev *dev)
{
struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
if (!rte_intr_allow_others(intr_handle)) {
I40E_WRITE_REG(hw, I40E_VFINT_DYN_CTL01,
@@ -1911,7 +1914,8 @@ i40evf_disable_queues_intr(struct rte_eth_dev *dev)
static int
i40evf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
{
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
uint16_t interval =
i40e_calc_itr_interval(RTE_LIBRTE_I40E_ITR_INTERVAL);
@@ -1937,7 +1941,7 @@ i40evf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
I40EVF_WRITE_FLUSH(hw);
- rte_intr_enable(&dev->pci_dev->intr_handle);
+ rte_intr_enable(&pci_dev->intr_handle);
return 0;
}
@@ -1945,7 +1949,8 @@ i40evf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
static int
i40evf_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
{
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
uint16_t msix_intr;
@@ -2025,7 +2030,8 @@ i40evf_dev_start(struct rte_eth_dev *dev)
{
struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
uint32_t intr_vector = 0;
PMD_INIT_FUNC_TRACE();
@@ -2090,7 +2096,8 @@ i40evf_dev_start(struct rte_eth_dev *dev)
static void
i40evf_dev_stop(struct rte_eth_dev *dev)
{
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
PMD_INIT_FUNC_TRACE();
@@ -2285,7 +2292,8 @@ static void
i40evf_dev_close(struct rte_eth_dev *dev)
{
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- struct rte_pci_device *pci_dev = dev->pci_dev;
+ struct rte_pci_device *pci_dev = I40E_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
i40evf_dev_stop(dev);
hw->adapter_stopped = 1;
@@ -2293,11 +2301,11 @@ i40evf_dev_close(struct rte_eth_dev *dev)
i40evf_reset_vf(hw);
i40e_shutdown_adminq(hw);
/* disable uio intr before callback unregister */
- rte_intr_disable(&pci_dev->intr_handle);
+ rte_intr_disable(intr_handle);
/* unregister callback func from eal lib */
- rte_intr_callback_unregister(&pci_dev->intr_handle,
- i40evf_dev_interrupt_handler, (void *)dev);
+ rte_intr_callback_unregister(intr_handle,
+ i40evf_dev_interrupt_handler, dev);
i40evf_disable_irq0(hw);
}
--
2.7.4
^ permalink raw reply related
* [PATCH v4 08/23] broadcom: localize mapping from eth_dev to pci
From: Jan Blunck @ 2016-12-21 15:09 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, shreyansh.jain, david.marchand,
Stephen Hemminger
In-Reply-To: <1482332986-7599-1-git-send-email-jblunck@infradead.org>
From: Stephen Hemminger <stephen@networkplumber.org>
Use existing information about pci and interrupt handle to minimize
the number of places that assume eth_dev contains pci_device
information.
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
Acked-by: Jan Blunck <jblunck@infradead.org>
---
drivers/net/bnxt/bnxt_ethdev.c | 22 +++++++++++++---------
drivers/net/bnxt/bnxt_ring.c | 16 ++++++----------
2 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 035fe07..529b6c8 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -743,6 +743,8 @@ static int bnxt_reta_query_op(struct rte_eth_dev *eth_dev,
{
struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
+ struct rte_intr_handle *intr_handle
+ = &bp->pdev->intr_handle;
/* Retrieve from the default VNIC */
if (!vnic)
@@ -759,7 +761,7 @@ static int bnxt_reta_query_op(struct rte_eth_dev *eth_dev,
/* EW - need to revisit here copying from u64 to u16 */
memcpy(reta_conf, vnic->rss_table, reta_size);
- if (rte_intr_allow_others(ð_dev->pci_dev->intr_handle)) {
+ if (rte_intr_allow_others(intr_handle)) {
if (eth_dev->data->dev_conf.intr_conf.lsc != 0)
bnxt_dev_lsc_intr_setup(eth_dev);
}
@@ -1009,11 +1011,12 @@ static bool bnxt_vf_pciid(uint16_t id)
static int bnxt_init_board(struct rte_eth_dev *eth_dev)
{
- int rc;
struct bnxt *bp = eth_dev->data->dev_private;
+ struct rte_pci_device *pci_dev = eth_dev->pci_dev;
+ int rc;
/* enable device (incl. PCI PM wakeup), and bus-mastering */
- if (!eth_dev->pci_dev->mem_resource[0].addr) {
+ if (!pci_dev->mem_resource[0].addr) {
RTE_LOG(ERR, PMD,
"Cannot find PCI device base address, aborting\n");
rc = -ENODEV;
@@ -1021,9 +1024,9 @@ static int bnxt_init_board(struct rte_eth_dev *eth_dev)
}
bp->eth_dev = eth_dev;
- bp->pdev = eth_dev->pci_dev;
+ bp->pdev = pci_dev;
- bp->bar0 = (void *)eth_dev->pci_dev->mem_resource[0].addr;
+ bp->bar0 = (void *)pci_dev->mem_resource[0].addr;
if (!bp->bar0) {
RTE_LOG(ERR, PMD, "Cannot map device registers, aborting\n");
rc = -ENOMEM;
@@ -1043,6 +1046,7 @@ static int bnxt_init_board(struct rte_eth_dev *eth_dev)
static int
bnxt_dev_init(struct rte_eth_dev *eth_dev)
{
+ struct rte_pci_device *pci_dev = eth_dev->pci_dev;
static int version_printed;
struct bnxt *bp;
int rc;
@@ -1050,10 +1054,10 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
if (version_printed++ == 0)
RTE_LOG(INFO, PMD, "%s", bnxt_version);
- rte_eth_copy_pci_info(eth_dev, eth_dev->pci_dev);
+ rte_eth_copy_pci_info(eth_dev, pci_dev);
bp = eth_dev->data->dev_private;
- if (bnxt_vf_pciid(eth_dev->pci_dev->id.device_id))
+ if (bnxt_vf_pciid(pci_dev->id.device_id))
bp->flags |= BNXT_FLAG_VF;
rc = bnxt_init_board(eth_dev);
@@ -1121,8 +1125,8 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
RTE_LOG(INFO, PMD,
DRV_MODULE_NAME " found at mem %" PRIx64 ", node addr %pM\n",
- eth_dev->pci_dev->mem_resource[0].phys_addr,
- eth_dev->pci_dev->mem_resource[0].addr);
+ pci_dev->mem_resource[0].phys_addr,
+ pci_dev->mem_resource[0].addr);
bp->dev_stopped = 0;
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index 3f81ffc..0fafa13 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -209,6 +209,7 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
*/
int bnxt_alloc_hwrm_rings(struct bnxt *bp)
{
+ struct rte_pci_device *pci_dev = bp->pdev;
unsigned int i;
int rc = 0;
@@ -222,8 +223,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
0, HWRM_NA_SIGNATURE);
if (rc)
goto err_out;
- cpr->cp_doorbell =
- (char *)bp->eth_dev->pci_dev->mem_resource[2].addr;
+ cpr->cp_doorbell = pci_dev->mem_resource[2].addr;
B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
bp->grp_info[0].cp_fw_ring_id = cp_ring->fw_ring_id;
}
@@ -242,8 +242,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
idx, HWRM_NA_SIGNATURE);
if (rc)
goto err_out;
- cpr->cp_doorbell =
- (char *)bp->eth_dev->pci_dev->mem_resource[2].addr +
+ cpr->cp_doorbell = (char *)pci_dev->mem_resource[2].addr +
idx * 0x80;
bp->grp_info[idx].cp_fw_ring_id = cp_ring->fw_ring_id;
B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
@@ -255,8 +254,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
if (rc)
goto err_out;
rxr->rx_prod = 0;
- rxr->rx_doorbell =
- (char *)bp->eth_dev->pci_dev->mem_resource[2].addr +
+ rxr->rx_doorbell = (char *)pci_dev->mem_resource[2].addr +
idx * 0x80;
bp->grp_info[idx].rx_fw_ring_id = ring->fw_ring_id;
B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
@@ -283,8 +281,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
if (rc)
goto err_out;
- cpr->cp_doorbell =
- (char *)bp->eth_dev->pci_dev->mem_resource[2].addr +
+ cpr->cp_doorbell = (char *)pci_dev->mem_resource[2].addr +
idx * 0x80;
bp->grp_info[idx].cp_fw_ring_id = cp_ring->fw_ring_id;
B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
@@ -296,8 +293,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
if (rc)
goto err_out;
- txr->tx_doorbell =
- (char *)bp->eth_dev->pci_dev->mem_resource[2].addr +
+ txr->tx_doorbell = (char *)pci_dev->mem_resource[2].addr +
idx * 0x80;
}
--
2.7.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox