Commit b5dd4d69 authored by D. Wythe's avatar D. Wythe Committed by David S. Miller

net/smc: llc_conf_mutex refactor, replace it with rw_semaphore

llc_conf_mutex was used to protect links and link related configurations
in the same link group, for example, add or delete links. However,
in most cases, the protected critical area has only read semantics and
with no write semantics at all, such as obtaining a usable link or an
available rmb_desc.

This patch do simply code refactoring, replace mutex with rw_semaphore,
replace mutex_lock with down_write and replace mutex_unlock with
up_write.

Theoretically, this replacement is equivalent, but after this patch,
we can distinguish lock granularity according to different semantics
of critical areas.
Signed-off-by: default avatarD. Wythe <alibuda@linux.alibaba.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 88c940cc
...@@ -502,7 +502,7 @@ static int smcr_lgr_reg_sndbufs(struct smc_link *link, ...@@ -502,7 +502,7 @@ static int smcr_lgr_reg_sndbufs(struct smc_link *link,
return -EINVAL; return -EINVAL;
/* protect against parallel smcr_link_reg_buf() */ /* protect against parallel smcr_link_reg_buf() */
mutex_lock(&lgr->llc_conf_mutex); down_write(&lgr->llc_conf_mutex);
for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) { for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) {
if (!smc_link_active(&lgr->lnk[i])) if (!smc_link_active(&lgr->lnk[i]))
continue; continue;
...@@ -510,7 +510,7 @@ static int smcr_lgr_reg_sndbufs(struct smc_link *link, ...@@ -510,7 +510,7 @@ static int smcr_lgr_reg_sndbufs(struct smc_link *link,
if (rc) if (rc)
break; break;
} }
mutex_unlock(&lgr->llc_conf_mutex); up_write(&lgr->llc_conf_mutex);
return rc; return rc;
} }
...@@ -527,7 +527,7 @@ static int smcr_lgr_reg_rmbs(struct smc_link *link, ...@@ -527,7 +527,7 @@ static int smcr_lgr_reg_rmbs(struct smc_link *link,
/* protect against parallel smc_llc_cli_rkey_exchange() and /* protect against parallel smc_llc_cli_rkey_exchange() and
* parallel smcr_link_reg_buf() * parallel smcr_link_reg_buf()
*/ */
mutex_lock(&lgr->llc_conf_mutex); down_write(&lgr->llc_conf_mutex);
for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) { for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) {
if (!smc_link_active(&lgr->lnk[i])) if (!smc_link_active(&lgr->lnk[i]))
continue; continue;
...@@ -544,7 +544,7 @@ static int smcr_lgr_reg_rmbs(struct smc_link *link, ...@@ -544,7 +544,7 @@ static int smcr_lgr_reg_rmbs(struct smc_link *link,
} }
rmb_desc->is_conf_rkey = true; rmb_desc->is_conf_rkey = true;
out: out:
mutex_unlock(&lgr->llc_conf_mutex); up_write(&lgr->llc_conf_mutex);
smc_llc_flow_stop(lgr, &lgr->llc_flow_lcl); smc_llc_flow_stop(lgr, &lgr->llc_flow_lcl);
return rc; return rc;
} }
......
...@@ -1106,10 +1106,10 @@ static void smcr_buf_unuse(struct smc_buf_desc *buf_desc, bool is_rmb, ...@@ -1106,10 +1106,10 @@ static void smcr_buf_unuse(struct smc_buf_desc *buf_desc, bool is_rmb,
rc = smc_llc_flow_initiate(lgr, SMC_LLC_FLOW_RKEY); rc = smc_llc_flow_initiate(lgr, SMC_LLC_FLOW_RKEY);
if (!rc) { if (!rc) {
/* protect against smc_llc_cli_rkey_exchange() */ /* protect against smc_llc_cli_rkey_exchange() */
mutex_lock(&lgr->llc_conf_mutex); down_write(&lgr->llc_conf_mutex);
smc_llc_do_delete_rkey(lgr, buf_desc); smc_llc_do_delete_rkey(lgr, buf_desc);
buf_desc->is_conf_rkey = false; buf_desc->is_conf_rkey = false;
mutex_unlock(&lgr->llc_conf_mutex); up_write(&lgr->llc_conf_mutex);
smc_llc_flow_stop(lgr, &lgr->llc_flow_lcl); smc_llc_flow_stop(lgr, &lgr->llc_flow_lcl);
} }
} }
...@@ -1377,12 +1377,12 @@ static void smc_lgr_free(struct smc_link_group *lgr) ...@@ -1377,12 +1377,12 @@ static void smc_lgr_free(struct smc_link_group *lgr)
int i; int i;
if (!lgr->is_smcd) { if (!lgr->is_smcd) {
mutex_lock(&lgr->llc_conf_mutex); down_write(&lgr->llc_conf_mutex);
for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) { for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) {
if (lgr->lnk[i].state != SMC_LNK_UNUSED) if (lgr->lnk[i].state != SMC_LNK_UNUSED)
smcr_link_clear(&lgr->lnk[i], false); smcr_link_clear(&lgr->lnk[i], false);
} }
mutex_unlock(&lgr->llc_conf_mutex); up_write(&lgr->llc_conf_mutex);
smc_llc_lgr_clear(lgr); smc_llc_lgr_clear(lgr);
} }
...@@ -1696,12 +1696,12 @@ static void smcr_link_down(struct smc_link *lnk) ...@@ -1696,12 +1696,12 @@ static void smcr_link_down(struct smc_link *lnk)
} else { } else {
if (lgr->llc_flow_lcl.type != SMC_LLC_FLOW_NONE) { if (lgr->llc_flow_lcl.type != SMC_LLC_FLOW_NONE) {
/* another llc task is ongoing */ /* another llc task is ongoing */
mutex_unlock(&lgr->llc_conf_mutex); up_write(&lgr->llc_conf_mutex);
wait_event_timeout(lgr->llc_flow_waiter, wait_event_timeout(lgr->llc_flow_waiter,
(list_empty(&lgr->list) || (list_empty(&lgr->list) ||
lgr->llc_flow_lcl.type == SMC_LLC_FLOW_NONE), lgr->llc_flow_lcl.type == SMC_LLC_FLOW_NONE),
SMC_LLC_WAIT_TIME); SMC_LLC_WAIT_TIME);
mutex_lock(&lgr->llc_conf_mutex); down_write(&lgr->llc_conf_mutex);
} }
if (!list_empty(&lgr->list)) { if (!list_empty(&lgr->list)) {
smc_llc_send_delete_link(to_lnk, del_link_id, smc_llc_send_delete_link(to_lnk, del_link_id,
...@@ -1761,9 +1761,9 @@ static void smc_link_down_work(struct work_struct *work) ...@@ -1761,9 +1761,9 @@ static void smc_link_down_work(struct work_struct *work)
if (list_empty(&lgr->list)) if (list_empty(&lgr->list))
return; return;
wake_up_all(&lgr->llc_msg_waiter); wake_up_all(&lgr->llc_msg_waiter);
mutex_lock(&lgr->llc_conf_mutex); down_write(&lgr->llc_conf_mutex);
smcr_link_down(link); smcr_link_down(link);
mutex_unlock(&lgr->llc_conf_mutex); up_write(&lgr->llc_conf_mutex);
} }
static int smc_vlan_by_tcpsk_walk(struct net_device *lower_dev, static int smc_vlan_by_tcpsk_walk(struct net_device *lower_dev,
...@@ -2247,7 +2247,7 @@ static int smcr_buf_map_usable_links(struct smc_link_group *lgr, ...@@ -2247,7 +2247,7 @@ static int smcr_buf_map_usable_links(struct smc_link_group *lgr,
int i, rc = 0, cnt = 0; int i, rc = 0, cnt = 0;
/* protect against parallel link reconfiguration */ /* protect against parallel link reconfiguration */
mutex_lock(&lgr->llc_conf_mutex); down_write(&lgr->llc_conf_mutex);
for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) { for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) {
struct smc_link *lnk = &lgr->lnk[i]; struct smc_link *lnk = &lgr->lnk[i];
...@@ -2260,7 +2260,7 @@ static int smcr_buf_map_usable_links(struct smc_link_group *lgr, ...@@ -2260,7 +2260,7 @@ static int smcr_buf_map_usable_links(struct smc_link_group *lgr,
cnt++; cnt++;
} }
out: out:
mutex_unlock(&lgr->llc_conf_mutex); up_write(&lgr->llc_conf_mutex);
if (!rc && !cnt) if (!rc && !cnt)
rc = -EINVAL; rc = -EINVAL;
return rc; return rc;
......
...@@ -298,7 +298,7 @@ struct smc_link_group { ...@@ -298,7 +298,7 @@ struct smc_link_group {
/* queue for llc events */ /* queue for llc events */
spinlock_t llc_event_q_lock; spinlock_t llc_event_q_lock;
/* protects llc_event_q */ /* protects llc_event_q */
struct mutex llc_conf_mutex; struct rw_semaphore llc_conf_mutex;
/* protects lgr reconfig. */ /* protects lgr reconfig. */
struct work_struct llc_add_link_work; struct work_struct llc_add_link_work;
struct work_struct llc_del_link_work; struct work_struct llc_del_link_work;
......
...@@ -1202,12 +1202,12 @@ static void smc_llc_process_cli_add_link(struct smc_link_group *lgr) ...@@ -1202,12 +1202,12 @@ static void smc_llc_process_cli_add_link(struct smc_link_group *lgr)
qentry = smc_llc_flow_qentry_clr(&lgr->llc_flow_lcl); qentry = smc_llc_flow_qentry_clr(&lgr->llc_flow_lcl);
mutex_lock(&lgr->llc_conf_mutex); down_write(&lgr->llc_conf_mutex);
if (smc_llc_is_local_add_link(&qentry->msg)) if (smc_llc_is_local_add_link(&qentry->msg))
smc_llc_cli_add_link_invite(qentry->link, qentry); smc_llc_cli_add_link_invite(qentry->link, qentry);
else else
smc_llc_cli_add_link(qentry->link, qentry); smc_llc_cli_add_link(qentry->link, qentry);
mutex_unlock(&lgr->llc_conf_mutex); up_write(&lgr->llc_conf_mutex);
} }
static int smc_llc_active_link_count(struct smc_link_group *lgr) static int smc_llc_active_link_count(struct smc_link_group *lgr)
...@@ -1509,13 +1509,13 @@ static void smc_llc_process_srv_add_link(struct smc_link_group *lgr) ...@@ -1509,13 +1509,13 @@ static void smc_llc_process_srv_add_link(struct smc_link_group *lgr)
qentry = smc_llc_flow_qentry_clr(&lgr->llc_flow_lcl); qentry = smc_llc_flow_qentry_clr(&lgr->llc_flow_lcl);
mutex_lock(&lgr->llc_conf_mutex); down_write(&lgr->llc_conf_mutex);
rc = smc_llc_srv_add_link(link, qentry); rc = smc_llc_srv_add_link(link, qentry);
if (!rc && lgr->type == SMC_LGR_SYMMETRIC) { if (!rc && lgr->type == SMC_LGR_SYMMETRIC) {
/* delete any asymmetric link */ /* delete any asymmetric link */
smc_llc_delete_asym_link(lgr); smc_llc_delete_asym_link(lgr);
} }
mutex_unlock(&lgr->llc_conf_mutex); up_write(&lgr->llc_conf_mutex);
kfree(qentry); kfree(qentry);
} }
...@@ -1582,7 +1582,7 @@ static void smc_llc_process_cli_delete_link(struct smc_link_group *lgr) ...@@ -1582,7 +1582,7 @@ static void smc_llc_process_cli_delete_link(struct smc_link_group *lgr)
smc_lgr_terminate_sched(lgr); smc_lgr_terminate_sched(lgr);
goto out; goto out;
} }
mutex_lock(&lgr->llc_conf_mutex); down_write(&lgr->llc_conf_mutex);
/* delete single link */ /* delete single link */
for (lnk_idx = 0; lnk_idx < SMC_LINKS_PER_LGR_MAX; lnk_idx++) { for (lnk_idx = 0; lnk_idx < SMC_LINKS_PER_LGR_MAX; lnk_idx++) {
if (lgr->lnk[lnk_idx].link_id != del_llc->link_num) if (lgr->lnk[lnk_idx].link_id != del_llc->link_num)
...@@ -1616,7 +1616,7 @@ static void smc_llc_process_cli_delete_link(struct smc_link_group *lgr) ...@@ -1616,7 +1616,7 @@ static void smc_llc_process_cli_delete_link(struct smc_link_group *lgr)
smc_lgr_terminate_sched(lgr); smc_lgr_terminate_sched(lgr);
} }
out_unlock: out_unlock:
mutex_unlock(&lgr->llc_conf_mutex); up_write(&lgr->llc_conf_mutex);
out: out:
kfree(qentry); kfree(qentry);
} }
...@@ -1652,7 +1652,7 @@ static void smc_llc_process_srv_delete_link(struct smc_link_group *lgr) ...@@ -1652,7 +1652,7 @@ static void smc_llc_process_srv_delete_link(struct smc_link_group *lgr)
int active_links; int active_links;
int i; int i;
mutex_lock(&lgr->llc_conf_mutex); down_write(&lgr->llc_conf_mutex);
qentry = smc_llc_flow_qentry_clr(&lgr->llc_flow_lcl); qentry = smc_llc_flow_qentry_clr(&lgr->llc_flow_lcl);
lnk = qentry->link; lnk = qentry->link;
del_llc = &qentry->msg.delete_link; del_llc = &qentry->msg.delete_link;
...@@ -1708,7 +1708,7 @@ static void smc_llc_process_srv_delete_link(struct smc_link_group *lgr) ...@@ -1708,7 +1708,7 @@ static void smc_llc_process_srv_delete_link(struct smc_link_group *lgr)
smc_llc_add_link_local(lnk); smc_llc_add_link_local(lnk);
} }
out: out:
mutex_unlock(&lgr->llc_conf_mutex); up_write(&lgr->llc_conf_mutex);
kfree(qentry); kfree(qentry);
} }
...@@ -2126,7 +2126,7 @@ void smc_llc_lgr_init(struct smc_link_group *lgr, struct smc_sock *smc) ...@@ -2126,7 +2126,7 @@ void smc_llc_lgr_init(struct smc_link_group *lgr, struct smc_sock *smc)
spin_lock_init(&lgr->llc_flow_lock); spin_lock_init(&lgr->llc_flow_lock);
init_waitqueue_head(&lgr->llc_flow_waiter); init_waitqueue_head(&lgr->llc_flow_waiter);
init_waitqueue_head(&lgr->llc_msg_waiter); init_waitqueue_head(&lgr->llc_msg_waiter);
mutex_init(&lgr->llc_conf_mutex); init_rwsem(&lgr->llc_conf_mutex);
lgr->llc_testlink_time = READ_ONCE(net->smc.sysctl_smcr_testlink_time); lgr->llc_testlink_time = READ_ONCE(net->smc.sysctl_smcr_testlink_time);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment