From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id 70436CC08 for ; Sat, 18 Jun 2016 23:47:48 +0200 (CEST) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga102.jf.intel.com with ESMTP; 18 Jun 2016 14:47:47 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.26,489,1459839600"; d="scan'208";a="124596498" Received: from irsmsx102.ger.corp.intel.com ([163.33.3.155]) by fmsmga004.fm.intel.com with ESMTP; 18 Jun 2016 14:47:46 -0700 Received: from irsmsx108.ger.corp.intel.com ([169.254.11.183]) by IRSMSX102.ger.corp.intel.com ([169.254.2.10]) with mapi id 14.03.0248.002; Sat, 18 Jun 2016 22:47:45 +0100 From: "Dumitrescu, Cristian" To: WeiJie Zhuang CC: "dev@dpdk.org" , "Singh, Jasvinder" , "Yigit, Ferruh" Thread-Topic: [PATCH v3 2/3] port: add kni nodrop writer Thread-Index: AQHRx8JEgfxIT1yTikSsKaEXlIhno5/vxIhg Date: Sat, 18 Jun 2016 21:47:45 +0000 Message-ID: <3EB4FA525960D640B5BDFFD6A3D8912647A0911D@IRSMSX108.ger.corp.intel.com> References: <1464434757-10860-1-git-send-email-zhuangwj@gmail.com> <1466076423-8680-1-git-send-email-zhuangwj@gmail.com> <1466076423-8680-2-git-send-email-zhuangwj@gmail.com> In-Reply-To: <1466076423-8680-2-git-send-email-zhuangwj@gmail.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiNTdkNmY0NmEtNzM1Yi00OTJjLTlkNDUtZjM1MDYyMzVjN2IyIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX0lDIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE1LjkuNi42IiwiVHJ1c3RlZExhYmVsSGFzaCI6ImJzZmxKVHp2QU1RbGNDNFA1TUtDQmlxY0tnYk1RXC9PNTJKTDRUNVRTTmNrPSJ9 x-ctpclassification: CTP_IC x-originating-ip: [163.33.239.180] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: [dpdk-dev] [PATCH v3 2/3] port: add kni nodrop writer X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 18 Jun 2016 21:47:49 -0000 > -----Original Message----- > From: WeiJie Zhuang [mailto:zhuangwj@gmail.com] > Sent: Thursday, June 16, 2016 12:27 PM > To: Dumitrescu, Cristian > Cc: dev@dpdk.org; Singh, Jasvinder ; Yigit, > Ferruh ; WeiJie Zhuang > Subject: [PATCH v3 2/3] port: add kni nodrop writer >=20 > 1. add no drop writing operations to the kni port > 2. support dropless kni config in the ip pipeline sample application >=20 > Signed-off-by: WeiJie Zhuang > --- > examples/ip_pipeline/app.h | 2 + > examples/ip_pipeline/config_parse.c | 31 ++++- > examples/ip_pipeline/init.c | 26 ++++- > examples/ip_pipeline/pipeline_be.h | 6 + > lib/librte_port/rte_port_kni.c | 220 > +++++++++++++++++++++++++++++++++++ > lib/librte_port/rte_port_kni.h | 13 +++ > lib/librte_port/rte_port_version.map | 1 + > 7 files changed, 292 insertions(+), 7 deletions(-) >=20 > diff --git a/examples/ip_pipeline/app.h b/examples/ip_pipeline/app.h > index abbd6d4..6a6fdd9 100644 > --- a/examples/ip_pipeline/app.h > +++ b/examples/ip_pipeline/app.h > @@ -147,6 +147,8 @@ struct app_pktq_kni_params { > uint32_t mempool_id; /* Position in the app->mempool_params */ > uint32_t burst_read; > uint32_t burst_write; > + uint32_t dropless; > + uint64_t n_retries; > }; >=20 > #ifndef APP_FILE_NAME_SIZE > diff --git a/examples/ip_pipeline/config_parse.c > b/examples/ip_pipeline/config_parse.c > index c55be31..31a50c2 100644 > --- a/examples/ip_pipeline/config_parse.c > +++ b/examples/ip_pipeline/config_parse.c > @@ -199,6 +199,8 @@ struct app_pktq_kni_params default_kni_params =3D { > .mempool_id =3D 0, > .burst_read =3D 32, > .burst_write =3D 32, > + .dropless =3D 0, > + .n_retries =3D 0, > }; >=20 > struct app_pktq_source_params default_source_params =3D { > @@ -1927,7 +1929,7 @@ parse_kni(struct app_params *app, >=20 > if (strcmp(ent->name, "mempool") =3D=3D 0) { > int status =3D validate_name(ent->value, > - > "MEMPOOL", 1); > + "MEMPOOL", 1); > ssize_t idx; >=20 > PARSE_ERROR((status =3D=3D 0), section_name, > @@ -1940,7 +1942,7 @@ parse_kni(struct app_params *app, >=20 > if (strcmp(ent->name, "burst_read") =3D=3D 0) { > int status =3D parser_read_uint32(¶m- > >burst_read, > - > ent->value); > + ent->value); >=20 > PARSE_ERROR((status =3D=3D 0), section_name, > ent->name); > @@ -1949,7 +1951,25 @@ parse_kni(struct app_params *app, >=20 > if (strcmp(ent->name, "burst_write") =3D=3D 0) { > int status =3D parser_read_uint32(¶m- > >burst_write, > - > ent->value); > + ent->value); > + > + PARSE_ERROR((status =3D=3D 0), section_name, > + ent->name); > + continue; > + } > + > + if (strcmp(ent->name, "dropless") =3D=3D 0) { > + int status =3D parser_read_arg_bool(ent->value); > + > + PARSE_ERROR((status !=3D -EINVAL), section_name, > + ent->name); > + param->dropless =3D status; > + continue; > + } > + > + if (strcmp(ent->name, "n_retries") =3D=3D 0) { > + int status =3D parser_read_uint64(¶m->n_retries, > + ent->value); >=20 > PARSE_ERROR((status =3D=3D 0), section_name, > ent->name); > @@ -2794,6 +2814,11 @@ save_kni_params(struct app_params *app, FILE > *f) > /* burst_write */ > fprintf(f, "%s =3D %" PRIu32 "\n", "burst_write", p- > >burst_write); >=20 > + /* dropless */ > + fprintf(f, "%s =3D %s\n", > + "dropless", > + p->dropless ? "yes" : "no"); Please also do not forget to save the number of retries parameter as well (= struct app_pktq_kni_params::n_retries): fprintf(f, "%s =3D %" PRIu64 "\n", "n_retries", p->n_retries); I realize that we forgot to save n_retires in function save_txq_params(), c= an you please add it as part of your patch? We have it for save_swq_params(= ). > + > fputc('\n', f); > } > } > diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c > index d522de4..af24f52 100644 > --- a/examples/ip_pipeline/init.c > +++ b/examples/ip_pipeline/init.c > @@ -1434,10 +1434,28 @@ void app_pipeline_params_get(struct > app_params *app, > #ifdef RTE_LIBRTE_KNI > case APP_PKTQ_OUT_KNI: > { > - out->type =3D PIPELINE_PORT_OUT_KNI_WRITER; > - out->params.kni.kni =3D app->kni[in->id]; > - out->params.kni.tx_burst_sz =3D > - app->kni_params[in->id].burst_write; > + struct app_pktq_kni_params *p_kni =3D > + &app->kni_params[in->id]; > + > + if (p_kni->dropless =3D=3D 0) { > + struct rte_port_kni_writer_params *params > =3D > + &out->params.kni; > + > + out->type =3D > PIPELINE_PORT_OUT_KNI_WRITER; > + params->kni =3D app->kni[in->id]; > + params->tx_burst_sz =3D > + app->kni_params[in- > >id].burst_write; > + } else { > + struct rte_port_kni_writer_nodrop_params > + *params =3D &out- > >params.kni_nodrop; > + > + out->type =3D > PIPELINE_PORT_OUT_KNI_WRITER_NODROP; > + params->kni =3D app->kni[in->id]; > + params->tx_burst_sz =3D > + app->kni_params[in- > >id].burst_write; > + params->n_retries =3D > + app->kni_params[in->id].n_retries; > + } > break; > } > #endif /* RTE_LIBRTE_KNI */ > diff --git a/examples/ip_pipeline/pipeline_be.h > b/examples/ip_pipeline/pipeline_be.h > index 0ee208c..b562472 100644 > --- a/examples/ip_pipeline/pipeline_be.h > +++ b/examples/ip_pipeline/pipeline_be.h > @@ -138,6 +138,7 @@ enum pipeline_port_out_type { > PIPELINE_PORT_OUT_RING_WRITER_IPV6_RAS, > PIPELINE_PORT_OUT_SCHED_WRITER, > PIPELINE_PORT_OUT_KNI_WRITER, > + PIPELINE_PORT_OUT_KNI_WRITER_NODROP, > PIPELINE_PORT_OUT_SINK, > }; >=20 > @@ -155,6 +156,7 @@ struct pipeline_port_out_params { > struct rte_port_sched_writer_params sched; > #ifdef RTE_LIBRTE_KNI > struct rte_port_kni_writer_params kni; > + struct rte_port_kni_writer_nodrop_params kni_nodrop; > #endif > struct rte_port_sink_params sink; > } params; > @@ -185,6 +187,8 @@ pipeline_port_out_params_convert(struct > pipeline_port_out_params *p) > #ifdef RTE_LIBRTE_KNI > case PIPELINE_PORT_OUT_KNI_WRITER: > return (void *) &p->params.kni; > + case PIPELINE_PORT_OUT_KNI_WRITER_NODROP: > + return (void *) &p->params.kni_nodrop; > #endif > case PIPELINE_PORT_OUT_SINK: > return (void *) &p->params.sink; > @@ -218,6 +222,8 @@ pipeline_port_out_params_get_ops(struct > pipeline_port_out_params *p) > #ifdef RTE_LIBRTE_KNI > case PIPELINE_PORT_OUT_KNI_WRITER: > return &rte_port_kni_writer_ops; > + case PIPELINE_PORT_OUT_KNI_WRITER_NODROP: > + return &rte_port_kni_writer_nodrop_ops; > #endif > case PIPELINE_PORT_OUT_SINK: > return &rte_port_sink_ops; > diff --git a/lib/librte_port/rte_port_kni.c b/lib/librte_port/rte_port_kn= i.c > index 4cbc345..08f4ac2 100644 > --- a/lib/librte_port/rte_port_kni.c > +++ b/lib/librte_port/rte_port_kni.c > @@ -306,6 +306,217 @@ static int rte_port_kni_writer_stats_read(void > *port, > } >=20 > /* > + * Port KNI Writer Nodrop > + */ > +#ifdef RTE_PORT_STATS_COLLECT > + > +#define RTE_PORT_KNI_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) > \ > + port->stats.n_pkts_in +=3D val > +#define RTE_PORT_KNI_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, > val) \ > + port->stats.n_pkts_drop +=3D val > + > +#else > + > +#define RTE_PORT_KNI_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) > +#define RTE_PORT_KNI_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, > val) > + > +#endif > + > +struct rte_port_kni_writer_nodrop { > + struct rte_port_out_stats stats; > + > + struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX]; > + uint32_t tx_burst_sz; > + uint32_t tx_buf_count; > + uint64_t bsz_mask; > + uint64_t n_retries; > + struct rte_kni *kni; > +}; > + > +static void * > +rte_port_kni_writer_nodrop_create(void *params, int socket_id) > +{ > + struct rte_port_kni_writer_nodrop_params *conf =3D > + (struct rte_port_kni_writer_nodrop_params *) params; > + struct rte_port_kni_writer_nodrop *port; > + > + /* Check input parameters */ > + if ((conf =3D=3D NULL) || > + (conf->tx_burst_sz =3D=3D 0) || > + (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) || > + (!rte_is_power_of_2(conf->tx_burst_sz))) { > + RTE_LOG(ERR, PORT, "%s: Invalid input parameters\n", > __func__); > + return NULL; > + } > + > + /* Memory allocation */ > + port =3D rte_zmalloc_socket("PORT", sizeof(*port), > + RTE_CACHE_LINE_SIZE, socket_id); > + if (port =3D=3D NULL) { > + RTE_LOG(ERR, PORT, "%s: Failed to allocate port\n", > __func__); > + return NULL; > + } > + > + /* Initialization */ > + port->kni =3D conf->kni; > + port->tx_burst_sz =3D conf->tx_burst_sz; > + port->tx_buf_count =3D 0; > + port->bsz_mask =3D 1LLU << (conf->tx_burst_sz - 1); > + > + /* > + * When n_retries is 0 it means that we should wait for every packet > to > + * send no matter how many retries should it take. To limit number of > + * branches in fast path, we use UINT64_MAX instead of branching. > + */ > + port->n_retries =3D (conf->n_retries =3D=3D 0) ? UINT64_MAX : conf- > >n_retries; > + > + return port; > +} > + > +static inline void > +send_burst_nodrop(struct rte_port_kni_writer_nodrop *p) > +{ > + uint32_t nb_tx =3D 0, i; > + > + nb_tx =3D rte_kni_tx_burst(p->kni, p->tx_buf, p->tx_buf_count); > + > + /* We sent all the packets in a first try */ > + if (nb_tx >=3D p->tx_buf_count) { > + p->tx_buf_count =3D 0; > + return; > + } > + > + for (i =3D 0; i < p->n_retries; i++) { > + nb_tx +=3D rte_kni_tx_burst(p->kni, > + p->tx_buf + nb_tx, > + p->tx_buf_count - nb_tx); > + > + /* We sent all the packets in more than one try */ > + if (nb_tx >=3D p->tx_buf_count) { > + p->tx_buf_count =3D 0; > + return; > + } > + } > + > + /* We didn't send the packets in maximum allowed attempts */ > + RTE_PORT_KNI_WRITER_NODROP_STATS_PKTS_DROP_ADD(p, p- > >tx_buf_count - nb_tx); > + for ( ; nb_tx < p->tx_buf_count; nb_tx++) > + rte_pktmbuf_free(p->tx_buf[nb_tx]); > + > + p->tx_buf_count =3D 0; > +} > + > +static int > +rte_port_kni_writer_nodrop_tx(void *port, struct rte_mbuf *pkt) > +{ > + struct rte_port_kni_writer_nodrop *p =3D > + (struct rte_port_kni_writer_nodrop *) port; > + > + p->tx_buf[p->tx_buf_count++] =3D pkt; > + RTE_PORT_KNI_WRITER_STATS_PKTS_IN_ADD(p, 1); > + if (p->tx_buf_count >=3D p->tx_burst_sz) > + send_burst_nodrop(p); > + > + return 0; > +} > + > +static int > +rte_port_kni_writer_nodrop_tx_bulk(void *port, > + struct rte_mbuf **pkts, > + uint64_t pkts_mask) > +{ > + struct rte_port_kni_writer_nodrop *p =3D > + (struct rte_port_kni_writer_nodrop *) port; > + > + uint64_t bsz_mask =3D p->bsz_mask; > + uint32_t tx_buf_count =3D p->tx_buf_count; > + uint64_t expr =3D (pkts_mask & (pkts_mask + 1)) | > + ((pkts_mask & bsz_mask) ^ > bsz_mask); > + > + if (expr =3D=3D 0) { > + uint64_t n_pkts =3D __builtin_popcountll(pkts_mask); > + uint32_t n_pkts_ok; > + > + if (tx_buf_count) > + send_burst_nodrop(p); > + > + RTE_PORT_KNI_WRITER_NODROP_STATS_PKTS_IN_ADD(p, > n_pkts); > + n_pkts_ok =3D rte_kni_tx_burst(p->kni, pkts, n_pkts); > + > + if (n_pkts_ok >=3D n_pkts) > + return 0; > + > + /* > + * If we didn't manage to send all packets in single burst, > move > + * remaining packets to the buffer and call send burst. > + */ > + for (; n_pkts_ok < n_pkts; n_pkts_ok++) { > + struct rte_mbuf *pkt =3D pkts[n_pkts_ok]; > + p->tx_buf[p->tx_buf_count++] =3D pkt; > + } > + send_burst_nodrop(p); > + } else { > + for ( ; pkts_mask; ) { > + uint32_t pkt_index =3D __builtin_ctzll(pkts_mask); > + uint64_t pkt_mask =3D 1LLU << pkt_index; > + struct rte_mbuf *pkt =3D pkts[pkt_index]; > + > + p->tx_buf[tx_buf_count++] =3D pkt; > + > RTE_PORT_KNI_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1); > + pkts_mask &=3D ~pkt_mask; > + } > + > + p->tx_buf_count =3D tx_buf_count; > + if (tx_buf_count >=3D p->tx_burst_sz) > + send_burst_nodrop(p); > + } > + > + return 0; > +} > + > +static int > +rte_port_kni_writer_nodrop_flush(void *port) > +{ > + struct rte_port_kni_writer_nodrop *p =3D > + (struct rte_port_kni_writer_nodrop *) port; > + > + if (p->tx_buf_count > 0) > + send_burst_nodrop(p); > + > + return 0; > +} > + > +static int > +rte_port_kni_writer_nodrop_free(void *port) > +{ > + if (port =3D=3D NULL) { > + RTE_LOG(ERR, PORT, "%s: Port is NULL\n", __func__); > + return -EINVAL; > + } > + > + rte_port_kni_writer_nodrop_flush(port); > + rte_free(port); > + > + return 0; > +} > + > +static int rte_port_kni_writer_nodrop_stats_read(void *port, > + struct rte_port_out_stats *stats, int clear) > +{ > + struct rte_port_kni_writer_nodrop *p =3D > + (struct rte_port_kni_writer_nodrop *) port; > + > + if (stats !=3D NULL) > + memcpy(stats, &p->stats, sizeof(p->stats)); > + > + if (clear) > + memset(&p->stats, 0, sizeof(p->stats)); > + > + return 0; > +} > + > + > +/* > * Summary of port operations > */ > struct rte_port_in_ops rte_port_kni_reader_ops =3D { > @@ -323,3 +534,12 @@ struct rte_port_out_ops rte_port_kni_writer_ops =3D > { > .f_flush =3D rte_port_kni_writer_flush, > .f_stats =3D rte_port_kni_writer_stats_read, > }; > + > +struct rte_port_out_ops rte_port_kni_writer_nodrop_ops =3D { > + .f_create =3D rte_port_kni_writer_nodrop_create, > + .f_free =3D rte_port_kni_writer_nodrop_free, > + .f_tx =3D rte_port_kni_writer_nodrop_tx, > + .f_tx_bulk =3D rte_port_kni_writer_nodrop_tx_bulk, > + .f_flush =3D rte_port_kni_writer_nodrop_flush, > + .f_stats =3D rte_port_kni_writer_nodrop_stats_read, > +}; > diff --git a/lib/librte_port/rte_port_kni.h b/lib/librte_port/rte_port_kn= i.h > index d4de8c4..4b60689 100644 > --- a/lib/librte_port/rte_port_kni.h > +++ b/lib/librte_port/rte_port_kni.h > @@ -75,6 +75,19 @@ struct rte_port_kni_writer_params { > /** kni_writer port operations */ > extern struct rte_port_out_ops rte_port_kni_writer_ops; >=20 > +/** kni_writer_nodrop port parameters */ > +struct rte_port_kni_writer_nodrop_params { > + /** KNI interface reference */ > + struct rte_kni *kni; > + /** Burst size to KNI interface. */ > + uint32_t tx_burst_sz; > + /** Maximum number of retries, 0 for no limit */ > + uint32_t n_retries; > +}; > + > +/** kni_writer_nodrop port operations */ > +extern struct rte_port_out_ops rte_port_kni_writer_nodrop_ops; > + > #ifdef __cplusplus > } > #endif > diff --git a/lib/librte_port/rte_port_version.map > b/lib/librte_port/rte_port_version.map > index e61b3fa..c528658 100644 > --- a/lib/librte_port/rte_port_version.map > +++ b/lib/librte_port/rte_port_version.map > @@ -41,5 +41,6 @@ DPDK_16.07 { >=20 > rte_port_kni_reader_ops; > rte_port_kni_writer_ops; > + rte_port_kni_writer_nodrop_ops; >=20 > } DPDK_2.2; > -- > 2.7.4