Blob Blame History Raw
From: Petr Tesarik <ptesarik@suse.com>
Subject: kABI: protect struct smc_link
Patch-mainline: never, kabi
References: bnc#1117947, LTC#173662

Upstream commit 60e03c62c5db22c5eb63bcb6ce226cf05f4ee47c adds new
fields to struct smc_link. However, this structure is embedded
inside struct smc_link_group, so its cannot be resized without
moving following fields inside that structure.

Thankfully, there is a one-to-one correspondence between a link
and its link group, because there can be currently only one link
per group. The extra fields can be added at the end of struct
smc_link_group, which is allocated dynamically, and its size
should never be needed by another module.

Signed-off-by: Petr Tesarik <ptesarik@suse.com>
---
 net/smc/smc_core.h |    7 +++++++
 net/smc/smc_llc.c  |   23 ++++++++++++++---------
 2 files changed, 21 insertions(+), 9 deletions(-)

--- a/net/smc/smc_core.h
+++ b/net/smc/smc_core.h
@@ -108,6 +108,9 @@ struct smc_link {
 	int			llc_testlink_time; /* testlink interval */
 	struct completion	llc_confirm_rkey; /* wait 4 rx of cnf rkey */
 	int			llc_confirm_rkey_rc; /* rc from cnf rkey msg */
+};
+
+struct smc_link_extra {
 	struct completion	llc_delete_rkey; /* wait 4 rx of del rkey */
 	int			llc_delete_rkey_rc; /* rc from del rkey msg */
 	struct mutex		llc_delete_rkey_mutex; /* serialize usage */
@@ -210,6 +213,10 @@ struct smc_link_group {
 						/* ISM device for VLAN reg. */
 		};
 	};
+#ifndef __GENKSYMS__
+	struct smc_link_extra	lnk_extra[SMC_LINKS_PER_LGR_MAX];
+				/* smc_link fields added after kABI freeze */
+#endif
 };
 
 /* Find the connection associated with the given alert token in the link group.
--- a/net/smc/smc_llc.c
+++ b/net/smc/smc_llc.c
@@ -531,9 +531,11 @@ static void smc_llc_rx_delete_rkey(struc
 	int i, max;
 
 	if (llc->hd.flags & SMC_LLC_FLAG_RESP) {
-		link->llc_delete_rkey_rc = llc->hd.flags &
+		struct smc_link_group *lgr = smc_get_lgr(link);
+		struct smc_link_extra *extra = &lgr->lnk_extra[SMC_SINGLE_LINK];
+		extra->llc_delete_rkey_rc = llc->hd.flags &
 					    SMC_LLC_FLAG_RKEY_NEG;
-		complete(&link->llc_delete_rkey);
+		complete(&extra->llc_delete_rkey);
 	} else {
 		max = min_t(u8, llc->num_rkeys, SMC_LLC_DEL_RKEY_MAX);
 		for (i = 0; i < max; i++) {
@@ -624,6 +626,7 @@ out:
 int smc_llc_link_init(struct smc_link *link)
 {
 	struct smc_link_group *lgr = smc_get_lgr(link);
+	struct smc_link_extra *extra = &lgr->lnk_extra[SMC_SINGLE_LINK];
 	link->llc_wq = alloc_ordered_workqueue("llc_wq-%x:%x)", WQ_MEM_RECLAIM,
 					       *((u32 *)lgr->id),
 					       link->link_id);
@@ -634,8 +637,8 @@ int smc_llc_link_init(struct smc_link *l
 	init_completion(&link->llc_add);
 	init_completion(&link->llc_add_resp);
 	init_completion(&link->llc_confirm_rkey);
-	init_completion(&link->llc_delete_rkey);
-	mutex_init(&link->llc_delete_rkey_mutex);
+	init_completion(&extra->llc_delete_rkey);
+	mutex_init(&extra->llc_delete_rkey_mutex);
 	init_completion(&link->llc_testlink_resp);
 	INIT_DELAYED_WORK(&link->llc_testlink_wrk, smc_llc_testlink_work);
 	return 0;
@@ -693,22 +696,24 @@ int smc_llc_do_confirm_rkey(struct smc_l
 int smc_llc_do_delete_rkey(struct smc_link *link,
 			   struct smc_buf_desc *rmb_desc)
 {
+	struct smc_link_group *lgr = smc_get_lgr(link);
+	struct smc_link_extra *extra = &lgr->lnk_extra[SMC_SINGLE_LINK];
 	int rc;
 
-	mutex_lock(&link->llc_delete_rkey_mutex);
-	reinit_completion(&link->llc_delete_rkey);
+	mutex_lock(&extra->llc_delete_rkey_mutex);
+	reinit_completion(&extra->llc_delete_rkey);
 	rc = smc_llc_send_delete_rkey(link, rmb_desc);
 	if (rc)
 		goto out;
 	/* receive DELETE RKEY response from server over RoCE fabric */
-	rc = wait_for_completion_interruptible_timeout(&link->llc_delete_rkey,
+	rc = wait_for_completion_interruptible_timeout(&extra->llc_delete_rkey,
 						       SMC_LLC_WAIT_TIME);
-	if (rc <= 0 || link->llc_delete_rkey_rc)
+	if (rc <= 0 || extra->llc_delete_rkey_rc)
 		rc = -EFAULT;
 	else
 		rc = 0;
 out:
-	mutex_unlock(&link->llc_delete_rkey_mutex);
+	mutex_unlock(&extra->llc_delete_rkey_mutex);
 	return rc;
 }