net/bnxt: add context list for timers

Add context in ULP for timers.
The alarm callback needs to have a valid context pointer when it is
invoked. The context could become invalid if the port goes down and
the callback is invoked before it is cancelled.

Signed-off-by: Kishore Padmanabha <kishore.padmanabha@broadcom.com>
Signed-off-by: Venkat Duvvuru <venkatkumar.duvvuru@broadcom.com>
Reviewed-by: Randy Schacher <stuart.schacher@broadcom.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
This commit is contained in:
Kishore Padmanabha 2021-05-30 14:29:26 +05:30 committed by Ajit Khaparde
parent a4d4308ef1
commit d75b55121b
4 changed files with 145 additions and 31 deletions

View File

@ -8,6 +8,7 @@
#include <rte_flow.h>
#include <rte_flow_driver.h>
#include <rte_tailq.h>
#include <rte_spinlock.h>
#include "bnxt.h"
#include "bnxt_ulp.h"
@ -32,6 +33,17 @@ STAILQ_HEAD(, bnxt_ulp_session_state) bnxt_ulp_session_list =
/* Mutex to synchronize bnxt_ulp_session_list operations. */
static pthread_mutex_t bnxt_ulp_global_mutex = PTHREAD_MUTEX_INITIALIZER;
/* Spin lock to protect context global list */
rte_spinlock_t bnxt_ulp_ctxt_lock;
TAILQ_HEAD(cntx_list_entry_list, ulp_context_list_entry);
static struct cntx_list_entry_list ulp_cntx_list =
TAILQ_HEAD_INITIALIZER(ulp_cntx_list);
/* Static function declarations */
static int32_t bnxt_ulp_cntxt_list_init(void);
static int32_t bnxt_ulp_cntxt_list_add(struct bnxt_ulp_context *ulp_ctx);
static void bnxt_ulp_cntxt_list_del(struct bnxt_ulp_context *ulp_ctx);
/*
* Allow the deletion of context only for the bnxt device that
* created the session.
@ -743,6 +755,16 @@ ulp_ctx_init(struct bnxt *bp,
int32_t rc = 0;
enum bnxt_ulp_device_id devid;
/* Initialize the context entries list */
bnxt_ulp_cntxt_list_init();
/* Add the context to the context entries list */
rc = bnxt_ulp_cntxt_list_add(bp->ulp_ctx);
if (rc) {
BNXT_TF_DBG(ERR, "Failed to add the context list entry\n");
return -ENOMEM;
}
/* Allocate memory to hold ulp context data. */
ulp_data = rte_zmalloc("bnxt_ulp_data",
sizeof(struct bnxt_ulp_data), 0);
@ -878,6 +900,13 @@ ulp_ctx_attach(struct bnxt *bp,
/* update the session details in bnxt tfp */
bp->tfp.session = session->g_tfp->session;
/* Add the context to the context entries list */
rc = bnxt_ulp_cntxt_list_add(bp->ulp_ctx);
if (rc) {
BNXT_TF_DBG(ERR, "Failed to add the context list entry\n");
return -EINVAL;
}
/*
* The supported flag will be set during the init. Use it now to
* know if we should go through the attach.
@ -1448,6 +1477,9 @@ bnxt_ulp_port_deinit(struct bnxt *bp)
BNXT_TF_DBG(DEBUG, "BNXT Port:%d ULP port deinit\n",
bp->eth_dev->data->port_id);
/* Free the ulp context in the context entry list */
bnxt_ulp_cntxt_list_del(bp->ulp_ctx);
/* Get the session details */
pci_dev = RTE_DEV_TO_PCI(bp->eth_dev->device);
pci_addr = &pci_dev->addr;
@ -1887,3 +1919,66 @@ bnxt_ulp_cntxt_ha_enabled(struct bnxt_ulp_context *ulp_ctx)
return false;
return !!ULP_HIGH_AVAIL_IS_ENABLED(ulp_ctx->cfg_data->ulp_flags);
}
static int32_t
bnxt_ulp_cntxt_list_init(void)
{
/* Create the cntxt spin lock */
rte_spinlock_init(&bnxt_ulp_ctxt_lock);
return 0;
}
static int32_t
bnxt_ulp_cntxt_list_add(struct bnxt_ulp_context *ulp_ctx)
{
struct ulp_context_list_entry *entry;
entry = rte_zmalloc(NULL, sizeof(struct ulp_context_list_entry), 0);
if (entry == NULL) {
BNXT_TF_DBG(ERR, "unable to allocate memory\n");
return -ENOMEM;
}
rte_spinlock_lock(&bnxt_ulp_ctxt_lock);
entry->ulp_ctx = ulp_ctx;
TAILQ_INSERT_TAIL(&ulp_cntx_list, entry, next);
rte_spinlock_unlock(&bnxt_ulp_ctxt_lock);
return 0;
}
static void
bnxt_ulp_cntxt_list_del(struct bnxt_ulp_context *ulp_ctx)
{
struct ulp_context_list_entry *entry, *temp;
rte_spinlock_lock(&bnxt_ulp_ctxt_lock);
TAILQ_FOREACH_SAFE(entry, &ulp_cntx_list, next, temp) {
if (entry->ulp_ctx == ulp_ctx) {
TAILQ_REMOVE(&ulp_cntx_list, entry, next);
rte_free(entry);
break;
}
}
rte_spinlock_unlock(&bnxt_ulp_ctxt_lock);
}
struct bnxt_ulp_context *
bnxt_ulp_cntxt_entry_acquire(void)
{
struct ulp_context_list_entry *entry;
/* take a lock and get the first ulp context available */
if (rte_spinlock_trylock(&bnxt_ulp_ctxt_lock)) {
TAILQ_FOREACH(entry, &ulp_cntx_list, next)
if (entry->ulp_ctx)
return entry->ulp_ctx;
}
return NULL;
}
void
bnxt_ulp_cntxt_entry_release(void)
{
rte_spinlock_unlock(&bnxt_ulp_ctxt_lock);
}

View File

@ -112,6 +112,11 @@ struct ulp_tlv_param {
uint8_t value[16];
};
struct ulp_context_list_entry {
TAILQ_ENTRY(ulp_context_list_entry) next;
struct bnxt_ulp_context *ulp_ctx;
};
/*
* Allow the deletion of context only for the bnxt device that
* created the session
@ -285,4 +290,11 @@ bnxt_ulp_cntxt_ptr2_ha_info_get(struct bnxt_ulp_context *ulp_ctx);
bool
bnxt_ulp_cntxt_ha_enabled(struct bnxt_ulp_context *ulp_ctx);
struct bnxt_ulp_context *
bnxt_ulp_cntxt_entry_acquire(void);
void
bnxt_ulp_cntxt_entry_release(void);
#endif /* _BNXT_ULP_H_ */

View File

@ -197,8 +197,7 @@ ulp_fc_mgr_thread_start(struct bnxt_ulp_context *ctxt)
if (ulp_fc_info && !(ulp_fc_info->flags & ULP_FLAG_FC_THREAD)) {
rte_eal_alarm_set(US_PER_S * ULP_FC_TIMER,
ulp_fc_mgr_alarm_cb,
(void *)ctxt);
ulp_fc_mgr_alarm_cb, NULL);
ulp_fc_info->flags |= ULP_FLAG_FC_THREAD;
}
@ -220,7 +219,7 @@ void ulp_fc_mgr_thread_cancel(struct bnxt_ulp_context *ctxt)
return;
ulp_fc_info->flags &= ~ULP_FLAG_FC_THREAD;
rte_eal_alarm_cancel(ulp_fc_mgr_alarm_cb, (void *)ctxt);
rte_eal_alarm_cancel(ulp_fc_mgr_alarm_cb, NULL);
}
/*
@ -363,35 +362,48 @@ static int ulp_get_single_flow_stat(struct bnxt_ulp_context *ctxt,
*/
void
ulp_fc_mgr_alarm_cb(void *arg)
ulp_fc_mgr_alarm_cb(void *arg __rte_unused)
{
int rc = 0;
unsigned int j;
enum tf_dir i;
struct bnxt_ulp_context *ctxt = arg;
struct bnxt_ulp_context *ctxt;
struct bnxt_ulp_fc_info *ulp_fc_info;
struct bnxt_ulp_device_params *dparms;
struct tf *tfp;
uint32_t dev_id, hw_cntr_id = 0, num_entries = 0;
ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ctxt);
if (!ulp_fc_info)
ctxt = bnxt_ulp_cntxt_entry_acquire();
if (ctxt == NULL) {
BNXT_TF_DBG(INFO, "could not get the ulp context lock\n");
rte_eal_alarm_set(US_PER_S * ULP_FC_TIMER,
ulp_fc_mgr_alarm_cb, NULL);
return;
}
ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ctxt);
if (!ulp_fc_info) {
bnxt_ulp_cntxt_entry_release();
return;
}
if (bnxt_ulp_cntxt_dev_id_get(ctxt, &dev_id)) {
BNXT_TF_DBG(DEBUG, "Failed to get device id\n");
bnxt_ulp_cntxt_entry_release();
return;
}
dparms = bnxt_ulp_device_params_get(dev_id);
if (!dparms) {
BNXT_TF_DBG(DEBUG, "Failed to device parms\n");
bnxt_ulp_cntxt_entry_release();
return;
}
tfp = bnxt_ulp_cntxt_tfp_get(ctxt, BNXT_ULP_SHARED_SESSION_NO);
if (!tfp) {
BNXT_TF_DBG(ERR, "Failed to get the truflow pointer\n");
bnxt_ulp_cntxt_entry_release();
return;
}
@ -405,6 +417,7 @@ ulp_fc_mgr_alarm_cb(void *arg)
if (!ulp_fc_info->num_entries) {
pthread_mutex_unlock(&ulp_fc_info->fc_lock);
ulp_fc_mgr_thread_cancel(ctxt);
bnxt_ulp_cntxt_entry_release();
return;
}
/*
@ -443,12 +456,13 @@ ulp_fc_mgr_alarm_cb(void *arg)
if (rc) {
ulp_fc_mgr_thread_cancel(ctxt);
bnxt_ulp_cntxt_entry_release();
return;
}
out:
bnxt_ulp_cntxt_entry_release();
rte_eal_alarm_set(US_PER_S * ULP_FC_TIMER,
ulp_fc_mgr_alarm_cb,
(void *)ctxt);
ulp_fc_mgr_alarm_cb, NULL);
}
/*

View File

@ -26,7 +26,7 @@
#define ULP_HA_IF_TBL_IDX 10
static void ulp_ha_mgr_timer_cancel(struct bnxt_ulp_context *ulp_ctx);
static int32_t ulp_ha_mgr_timer_start(struct bnxt_ulp_context *ulp_ctx);
static int32_t ulp_ha_mgr_timer_start(void);
static void ulp_ha_mgr_timer_cb(void *arg);
static int32_t ulp_ha_mgr_app_type_set(struct bnxt_ulp_context *ulp_ctx,
enum ulp_ha_mgr_app_type app_type);
@ -126,7 +126,7 @@ ulp_ha_mgr_app_type_set(struct bnxt_ulp_context *ulp_ctx,
* - Release the flow db lock for flows to continue
*/
static void
ulp_ha_mgr_timer_cb(void *arg)
ulp_ha_mgr_timer_cb(void *arg __rte_unused)
{
struct tf_move_tcam_shared_entries_parms mparms = { 0 };
struct bnxt_ulp_context *ulp_ctx;
@ -134,7 +134,13 @@ ulp_ha_mgr_timer_cb(void *arg)
struct tf *tfp;
int32_t rc;
ulp_ctx = (struct bnxt_ulp_context *)arg;
ulp_ctx = bnxt_ulp_cntxt_entry_acquire();
if (ulp_ctx == NULL) {
BNXT_TF_DBG(INFO, "could not get the ulp context lock\n");
ulp_ha_mgr_timer_start();
return;
}
rc = ulp_ha_mgr_state_get(ulp_ctx, &curr_state);
if (rc) {
/*
@ -180,31 +186,18 @@ ulp_ha_mgr_timer_cb(void *arg)
BNXT_TF_DBG(INFO, "On HA CB: SEC[SEC_TIMER_COPY] => PRIM[PRIM_RUN]\n");
unlock:
bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);
bnxt_ulp_cntxt_entry_release();
return;
cb_restart:
ulp_ha_mgr_timer_start(ulp_ctx);
bnxt_ulp_cntxt_entry_release();
ulp_ha_mgr_timer_start();
}
static int32_t
ulp_ha_mgr_timer_start(struct bnxt_ulp_context *ulp_ctx)
ulp_ha_mgr_timer_start(void)
{
struct bnxt_ulp_ha_mgr_info *ha_info;
if (ulp_ctx == NULL) {
BNXT_TF_DBG(ERR, "Invalid parmsi for ha timer start.\n");
return -EINVAL;
}
ha_info = bnxt_ulp_cntxt_ptr2_ha_info_get(ulp_ctx);
if (ha_info == NULL) {
BNXT_TF_DBG(ERR, "Unable to get HA Info in timer start.\n");
return -EINVAL;
}
ha_info->flags |= ULP_HA_TIMER_THREAD;
rte_eal_alarm_set(US_PER_S * ULP_HA_TIMER_SEC,
ulp_ha_mgr_timer_cb,
(void *)ulp_ctx);
ulp_ha_mgr_timer_cb, NULL);
return 0;
}
@ -374,7 +367,7 @@ ulp_ha_mgr_open(struct bnxt_ulp_context *ulp_ctx)
* Clear the high region so the secondary can begin overriding
* the current entries.
*/
rc = ulp_ha_mgr_timer_start(ulp_ctx);
rc = ulp_ha_mgr_timer_start();
if (rc) {
BNXT_TF_DBG(ERR, "Unable to start timer on HA Open.\n");
return -EINVAL;