qcacmn: Handle overflow of management rx reorder list

Deliver the oldest management frames to upper layers if
the management rx reorder list grows beyond the maximum
configured size.

Change-Id: Id0199849e26804310dd502051b8e14f56f0df795
CRs-Fixed: 3051431
Este commit está contenido en:
Edayilliam Jayadev
2021-10-06 13:38:30 +05:30
cometido por Madan Koyyalamudi
padre 7c24c73fd8
commit f1527f6374
Se han modificado 3 ficheros con 44 adiciones y 13 borrados

Ver fichero

@@ -570,21 +570,28 @@ mgmt_rx_reo_list_display(struct mgmt_rx_reo_list *reo_list,
* mgmt_rx_reo_list_entry_get_release_reason() - Helper API to get the reason
* for releasing the reorder list entry to upper layer.
* reorder list.
* @reo_list: Pointer to reorder list
* @entry: List entry
* @ts_latest_aged_out_frame: Global time stamp of latest aged out frame
*
* This API expects the caller to acquire the spin lock protecting the reorder
* list.
*
* Return: Reason for releasing the frame.
*/
static uint8_t
mgmt_rx_reo_list_entry_get_release_reason(
struct mgmt_rx_reo_list_entry *entry,
struct mgmt_rx_reo_global_ts_info *ts_latest_aged_out_frame)
struct mgmt_rx_reo_list *reo_list,
struct mgmt_rx_reo_list_entry *entry)
{
uint8_t release_reason = 0;
if (!entry || !ts_latest_aged_out_frame)
if (!reo_list || !entry)
return 0;
if (mgmt_rx_reo_list_max_size_exceeded(reo_list))
release_reason |=
MGMT_RX_REO_LIST_ENTRY_RELEASE_REASON_LIST_MAX_SIZE_EXCEEDED;
if (!MGMT_RX_REO_LIST_ENTRY_IS_WAITING_FOR_FRAME_ON_OTHER_LINK(entry))
release_reason |=
MGMT_RX_REO_LIST_ENTRY_RELEASE_REASON_ZERO_WAIT_COUNT;
@@ -593,9 +600,9 @@ mgmt_rx_reo_list_entry_get_release_reason(
release_reason |=
MGMT_RX_REO_LIST_ENTRY_RELEASE_REASON_AGED_OUT;
if (ts_latest_aged_out_frame->valid &&
if (reo_list->ts_latest_aged_out_frame.valid &&
MGMT_RX_REO_LIST_ENTRY_IS_OLDER_THAN_LATEST_AGED_OUT_FRAME(
ts_latest_aged_out_frame, entry))
&reo_list->ts_latest_aged_out_frame, entry))
release_reason |=
MGMT_RX_REO_LIST_ENTRY_RELEASE_REASON_OLDER_THAN_AGED_OUT_FRAME;
@@ -633,7 +640,7 @@ mgmt_rx_reo_list_entry_send_up(struct mgmt_rx_reo_list *reo_list,
ts_last_delivered_frame = &reo_list->ts_last_delivered_frame;
release_reason = mgmt_rx_reo_list_entry_get_release_reason(
entry, &reo_list->ts_latest_aged_out_frame);
reo_list, entry);
qdf_assert_always(release_reason != 0);
@@ -704,7 +711,8 @@ mgmt_rx_reo_list_is_ready_to_send_up_entry(struct mgmt_rx_reo_list *reo_list,
if (!reo_list || !entry)
return false;
return !MGMT_RX_REO_LIST_ENTRY_IS_WAITING_FOR_FRAME_ON_OTHER_LINK(
return mgmt_rx_reo_list_max_size_exceeded(reo_list) ||
!MGMT_RX_REO_LIST_ENTRY_IS_WAITING_FOR_FRAME_ON_OTHER_LINK(
entry) || MGMT_RX_REO_LIST_ENTRY_IS_AGED_OUT(entry) ||
(reo_list->ts_latest_aged_out_frame.valid &&
MGMT_RX_REO_LIST_ENTRY_IS_OLDER_THAN_LATEST_AGED_OUT_FRAME(
@@ -791,7 +799,7 @@ mgmt_rx_reo_list_ageout_timer_handler(void *arg)
qdf_list_for_each(&reo_list->list, cur_entry, node) {
if (cur_ts - cur_entry->insertion_ts >=
MGMT_RX_REO_LIST_TIMEOUT) {
reo_list->list_entry_timeout_us) {
uint32_t cur_entry_global_ts;
struct mgmt_rx_reo_global_ts_info *ts_ageout;
@@ -1130,7 +1138,9 @@ mgmt_rx_reo_list_init(struct mgmt_rx_reo_list *reo_list)
{
QDF_STATUS status;
reo_list->max_list_size = MGMT_RX_REO_MAX_LIST_SIZE;
reo_list->max_list_size = MGMT_RX_REO_LIST_MAX_SIZE;
reo_list->list_entry_timeout_us = MGMT_RX_REO_LIST_TIMEOUT_US;
qdf_list_create(&reo_list->list, reo_list->max_list_size);
qdf_spinlock_create(&reo_list->list_lock);

Ver fichero

@@ -32,10 +32,11 @@
#include <wlan_objmgr_pdev_obj.h>
#include <wlan_objmgr_psoc_obj.h>
#define MGMT_RX_REO_MAX_LIST_SIZE (100)
#define MGMT_RX_REO_LIST_TIMEOUT (10 * USEC_PER_MSEC)
#define MGMT_RX_REO_LIST_MAX_SIZE (100)
#define MGMT_RX_REO_LIST_TIMEOUT_US (10 * USEC_PER_MSEC)
#define MGMT_RX_REO_STATUS_WAIT_FOR_FRAME_ON_OTHER_LINKS (BIT(0))
#define MGMT_RX_REO_STATUS_AGED_OUT (BIT(1))
/**
* TODO: Dummy macro for Maximum MLO links on the system
* This is added only as a place holder for the time being.
@@ -47,6 +48,7 @@
#define MGMT_RX_REO_LIST_ENTRY_RELEASE_REASON_ZERO_WAIT_COUNT (BIT(0))
#define MGMT_RX_REO_LIST_ENTRY_RELEASE_REASON_AGED_OUT (BIT(1))
#define MGMT_RX_REO_LIST_ENTRY_RELEASE_REASON_OLDER_THAN_AGED_OUT_FRAME (BIT(2))
#define MGMT_RX_REO_LIST_ENTRY_RELEASE_REASON_LIST_MAX_SIZE_EXCEEDED (BIT(3))
#define MGMT_RX_REO_LIST_ENTRY_IS_WAITING_FOR_FRAME_ON_OTHER_LINK(entry) \
((entry)->status & MGMT_RX_REO_STATUS_WAIT_FOR_FRAME_ON_OTHER_LINKS)
@@ -142,6 +144,8 @@ struct mgmt_rx_reo_global_ts_info {
* @list: List used for reordering
* @list_lock: Lock to protect the list
* @max_list_size: Maximum size of the reorder list
* @list_entry_timeout_us: Time out value(microsecond) for the reorder list
* entries
* @ageout_timer: Periodic timer to age-out the list entries
* @ts_latest_aged_out_frame: Stores the global time stamp for the latest aged
* out frame. Latest aged out frame is the aged out frame in reorder list which
@@ -153,6 +157,7 @@ struct mgmt_rx_reo_list {
qdf_list_t list;
qdf_spinlock_t list_lock;
uint32_t max_list_size;
uint32_t list_entry_timeout_us;
qdf_timer_t ageout_timer;
struct mgmt_rx_reo_global_ts_info ts_latest_aged_out_frame;
struct mgmt_rx_reo_global_ts_info ts_last_delivered_frame;
@@ -336,5 +341,21 @@ QDF_STATUS
wlan_mgmt_rx_reo_algo_entry(struct wlan_objmgr_pdev *pdev,
struct mgmt_rx_reo_frame_descriptor *desc,
bool *is_queued);
/**
* mgmt_rx_reo_list_max_size_exceeded() - Helper API to check whether
* list has exceeded the maximum configured size
* @reo_list: Pointer to reorder list
*
* This API expects the caller to acquire the spin lock protecting the reorder
* list.
*
* Return: true if reorder list has exceeded the max size
*/
static inline bool
mgmt_rx_reo_list_max_size_exceeded(struct mgmt_rx_reo_list *reo_list)
{
return (qdf_list_size(&reo_list->list) > reo_list->max_list_size);
}
#endif /* WLAN_MGMT_RX_REO_SUPPORT */
#endif /* _WLAN_MGMT_TXRX_RX_REO_I_H */

Ver fichero

@@ -15,7 +15,7 @@
*/
/**
* DOC: cfg_mgmt_txrx.h
* DOC: cfg_mgmt_rx_reo.h
* This file contains cfg definitions of mgmt rx reo sub-component
*/