[PATCH v2 16/22] pdcp: add timer expiry handle
Akhil Goyal
gakhil at marvell.com
Thu May 18 11:43:05 CEST 2023
> Subject: [PATCH v2 16/22] pdcp: add timer expiry handle
>
> From: Volodymyr Fialko <vfialko at 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 <anoobj at marvell.com>
> Signed-off-by: Volodymyr Fialko <vfialko at 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
More information about the dev
mailing list