Hi Eelco, > -----Original Message----- > From: Eelco Chaudron [mailto:echau...@redhat.com] > Sent: Thursday, November 29, 2018 11:29 AM > To: Dumitrescu, Cristian <cristian.dumitre...@intel.com> > Cc: dev@dpdk.org > Subject: [PATCH v2 1/2] lib/librte_meter: add RFC4115 trTCM meter support > > This patch adds support for RFC4115 trTCM meters. > > Signed-off-by: Eelco Chaudron <echau...@redhat.com> > --- > lib/librte_meter/rte_meter.c | 40 +++++ > lib/librte_meter/rte_meter.h | 236 > ++++++++++++++++++++++++++++++-- > lib/librte_meter/rte_meter_version.map | 9 + > 3 files changed, 269 insertions(+), 16 deletions(-) > > diff --git a/lib/librte_meter/rte_meter.c b/lib/librte_meter/rte_meter.c > index 473f69aba..817680dbb 100644 > --- a/lib/librte_meter/rte_meter.c > +++ b/lib/librte_meter/rte_meter.c > @@ -110,3 +110,43 @@ rte_meter_trtcm_config(struct rte_meter_trtcm > *m, > > return 0; > } > + > +int __rte_experimental > +rte_meter_trtcm_rfc4115_profile_config(struct rte_meter_trtcm_profile > *p, > + struct rte_meter_trtcm_params *params) > +{ > + uint64_t hz = rte_get_tsc_hz(); > + > + /* Check input parameters */ > + if ((p == NULL) || > + (params == NULL) || > + (params->cir != 0 && params->cbs == 0) || > + (params->eir != 0 && params->ebs == 0)) > + return -EINVAL; > + > + /* Initialize trTCM run-time structure */ > + p->cbs = params->cbs; > + p->ebs = params->ebs; > + rte_meter_get_tb_params(hz, params->cir, &p->cir_period, > + &p->cir_bytes_per_period); > + rte_meter_get_tb_params(hz, params->eir, &p->eir_period, > + &p->eir_bytes_per_period); > + > + return 0; > +} > + > +int __rte_experimental > +rte_meter_trtcm_rfc4115_config(struct rte_meter_trtcm *m, > + struct rte_meter_trtcm_profile *p) > +{ > + /* Check input parameters */ > + if ((m == NULL) || (p == NULL)) > + return -EINVAL; > + > + /* Initialize trTCM run-time structure */ > + m->time_tc = m->time_te = rte_get_tsc_cycles(); > + m->tc = p->cbs; > + m->te = p->ebs; > + > + return 0; > +} > diff --git a/lib/librte_meter/rte_meter.h b/lib/librte_meter/rte_meter.h > index 58a051583..c3f88d0cb 100644 > --- a/lib/librte_meter/rte_meter.h > +++ b/lib/librte_meter/rte_meter.h > @@ -16,6 +16,7 @@ extern "C" { > * Traffic metering algorithms: > * 1. Single Rate Three Color Marker (srTCM): defined by IETF RFC 2697 > * 2. Two Rate Three Color Marker (trTCM): defined by IETF RFC 2698 > + * 3. Two Rate Three Color Marker (trTCM): defined by IETF RFC 4115 > * > ***/ > > @@ -43,14 +44,25 @@ struct rte_meter_srtcm_params { > uint64_t ebs; /**< Excess Burst Size (EBS). Measured in bytes. */ > }; > > -/** trTCM parameters per metered traffic flow. The CIR, PIR, CBS and PBS > parameters > -only count bytes of IP packets and do not include link specific headers. PIR > has to > -be greater than or equal to CIR. Both CBS or EBS have to be greater than > zero. */ > +/** trTCM parameters per metered traffic flow. The CIR, PIR/EIT, CBS and > PBS/EBS > +parameters only count bytes of IP packets and do not include link specific > +headers. > + > +- For RFC2698 operations PIR has to be greater than or equal to CIR. Both > CBS > + or EBS have to be greater than zero. > +- For RFC4115 operations CBS and EBS need to be greater than zero if CIR > and > + EIR are none-zero respectively.*/ > struct rte_meter_trtcm_params { > uint64_t cir; /**< Committed Information Rate (CIR). Measured in > bytes per second. */ > - uint64_t pir; /**< Peak Information Rate (PIR). Measured in bytes > per second. */ > - uint64_t cbs; /**< Committed Burst Size (CBS). Measured in byes. */ > - uint64_t pbs; /**< Peak Burst Size (PBS). Measured in bytes. */ > + union { > + uint64_t pir; /**< Peak Information Rate (PIR). Measured in > bytes per second. */ > + uint64_t eir; /**< Excess Information Rate (EIR). Measured in > bytes per second. */ > + }; > + uint64_t cbs; /**< Committed Burst Size (CBS). Measured in bytes. > */ > + union { > + uint64_t pbs; /**< Peak Burst Size (PBS). Measured in bytes. > */ > + uint64_t ebs; /**< Excess Burst Size (EBS). Measured in > bytes. */ > + }; > }; >
In order to prevent complicating the data structures and/or creating false dependencies between algs, please create a separate data structure struct rte_meter_trtcm_rfc4115_params. This is also inline with the naming conventions from librte_ethdev/rte_mtr.h > /** > @@ -98,6 +110,22 @@ rte_meter_srtcm_profile_config(struct > rte_meter_srtcm_profile *p, > int > rte_meter_trtcm_profile_config(struct rte_meter_trtcm_profile *p, > struct rte_meter_trtcm_params *params); > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change without prior notice > + * > + * trTCM RFC 4115 profile configuration > + * > + * @param p > + * Pointer to pre-allocated trTCM profile data structure > + * @param params > + * trTCM profile parameters > + * @return > + * 0 upon success, error code otherwise > + */ > +int __rte_experimental > +rte_meter_trtcm_rfc4115_profile_config(struct rte_meter_trtcm_profile > *p, > + struct rte_meter_trtcm_params *params); > > /** > * srTCM configuration per metered traffic flow > @@ -127,6 +155,23 @@ int > rte_meter_trtcm_config(struct rte_meter_trtcm *m, > struct rte_meter_trtcm_profile *p); > > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change without prior notice > + * > + * trTCM RFC 4115 configuration per metered traffic flow > + * > + * @param m > + * Pointer to pre-allocated trTCM data structure > + * @param p > + * trTCM profile. Needs to be valid. > + * @return > + * 0 upon success, error code otherwise > + */ > +int __rte_experimental > +rte_meter_trtcm_rfc4115_config(struct rte_meter_trtcm *m, > + struct rte_meter_trtcm_profile *p); > + > /** > * srTCM color blind traffic metering > * > @@ -213,6 +258,55 @@ rte_meter_trtcm_color_aware_check(struct > rte_meter_trtcm *m, > uint32_t pkt_len, > enum rte_meter_color pkt_color); > > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change without prior notice > + * > + * trTCM RFC4115 color blind traffic metering > + * > + * @param m > + * Handle to trTCM instance > + * @param p > + * trTCM profile specified at trTCM object creation time > + * @param time > + * Current CPU time stamp (measured in CPU cycles) > + * @param pkt_len > + * Length of the current IP packet (measured in bytes) > + * @return > + * Color assigned to the current IP packet > + */ > +static inline enum rte_meter_color __rte_experimental > +rte_meter_trtcm_rfc4115_color_blind_check(struct rte_meter_trtcm *m, > + struct rte_meter_trtcm_profile *p, > + uint64_t time, > + uint32_t pkt_len); > + > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change without prior notice > + * > + * trTCM RFC4115 color aware traffic metering > + * > + * @param m > + * Handle to trTCM instance > + * @param p > + * trTCM profile specified at trTCM object creation time > + * @param time > + * Current CPU time stamp (measured in CPU cycles) > + * @param pkt_len > + * Length of the current IP packet (measured in bytes) > + * @param pkt_color > + * Input color of the current IP packet > + * @return > + * Color assigned to the current IP packet > + */ > +static inline enum rte_meter_color __rte_experimental > +rte_meter_trtcm_rfc4115_color_aware_check(struct rte_meter_trtcm *m, > + struct rte_meter_trtcm_profile *p, > + uint64_t time, > + uint32_t pkt_len, > + enum rte_meter_color pkt_color); > + > /* > * Inline implementation of run-time methods > * > @@ -239,16 +333,28 @@ struct rte_meter_srtcm { > struct rte_meter_trtcm_profile { > uint64_t cbs; > /**< Upper limit for C token bucket */ > - uint64_t pbs; > - /**< Upper limit for P token bucket */ > + union { > + uint64_t pbs; > + /**< Upper limit for P token bucket */ > + uint64_t ebs; > + /**< Upper limit for E token bucket */ > + }; > uint64_t cir_period; > /**< Number of CPU cycles for one update of C token bucket */ > uint64_t cir_bytes_per_period; > /**< Number of bytes to add to C token bucket on each update */ > - uint64_t pir_period; > - /**< Number of CPU cycles for one update of P token bucket */ > - uint64_t pir_bytes_per_period; > - /**< Number of bytes to add to P token bucket on each update */ > + union { > + uint64_t pir_period; > + /**< Number of CPU cycles for one update of P token bucket > */ > + uint64_t eir_period; > + /**< Number of CPU cycles for one update of E token bucket > */ > + }; > + union { > + uint64_t pir_bytes_per_period; > + /**< Number of bytes to add to P token bucket on each > update */ > + uint64_t eir_bytes_per_period; > + /**< Number of bytes to add to E token bucket on each > update */ > + }; > }; > Same here, please create dedicated data structure struct rte_meter_trtcm_rfc4115_profile. > /** > @@ -258,12 +364,20 @@ struct rte_meter_trtcm_profile { > struct rte_meter_trtcm { > uint64_t time_tc; > /**< Time of latest update of C token bucket */ > - uint64_t time_tp; > - /**< Time of latest update of E token bucket */ > + union { > + uint64_t time_tp; > + /**< Time of latest update of P token bucket */ > + uint64_t time_te; > + /**< Time of latest update of E token bucket */ > + }; > uint64_t tc; > /**< Number of bytes currently available in committed(C) token > bucket */ > - uint64_t tp; > - /**< Number of bytes currently available in the peak(P) token > bucket */ > + union { > + uint64_t tp; > + /**< Number of bytes currently available in the peak(P) > token bucket */ > + uint64_t te; > + /**< Number of bytes currently available in the excess(E) > token bucket */ > + }; > }; > Same here, please create dedicated data structure struct rte_meter_trtcm_rfc4115. > static inline enum rte_meter_color > @@ -434,6 +548,96 @@ rte_meter_trtcm_color_aware_check(struct > rte_meter_trtcm *m, > return e_RTE_METER_GREEN; > } > > +static inline enum rte_meter_color __rte_experimental > +rte_meter_trtcm_rfc4115_color_blind_check(struct rte_meter_trtcm *m, > + struct rte_meter_trtcm_profile *p, > + uint64_t time, > + uint32_t pkt_len) > +{ > + uint64_t time_diff_tc, time_diff_te, n_periods_tc, n_periods_te, tc, > te; > + > + /* Bucket update */ > + time_diff_tc = time - m->time_tc; > + time_diff_te = time - m->time_te; > + n_periods_tc = time_diff_tc / p->cir_period; > + n_periods_te = time_diff_te / p->eir_period; > + m->time_tc += n_periods_tc * p->cir_period; > + m->time_te += n_periods_te * p->eir_period; > + > + tc = m->tc + n_periods_tc * p->cir_bytes_per_period; > + if (tc > p->cbs) > + tc = p->cbs; > + > + te = m->te + n_periods_te * p->eir_bytes_per_period; > + if (te > p->ebs) > + te = p->ebs; > + > + /* Color logic */ > + if (tc >= pkt_len) { > + m->tc = tc - pkt_len; > + m->te = te; > + return e_RTE_METER_GREEN; > + } else if (te >= pkt_len) { > + m->tc = tc; > + m->te = te - pkt_len; > + return e_RTE_METER_YELLOW; > + } > + > + /* If we end up here the color is RED */ > + m->tc = tc; > + m->te = te; > + return e_RTE_METER_RED; > +} > + > +static inline enum rte_meter_color __rte_experimental > +rte_meter_trtcm_rfc4115_color_aware_check(struct rte_meter_trtcm *m, > + struct rte_meter_trtcm_profile *p, > + uint64_t time, > + uint32_t pkt_len, > + enum rte_meter_color pkt_color) > +{ > + uint64_t time_diff_tc, time_diff_te, n_periods_tc, n_periods_te, tc, > te; > + > + /* Bucket update */ > + time_diff_tc = time - m->time_tc; > + time_diff_te = time - m->time_te; > + n_periods_tc = time_diff_tc / p->cir_period; > + n_periods_te = time_diff_te / p->eir_period; > + m->time_tc += n_periods_tc * p->cir_period; > + m->time_te += n_periods_te * p->eir_period; > + > + tc = m->tc + n_periods_tc * p->cir_bytes_per_period; > + if (tc > p->cbs) > + tc = p->cbs; > + > + te = m->te + n_periods_te * p->eir_bytes_per_period; > + if (te > p->ebs) > + te = p->ebs; > + > + /* Color logic */ > + if (pkt_color == e_RTE_METER_GREEN) { > + if (tc >= pkt_len) { > + m->tc = tc - pkt_len; > + m->te = te; > + return e_RTE_METER_GREEN; > + } else if (te >= pkt_len) { > + m->tc = tc; > + m->te = te - pkt_len; > + return e_RTE_METER_YELLOW; > + } > + } else if (pkt_color == e_RTE_METER_YELLOW && te >= pkt_len) { > + m->tc = tc; > + m->te = te - pkt_len; > + return e_RTE_METER_YELLOW; > + } > + > + /* If we end up here the color is RED */ > + m->tc = tc; > + m->te = te; > + return e_RTE_METER_RED; > +} > + > + > #ifdef __cplusplus > } > #endif > diff --git a/lib/librte_meter/rte_meter_version.map > b/lib/librte_meter/rte_meter_version.map > index cb79f0c2b..4b460d580 100644 > --- a/lib/librte_meter/rte_meter_version.map > +++ b/lib/librte_meter/rte_meter_version.map > @@ -17,3 +17,12 @@ DPDK_18.08 { > rte_meter_srtcm_profile_config; > rte_meter_trtcm_profile_config; > }; > + > +EXPERIMENTAL { > + global: > + > + rte_meter_trtcm_rfc4115_color_aware_check; > + rte_meter_trtcm_rfc4115_color_blind_check; > + rte_meter_trtcm_rfc4115_config; > + rte_meter_trtcm_rfc4115_profile_config; > +}; Regards, Cristian