> Subject: [PATCH v2 16/22] pdcp: add timer expiry handle > > From: Volodymyr Fialko <vfia...@marvell.com> > > The PDCP protocol requires usage of timers to keep track of how long > an out-of-order packet should be buffered while waiting for missing > packets. Applications can register a desired timer implementation with the > PDCP library. Once the timer expires, the application will be notified, and > further handling of the event will be performed in the PDCP library. > > When the timer expires, the PDCP library will return the cached packets, > and PDCP internal state variables (like RX_REORD, RX_DELIV etc) will be > updated accordingly. > > Signed-off-by: Anoob Joseph <ano...@marvell.com> > Signed-off-by: Volodymyr Fialko <vfia...@marvell.com> > --- > doc/guides/prog_guide/pdcp_lib.rst | 29 ++++++++++++++++++ > lib/pdcp/pdcp_process.c | 49 ++++++++++++++++++++++++++++++ > lib/pdcp/rte_pdcp.h | 31 +++++++++++++++++++ > lib/pdcp/version.map | 2 ++ > 4 files changed, 111 insertions(+) > > diff --git a/doc/guides/prog_guide/pdcp_lib.rst > b/doc/guides/prog_guide/pdcp_lib.rst > index f23360dfc3..32370633e5 100644 > --- a/doc/guides/prog_guide/pdcp_lib.rst > +++ b/doc/guides/prog_guide/pdcp_lib.rst > @@ -229,6 +229,35 @@ parameters for entity creation. > } > } > > +Timers > +------ > + > +PDCP utilizes a reception window mechanism to limit the bits of COUNT value > +transmitted in the packet. It utilizes state variables such as RX_REORD, > +RX_DELIV to define the window and uses RX_DELIV as the lower pivot point of > the > +window. > + > +RX_DELIV would be updated only when packets are received in-order. Any > missing > +packet would mean RX_DELIV won't be updated. A timer, t-Reordering, helps > PDCP > +to slide the window if the missing packet is not received in a specified time > +duration. > + > +While starting and stopping the timer need to be done by lib PDCP, > application > +could register its own timer implementation. This is to make sure application > +can choose between timers such as rte_timer and rte_event based timers. > Starting > +and stopping of timer would happen during pre & post process API. > + > +When the t-Reordering timer expires, application would receive the expiry > event. > +To perform the PDCP handling of the expiry event, > +``rte_pdcp_t_reordering_expiry_handle`` can be used. Expiry handling would > +involve sliding the window by updating state variables and passing the > expired > +packets to the application. > + > +.. literalinclude:: ../../../lib/pdcp/rte_pdcp.h > + :language: c > + :start-after: Structure rte_pdcp_t_reordering 8< > + :end-before: >8 End of structure rte_pdcp_t_reordering. > + > > Supported features > ------------------ > diff --git a/lib/pdcp/pdcp_process.c b/lib/pdcp/pdcp_process.c > index 9ba07d5255..91b87a2a81 100644 > --- a/lib/pdcp/pdcp_process.c > +++ b/lib/pdcp/pdcp_process.c > @@ -1285,3 +1285,52 @@ pdcp_process_func_set(struct rte_pdcp_entity > *entity, const struct rte_pdcp_enti > > return 0; > } > + > +uint16_t > +rte_pdcp_t_reordering_expiry_handle(const struct rte_pdcp_entity *entity, > struct rte_mbuf *out_mb[])
Move this public API implementation to rte_pdcp.c > +{ > + struct entity_priv_dl_part *dl = entity_dl_part_get(entity); > + struct entity_priv *en_priv = entity_priv_get(entity); > + uint16_t capacity = entity->max_pkt_cache; > + uint16_t nb_out, nb_seq; > + > + /* 5.2.2.2 Actions when a t-Reordering expires */ > + > + /* > + * - deliver to upper layers in ascending order of the associated COUNT > value after > + * performing header decompression, if not decompressed before: > + */ > + > + /* - all stored PDCP SDU(s) with associated COUNT value(s) < > RX_REORD; */ > + nb_out = pdcp_reorder_up_to_get(&dl->reorder, out_mb, capacity, > en_priv->state.rx_reord); > + capacity -= nb_out; > + out_mb = &out_mb[nb_out]; > + > + /* > + * - all stored PDCP SDU(s) with consecutively associated COUNT > value(s) starting from > + * RX_REORD; > + */ > + nb_seq = pdcp_reorder_get_sequential(&dl->reorder, out_mb, > capacity); > + nb_out += nb_seq; > + > + /* > + * - update RX_DELIV to the COUNT value of the first PDCP SDU which > has not been delivered > + * to upper layers, with COUNT value >= RX_REORD; > + */ > + en_priv->state.rx_deliv = en_priv->state.rx_reord + nb_seq; > + > + /* > + * - if RX_DELIV < RX_NEXT: > + * - update RX_REORD to RX_NEXT; > + * - start t-Reordering. > + */ > + if (en_priv->state.rx_deliv < en_priv->state.rx_next) { > + en_priv->state.rx_reord = en_priv->state.rx_next; > + dl->t_reorder.state = TIMER_RUNNING; > + dl->t_reorder.handle.start(dl->t_reorder.handle.timer, dl- > >t_reorder.handle.args); > + } else { > + dl->t_reorder.state = TIMER_EXPIRED; > + } > + > + return nb_out; > +} > diff --git a/lib/pdcp/rte_pdcp.h b/lib/pdcp/rte_pdcp.h > index 55e57c3b9b..c077acce63 100644 > --- a/lib/pdcp/rte_pdcp.h > +++ b/lib/pdcp/rte_pdcp.h > @@ -100,6 +100,7 @@ typedef void (*rte_pdcp_t_reordering_stop_cb_t)(void > *timer, void *args); > * > * Configuration provided by user, that PDCP library will invoke according to > timer behaviour. > */ > +/* Structure rte_pdcp_t_reordering 8< */ > struct rte_pdcp_t_reordering { > /** Timer pointer, stored for later use in callback functions */ > void *timer; > @@ -110,6 +111,7 @@ struct rte_pdcp_t_reordering { > /** Timer start callback handle */ > rte_pdcp_t_reordering_stop_cb_t stop; > }; > +/* >8 End of structure rte_pdcp_t_reordering. */ > > /** > * PDCP entity configuration to be used for establishing an entity. > @@ -327,6 +329,35 @@ rte_pdcp_pkt_post_process(const struct > rte_pdcp_entity *entity, > return entity->post_process(entity, in_mb, out_mb, num, nb_err); > } > > +/** > + * @warning > + * @b EXPERIMENTAL: this API may change without prior notice > + * > + * 5.2.2.2 Actions when a t-Reordering expires > + * > + * When t-Reordering timer expires, PDCP is required to slide the reception > + * window by updating state variables such as RX_REORD & RX_DELIV. PDCP > would > + * need to deliver some of the buffered packets based on the state variables > and > + * conditions described. > + * > + * The expiry handle need to be invoked by the application when t-Reordering > + * timer expires. In addition to returning buffered packets, it may also > restart > + * timer based on the state variables. > + * > + * @param entity > + * Pointer to the *rte_pdcp_entity* for which the timer expired. > + * @param[out] out_mb > + * The address of an array that can hold up to > *rte_pdcp_entity.max_pkt_cache* > + * pointers to *rte_mbuf* structures. Used to return buffered packets that > are > + * expired. > + * @return > + * Number of packets returned in *out_mb* buffer. > + */ > +__rte_experimental > +uint16_t > +rte_pdcp_t_reordering_expiry_handle(const struct rte_pdcp_entity *entity, > + struct rte_mbuf *out_mb[]); > + > #include <rte_pdcp_group.h> > > #ifdef __cplusplus > diff --git a/lib/pdcp/version.map b/lib/pdcp/version.map > index d0cf338e1f..89b0463be6 100644 > --- a/lib/pdcp/version.map > +++ b/lib/pdcp/version.map > @@ -11,5 +11,7 @@ EXPERIMENTAL { > rte_pdcp_pkt_post_process; > rte_pdcp_pkt_pre_process; > > + rte_pdcp_t_reordering_expiry_handle; > + > local: *; > }; > -- > 2.25.1