Unverified Commit bc8d0e2f authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!826 [OLK-5.10] net/smc: mutex lock optimize

Merge Pull Request from: @giree2 
 
1. replace llc_conf_mutex with rw_semaphore
2. use read semaphores to reduce unnecessary blocking in smc_buf_create() & smcr_buf_unuse()
3. replace mutex rmbs_lock and sndbufs_lock with rw_semaphore
4. modify llc_conf_mutex variable to llc_conf_lock. 
 
Link:https://gitee.com/openeuler/kernel/pulls/826

 

Reviewed-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
parents 0f9e7446 d12efaa4
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -368,7 +368,7 @@ static int smcr_lgr_reg_rmbs(struct smc_link *link,
	/* protect against parallel smc_llc_cli_rkey_exchange() and
	 * parallel smcr_link_reg_rmb()
	 */
	mutex_lock(&lgr->llc_conf_mutex);
	down_write(&lgr->llc_conf_lock);
	for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) {
		if (!smc_link_active(&lgr->lnk[i]))
			continue;
@@ -385,7 +385,7 @@ static int smcr_lgr_reg_rmbs(struct smc_link *link,
	}
	rmb_desc->is_conf_rkey = true;
out:
	mutex_unlock(&lgr->llc_conf_mutex);
	up_write(&lgr->llc_conf_lock);
	smc_llc_flow_stop(lgr, &lgr->llc_flow_lcl);
	return rc;
}
+32 −32
Original line number Diff line number Diff line
@@ -398,8 +398,8 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
	lgr->terminating = 0;
	lgr->freeing = 0;
	lgr->vlan_id = ini->vlan_id;
	mutex_init(&lgr->sndbufs_lock);
	mutex_init(&lgr->rmbs_lock);
	init_rwsem(&lgr->sndbufs_lock);
	init_rwsem(&lgr->rmbs_lock);
	rwlock_init(&lgr->conns_lock);
	for (i = 0; i < SMC_RMBE_SIZES; i++) {
		INIT_LIST_HEAD(&lgr->sndbufs[i]);
@@ -614,19 +614,19 @@ static void smcr_buf_unuse(struct smc_buf_desc *rmb_desc,
		rc = smc_llc_flow_initiate(lgr, SMC_LLC_FLOW_RKEY);
		if (!rc) {
			/* protect against smc_llc_cli_rkey_exchange() */
			mutex_lock(&lgr->llc_conf_mutex);
			down_read(&lgr->llc_conf_lock);
			smc_llc_do_delete_rkey(lgr, rmb_desc);
			rmb_desc->is_conf_rkey = false;
			mutex_unlock(&lgr->llc_conf_mutex);
			up_read(&lgr->llc_conf_lock);
			smc_llc_flow_stop(lgr, &lgr->llc_flow_lcl);
		}
	}

	if (rmb_desc->is_reg_err) {
		/* buf registration failed, reuse not possible */
		mutex_lock(&lgr->rmbs_lock);
		down_write(&lgr->rmbs_lock);
		list_del(&rmb_desc->list);
		mutex_unlock(&lgr->rmbs_lock);
		up_write(&lgr->rmbs_lock);

		smc_buf_free(lgr, true, rmb_desc);
	} else {
@@ -700,15 +700,15 @@ static void smcr_buf_unmap_lgr(struct smc_link *lnk)
	int i;

	for (i = 0; i < SMC_RMBE_SIZES; i++) {
		mutex_lock(&lgr->rmbs_lock);
		down_write(&lgr->rmbs_lock);
		list_for_each_entry_safe(buf_desc, bf, &lgr->rmbs[i], list)
			smcr_buf_unmap_link(buf_desc, true, lnk);
		mutex_unlock(&lgr->rmbs_lock);
		mutex_lock(&lgr->sndbufs_lock);
		up_write(&lgr->rmbs_lock);
		down_write(&lgr->sndbufs_lock);
		list_for_each_entry_safe(buf_desc, bf, &lgr->sndbufs[i],
					 list)
			smcr_buf_unmap_link(buf_desc, false, lnk);
		mutex_unlock(&lgr->sndbufs_lock);
		up_write(&lgr->sndbufs_lock);
	}
}

@@ -815,12 +815,12 @@ static void smc_lgr_free(struct smc_link_group *lgr)
	int i;

	if (!lgr->is_smcd) {
		mutex_lock(&lgr->llc_conf_mutex);
		down_write(&lgr->llc_conf_lock);
		for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) {
			if (lgr->lnk[i].state != SMC_LNK_UNUSED)
				smcr_link_clear(&lgr->lnk[i], false);
		}
		mutex_unlock(&lgr->llc_conf_mutex);
		up_write(&lgr->llc_conf_lock);
		smc_llc_lgr_clear(lgr);
	}

@@ -1143,12 +1143,12 @@ static void smcr_link_down(struct smc_link *lnk)
	} else {
		if (lgr->llc_flow_lcl.type != SMC_LLC_FLOW_NONE) {
			/* another llc task is ongoing */
			mutex_unlock(&lgr->llc_conf_mutex);
			up_write(&lgr->llc_conf_lock);
			wait_event_timeout(lgr->llc_flow_waiter,
				(list_empty(&lgr->list) ||
				 lgr->llc_flow_lcl.type == SMC_LLC_FLOW_NONE),
				SMC_LLC_WAIT_TIME);
			mutex_lock(&lgr->llc_conf_mutex);
			down_write(&lgr->llc_conf_lock);
		}
		if (!list_empty(&lgr->list)) {
			smc_llc_send_delete_link(to_lnk, del_link_id,
@@ -1204,9 +1204,9 @@ static void smc_link_down_work(struct work_struct *work)
	if (list_empty(&lgr->list))
		return;
	wake_up_all(&lgr->llc_msg_waiter);
	mutex_lock(&lgr->llc_conf_mutex);
	down_write(&lgr->llc_conf_lock);
	smcr_link_down(link);
	mutex_unlock(&lgr->llc_conf_mutex);
	up_write(&lgr->llc_conf_lock);
}

static int smc_vlan_by_tcpsk_walk(struct net_device *lower_dev,
@@ -1404,19 +1404,19 @@ int smc_uncompress_bufsize(u8 compressed)
 * buffer size; if not available, return NULL
 */
static struct smc_buf_desc *smc_buf_get_slot(int compressed_bufsize,
					     struct mutex *lock,
					     struct rw_semaphore *lock,
					     struct list_head *buf_list)
{
	struct smc_buf_desc *buf_slot;

	mutex_lock(lock);
	down_read(lock);
	list_for_each_entry(buf_slot, buf_list, list) {
		if (cmpxchg(&buf_slot->used, 0, 1) == 0) {
			mutex_unlock(lock);
			up_read(lock);
			return buf_slot;
		}
	}
	mutex_unlock(lock);
	up_read(lock);
	return NULL;
}

@@ -1495,13 +1495,13 @@ int smcr_link_reg_rmb(struct smc_link *link, struct smc_buf_desc *rmb_desc)
	return 0;
}

static int _smcr_buf_map_lgr(struct smc_link *lnk, struct mutex *lock,
static int _smcr_buf_map_lgr(struct smc_link *lnk, struct rw_semaphore *lock,
			     struct list_head *lst, bool is_rmb)
{
	struct smc_buf_desc *buf_desc, *bf;
	int rc = 0;

	mutex_lock(lock);
	down_write(lock);
	list_for_each_entry_safe(buf_desc, bf, lst, list) {
		if (!buf_desc->used)
			continue;
@@ -1510,7 +1510,7 @@ static int _smcr_buf_map_lgr(struct smc_link *lnk, struct mutex *lock,
			goto out;
	}
out:
	mutex_unlock(lock);
	up_write(lock);
	return rc;
}

@@ -1542,7 +1542,7 @@ int smcr_buf_reg_lgr(struct smc_link *lnk)
	struct smc_buf_desc *buf_desc, *bf;
	int i, rc = 0;

	mutex_lock(&lgr->rmbs_lock);
	down_write(&lgr->rmbs_lock);
	for (i = 0; i < SMC_RMBE_SIZES; i++) {
		list_for_each_entry_safe(buf_desc, bf, &lgr->rmbs[i], list) {
			if (!buf_desc->used)
@@ -1553,7 +1553,7 @@ int smcr_buf_reg_lgr(struct smc_link *lnk)
		}
	}
out:
	mutex_unlock(&lgr->rmbs_lock);
	up_write(&lgr->rmbs_lock);
	return rc;
}

@@ -1590,7 +1590,7 @@ static int smcr_buf_map_usable_links(struct smc_link_group *lgr,
	int i, rc = 0, cnt = 0;

	/* protect against parallel link reconfiguration */
	mutex_lock(&lgr->llc_conf_mutex);
	down_read(&lgr->llc_conf_lock);
	for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) {
		struct smc_link *lnk = &lgr->lnk[i];

@@ -1603,7 +1603,7 @@ static int smcr_buf_map_usable_links(struct smc_link_group *lgr,
		cnt++;
	}
out:
	mutex_unlock(&lgr->llc_conf_mutex);
	up_read(&lgr->llc_conf_lock);
	if (!rc && !cnt)
		rc = -EINVAL;
	return rc;
@@ -1657,7 +1657,7 @@ static int __smc_buf_create(struct smc_sock *smc, bool is_smcd, bool is_rmb)
	struct smc_link_group *lgr = conn->lgr;
	struct list_head *buf_list;
	int bufsize, bufsize_short;
	struct mutex *lock;	/* lock buffer list */
	struct rw_semaphore *lock;	/* lock buffer list */
	int sk_buf_size;

	if (is_rmb)
@@ -1700,9 +1700,9 @@ static int __smc_buf_create(struct smc_sock *smc, bool is_smcd, bool is_rmb)
			continue;

		buf_desc->used = 1;
		mutex_lock(lock);
		down_write(lock);
		list_add(&buf_desc->list, buf_list);
		mutex_unlock(lock);
		up_write(lock);
		break; /* found */
	}

@@ -1775,9 +1775,9 @@ int smc_buf_create(struct smc_sock *smc, bool is_smcd)
	/* create rmb */
	rc = __smc_buf_create(smc, is_smcd, true);
	if (rc) {
		mutex_lock(&smc->conn.lgr->sndbufs_lock);
		down_write(&smc->conn.lgr->sndbufs_lock);
		list_del(&smc->conn.sndbuf_desc->list);
		mutex_unlock(&smc->conn.lgr->sndbufs_lock);
		up_write(&smc->conn.lgr->sndbufs_lock);
		smc_buf_free(smc->conn.lgr, false, smc->conn.sndbuf_desc);
		smc->conn.sndbuf_desc = NULL;
	}
+3 −3
Original line number Diff line number Diff line
@@ -221,9 +221,9 @@ struct smc_link_group {
	unsigned short		vlan_id;	/* vlan id of link group */

	struct list_head	sndbufs[SMC_RMBE_SIZES];/* tx buffers */
	struct mutex		sndbufs_lock;	/* protects tx buffers */
	struct rw_semaphore	sndbufs_lock;	/* protects tx buffers */
	struct list_head	rmbs[SMC_RMBE_SIZES];	/* rx buffers */
	struct mutex		rmbs_lock;	/* protects rx buffers */
	struct rw_semaphore	rmbs_lock;	/* protects rx buffers */

	u8			id[SMC_LGR_ID_SIZE];	/* unique lgr id */
	struct delayed_work	free_work;	/* delayed freeing of an lgr */
@@ -261,7 +261,7 @@ struct smc_link_group {
						/* queue for llc events */
			spinlock_t		llc_event_q_lock;
						/* protects llc_event_q */
			struct mutex		llc_conf_mutex;
			struct rw_semaphore	llc_conf_lock;
						/* protects lgr reconfig. */
			struct work_struct	llc_add_link_work;
			struct work_struct	llc_del_link_work;
+13 −13
Original line number Diff line number Diff line
@@ -756,7 +756,7 @@ static int smc_llc_cli_rkey_exchange(struct smc_link *link,
	int rc = 0;
	int i;

	mutex_lock(&lgr->rmbs_lock);
	down_write(&lgr->rmbs_lock);
	num_rkeys_send = lgr->conns_num;
	buf_pos = smc_llc_get_first_rmb(lgr, &buf_lst);
	do {
@@ -783,7 +783,7 @@ static int smc_llc_cli_rkey_exchange(struct smc_link *link,
			break;
	} while (num_rkeys_send || num_rkeys_recv);

	mutex_unlock(&lgr->rmbs_lock);
	up_write(&lgr->rmbs_lock);
	return rc;
}

@@ -978,12 +978,12 @@ static void smc_llc_process_cli_add_link(struct smc_link_group *lgr)

	qentry = smc_llc_flow_qentry_clr(&lgr->llc_flow_lcl);

	mutex_lock(&lgr->llc_conf_mutex);
	down_write(&lgr->llc_conf_lock);
	if (smc_llc_is_local_add_link(&qentry->msg))
		smc_llc_cli_add_link_invite(qentry->link, qentry);
	else
		smc_llc_cli_add_link(qentry->link, qentry);
	mutex_unlock(&lgr->llc_conf_mutex);
	up_write(&lgr->llc_conf_lock);
}

static int smc_llc_active_link_count(struct smc_link_group *lgr)
@@ -1089,7 +1089,7 @@ static int smc_llc_srv_rkey_exchange(struct smc_link *link,
	int rc = 0;
	int i;

	mutex_lock(&lgr->rmbs_lock);
	down_write(&lgr->rmbs_lock);
	num_rkeys_send = lgr->conns_num;
	buf_pos = smc_llc_get_first_rmb(lgr, &buf_lst);
	do {
@@ -1114,7 +1114,7 @@ static int smc_llc_srv_rkey_exchange(struct smc_link *link,
		smc_llc_flow_qentry_del(&lgr->llc_flow_lcl);
	} while (num_rkeys_send || num_rkeys_recv);
out:
	mutex_unlock(&lgr->rmbs_lock);
	up_write(&lgr->rmbs_lock);
	return rc;
}

@@ -1232,13 +1232,13 @@ static void smc_llc_process_srv_add_link(struct smc_link_group *lgr)

	smc_llc_flow_qentry_del(&lgr->llc_flow_lcl);

	mutex_lock(&lgr->llc_conf_mutex);
	down_write(&lgr->llc_conf_lock);
	rc = smc_llc_srv_add_link(link);
	if (!rc && lgr->type == SMC_LGR_SYMMETRIC) {
		/* delete any asymmetric link */
		smc_llc_delete_asym_link(lgr);
	}
	mutex_unlock(&lgr->llc_conf_mutex);
	up_write(&lgr->llc_conf_lock);
}

/* enqueue a local add_link req to trigger a new add_link flow */
@@ -1303,7 +1303,7 @@ static void smc_llc_process_cli_delete_link(struct smc_link_group *lgr)
		smc_lgr_terminate_sched(lgr);
		goto out;
	}
	mutex_lock(&lgr->llc_conf_mutex);
	down_write(&lgr->llc_conf_lock);
	/* delete single link */
	for (lnk_idx = 0; lnk_idx < SMC_LINKS_PER_LGR_MAX; lnk_idx++) {
		if (lgr->lnk[lnk_idx].link_id != del_llc->link_num)
@@ -1337,7 +1337,7 @@ static void smc_llc_process_cli_delete_link(struct smc_link_group *lgr)
		smc_lgr_terminate_sched(lgr);
	}
out_unlock:
	mutex_unlock(&lgr->llc_conf_mutex);
	up_write(&lgr->llc_conf_lock);
out:
	kfree(qentry);
}
@@ -1373,7 +1373,7 @@ static void smc_llc_process_srv_delete_link(struct smc_link_group *lgr)
	int active_links;
	int i;

	mutex_lock(&lgr->llc_conf_mutex);
	down_write(&lgr->llc_conf_lock);
	qentry = smc_llc_flow_qentry_clr(&lgr->llc_flow_lcl);
	lnk = qentry->link;
	del_llc = &qentry->msg.delete_link;
@@ -1429,7 +1429,7 @@ static void smc_llc_process_srv_delete_link(struct smc_link_group *lgr)
		smc_llc_add_link_local(lnk);
	}
out:
	mutex_unlock(&lgr->llc_conf_mutex);
	up_write(&lgr->llc_conf_lock);
	kfree(qentry);
}

@@ -1786,7 +1786,7 @@ void smc_llc_lgr_init(struct smc_link_group *lgr, struct smc_sock *smc)
	spin_lock_init(&lgr->llc_flow_lock);
	init_waitqueue_head(&lgr->llc_flow_waiter);
	init_waitqueue_head(&lgr->llc_msg_waiter);
	mutex_init(&lgr->llc_conf_mutex);
	init_rwsem(&lgr->llc_conf_lock);
	lgr->llc_testlink_time = READ_ONCE(net->ipv4.sysctl_tcp_keepalive_time);
}