cxgb4/ch_ktls: Clear resources when pf4 device is removed
This patch maintain the list of active tids and clear all the active
connection resources when DETACH notification comes.
Fixes: a8c16e8ed6
("crypto/chcr: move nic TLS functionality to drivers/net")
Signed-off-by: Ayush Sawal <ayush.sawal@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
e1d027dd97
Коммит
65e302a9bd
|
@ -6480,9 +6480,9 @@ static void cxgb4_ktls_dev_del(struct net_device *netdev,
|
||||||
|
|
||||||
adap->uld[CXGB4_ULD_KTLS].tlsdev_ops->tls_dev_del(netdev, tls_ctx,
|
adap->uld[CXGB4_ULD_KTLS].tlsdev_ops->tls_dev_del(netdev, tls_ctx,
|
||||||
direction);
|
direction);
|
||||||
cxgb4_set_ktls_feature(adap, FW_PARAMS_PARAM_DEV_KTLS_HW_DISABLE);
|
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
|
cxgb4_set_ktls_feature(adap, FW_PARAMS_PARAM_DEV_KTLS_HW_DISABLE);
|
||||||
mutex_unlock(&uld_mutex);
|
mutex_unlock(&uld_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@ static int chcr_get_nfrags_to_send(struct sk_buff *skb, u32 start, u32 len)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int chcr_init_tcb_fields(struct chcr_ktls_info *tx_info);
|
static int chcr_init_tcb_fields(struct chcr_ktls_info *tx_info);
|
||||||
|
static void clear_conn_resources(struct chcr_ktls_info *tx_info);
|
||||||
/*
|
/*
|
||||||
* chcr_ktls_save_keys: calculate and save crypto keys.
|
* chcr_ktls_save_keys: calculate and save crypto keys.
|
||||||
* @tx_info - driver specific tls info.
|
* @tx_info - driver specific tls info.
|
||||||
|
@ -364,10 +365,14 @@ static void chcr_ktls_dev_del(struct net_device *netdev,
|
||||||
chcr_get_ktls_tx_context(tls_ctx);
|
chcr_get_ktls_tx_context(tls_ctx);
|
||||||
struct chcr_ktls_info *tx_info = tx_ctx->chcr_info;
|
struct chcr_ktls_info *tx_info = tx_ctx->chcr_info;
|
||||||
struct ch_ktls_port_stats_debug *port_stats;
|
struct ch_ktls_port_stats_debug *port_stats;
|
||||||
|
struct chcr_ktls_uld_ctx *u_ctx;
|
||||||
|
|
||||||
if (!tx_info)
|
if (!tx_info)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
u_ctx = tx_info->adap->uld[CXGB4_ULD_KTLS].handle;
|
||||||
|
if (u_ctx && u_ctx->detach)
|
||||||
|
return;
|
||||||
/* clear l2t entry */
|
/* clear l2t entry */
|
||||||
if (tx_info->l2te)
|
if (tx_info->l2te)
|
||||||
cxgb4_l2t_release(tx_info->l2te);
|
cxgb4_l2t_release(tx_info->l2te);
|
||||||
|
@ -384,6 +389,8 @@ static void chcr_ktls_dev_del(struct net_device *netdev,
|
||||||
if (tx_info->tid != -1) {
|
if (tx_info->tid != -1) {
|
||||||
cxgb4_remove_tid(&tx_info->adap->tids, tx_info->tx_chan,
|
cxgb4_remove_tid(&tx_info->adap->tids, tx_info->tx_chan,
|
||||||
tx_info->tid, tx_info->ip_family);
|
tx_info->tid, tx_info->ip_family);
|
||||||
|
|
||||||
|
xa_erase(&u_ctx->tid_list, tx_info->tid);
|
||||||
}
|
}
|
||||||
|
|
||||||
port_stats = &tx_info->adap->ch_ktls_stats.ktls_port[tx_info->port_id];
|
port_stats = &tx_info->adap->ch_ktls_stats.ktls_port[tx_info->port_id];
|
||||||
|
@ -411,6 +418,7 @@ static int chcr_ktls_dev_add(struct net_device *netdev, struct sock *sk,
|
||||||
struct tls_context *tls_ctx = tls_get_ctx(sk);
|
struct tls_context *tls_ctx = tls_get_ctx(sk);
|
||||||
struct ch_ktls_port_stats_debug *port_stats;
|
struct ch_ktls_port_stats_debug *port_stats;
|
||||||
struct chcr_ktls_ofld_ctx_tx *tx_ctx;
|
struct chcr_ktls_ofld_ctx_tx *tx_ctx;
|
||||||
|
struct chcr_ktls_uld_ctx *u_ctx;
|
||||||
struct chcr_ktls_info *tx_info;
|
struct chcr_ktls_info *tx_info;
|
||||||
struct dst_entry *dst;
|
struct dst_entry *dst;
|
||||||
struct adapter *adap;
|
struct adapter *adap;
|
||||||
|
@ -425,6 +433,7 @@ static int chcr_ktls_dev_add(struct net_device *netdev, struct sock *sk,
|
||||||
adap = pi->adapter;
|
adap = pi->adapter;
|
||||||
port_stats = &adap->ch_ktls_stats.ktls_port[pi->port_id];
|
port_stats = &adap->ch_ktls_stats.ktls_port[pi->port_id];
|
||||||
atomic64_inc(&port_stats->ktls_tx_connection_open);
|
atomic64_inc(&port_stats->ktls_tx_connection_open);
|
||||||
|
u_ctx = adap->uld[CXGB4_ULD_KTLS].handle;
|
||||||
|
|
||||||
if (direction == TLS_OFFLOAD_CTX_DIR_RX) {
|
if (direction == TLS_OFFLOAD_CTX_DIR_RX) {
|
||||||
pr_err("not expecting for RX direction\n");
|
pr_err("not expecting for RX direction\n");
|
||||||
|
@ -434,6 +443,9 @@ static int chcr_ktls_dev_add(struct net_device *netdev, struct sock *sk,
|
||||||
if (tx_ctx->chcr_info)
|
if (tx_ctx->chcr_info)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
if (u_ctx && u_ctx->detach)
|
||||||
|
goto out;
|
||||||
|
|
||||||
tx_info = kvzalloc(sizeof(*tx_info), GFP_KERNEL);
|
tx_info = kvzalloc(sizeof(*tx_info), GFP_KERNEL);
|
||||||
if (!tx_info)
|
if (!tx_info)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -569,6 +581,8 @@ free_tid:
|
||||||
cxgb4_remove_tid(&tx_info->adap->tids, tx_info->tx_chan,
|
cxgb4_remove_tid(&tx_info->adap->tids, tx_info->tx_chan,
|
||||||
tx_info->tid, tx_info->ip_family);
|
tx_info->tid, tx_info->ip_family);
|
||||||
|
|
||||||
|
xa_erase(&u_ctx->tid_list, tx_info->tid);
|
||||||
|
|
||||||
put_module:
|
put_module:
|
||||||
/* release module refcount */
|
/* release module refcount */
|
||||||
module_put(THIS_MODULE);
|
module_put(THIS_MODULE);
|
||||||
|
@ -633,8 +647,12 @@ static int chcr_ktls_cpl_act_open_rpl(struct adapter *adap,
|
||||||
{
|
{
|
||||||
const struct cpl_act_open_rpl *p = (void *)input;
|
const struct cpl_act_open_rpl *p = (void *)input;
|
||||||
struct chcr_ktls_info *tx_info = NULL;
|
struct chcr_ktls_info *tx_info = NULL;
|
||||||
|
struct chcr_ktls_ofld_ctx_tx *tx_ctx;
|
||||||
|
struct chcr_ktls_uld_ctx *u_ctx;
|
||||||
unsigned int atid, tid, status;
|
unsigned int atid, tid, status;
|
||||||
|
struct tls_context *tls_ctx;
|
||||||
struct tid_info *t;
|
struct tid_info *t;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
tid = GET_TID(p);
|
tid = GET_TID(p);
|
||||||
status = AOPEN_STATUS_G(ntohl(p->atid_status));
|
status = AOPEN_STATUS_G(ntohl(p->atid_status));
|
||||||
|
@ -666,14 +684,29 @@ static int chcr_ktls_cpl_act_open_rpl(struct adapter *adap,
|
||||||
if (!status) {
|
if (!status) {
|
||||||
tx_info->tid = tid;
|
tx_info->tid = tid;
|
||||||
cxgb4_insert_tid(t, tx_info, tx_info->tid, tx_info->ip_family);
|
cxgb4_insert_tid(t, tx_info, tx_info->tid, tx_info->ip_family);
|
||||||
|
/* Adding tid */
|
||||||
|
tls_ctx = tls_get_ctx(tx_info->sk);
|
||||||
|
tx_ctx = chcr_get_ktls_tx_context(tls_ctx);
|
||||||
|
u_ctx = adap->uld[CXGB4_ULD_KTLS].handle;
|
||||||
|
if (u_ctx) {
|
||||||
|
ret = xa_insert_bh(&u_ctx->tid_list, tid, tx_ctx,
|
||||||
|
GFP_NOWAIT);
|
||||||
|
if (ret < 0) {
|
||||||
|
pr_err("%s: Failed to allocate tid XA entry = %d\n",
|
||||||
|
__func__, tx_info->tid);
|
||||||
|
tx_info->open_state = CH_KTLS_OPEN_FAILURE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
tx_info->open_state = CH_KTLS_OPEN_SUCCESS;
|
tx_info->open_state = CH_KTLS_OPEN_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
tx_info->open_state = CH_KTLS_OPEN_FAILURE;
|
tx_info->open_state = CH_KTLS_OPEN_FAILURE;
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
spin_unlock(&tx_info->lock);
|
spin_unlock(&tx_info->lock);
|
||||||
|
|
||||||
complete(&tx_info->completion);
|
complete(&tx_info->completion);
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2090,6 +2123,8 @@ static void *chcr_ktls_uld_add(const struct cxgb4_lld_info *lldi)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
u_ctx->lldi = *lldi;
|
u_ctx->lldi = *lldi;
|
||||||
|
u_ctx->detach = false;
|
||||||
|
xa_init_flags(&u_ctx->tid_list, XA_FLAGS_LOCK_BH);
|
||||||
out:
|
out:
|
||||||
return u_ctx;
|
return u_ctx;
|
||||||
}
|
}
|
||||||
|
@ -2123,6 +2158,45 @@ static int chcr_ktls_uld_rx_handler(void *handle, const __be64 *rsp,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void clear_conn_resources(struct chcr_ktls_info *tx_info)
|
||||||
|
{
|
||||||
|
/* clear l2t entry */
|
||||||
|
if (tx_info->l2te)
|
||||||
|
cxgb4_l2t_release(tx_info->l2te);
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_IPV6)
|
||||||
|
/* clear clip entry */
|
||||||
|
if (tx_info->ip_family == AF_INET6)
|
||||||
|
cxgb4_clip_release(tx_info->netdev, (const u32 *)
|
||||||
|
&tx_info->sk->sk_v6_rcv_saddr,
|
||||||
|
1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* clear tid */
|
||||||
|
if (tx_info->tid != -1)
|
||||||
|
cxgb4_remove_tid(&tx_info->adap->tids, tx_info->tx_chan,
|
||||||
|
tx_info->tid, tx_info->ip_family);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ch_ktls_reset_all_conn(struct chcr_ktls_uld_ctx *u_ctx)
|
||||||
|
{
|
||||||
|
struct ch_ktls_port_stats_debug *port_stats;
|
||||||
|
struct chcr_ktls_ofld_ctx_tx *tx_ctx;
|
||||||
|
struct chcr_ktls_info *tx_info;
|
||||||
|
unsigned long index;
|
||||||
|
|
||||||
|
xa_for_each(&u_ctx->tid_list, index, tx_ctx) {
|
||||||
|
tx_info = tx_ctx->chcr_info;
|
||||||
|
clear_conn_resources(tx_info);
|
||||||
|
port_stats = &tx_info->adap->ch_ktls_stats.ktls_port[tx_info->port_id];
|
||||||
|
atomic64_inc(&port_stats->ktls_tx_connection_close);
|
||||||
|
kvfree(tx_info);
|
||||||
|
tx_ctx->chcr_info = NULL;
|
||||||
|
/* release module refcount */
|
||||||
|
module_put(THIS_MODULE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int chcr_ktls_uld_state_change(void *handle, enum cxgb4_state new_state)
|
static int chcr_ktls_uld_state_change(void *handle, enum cxgb4_state new_state)
|
||||||
{
|
{
|
||||||
struct chcr_ktls_uld_ctx *u_ctx = handle;
|
struct chcr_ktls_uld_ctx *u_ctx = handle;
|
||||||
|
@ -2139,7 +2213,10 @@ static int chcr_ktls_uld_state_change(void *handle, enum cxgb4_state new_state)
|
||||||
case CXGB4_STATE_DETACH:
|
case CXGB4_STATE_DETACH:
|
||||||
pr_info("%s: Down\n", pci_name(u_ctx->lldi.pdev));
|
pr_info("%s: Down\n", pci_name(u_ctx->lldi.pdev));
|
||||||
mutex_lock(&dev_mutex);
|
mutex_lock(&dev_mutex);
|
||||||
|
u_ctx->detach = true;
|
||||||
list_del(&u_ctx->entry);
|
list_del(&u_ctx->entry);
|
||||||
|
ch_ktls_reset_all_conn(u_ctx);
|
||||||
|
xa_destroy(&u_ctx->tid_list);
|
||||||
mutex_unlock(&dev_mutex);
|
mutex_unlock(&dev_mutex);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -2178,6 +2255,7 @@ static void __exit chcr_ktls_exit(void)
|
||||||
adap = pci_get_drvdata(u_ctx->lldi.pdev);
|
adap = pci_get_drvdata(u_ctx->lldi.pdev);
|
||||||
memset(&adap->ch_ktls_stats, 0, sizeof(adap->ch_ktls_stats));
|
memset(&adap->ch_ktls_stats, 0, sizeof(adap->ch_ktls_stats));
|
||||||
list_del(&u_ctx->entry);
|
list_del(&u_ctx->entry);
|
||||||
|
xa_destroy(&u_ctx->tid_list);
|
||||||
kfree(u_ctx);
|
kfree(u_ctx);
|
||||||
}
|
}
|
||||||
mutex_unlock(&dev_mutex);
|
mutex_unlock(&dev_mutex);
|
||||||
|
|
|
@ -75,6 +75,8 @@ struct chcr_ktls_ofld_ctx_tx {
|
||||||
struct chcr_ktls_uld_ctx {
|
struct chcr_ktls_uld_ctx {
|
||||||
struct list_head entry;
|
struct list_head entry;
|
||||||
struct cxgb4_lld_info lldi;
|
struct cxgb4_lld_info lldi;
|
||||||
|
struct xarray tid_list;
|
||||||
|
bool detach;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct chcr_ktls_ofld_ctx_tx *
|
static inline struct chcr_ktls_ofld_ctx_tx *
|
||||||
|
|
Загрузка…
Ссылка в новой задаче