* [dpdk-dev] [PATCH] app/flow-perf: added option to support flow priority
@ 2021-10-29 4:08 psatheesh
2021-11-01 9:06 ` Wisam Monther
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: psatheesh @ 2021-10-29 4:08 UTC (permalink / raw)
To: Wisam Jaddo; +Cc: dev, Satheesh Paul
From: Satheesh Paul <psatheesh@marvell.com>
Added support to specify maximum flow priority option. When
this option is given, each flow will be created with the
priority attribute and the priority will be random between
0 to max-flow-priority. This is useful to measure performance
on NICs which may have to rearrange flows to honor flow priority.
Removed the lower limit of 100000 flows per batch.
Signed-off-by: Satheesh Paul <psatheesh@marvell.com>
---
app/test-flow-perf/flow_gen.c | 7 ++++--
app/test-flow-perf/flow_gen.h | 1 +
app/test-flow-perf/main.c | 44 +++++++++++++++++++++-------------
doc/guides/tools/flow-perf.rst | 5 ++++
4 files changed, 38 insertions(+), 19 deletions(-)
diff --git a/app/test-flow-perf/flow_gen.c b/app/test-flow-perf/flow_gen.c
index 51871dbfdc..414ec0bc5e 100644
--- a/app/test-flow-perf/flow_gen.c
+++ b/app/test-flow-perf/flow_gen.c
@@ -18,7 +18,7 @@
static void
fill_attributes(struct rte_flow_attr *attr,
- uint64_t *flow_attrs, uint16_t group)
+ uint64_t *flow_attrs, uint16_t group, uint8_t max_priority)
{
uint8_t i;
for (i = 0; i < MAX_ATTRS_NUM; i++) {
@@ -32,6 +32,8 @@ fill_attributes(struct rte_flow_attr *attr,
attr->transfer = 1;
}
attr->group = group;
+ if (max_priority)
+ attr->priority = rte_rand_max(max_priority);
}
struct rte_flow *
@@ -48,6 +50,7 @@ generate_flow(uint16_t port_id,
uint8_t core_idx,
uint8_t rx_queues_count,
bool unique_data,
+ uint8_t max_priority,
struct rte_flow_error *error)
{
struct rte_flow_attr attr;
@@ -59,7 +62,7 @@ generate_flow(uint16_t port_id,
memset(actions, 0, sizeof(actions));
memset(&attr, 0, sizeof(struct rte_flow_attr));
- fill_attributes(&attr, flow_attrs, group);
+ fill_attributes(&attr, flow_attrs, group, max_priority);
fill_actions(actions, flow_actions,
outer_ip_src, next_table, hairpinq,
diff --git a/app/test-flow-perf/flow_gen.h b/app/test-flow-perf/flow_gen.h
index 1118a9fc14..40eeceae6e 100644
--- a/app/test-flow-perf/flow_gen.h
+++ b/app/test-flow-perf/flow_gen.h
@@ -37,6 +37,7 @@ generate_flow(uint16_t port_id,
uint8_t core_idx,
uint8_t rx_queues_count,
bool unique_data,
+ uint8_t max_priority,
struct rte_flow_error *error);
#endif /* FLOW_PERF_FLOW_GEN */
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index 3ebc025fb2..1d91f308fd 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -77,6 +77,7 @@ static uint32_t rules_count;
static uint32_t rules_batch;
static uint32_t hairpin_queues_num; /* total hairpin q number - default: 0 */
static uint32_t nb_lcores;
+static uint8_t max_priority;
#define MAX_PKT_BURST 32
#define LCORE_MODE_PKT 1
@@ -140,6 +141,7 @@ usage(char *progname)
printf(" --enable-fwd: To enable packets forwarding"
" after insertion\n");
printf(" --portmask=N: hexadecimal bitmask of ports used\n");
+ printf(" --max-priority=N: Maximum priority level for flows\n");
printf(" --unique-data: flag to set using unique data for all"
" actions that support data, such as header modify and encap actions\n");
@@ -589,6 +591,7 @@ args_parse(int argc, char **argv)
{ "unique-data", 0, 0, 0 },
{ "portmask", 1, 0, 0 },
{ "cores", 1, 0, 0 },
+ { "max-priority", 1, 0, 0 },
{ "meter-profile-alg", 1, 0, 0 },
{ "rxq", 1, 0, 0 },
{ "txq", 1, 0, 0 },
@@ -767,26 +770,21 @@ args_parse(int argc, char **argv)
/* Control */
if (strcmp(lgopts[opt_idx].name,
"rules-batch") == 0) {
- n = atoi(optarg);
- if (n >= DEFAULT_RULES_BATCH)
- rules_batch = n;
- else {
- rte_exit(EXIT_FAILURE,
- "rules_batch should be >= %d\n",
- DEFAULT_RULES_BATCH);
- }
+ rules_batch = atoi(optarg);
}
if (strcmp(lgopts[opt_idx].name,
"rules-count") == 0) {
- n = atoi(optarg);
- if (n >= (int) rules_batch)
- rules_count = n;
- else {
- rte_exit(EXIT_FAILURE,
- "rules_count should be >= %d\n",
- rules_batch);
+ rules_count = atoi(optarg);
+ }
+ if (strcmp(lgopts[opt_idx].name, "max-priority") == 0) {
+ max_priority = atoi(optarg);
+ if (max_priority > 32) {
+ rte_exit(
+ EXIT_FAILURE,
+ "max-priority cannot be > 32\n");
}
}
+
if (strcmp(lgopts[opt_idx].name,
"dump-iterations") == 0)
dump_iterations = true;
@@ -862,6 +860,16 @@ args_parse(int argc, char **argv)
break;
}
}
+ if (rules_count % rules_batch != 0) {
+ rte_exit(EXIT_FAILURE,
+ "rules_count %% rules_batch should be 0\n");
+ }
+ if (rules_count / rules_batch > MAX_BATCHES_COUNT) {
+ rte_exit(EXIT_FAILURE,
+ "rules_count / rules_batch should be <= %d\n",
+ MAX_BATCHES_COUNT);
+ }
+
printf("end_flow\n");
}
@@ -1227,7 +1235,7 @@ insert_flows(int port_id, uint8_t core_id)
flow = generate_flow(port_id, 0, flow_attrs,
global_items, global_actions,
flow_group, 0, 0, 0, 0, core_id, rx_queues_count,
- unique_data, &error);
+ unique_data, max_priority, &error);
if (flow == NULL) {
print_flow_error(error);
@@ -1244,7 +1252,7 @@ insert_flows(int port_id, uint8_t core_id)
hairpin_queues_num,
encap_data, decap_data,
core_id, rx_queues_count,
- unique_data, &error);
+ unique_data, max_priority, &error);
if (!counter) {
first_flow_latency = (double) (rte_get_timer_cycles() - start_batch);
@@ -1975,6 +1983,8 @@ main(int argc, char **argv)
printf(":: Flows Count per port: %d\n\n", rules_count);
+ rte_srand(rte_rdtsc());
+
if (has_meter())
create_meter_profile();
rte_eal_mp_remote_launch(run_rte_flow_handler_cores, NULL, CALL_MAIN);
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index 0855f88689..0dfdeab832 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -100,6 +100,11 @@ The command line options are:
Set the number of needed cores to insert/delete rte_flow rules.
Default cores count is 1.
+* ``--max-priority=N``
+ Maximum priority level for flows. Flows will be created with the
+ priority attribute set randomly between 0 to N - 1.
+ Default is 0 and maximum is 32.
+
* ``--meter-profile-alg``
Set the traffic metering algorithm.
Example: meter-profile-alg=srtcmp, default algorithm is srtcm_rfc2697
--
2.25.4
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [dpdk-dev] [PATCH] app/flow-perf: added option to support flow priority
2021-10-29 4:08 [dpdk-dev] [PATCH] app/flow-perf: added option to support flow priority psatheesh
@ 2021-11-01 9:06 ` Wisam Monther
2021-11-02 10:39 ` Satheesh Paul
2021-11-02 10:39 ` [dpdk-dev] [PATCH v2] " psatheesh
2021-11-02 10:50 ` [dpdk-dev] [PATCH v3] " psatheesh
2 siblings, 1 reply; 7+ messages in thread
From: Wisam Monther @ 2021-11-01 9:06 UTC (permalink / raw)
To: psatheesh; +Cc: dev, Asaf Penso
Hi,
Please see my inline comments, thanks 😊
> -----Original Message-----
> From: psatheesh@marvell.com <psatheesh@marvell.com>
> Sent: Friday, October 29, 2021 7:09 AM
> To: Wisam Monther <wisamm@nvidia.com>
> Cc: dev@dpdk.org; Satheesh Paul <psatheesh@marvell.com>
> Subject: [dpdk-dev] [PATCH] app/flow-perf: added option to support flow
> priority
>
> From: Satheesh Paul <psatheesh@marvell.com>
>
> Added support to specify maximum flow priority option. When this option is
> given, each flow will be created with the priority attribute and the priority will
> be random between
> 0 to max-flow-priority. This is useful to measure performance on NICs which
> may have to rearrange flows to honor flow priority.
>
> Removed the lower limit of 100000 flows per batch.
>
> Signed-off-by: Satheesh Paul <psatheesh@marvell.com>
> ---
> app/test-flow-perf/flow_gen.c | 7 ++++-- app/test-flow-perf/flow_gen.h
> | 1 +
> app/test-flow-perf/main.c | 44 +++++++++++++++++++++-------------
> doc/guides/tools/flow-perf.rst | 5 ++++
> 4 files changed, 38 insertions(+), 19 deletions(-)
>
> diff --git a/app/test-flow-perf/flow_gen.c b/app/test-flow-perf/flow_gen.c
> index 51871dbfdc..414ec0bc5e 100644
> --- a/app/test-flow-perf/flow_gen.c
> +++ b/app/test-flow-perf/flow_gen.c
> @@ -18,7 +18,7 @@
>
> static void
> fill_attributes(struct rte_flow_attr *attr,
> - uint64_t *flow_attrs, uint16_t group)
> + uint64_t *flow_attrs, uint16_t group, uint8_t max_priority)
> {
> uint8_t i;
> for (i = 0; i < MAX_ATTRS_NUM; i++) {
> @@ -32,6 +32,8 @@ fill_attributes(struct rte_flow_attr *attr,
> attr->transfer = 1;
> }
> attr->group = group;
> + if (max_priority)
> + attr->priority = rte_rand_max(max_priority);
No need to do this, since it's static and default is zero you can always set it without the condition
> }
>
> struct rte_flow *
> @@ -48,6 +50,7 @@ generate_flow(uint16_t port_id,
> uint8_t core_idx,
> uint8_t rx_queues_count,
> bool unique_data,
> + uint8_t max_priority,
--max-priority=N is good, but I think to reflect the exact usage of it we need something like:
--random-priority=lower_hand-upper_hand
That do random prio from lower to upper.
> struct rte_flow_error *error)
> {
> struct rte_flow_attr attr;
> @@ -59,7 +62,7 @@ generate_flow(uint16_t port_id,
> memset(actions, 0, sizeof(actions));
> memset(&attr, 0, sizeof(struct rte_flow_attr));
>
> - fill_attributes(&attr, flow_attrs, group);
> + fill_attributes(&attr, flow_attrs, group, max_priority);
>
> fill_actions(actions, flow_actions,
> outer_ip_src, next_table, hairpinq,
> diff --git a/app/test-flow-perf/flow_gen.h b/app/test-flow-perf/flow_gen.h
> index 1118a9fc14..40eeceae6e 100644
> --- a/app/test-flow-perf/flow_gen.h
> +++ b/app/test-flow-perf/flow_gen.h
> @@ -37,6 +37,7 @@ generate_flow(uint16_t port_id,
> uint8_t core_idx,
> uint8_t rx_queues_count,
> bool unique_data,
> + uint8_t max_priority,
> struct rte_flow_error *error);
>
> #endif /* FLOW_PERF_FLOW_GEN */
> diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c index
> 3ebc025fb2..1d91f308fd 100644
> --- a/app/test-flow-perf/main.c
> +++ b/app/test-flow-perf/main.c
> @@ -77,6 +77,7 @@ static uint32_t rules_count; static uint32_t rules_batch;
> static uint32_t hairpin_queues_num; /* total hairpin q number - default: 0 */
> static uint32_t nb_lcores;
> +static uint8_t max_priority;
>
> #define MAX_PKT_BURST 32
> #define LCORE_MODE_PKT 1
> @@ -140,6 +141,7 @@ usage(char *progname)
> printf(" --enable-fwd: To enable packets forwarding"
> " after insertion\n");
> printf(" --portmask=N: hexadecimal bitmask of ports used\n");
> + printf(" --max-priority=N: Maximum priority level for flows\n");
It talks also about random values, you need to mention that it will do the random also.
> printf(" --unique-data: flag to set using unique data for all"
> " actions that support data, such as header modify and encap
> actions\n");
>
> @@ -589,6 +591,7 @@ args_parse(int argc, char **argv)
> { "unique-data", 0, 0, 0 },
> { "portmask", 1, 0, 0 },
> { "cores", 1, 0, 0 },
> + { "max-priority", 1, 0, 0 },
> { "meter-profile-alg", 1, 0, 0 },
> { "rxq", 1, 0, 0 },
> { "txq", 1, 0, 0 },
> @@ -767,26 +770,21 @@ args_parse(int argc, char **argv)
> /* Control */
> if (strcmp(lgopts[opt_idx].name,
> "rules-batch") == 0) {
> - n = atoi(optarg);
> - if (n >= DEFAULT_RULES_BATCH)
> - rules_batch = n;
> - else {
> - rte_exit(EXIT_FAILURE,
> - "rules_batch should be >=
> %d\n",
> - DEFAULT_RULES_BATCH);
> - }
> + rules_batch = atoi(optarg);
> }
> if (strcmp(lgopts[opt_idx].name,
> "rules-count") == 0) {
> - n = atoi(optarg);
> - if (n >= (int) rules_batch)
> - rules_count = n;
> - else {
> - rte_exit(EXIT_FAILURE,
> - "rules_count should be >=
> %d\n",
> - rules_batch);
> + rules_count = atoi(optarg);
> + }
> + if (strcmp(lgopts[opt_idx].name, "max-priority") ==
> 0) {
> + max_priority = atoi(optarg);
> + if (max_priority > 32) {
> + rte_exit(
> + EXIT_FAILURE,
> + "max-priority cannot be >
> 32\n");
The 32 is some PMD limitation? I don't think all PMDs will have the same limitation, please remove this condition.
> }
> }
> +
> if (strcmp(lgopts[opt_idx].name,
> "dump-iterations") == 0)
> dump_iterations = true;
> @@ -862,6 +860,16 @@ args_parse(int argc, char **argv)
> break;
> }
> }
> + if (rules_count % rules_batch != 0) {
> + rte_exit(EXIT_FAILURE,
> + "rules_count %% rules_batch should be 0\n");
> + }
> + if (rules_count / rules_batch > MAX_BATCHES_COUNT) {
> + rte_exit(EXIT_FAILURE,
> + "rules_count / rules_batch should be <= %d\n",
> + MAX_BATCHES_COUNT);
> + }
> +
Thanks for this 😊
> printf("end_flow\n");
> }
>
> @@ -1227,7 +1235,7 @@ insert_flows(int port_id, uint8_t core_id)
> flow = generate_flow(port_id, 0, flow_attrs,
> global_items, global_actions,
> flow_group, 0, 0, 0, 0, core_id, rx_queues_count,
> - unique_data, &error);
> + unique_data, max_priority, &error);
>
> if (flow == NULL) {
> print_flow_error(error);
> @@ -1244,7 +1252,7 @@ insert_flows(int port_id, uint8_t core_id)
> hairpin_queues_num,
> encap_data, decap_data,
> core_id, rx_queues_count,
> - unique_data, &error);
> + unique_data, max_priority, &error);
>
> if (!counter) {
> first_flow_latency = (double)
> (rte_get_timer_cycles() - start_batch); @@ -1975,6 +1983,8 @@ main(int
> argc, char **argv)
>
> printf(":: Flows Count per port: %d\n\n", rules_count);
>
> + rte_srand(rte_rdtsc());
This doesn't make sense, the set for pseudo random generator need to store the seed to make sure that you can reproduce the
Same numbers.
The current usage is per core and also it passes rte_rdtsc() which is not pre-known value.
I suggest to pass the seed from the same parameter:
--random-priority=lower-upper;seed
Otherwise you cannot replicate the same test case twice.
> +
> if (has_meter())
> create_meter_profile();
> rte_eal_mp_remote_launch(run_rte_flow_handler_cores, NULL,
> CALL_MAIN); diff --git a/doc/guides/tools/flow-perf.rst
> b/doc/guides/tools/flow-perf.rst index 0855f88689..0dfdeab832 100644
> --- a/doc/guides/tools/flow-perf.rst
> +++ b/doc/guides/tools/flow-perf.rst
> @@ -100,6 +100,11 @@ The command line options are:
> Set the number of needed cores to insert/delete rte_flow rules.
> Default cores count is 1.
>
> +* ``--max-priority=N``
> + Maximum priority level for flows. Flows will be created with the
> + priority attribute set randomly between 0 to N - 1.
> + Default is 0 and maximum is 32.
I think the max here should be removed also.
> +
> * ``--meter-profile-alg``
> Set the traffic metering algorithm.
> Example: meter-profile-alg=srtcmp, default algorithm is
> srtcm_rfc2697
> --
> 2.25.4
BRs,
Wisam Jaddo
^ permalink raw reply [flat|nested] 7+ messages in thread
* [dpdk-dev] [PATCH v2] app/flow-perf: added option to support flow priority
2021-10-29 4:08 [dpdk-dev] [PATCH] app/flow-perf: added option to support flow priority psatheesh
2021-11-01 9:06 ` Wisam Monther
@ 2021-11-02 10:39 ` psatheesh
2021-11-02 10:50 ` [dpdk-dev] [PATCH v3] " psatheesh
2 siblings, 0 replies; 7+ messages in thread
From: psatheesh @ 2021-11-02 10:39 UTC (permalink / raw)
To: Wisam Jaddo; +Cc: dev, Satheesh Paul
From: Satheesh Paul <psatheesh@marvell.com>
Added support to create flows with priority attribute set
randomly between 0 and a user supplied maximum value. This
is useful to measure performance on NICs which may have to
rearrange flows to honor flow priority.
Removed the lower limit of 100000 flows per batch.
Signed-off-by: Satheesh Paul <psatheesh@marvell.com>
---
v2:
* Changed "--max-priority" to "--random-priority".
* Added support to take seed for pseudo-random number generator.
* Updated documentation for the above.
app/test-flow-perf/flow_gen.c | 6 ++--
app/test-flow-perf/flow_gen.h | 1 +
app/test-flow-perf/main.c | 56 +++++++++++++++++++++++-----------
doc/guides/tools/flow-perf.rst | 4 +++
4 files changed, 47 insertions(+), 20 deletions(-)
diff --git a/app/test-flow-perf/flow_gen.c b/app/test-flow-perf/flow_gen.c
index 51871dbfdc..4eea8fb7c5 100644
--- a/app/test-flow-perf/flow_gen.c
+++ b/app/test-flow-perf/flow_gen.c
@@ -18,7 +18,7 @@
static void
fill_attributes(struct rte_flow_attr *attr,
- uint64_t *flow_attrs, uint16_t group)
+ uint64_t *flow_attrs, uint16_t group, uint8_t max_priority)
{
uint8_t i;
for (i = 0; i < MAX_ATTRS_NUM; i++) {
@@ -32,6 +32,7 @@ fill_attributes(struct rte_flow_attr *attr,
attr->transfer = 1;
}
attr->group = group;
+ attr->priority = rte_rand_max(max_priority);
}
struct rte_flow *
@@ -48,6 +49,7 @@ generate_flow(uint16_t port_id,
uint8_t core_idx,
uint8_t rx_queues_count,
bool unique_data,
+ uint8_t max_priority,
struct rte_flow_error *error)
{
struct rte_flow_attr attr;
@@ -59,7 +61,7 @@ generate_flow(uint16_t port_id,
memset(actions, 0, sizeof(actions));
memset(&attr, 0, sizeof(struct rte_flow_attr));
- fill_attributes(&attr, flow_attrs, group);
+ fill_attributes(&attr, flow_attrs, group, max_priority);
fill_actions(actions, flow_actions,
outer_ip_src, next_table, hairpinq,
diff --git a/app/test-flow-perf/flow_gen.h b/app/test-flow-perf/flow_gen.h
index 1118a9fc14..40eeceae6e 100644
--- a/app/test-flow-perf/flow_gen.h
+++ b/app/test-flow-perf/flow_gen.h
@@ -37,6 +37,7 @@ generate_flow(uint16_t port_id,
uint8_t core_idx,
uint8_t rx_queues_count,
bool unique_data,
+ uint8_t max_priority,
struct rte_flow_error *error);
#endif /* FLOW_PERF_FLOW_GEN */
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index 3ebc025fb2..c49c5e44e6 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -77,6 +77,8 @@ static uint32_t rules_count;
static uint32_t rules_batch;
static uint32_t hairpin_queues_num; /* total hairpin q number - default: 0 */
static uint32_t nb_lcores;
+static uint8_t max_priority;
+static uint32_t rand_seed;
#define MAX_PKT_BURST 32
#define LCORE_MODE_PKT 1
@@ -140,6 +142,8 @@ usage(char *progname)
printf(" --enable-fwd: To enable packets forwarding"
" after insertion\n");
printf(" --portmask=N: hexadecimal bitmask of ports used\n");
+ printf( " --random-priority=N,S: Use random priority levels from 0 to"
+ "(N - 1) for flows and S as seed for pseudo-random number generator\n");
printf(" --unique-data: flag to set using unique data for all"
" actions that support data, such as header modify and encap actions\n");
@@ -238,8 +242,9 @@ usage(char *progname)
static void
args_parse(int argc, char **argv)
{
- uint64_t pm;
+ uint64_t pm, seed;
char **argvopt;
+ uint32_t prio;
char *token;
char *end;
int n, opt;
@@ -589,6 +594,7 @@ args_parse(int argc, char **argv)
{ "unique-data", 0, 0, 0 },
{ "portmask", 1, 0, 0 },
{ "cores", 1, 0, 0 },
+ { "random-priority", 1, 0, 0 },
{ "meter-profile-alg", 1, 0, 0 },
{ "rxq", 1, 0, 0 },
{ "txq", 1, 0, 0 },
@@ -767,25 +773,27 @@ args_parse(int argc, char **argv)
/* Control */
if (strcmp(lgopts[opt_idx].name,
"rules-batch") == 0) {
- n = atoi(optarg);
- if (n >= DEFAULT_RULES_BATCH)
- rules_batch = n;
- else {
- rte_exit(EXIT_FAILURE,
- "rules_batch should be >= %d\n",
- DEFAULT_RULES_BATCH);
- }
+ rules_batch = atoi(optarg);
}
if (strcmp(lgopts[opt_idx].name,
"rules-count") == 0) {
- n = atoi(optarg);
- if (n >= (int) rules_batch)
- rules_count = n;
- else {
+ rules_count = atoi(optarg);
+ }
+ if (strcmp(lgopts[opt_idx].name, "random-priority") == 0) {
+ end = NULL;
+ prio = strtol(optarg, &end, 10);
+ if ((optarg[0] == '\0') || (end == NULL))
rte_exit(EXIT_FAILURE,
- "rules_count should be >= %d\n",
- rules_batch);
- }
+ "Invalid value for "
+ "random-priority\n");
+ max_priority = prio;
+ token = end + 1;
+ seed = strtoll(token, &end, 10);
+ if ((token[0] == '\0') || (*end != '\0'))
+ rte_exit(EXIT_FAILURE,
+ "Invalid value for "
+ "random-priority\n");
+ rand_seed = seed;
}
if (strcmp(lgopts[opt_idx].name,
"dump-iterations") == 0)
@@ -862,6 +870,16 @@ args_parse(int argc, char **argv)
break;
}
}
+ if (rules_count % rules_batch != 0) {
+ rte_exit(EXIT_FAILURE,
+ "rules_count %% rules_batch should be 0\n");
+ }
+ if (rules_count / rules_batch > MAX_BATCHES_COUNT) {
+ rte_exit(EXIT_FAILURE,
+ "rules_count / rules_batch should be <= %d\n",
+ MAX_BATCHES_COUNT);
+ }
+
printf("end_flow\n");
}
@@ -1227,7 +1245,7 @@ insert_flows(int port_id, uint8_t core_id)
flow = generate_flow(port_id, 0, flow_attrs,
global_items, global_actions,
flow_group, 0, 0, 0, 0, core_id, rx_queues_count,
- unique_data, &error);
+ unique_data, max_priority, &error);
if (flow == NULL) {
print_flow_error(error);
@@ -1244,7 +1262,7 @@ insert_flows(int port_id, uint8_t core_id)
hairpin_queues_num,
encap_data, decap_data,
core_id, rx_queues_count,
- unique_data, &error);
+ unique_data, max_priority, &error);
if (!counter) {
first_flow_latency = (double) (rte_get_timer_cycles() - start_batch);
@@ -1975,6 +1993,8 @@ main(int argc, char **argv)
printf(":: Flows Count per port: %d\n\n", rules_count);
+ rte_srand(rand_seed);
+
if (has_meter())
create_meter_profile();
rte_eal_mp_remote_launch(run_rte_flow_handler_cores, NULL, CALL_MAIN);
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index 0855f88689..b57452662f 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -100,6 +100,10 @@ The command line options are:
Set the number of needed cores to insert/delete rte_flow rules.
Default cores count is 1.
+* ``--random-priority=N,S``
+ Create flows with the priority attribute set randomly between 0 to N - 1
+ and use S as seed for the pseudo-random number generator.
+
* ``--meter-profile-alg``
Set the traffic metering algorithm.
Example: meter-profile-alg=srtcmp, default algorithm is srtcm_rfc2697
--
2.25.4
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [dpdk-dev] [PATCH] app/flow-perf: added option to support flow priority
2021-11-01 9:06 ` Wisam Monther
@ 2021-11-02 10:39 ` Satheesh Paul
0 siblings, 0 replies; 7+ messages in thread
From: Satheesh Paul @ 2021-11-02 10:39 UTC (permalink / raw)
To: Wisam Monther; +Cc: dev, Asaf Penso
Hi,
Thanks for the review. Please find the reply inline.
-----Original Message-----
From: Wisam Monther <wisamm@nvidia.com>
Sent: 01 November 2021 02:37 PM
To: Satheesh Paul <psatheesh@marvell.com>
Cc: dev@dpdk.org; Asaf Penso <asafp@nvidia.com>
Subject: [EXT] RE: [dpdk-dev] [PATCH] app/flow-perf: added option to support flow priority
External Email
----------------------------------------------------------------------
Hi,
Please see my inline comments, thanks 😊
> -----Original Message-----
> From: psatheesh@marvell.com <psatheesh@marvell.com>
> Sent: Friday, October 29, 2021 7:09 AM
> To: Wisam Monther <wisamm@nvidia.com>
> Cc: dev@dpdk.org; Satheesh Paul <psatheesh@marvell.com>
> Subject: [dpdk-dev] [PATCH] app/flow-perf: added option to support
> flow priority
>
> From: Satheesh Paul <psatheesh@marvell.com>
>
> Added support to specify maximum flow priority option. When this
> option is given, each flow will be created with the priority attribute
> and the priority will be random between
> 0 to max-flow-priority. This is useful to measure performance on NICs
> which may have to rearrange flows to honor flow priority.
>
> Removed the lower limit of 100000 flows per batch.
>
> Signed-off-by: Satheesh Paul <psatheesh@marvell.com>
> ---
> app/test-flow-perf/flow_gen.c | 7 ++++--
> app/test-flow-perf/flow_gen.h
> | 1 +
> app/test-flow-perf/main.c | 44 +++++++++++++++++++++-------------
> doc/guides/tools/flow-perf.rst | 5 ++++
> 4 files changed, 38 insertions(+), 19 deletions(-)
>
> diff --git a/app/test-flow-perf/flow_gen.c
> b/app/test-flow-perf/flow_gen.c index 51871dbfdc..414ec0bc5e 100644
> --- a/app/test-flow-perf/flow_gen.c
> +++ b/app/test-flow-perf/flow_gen.c
> @@ -18,7 +18,7 @@
>
> static void
> fill_attributes(struct rte_flow_attr *attr,
> - uint64_t *flow_attrs, uint16_t group)
> + uint64_t *flow_attrs, uint16_t group, uint8_t max_priority)
> {
> uint8_t i;
> for (i = 0; i < MAX_ATTRS_NUM; i++) { @@ -32,6 +32,8 @@
> fill_attributes(struct rte_flow_attr *attr,
> attr->transfer = 1;
> }
> attr->group = group;
> + if (max_priority)
> + attr->priority = rte_rand_max(max_priority);
No need to do this, since it's static and default is zero you can always set it without the condition
Ack.
> }
>
> struct rte_flow *
> @@ -48,6 +50,7 @@ generate_flow(uint16_t port_id,
> uint8_t core_idx,
> uint8_t rx_queues_count,
> bool unique_data,
> + uint8_t max_priority,
--max-priority=N is good, but I think to reflect the exact usage of it we need something like:
--random-priority=lower_hand-upper_hand
That do random prio from lower to upper.
The spec says priority 0 must be supported. Since we have one side of the interval, it may not be useful to take "lower_hand" as input.
> struct rte_flow_error *error)
> {
> struct rte_flow_attr attr;
> @@ -59,7 +62,7 @@ generate_flow(uint16_t port_id,
> memset(actions, 0, sizeof(actions));
> memset(&attr, 0, sizeof(struct rte_flow_attr));
>
> - fill_attributes(&attr, flow_attrs, group);
> + fill_attributes(&attr, flow_attrs, group, max_priority);
>
> fill_actions(actions, flow_actions,
> outer_ip_src, next_table, hairpinq, diff --git
> a/app/test-flow-perf/flow_gen.h b/app/test-flow-perf/flow_gen.h index
> 1118a9fc14..40eeceae6e 100644
> --- a/app/test-flow-perf/flow_gen.h
> +++ b/app/test-flow-perf/flow_gen.h
> @@ -37,6 +37,7 @@ generate_flow(uint16_t port_id,
> uint8_t core_idx,
> uint8_t rx_queues_count,
> bool unique_data,
> + uint8_t max_priority,
> struct rte_flow_error *error);
>
> #endif /* FLOW_PERF_FLOW_GEN */
> diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
> index 3ebc025fb2..1d91f308fd 100644
> --- a/app/test-flow-perf/main.c
> +++ b/app/test-flow-perf/main.c
> @@ -77,6 +77,7 @@ static uint32_t rules_count; static uint32_t
> rules_batch; static uint32_t hairpin_queues_num; /* total hairpin q
> number - default: 0 */ static uint32_t nb_lcores;
> +static uint8_t max_priority;
>
> #define MAX_PKT_BURST 32
> #define LCORE_MODE_PKT 1
> @@ -140,6 +141,7 @@ usage(char *progname)
> printf(" --enable-fwd: To enable packets forwarding"
> " after insertion\n");
> printf(" --portmask=N: hexadecimal bitmask of ports used\n");
> + printf(" --max-priority=N: Maximum priority level for flows\n");
It talks also about random values, you need to mention that it will do the random also.
Ack.
> printf(" --unique-data: flag to set using unique data for all"
> " actions that support data, such as header modify and encap
> actions\n");
>
> @@ -589,6 +591,7 @@ args_parse(int argc, char **argv)
> { "unique-data", 0, 0, 0 },
> { "portmask", 1, 0, 0 },
> { "cores", 1, 0, 0 },
> + { "max-priority", 1, 0, 0 },
> { "meter-profile-alg", 1, 0, 0 },
> { "rxq", 1, 0, 0 },
> { "txq", 1, 0, 0 },
> @@ -767,26 +770,21 @@ args_parse(int argc, char **argv)
> /* Control */
> if (strcmp(lgopts[opt_idx].name,
> "rules-batch") == 0) {
> - n = atoi(optarg);
> - if (n >= DEFAULT_RULES_BATCH)
> - rules_batch = n;
> - else {
> - rte_exit(EXIT_FAILURE,
> - "rules_batch should be >=
> %d\n",
> - DEFAULT_RULES_BATCH);
> - }
> + rules_batch = atoi(optarg);
> }
> if (strcmp(lgopts[opt_idx].name,
> "rules-count") == 0) {
> - n = atoi(optarg);
> - if (n >= (int) rules_batch)
> - rules_count = n;
> - else {
> - rte_exit(EXIT_FAILURE,
> - "rules_count should be >=
> %d\n",
> - rules_batch);
> + rules_count = atoi(optarg);
> + }
> + if (strcmp(lgopts[opt_idx].name, "max-priority") ==
> 0) {
> + max_priority = atoi(optarg);
> + if (max_priority > 32) {
> + rte_exit(
> + EXIT_FAILURE,
> + "max-priority cannot be >
> 32\n");
The 32 is some PMD limitation? I don't think all PMDs will have the same limitation, please remove this condition.
Ack.
> }
> }
> +
> if (strcmp(lgopts[opt_idx].name,
> "dump-iterations") == 0)
> dump_iterations = true;
> @@ -862,6 +860,16 @@ args_parse(int argc, char **argv)
> break;
> }
> }
> + if (rules_count % rules_batch != 0) {
> + rte_exit(EXIT_FAILURE,
> + "rules_count %% rules_batch should be 0\n");
> + }
> + if (rules_count / rules_batch > MAX_BATCHES_COUNT) {
> + rte_exit(EXIT_FAILURE,
> + "rules_count / rules_batch should be <= %d\n",
> + MAX_BATCHES_COUNT);
> + }
> +
Thanks for this 😊
> printf("end_flow\n");
> }
>
> @@ -1227,7 +1235,7 @@ insert_flows(int port_id, uint8_t core_id)
> flow = generate_flow(port_id, 0, flow_attrs,
> global_items, global_actions,
> flow_group, 0, 0, 0, 0, core_id, rx_queues_count,
> - unique_data, &error);
> + unique_data, max_priority, &error);
>
> if (flow == NULL) {
> print_flow_error(error);
> @@ -1244,7 +1252,7 @@ insert_flows(int port_id, uint8_t core_id)
> hairpin_queues_num,
> encap_data, decap_data,
> core_id, rx_queues_count,
> - unique_data, &error);
> + unique_data, max_priority, &error);
>
> if (!counter) {
> first_flow_latency = (double)
> (rte_get_timer_cycles() - start_batch); @@ -1975,6 +1983,8 @@ main(int
> argc, char **argv)
>
> printf(":: Flows Count per port: %d\n\n", rules_count);
>
> + rte_srand(rte_rdtsc());
This doesn't make sense, the set for pseudo random generator need to store the seed to make sure that you can reproduce the Same numbers.
The current usage is per core and also it passes rte_rdtsc() which is not pre-known value.
I suggest to pass the seed from the same parameter:
--random-priority=lower-upper;seed
Otherwise you cannot replicate the same test case twice.
Ack. But can we have it as "--random-priority=N,S" which would mean random priority between (0, N - 1) will be used in flow creation and S is the seed for pseudo-random number generator?
> +
> if (has_meter())
> create_meter_profile();
> rte_eal_mp_remote_launch(run_rte_flow_handler_cores, NULL,
> CALL_MAIN); diff --git a/doc/guides/tools/flow-perf.rst
> b/doc/guides/tools/flow-perf.rst index 0855f88689..0dfdeab832 100644
> --- a/doc/guides/tools/flow-perf.rst
> +++ b/doc/guides/tools/flow-perf.rst
> @@ -100,6 +100,11 @@ The command line options are:
> Set the number of needed cores to insert/delete rte_flow rules.
> Default cores count is 1.
>
> +* ``--max-priority=N``
> + Maximum priority level for flows. Flows will be created with the
> + priority attribute set randomly between 0 to N - 1.
> + Default is 0 and maximum is 32.
I think the max here should be removed also.
Ack.
> +
> * ``--meter-profile-alg``
> Set the traffic metering algorithm.
> Example: meter-profile-alg=srtcmp, default algorithm is
> srtcm_rfc2697
> --
> 2.25.4
BRs,
Wisam Jaddo
^ permalink raw reply [flat|nested] 7+ messages in thread
* [dpdk-dev] [PATCH v3] app/flow-perf: added option to support flow priority
2021-10-29 4:08 [dpdk-dev] [PATCH] app/flow-perf: added option to support flow priority psatheesh
2021-11-01 9:06 ` Wisam Monther
2021-11-02 10:39 ` [dpdk-dev] [PATCH v2] " psatheesh
@ 2021-11-02 10:50 ` psatheesh
2021-11-07 9:26 ` Wisam Monther
2 siblings, 1 reply; 7+ messages in thread
From: psatheesh @ 2021-11-02 10:50 UTC (permalink / raw)
To: Wisam Jaddo; +Cc: dev, Satheesh Paul
From: Satheesh Paul <psatheesh@marvell.com>
Added support to create flows with priority attribute set
randomly between 0 and a user supplied maximum value. This
is useful to measure performance on NICs which may have to
rearrange flows to honor flow priority.
Removed the lower limit of 100000 flows per batch.
Signed-off-by: Satheesh Paul <psatheesh@marvell.com>
---
v3:
* Fixed checkpatch errors
v2:
* Changed "--max-priority" to "--random-priority".
* Added support to take seed for pseudo-random number generator.
* Updated documentation for the above.
app/test-flow-perf/flow_gen.c | 6 ++--
app/test-flow-perf/flow_gen.h | 1 +
app/test-flow-perf/main.c | 58 +++++++++++++++++++++++-----------
doc/guides/tools/flow-perf.rst | 4 +++
4 files changed, 49 insertions(+), 20 deletions(-)
diff --git a/app/test-flow-perf/flow_gen.c b/app/test-flow-perf/flow_gen.c
index 51871dbfdc..4eea8fb7c5 100644
--- a/app/test-flow-perf/flow_gen.c
+++ b/app/test-flow-perf/flow_gen.c
@@ -18,7 +18,7 @@
static void
fill_attributes(struct rte_flow_attr *attr,
- uint64_t *flow_attrs, uint16_t group)
+ uint64_t *flow_attrs, uint16_t group, uint8_t max_priority)
{
uint8_t i;
for (i = 0; i < MAX_ATTRS_NUM; i++) {
@@ -32,6 +32,7 @@ fill_attributes(struct rte_flow_attr *attr,
attr->transfer = 1;
}
attr->group = group;
+ attr->priority = rte_rand_max(max_priority);
}
struct rte_flow *
@@ -48,6 +49,7 @@ generate_flow(uint16_t port_id,
uint8_t core_idx,
uint8_t rx_queues_count,
bool unique_data,
+ uint8_t max_priority,
struct rte_flow_error *error)
{
struct rte_flow_attr attr;
@@ -59,7 +61,7 @@ generate_flow(uint16_t port_id,
memset(actions, 0, sizeof(actions));
memset(&attr, 0, sizeof(struct rte_flow_attr));
- fill_attributes(&attr, flow_attrs, group);
+ fill_attributes(&attr, flow_attrs, group, max_priority);
fill_actions(actions, flow_actions,
outer_ip_src, next_table, hairpinq,
diff --git a/app/test-flow-perf/flow_gen.h b/app/test-flow-perf/flow_gen.h
index 1118a9fc14..40eeceae6e 100644
--- a/app/test-flow-perf/flow_gen.h
+++ b/app/test-flow-perf/flow_gen.h
@@ -37,6 +37,7 @@ generate_flow(uint16_t port_id,
uint8_t core_idx,
uint8_t rx_queues_count,
bool unique_data,
+ uint8_t max_priority,
struct rte_flow_error *error);
#endif /* FLOW_PERF_FLOW_GEN */
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index 3ebc025fb2..abb9908306 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -77,6 +77,8 @@ static uint32_t rules_count;
static uint32_t rules_batch;
static uint32_t hairpin_queues_num; /* total hairpin q number - default: 0 */
static uint32_t nb_lcores;
+static uint8_t max_priority;
+static uint32_t rand_seed;
#define MAX_PKT_BURST 32
#define LCORE_MODE_PKT 1
@@ -140,6 +142,9 @@ usage(char *progname)
printf(" --enable-fwd: To enable packets forwarding"
" after insertion\n");
printf(" --portmask=N: hexadecimal bitmask of ports used\n");
+ printf(" --random-priority=N,S: Use random priority levels from 0 to"
+ " (N - 1) for flows and S as seed for pseudo-random number"
+ " generator\n");
printf(" --unique-data: flag to set using unique data for all"
" actions that support data, such as header modify and encap actions\n");
@@ -238,8 +243,9 @@ usage(char *progname)
static void
args_parse(int argc, char **argv)
{
- uint64_t pm;
+ uint64_t pm, seed;
char **argvopt;
+ uint32_t prio;
char *token;
char *end;
int n, opt;
@@ -589,6 +595,7 @@ args_parse(int argc, char **argv)
{ "unique-data", 0, 0, 0 },
{ "portmask", 1, 0, 0 },
{ "cores", 1, 0, 0 },
+ { "random-priority", 1, 0, 0 },
{ "meter-profile-alg", 1, 0, 0 },
{ "rxq", 1, 0, 0 },
{ "txq", 1, 0, 0 },
@@ -767,25 +774,28 @@ args_parse(int argc, char **argv)
/* Control */
if (strcmp(lgopts[opt_idx].name,
"rules-batch") == 0) {
- n = atoi(optarg);
- if (n >= DEFAULT_RULES_BATCH)
- rules_batch = n;
- else {
- rte_exit(EXIT_FAILURE,
- "rules_batch should be >= %d\n",
- DEFAULT_RULES_BATCH);
- }
+ rules_batch = atoi(optarg);
}
if (strcmp(lgopts[opt_idx].name,
"rules-count") == 0) {
- n = atoi(optarg);
- if (n >= (int) rules_batch)
- rules_count = n;
- else {
+ rules_count = atoi(optarg);
+ }
+ if (strcmp(lgopts[opt_idx].name, "random-priority") ==
+ 0) {
+ end = NULL;
+ prio = strtol(optarg, &end, 10);
+ if ((optarg[0] == '\0') || (end == NULL))
rte_exit(EXIT_FAILURE,
- "rules_count should be >= %d\n",
- rules_batch);
- }
+ "Invalid value for "
+ "random-priority\n");
+ max_priority = prio;
+ token = end + 1;
+ seed = strtoll(token, &end, 10);
+ if ((token[0] == '\0') || (*end != '\0'))
+ rte_exit(EXIT_FAILURE,
+ "Invalid value for "
+ "random-priority\n");
+ rand_seed = seed;
}
if (strcmp(lgopts[opt_idx].name,
"dump-iterations") == 0)
@@ -862,6 +872,16 @@ args_parse(int argc, char **argv)
break;
}
}
+ if (rules_count % rules_batch != 0) {
+ rte_exit(EXIT_FAILURE,
+ "rules_count %% rules_batch should be 0\n");
+ }
+ if (rules_count / rules_batch > MAX_BATCHES_COUNT) {
+ rte_exit(EXIT_FAILURE,
+ "rules_count / rules_batch should be <= %d\n",
+ MAX_BATCHES_COUNT);
+ }
+
printf("end_flow\n");
}
@@ -1227,7 +1247,7 @@ insert_flows(int port_id, uint8_t core_id)
flow = generate_flow(port_id, 0, flow_attrs,
global_items, global_actions,
flow_group, 0, 0, 0, 0, core_id, rx_queues_count,
- unique_data, &error);
+ unique_data, max_priority, &error);
if (flow == NULL) {
print_flow_error(error);
@@ -1244,7 +1264,7 @@ insert_flows(int port_id, uint8_t core_id)
hairpin_queues_num,
encap_data, decap_data,
core_id, rx_queues_count,
- unique_data, &error);
+ unique_data, max_priority, &error);
if (!counter) {
first_flow_latency = (double) (rte_get_timer_cycles() - start_batch);
@@ -1975,6 +1995,8 @@ main(int argc, char **argv)
printf(":: Flows Count per port: %d\n\n", rules_count);
+ rte_srand(rand_seed);
+
if (has_meter())
create_meter_profile();
rte_eal_mp_remote_launch(run_rte_flow_handler_cores, NULL, CALL_MAIN);
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index 0855f88689..b57452662f 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -100,6 +100,10 @@ The command line options are:
Set the number of needed cores to insert/delete rte_flow rules.
Default cores count is 1.
+* ``--random-priority=N,S``
+ Create flows with the priority attribute set randomly between 0 to N - 1
+ and use S as seed for the pseudo-random number generator.
+
* ``--meter-profile-alg``
Set the traffic metering algorithm.
Example: meter-profile-alg=srtcmp, default algorithm is srtcm_rfc2697
--
2.25.4
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [dpdk-dev] [PATCH v3] app/flow-perf: added option to support flow priority
2021-11-02 10:50 ` [dpdk-dev] [PATCH v3] " psatheesh
@ 2021-11-07 9:26 ` Wisam Monther
2021-11-08 9:32 ` Thomas Monjalon
0 siblings, 1 reply; 7+ messages in thread
From: Wisam Monther @ 2021-11-07 9:26 UTC (permalink / raw)
To: psatheesh; +Cc: dev
Hi,
> -----Original Message-----
> From: psatheesh@marvell.com <psatheesh@marvell.com>
> Sent: Tuesday, November 2, 2021 12:51 PM
> To: Wisam Monther <wisamm@nvidia.com>
> Cc: dev@dpdk.org; Satheesh Paul <psatheesh@marvell.com>
> Subject: [dpdk-dev] [PATCH v3] app/flow-perf: added option to support flow
> priority
>
> From: Satheesh Paul <psatheesh@marvell.com>
>
> Added support to create flows with priority attribute set randomly between
> 0 and a user supplied maximum value. This is useful to measure performance
> on NICs which may have to rearrange flows to honor flow priority.
>
> Removed the lower limit of 100000 flows per batch.
>
> Signed-off-by: Satheesh Paul <psatheesh@marvell.com>
> ---
> v3:
> * Fixed checkpatch errors
>
> v2:
> * Changed "--max-priority" to "--random-priority".
> * Added support to take seed for pseudo-random number generator.
> * Updated documentation for the above.
>
Acked-by: Wisam Jaddo <wisamm@nvidia.com>
BRs,
Wisam Jaddo
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [dpdk-dev] [PATCH v3] app/flow-perf: added option to support flow priority
2021-11-07 9:26 ` Wisam Monther
@ 2021-11-08 9:32 ` Thomas Monjalon
0 siblings, 0 replies; 7+ messages in thread
From: Thomas Monjalon @ 2021-11-08 9:32 UTC (permalink / raw)
To: psatheesh; +Cc: dev, Wisam Monther
> > Added support to create flows with priority attribute set randomly between
> > 0 and a user supplied maximum value. This is useful to measure performance
> > on NICs which may have to rearrange flows to honor flow priority.
> >
> > Removed the lower limit of 100000 flows per batch.
> >
> > Signed-off-by: Satheesh Paul <psatheesh@marvell.com>
>
> Acked-by: Wisam Jaddo <wisamm@nvidia.com>
Applied, thanks.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2021-11-08 9:32 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-29 4:08 [dpdk-dev] [PATCH] app/flow-perf: added option to support flow priority psatheesh
2021-11-01 9:06 ` Wisam Monther
2021-11-02 10:39 ` Satheesh Paul
2021-11-02 10:39 ` [dpdk-dev] [PATCH v2] " psatheesh
2021-11-02 10:50 ` [dpdk-dev] [PATCH v3] " psatheesh
2021-11-07 9:26 ` Wisam Monther
2021-11-08 9:32 ` Thomas Monjalon
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).