Skip to content

Commit

Permalink
cxgb4/ch_ktls: Clear resources when pf4 device is removed
Browse files Browse the repository at this point in the history
This patch maintain the list of active tids and clear all the active
connection resources when DETACH notification comes.

Fixes: a8c16e8 ("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>
  • Loading branch information
ayushsawl authored and davem330 committed May 13, 2021
1 parent e1d027d commit 65e302a
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 2 deletions.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
direction);
cxgb4_set_ktls_feature(adap, FW_PARAMS_PARAM_DEV_KTLS_HW_DISABLE);

out_unlock:
cxgb4_set_ktls_feature(adap, FW_PARAMS_PARAM_DEV_KTLS_HW_DISABLE);
mutex_unlock(&uld_mutex);
}

Expand Down
80 changes: 79 additions & 1 deletion drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 void clear_conn_resources(struct chcr_ktls_info *tx_info);
/*
* chcr_ktls_save_keys: calculate and save crypto keys.
* @tx_info - driver specific tls info.
Expand Down Expand Up @@ -364,10 +365,14 @@ static void chcr_ktls_dev_del(struct net_device *netdev,
chcr_get_ktls_tx_context(tls_ctx);
struct chcr_ktls_info *tx_info = tx_ctx->chcr_info;
struct ch_ktls_port_stats_debug *port_stats;
struct chcr_ktls_uld_ctx *u_ctx;

if (!tx_info)
return;

u_ctx = tx_info->adap->uld[CXGB4_ULD_KTLS].handle;
if (u_ctx && u_ctx->detach)
return;
/* clear l2t entry */
if (tx_info->l2te)
cxgb4_l2t_release(tx_info->l2te);
Expand All @@ -384,6 +389,8 @@ static void chcr_ktls_dev_del(struct net_device *netdev,
if (tx_info->tid != -1) {
cxgb4_remove_tid(&tx_info->adap->tids, tx_info->tx_chan,
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];
Expand Down Expand Up @@ -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 ch_ktls_port_stats_debug *port_stats;
struct chcr_ktls_ofld_ctx_tx *tx_ctx;
struct chcr_ktls_uld_ctx *u_ctx;
struct chcr_ktls_info *tx_info;
struct dst_entry *dst;
struct adapter *adap;
Expand All @@ -425,6 +433,7 @@ static int chcr_ktls_dev_add(struct net_device *netdev, struct sock *sk,
adap = pi->adapter;
port_stats = &adap->ch_ktls_stats.ktls_port[pi->port_id];
atomic64_inc(&port_stats->ktls_tx_connection_open);
u_ctx = adap->uld[CXGB4_ULD_KTLS].handle;

if (direction == TLS_OFFLOAD_CTX_DIR_RX) {
pr_err("not expecting for RX direction\n");
Expand All @@ -434,6 +443,9 @@ static int chcr_ktls_dev_add(struct net_device *netdev, struct sock *sk,
if (tx_ctx->chcr_info)
goto out;

if (u_ctx && u_ctx->detach)
goto out;

tx_info = kvzalloc(sizeof(*tx_info), GFP_KERNEL);
if (!tx_info)
goto out;
Expand Down Expand Up @@ -569,6 +581,8 @@ static int chcr_ktls_dev_add(struct net_device *netdev, struct sock *sk,
cxgb4_remove_tid(&tx_info->adap->tids, tx_info->tx_chan,
tx_info->tid, tx_info->ip_family);

xa_erase(&u_ctx->tid_list, tx_info->tid);

put_module:
/* release module refcount */
module_put(THIS_MODULE);
Expand Down Expand Up @@ -633,8 +647,12 @@ static int chcr_ktls_cpl_act_open_rpl(struct adapter *adap,
{
const struct cpl_act_open_rpl *p = (void *)input;
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;
struct tls_context *tls_ctx;
struct tid_info *t;
int ret = 0;

tid = GET_TID(p);
status = AOPEN_STATUS_G(ntohl(p->atid_status));
Expand Down Expand Up @@ -666,14 +684,29 @@ static int chcr_ktls_cpl_act_open_rpl(struct adapter *adap,
if (!status) {
tx_info->tid = tid;
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;
} else {
tx_info->open_state = CH_KTLS_OPEN_FAILURE;
}
out:
spin_unlock(&tx_info->lock);

complete(&tx_info->completion);
return 0;
return ret;
}

/*
Expand Down Expand Up @@ -2090,6 +2123,8 @@ static void *chcr_ktls_uld_add(const struct cxgb4_lld_info *lldi)
goto out;
}
u_ctx->lldi = *lldi;
u_ctx->detach = false;
xa_init_flags(&u_ctx->tid_list, XA_FLAGS_LOCK_BH);
out:
return u_ctx;
}
Expand Down Expand Up @@ -2123,6 +2158,45 @@ static int chcr_ktls_uld_rx_handler(void *handle, const __be64 *rsp,
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)
{
struct chcr_ktls_uld_ctx *u_ctx = handle;
Expand All @@ -2139,7 +2213,10 @@ static int chcr_ktls_uld_state_change(void *handle, enum cxgb4_state new_state)
case CXGB4_STATE_DETACH:
pr_info("%s: Down\n", pci_name(u_ctx->lldi.pdev));
mutex_lock(&dev_mutex);
u_ctx->detach = true;
list_del(&u_ctx->entry);
ch_ktls_reset_all_conn(u_ctx);
xa_destroy(&u_ctx->tid_list);
mutex_unlock(&dev_mutex);
break;
default:
Expand Down Expand Up @@ -2178,6 +2255,7 @@ static void __exit chcr_ktls_exit(void)
adap = pci_get_drvdata(u_ctx->lldi.pdev);
memset(&adap->ch_ktls_stats, 0, sizeof(adap->ch_ktls_stats));
list_del(&u_ctx->entry);
xa_destroy(&u_ctx->tid_list);
kfree(u_ctx);
}
mutex_unlock(&dev_mutex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ struct chcr_ktls_ofld_ctx_tx {
struct chcr_ktls_uld_ctx {
struct list_head entry;
struct cxgb4_lld_info lldi;
struct xarray tid_list;
bool detach;
};

static inline struct chcr_ktls_ofld_ctx_tx *
Expand Down

0 comments on commit 65e302a

Please sign in to comment.