lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <aJxnVjItIEW4iYAv@kspp>
Date: Wed, 13 Aug 2025 19:22:14 +0900
From: "Gustavo A. R. Silva" <gustavoars@...nel.org>
To: Jason Gunthorpe <jgg@...pe.ca>, Leon Romanovsky <leon@...nel.org>
Cc: linux-rdma@...r.kernel.org, linux-kernel@...r.kernel.org,
	"Gustavo A. R. Silva" <gustavoars@...nel.org>,
	linux-hardening@...r.kernel.org
Subject: [PATCH v2][next] RDMA/cm: Avoid -Wflex-array-member-not-at-end
 warning

-Wflex-array-member-not-at-end was introduced in GCC-14, and we are
getting ready to enable it, globally.

We have a flexible `struct cm_work` in the top of `struct
cm_timewait_info`, but this struct don't even need the flexible
part.

So, we add `struct cm_work_hdr`, that will contain everything
except the flexible array and use this one as the type for member
`work` in `struct cm_timewait_info`, and refactor the rest of the
code accordingly.

Also, add a static_assert() to ensure no member is ever added
outside `struct cm_work_hdr` in `struct cm_work`.

So, with these changes, fix the following warning:
drivers/infiniband/core/cm.c:196:24: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]

Signed-off-by: Gustavo A. R. Silva <gustavoars@...nel.org>
---
Changes in v2:
 - Use new `struct cm_work_hdr` instead of struct_group_tagged()

v1:
 - Link: https://lore.kernel.org/linux-hardening/ZgHdZ15cQ7MIHsGL@neat/

 drivers/infiniband/core/cm.c | 236 ++++++++++++++++++-----------------
 1 file changed, 121 insertions(+), 115 deletions(-)

diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 92678e438ff4..a0f3dfd03c74 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -184,7 +184,7 @@ struct cm_av {
 	u8 timeout;
 };
 
-struct cm_work {
+struct cm_work_hdr {
 	struct delayed_work work;
 	struct list_head list;
 	struct cm_port *port;
@@ -192,11 +192,17 @@ struct cm_work {
 	__be32 local_id;			/* Established / timewait */
 	__be32 remote_id;
 	struct ib_cm_event cm_event;
+};
+
+struct cm_work {
+	struct cm_work_hdr hdr;
 	struct sa_path_rec path[];
 };
+static_assert(offsetof(struct cm_work, path) == sizeof(struct cm_work_hdr),
+	      "struct member likely outside of struct cm_work_hdr");
 
 struct cm_timewait_info {
-	struct cm_work work;
+	struct cm_work_hdr work;
 	struct list_head list;
 	struct rb_node remote_qp_node;
 	struct rb_node remote_id_node;
@@ -891,15 +897,15 @@ static struct cm_work *cm_dequeue_work(struct cm_id_private *cm_id_priv)
 	if (list_empty(&cm_id_priv->work_list))
 		return NULL;
 
-	work = list_entry(cm_id_priv->work_list.next, struct cm_work, list);
-	list_del(&work->list);
+	work = list_entry(cm_id_priv->work_list.next, struct cm_work, hdr.list);
+	list_del(&work->hdr.list);
 	return work;
 }
 
 static void cm_free_work(struct cm_work *work)
 {
-	if (work->mad_recv_wc)
-		ib_free_recv_mad(work->mad_recv_wc);
+	if (work->hdr.mad_recv_wc)
+		ib_free_recv_mad(work->hdr.mad_recv_wc);
 	kfree(work);
 }
 
@@ -918,7 +924,7 @@ static void cm_queue_work_unlock(struct cm_id_private *cm_id_priv,
 	 */
 	immediate = atomic_inc_and_test(&cm_id_priv->work_count);
 	if (!immediate) {
-		list_add_tail(&work->list, &cm_id_priv->work_list);
+		list_add_tail(&work->hdr.list, &cm_id_priv->work_list);
 		/*
 		 * This routine always consumes incoming reference. Once queued
 		 * to the work_list then a reference is held by the thread
@@ -1771,9 +1777,9 @@ static void cm_format_paths_from_req(struct cm_req_msg *req_msg,
 
 static u16 cm_get_bth_pkey(struct cm_work *work)
 {
-	struct ib_device *ib_dev = work->port->cm_dev->ib_device;
-	u32 port_num = work->port->port_num;
-	u16 pkey_index = work->mad_recv_wc->wc->pkey_index;
+	struct ib_device *ib_dev = work->hdr.port->cm_dev->ib_device;
+	u32 port_num = work->hdr.port->port_num;
+	u16 pkey_index = work->hdr.mad_recv_wc->wc->pkey_index;
 	u16 pkey;
 	int ret;
 
@@ -1799,8 +1805,8 @@ static u16 cm_get_bth_pkey(struct cm_work *work)
 static void cm_opa_to_ib_sgid(struct cm_work *work,
 			      struct sa_path_rec *path)
 {
-	struct ib_device *dev = work->port->cm_dev->ib_device;
-	u32 port_num = work->port->port_num;
+	struct ib_device *dev = work->hdr.port->cm_dev->ib_device;
+	u32 port_num = work->hdr.port->port_num;
 
 	if (rdma_cap_opa_ah(dev, port_num) &&
 	    (ib_is_opa_gid(&path->sgid))) {
@@ -1823,8 +1829,8 @@ static void cm_format_req_event(struct cm_work *work,
 	struct cm_req_msg *req_msg;
 	struct ib_cm_req_event_param *param;
 
-	req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad;
-	param = &work->cm_event.param.req_rcvd;
+	req_msg = (struct cm_req_msg *)work->hdr.mad_recv_wc->recv_buf.mad;
+	param = &work->hdr.cm_event.param.req_rcvd;
 	param->listen_id = listen_id;
 	param->bth_pkey = cm_get_bth_pkey(work);
 	param->port = cm_id_priv->av.port->port_num;
@@ -1856,7 +1862,7 @@ static void cm_format_req_event(struct cm_work *work,
 	param->ece.vendor_id = IBA_GET(CM_REQ_VENDOR_ID, req_msg);
 	param->ece.attr_mod = be32_to_cpu(req_msg->hdr.attr_mod);
 
-	work->cm_event.private_data =
+	work->hdr.cm_event.private_data =
 		IBA_GET_MEM_PTR(CM_REQ_PRIVATE_DATA, req_msg);
 }
 
@@ -1866,7 +1872,7 @@ static void cm_process_work(struct cm_id_private *cm_id_priv,
 	int ret;
 
 	/* We will typically only have the current event to report. */
-	ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, &work->cm_event);
+	ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, &work->hdr.cm_event);
 	cm_free_work(work);
 
 	while (!ret && !atomic_add_negative(-1, &cm_id_priv->work_count)) {
@@ -1877,7 +1883,7 @@ static void cm_process_work(struct cm_id_private *cm_id_priv,
 			return;
 
 		ret = cm_id_priv->id.cm_handler(&cm_id_priv->id,
-						&work->cm_event);
+						&work->hdr.cm_event);
 		cm_free_work(work);
 	}
 	cm_deref_id(cm_id_priv);
@@ -1957,7 +1963,7 @@ static void cm_dup_req_handler(struct cm_work *work,
 	int ret;
 
 	atomic_long_inc(
-		&work->port->counters[CM_RECV_DUPLICATES][CM_REQ_COUNTER]);
+		&work->hdr.port->counters[CM_RECV_DUPLICATES][CM_REQ_COUNTER]);
 
 	/* Quick state check to discard duplicate REQs. */
 	spin_lock_irq(&cm_id_priv->lock);
@@ -1967,7 +1973,7 @@ static void cm_dup_req_handler(struct cm_work *work,
 	}
 	spin_unlock_irq(&cm_id_priv->lock);
 
-	ret = cm_alloc_response_msg(work->port, work->mad_recv_wc, true, &msg);
+	ret = cm_alloc_response_msg(work->hdr.port, work->hdr.mad_recv_wc, true, &msg);
 	if (ret)
 		return;
 
@@ -2006,7 +2012,7 @@ static struct cm_id_private *cm_match_req(struct cm_work *work,
 	struct cm_timewait_info *timewait_info;
 	struct cm_req_msg *req_msg;
 
-	req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad;
+	req_msg = (struct cm_req_msg *)work->hdr.mad_recv_wc->recv_buf.mad;
 
 	/* Check for possible duplicate REQ. */
 	spin_lock_irq(&cm.lock);
@@ -2030,7 +2036,7 @@ static struct cm_id_private *cm_match_req(struct cm_work *work,
 					   timewait_info->work.remote_id);
 
 		spin_unlock_irq(&cm.lock);
-		cm_issue_rej(work->port, work->mad_recv_wc,
+		cm_issue_rej(work->hdr.port, work->hdr.mad_recv_wc,
 			     IB_CM_REJ_STALE_CONN, CM_MSG_RESPONSE_REQ,
 			     NULL, 0);
 		if (cur_cm_id_priv) {
@@ -2047,7 +2053,7 @@ static struct cm_id_private *cm_match_req(struct cm_work *work,
 	if (!listen_cm_id_priv) {
 		cm_remove_remote(cm_id_priv);
 		spin_unlock_irq(&cm.lock);
-		cm_issue_rej(work->port, work->mad_recv_wc,
+		cm_issue_rej(work->hdr.port, work->hdr.mad_recv_wc,
 			     IB_CM_REJ_INVALID_SERVICE_ID, CM_MSG_RESPONSE_REQ,
 			     NULL, 0);
 		return NULL;
@@ -2100,10 +2106,10 @@ static int cm_req_handler(struct cm_work *work)
 	const struct ib_gid_attr *gid_attr;
 	int ret;
 
-	req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad;
+	req_msg = (struct cm_req_msg *)work->hdr.mad_recv_wc->recv_buf.mad;
 
 	cm_id_priv =
-		cm_alloc_id_priv(work->port->cm_dev->ib_device, NULL, NULL);
+		cm_alloc_id_priv(work->hdr.port->cm_dev->ib_device, NULL, NULL);
 	if (IS_ERR(cm_id_priv))
 		return PTR_ERR(cm_id_priv);
 
@@ -2128,8 +2134,8 @@ static int cm_req_handler(struct cm_work *work)
 	cm_id_priv->rnr_retry_count = IBA_GET(CM_REQ_RNR_RETRY_COUNT, req_msg);
 	cm_id_priv->qp_type = cm_req_get_qp_type(req_msg);
 
-	ret = cm_init_av_for_response(work->port, work->mad_recv_wc->wc,
-				      work->mad_recv_wc->recv_buf.grh,
+	ret = cm_init_av_for_response(work->hdr.port, work->hdr.mad_recv_wc->wc,
+				      work->hdr.mad_recv_wc->recv_buf.grh,
 				      &cm_id_priv->av);
 	if (ret)
 		goto destroy;
@@ -2169,9 +2175,9 @@ static int cm_req_handler(struct cm_work *work)
 		work->path[0].rec_type =
 			sa_conv_gid_to_pathrec_type(gid_attr->gid_type);
 	} else {
-		cm_process_routed_req(req_msg, work->mad_recv_wc->wc);
+		cm_process_routed_req(req_msg, work->hdr.mad_recv_wc->wc);
 		cm_path_set_rec_type(
-			work->port->cm_dev->ib_device, work->port->port_num,
+			work->hdr.port->cm_dev->ib_device, work->hdr.port->port_num,
 			&work->path[0],
 			IBA_GET_MEM_PTR(CM_REQ_PRIMARY_LOCAL_PORT_GID,
 					req_msg));
@@ -2179,7 +2185,7 @@ static int cm_req_handler(struct cm_work *work)
 	if (cm_req_has_alt_path(req_msg))
 		work->path[1].rec_type = work->path[0].rec_type;
 	cm_format_paths_from_req(req_msg, &work->path[0],
-				 &work->path[1], work->mad_recv_wc->wc);
+				 &work->path[1], work->hdr.mad_recv_wc->wc);
 	if (cm_id_priv->av.ah_attr.type == RDMA_AH_ATTR_TYPE_ROCE)
 		sa_path_set_dmac(&work->path[0],
 				 cm_id_priv->av.ah_attr.roce.dmac);
@@ -2191,8 +2197,8 @@ static int cm_req_handler(struct cm_work *work)
 	if (ret) {
 		int err;
 
-		err = rdma_query_gid(work->port->cm_dev->ib_device,
-				     work->port->port_num, 0,
+		err = rdma_query_gid(work->hdr.port->cm_dev->ib_device,
+				     work->hdr.port->port_num, 0,
 				     &work->path[0].sgid);
 		if (err)
 			ib_send_cm_rej(&cm_id_priv->id, IB_CM_REJ_INVALID_GID,
@@ -2419,8 +2425,8 @@ static void cm_format_rep_event(struct cm_work *work, enum ib_qp_type qp_type)
 	struct cm_rep_msg *rep_msg;
 	struct ib_cm_rep_event_param *param;
 
-	rep_msg = (struct cm_rep_msg *)work->mad_recv_wc->recv_buf.mad;
-	param = &work->cm_event.param.rep_rcvd;
+	rep_msg = (struct cm_rep_msg *)work->hdr.mad_recv_wc->recv_buf.mad;
+	param = &work->hdr.cm_event.param.rep_rcvd;
 	param->remote_ca_guid =
 		cpu_to_be64(IBA_GET(CM_REP_LOCAL_CA_GUID, rep_msg));
 	param->remote_qkey = IBA_GET(CM_REP_LOCAL_Q_KEY, rep_msg);
@@ -2438,7 +2444,7 @@ static void cm_format_rep_event(struct cm_work *work, enum ib_qp_type qp_type)
 	param->ece.vendor_id |= IBA_GET(CM_REP_VENDOR_ID_L, rep_msg);
 	param->ece.attr_mod = be32_to_cpu(rep_msg->hdr.attr_mod);
 
-	work->cm_event.private_data =
+	work->hdr.cm_event.private_data =
 		IBA_GET_MEM_PTR(CM_REP_PRIVATE_DATA, rep_msg);
 }
 
@@ -2449,7 +2455,7 @@ static void cm_dup_rep_handler(struct cm_work *work)
 	struct ib_mad_send_buf *msg = NULL;
 	int ret;
 
-	rep_msg = (struct cm_rep_msg *) work->mad_recv_wc->recv_buf.mad;
+	rep_msg = (struct cm_rep_msg *) work->hdr.mad_recv_wc->recv_buf.mad;
 	cm_id_priv = cm_acquire_id(
 		cpu_to_be32(IBA_GET(CM_REP_REMOTE_COMM_ID, rep_msg)),
 		cpu_to_be32(IBA_GET(CM_REP_LOCAL_COMM_ID, rep_msg)));
@@ -2457,8 +2463,8 @@ static void cm_dup_rep_handler(struct cm_work *work)
 		return;
 
 	atomic_long_inc(
-		&work->port->counters[CM_RECV_DUPLICATES][CM_REP_COUNTER]);
-	ret = cm_alloc_response_msg(work->port, work->mad_recv_wc, true, &msg);
+		&work->hdr.port->counters[CM_RECV_DUPLICATES][CM_REP_COUNTER]);
+	ret = cm_alloc_response_msg(work->hdr.port, work->hdr.mad_recv_wc, true, &msg);
 	if (ret)
 		goto deref;
 
@@ -2495,7 +2501,7 @@ static int cm_rep_handler(struct cm_work *work)
 	struct cm_id_private *cur_cm_id_priv;
 	struct cm_timewait_info *timewait_info;
 
-	rep_msg = (struct cm_rep_msg *)work->mad_recv_wc->recv_buf.mad;
+	rep_msg = (struct cm_rep_msg *)work->hdr.mad_recv_wc->recv_buf.mad;
 	cm_id_priv = cm_acquire_id(
 		cpu_to_be32(IBA_GET(CM_REP_REMOTE_COMM_ID, rep_msg)), 0);
 	if (!cm_id_priv) {
@@ -2547,7 +2553,7 @@ static int cm_rep_handler(struct cm_work *work)
 
 		spin_unlock(&cm.lock);
 		spin_unlock_irq(&cm_id_priv->lock);
-		cm_issue_rej(work->port, work->mad_recv_wc,
+		cm_issue_rej(work->hdr.port, work->hdr.mad_recv_wc,
 			     IB_CM_REJ_STALE_CONN, CM_MSG_RESPONSE_REP,
 			     NULL, 0);
 		ret = -EINVAL;
@@ -2597,7 +2603,7 @@ static int cm_establish_handler(struct cm_work *work)
 	struct cm_id_private *cm_id_priv;
 
 	/* See comment in cm_establish about lookup. */
-	cm_id_priv = cm_acquire_id(work->local_id, work->remote_id);
+	cm_id_priv = cm_acquire_id(work->hdr.local_id, work->hdr.remote_id);
 	if (!cm_id_priv)
 		return -EINVAL;
 
@@ -2620,21 +2626,21 @@ static int cm_rtu_handler(struct cm_work *work)
 	struct cm_id_private *cm_id_priv;
 	struct cm_rtu_msg *rtu_msg;
 
-	rtu_msg = (struct cm_rtu_msg *)work->mad_recv_wc->recv_buf.mad;
+	rtu_msg = (struct cm_rtu_msg *)work->hdr.mad_recv_wc->recv_buf.mad;
 	cm_id_priv = cm_acquire_id(
 		cpu_to_be32(IBA_GET(CM_RTU_REMOTE_COMM_ID, rtu_msg)),
 		cpu_to_be32(IBA_GET(CM_RTU_LOCAL_COMM_ID, rtu_msg)));
 	if (!cm_id_priv)
 		return -EINVAL;
 
-	work->cm_event.private_data =
+	work->hdr.cm_event.private_data =
 		IBA_GET_MEM_PTR(CM_RTU_PRIVATE_DATA, rtu_msg);
 
 	spin_lock_irq(&cm_id_priv->lock);
 	if (cm_id_priv->id.state != IB_CM_REP_SENT &&
 	    cm_id_priv->id.state != IB_CM_MRA_REP_RCVD) {
 		spin_unlock_irq(&cm_id_priv->lock);
-		atomic_long_inc(&work->port->counters[CM_RECV_DUPLICATES]
+		atomic_long_inc(&work->hdr.port->counters[CM_RECV_DUPLICATES]
 						     [CM_RTU_COUNTER]);
 		goto out;
 	}
@@ -2843,21 +2849,21 @@ static int cm_dreq_handler(struct cm_work *work)
 	struct cm_dreq_msg *dreq_msg;
 	struct ib_mad_send_buf *msg = NULL;
 
-	dreq_msg = (struct cm_dreq_msg *)work->mad_recv_wc->recv_buf.mad;
+	dreq_msg = (struct cm_dreq_msg *)work->hdr.mad_recv_wc->recv_buf.mad;
 	cm_id_priv = cm_acquire_id(
 		cpu_to_be32(IBA_GET(CM_DREQ_REMOTE_COMM_ID, dreq_msg)),
 		cpu_to_be32(IBA_GET(CM_DREQ_LOCAL_COMM_ID, dreq_msg)));
 	if (!cm_id_priv) {
-		atomic_long_inc(&work->port->counters[CM_RECV_DUPLICATES]
+		atomic_long_inc(&work->hdr.port->counters[CM_RECV_DUPLICATES]
 						     [CM_DREQ_COUNTER]);
-		cm_issue_drep(work->port, work->mad_recv_wc);
+		cm_issue_drep(work->hdr.port, work->hdr.mad_recv_wc);
 		trace_icm_no_priv_err(
 			IBA_GET(CM_DREQ_LOCAL_COMM_ID, dreq_msg),
 			IBA_GET(CM_DREQ_REMOTE_COMM_ID, dreq_msg));
 		return -EINVAL;
 	}
 
-	work->cm_event.private_data =
+	work->hdr.cm_event.private_data =
 		IBA_GET_MEM_PTR(CM_DREQ_PRIVATE_DATA, dreq_msg);
 
 	spin_lock_irq(&cm_id_priv->lock);
@@ -2877,9 +2883,9 @@ static int cm_dreq_handler(struct cm_work *work)
 			ib_cancel_mad(cm_id_priv->msg);
 		break;
 	case IB_CM_TIMEWAIT:
-		atomic_long_inc(&work->port->counters[CM_RECV_DUPLICATES]
+		atomic_long_inc(&work->hdr.port->counters[CM_RECV_DUPLICATES]
 						     [CM_DREQ_COUNTER]);
-		msg = cm_alloc_response_msg_no_ah(work->port, work->mad_recv_wc,
+		msg = cm_alloc_response_msg_no_ah(work->hdr.port, work->hdr.mad_recv_wc,
 						  true);
 		if (IS_ERR(msg))
 			goto unlock;
@@ -2889,12 +2895,12 @@ static int cm_dreq_handler(struct cm_work *work)
 			       cm_id_priv->private_data_len);
 		spin_unlock_irq(&cm_id_priv->lock);
 
-		if (cm_create_response_msg_ah(work->port, work->mad_recv_wc, msg) ||
+		if (cm_create_response_msg_ah(work->hdr.port, work->hdr.mad_recv_wc, msg) ||
 		    ib_post_send_mad(msg, NULL))
 			cm_free_msg(msg);
 		goto deref;
 	case IB_CM_DREQ_RCVD:
-		atomic_long_inc(&work->port->counters[CM_RECV_DUPLICATES]
+		atomic_long_inc(&work->hdr.port->counters[CM_RECV_DUPLICATES]
 						     [CM_DREQ_COUNTER]);
 		goto unlock;
 	default:
@@ -2916,14 +2922,14 @@ static int cm_drep_handler(struct cm_work *work)
 	struct cm_id_private *cm_id_priv;
 	struct cm_drep_msg *drep_msg;
 
-	drep_msg = (struct cm_drep_msg *)work->mad_recv_wc->recv_buf.mad;
+	drep_msg = (struct cm_drep_msg *)work->hdr.mad_recv_wc->recv_buf.mad;
 	cm_id_priv = cm_acquire_id(
 		cpu_to_be32(IBA_GET(CM_DREP_REMOTE_COMM_ID, drep_msg)),
 		cpu_to_be32(IBA_GET(CM_DREP_LOCAL_COMM_ID, drep_msg)));
 	if (!cm_id_priv)
 		return -EINVAL;
 
-	work->cm_event.private_data =
+	work->hdr.cm_event.private_data =
 		IBA_GET_MEM_PTR(CM_DREP_PRIVATE_DATA, drep_msg);
 
 	spin_lock_irq(&cm_id_priv->lock);
@@ -3020,12 +3026,12 @@ static void cm_format_rej_event(struct cm_work *work)
 	struct cm_rej_msg *rej_msg;
 	struct ib_cm_rej_event_param *param;
 
-	rej_msg = (struct cm_rej_msg *)work->mad_recv_wc->recv_buf.mad;
-	param = &work->cm_event.param.rej_rcvd;
+	rej_msg = (struct cm_rej_msg *)work->hdr.mad_recv_wc->recv_buf.mad;
+	param = &work->hdr.cm_event.param.rej_rcvd;
 	param->ari = IBA_GET_MEM_PTR(CM_REJ_ARI, rej_msg);
 	param->ari_length = IBA_GET(CM_REJ_REJECTED_INFO_LENGTH, rej_msg);
 	param->reason = IBA_GET(CM_REJ_REASON, rej_msg);
-	work->cm_event.private_data =
+	work->hdr.cm_event.private_data =
 		IBA_GET_MEM_PTR(CM_REJ_PRIVATE_DATA, rej_msg);
 }
 
@@ -3058,7 +3064,7 @@ static int cm_rej_handler(struct cm_work *work)
 	struct cm_id_private *cm_id_priv;
 	struct cm_rej_msg *rej_msg;
 
-	rej_msg = (struct cm_rej_msg *)work->mad_recv_wc->recv_buf.mad;
+	rej_msg = (struct cm_rej_msg *)work->hdr.mad_recv_wc->recv_buf.mad;
 	cm_id_priv = cm_acquire_rejected_id(rej_msg);
 	if (!cm_id_priv)
 		return -EINVAL;
@@ -3175,14 +3181,14 @@ static int cm_mra_handler(struct cm_work *work)
 	struct cm_mra_msg *mra_msg;
 	int timeout;
 
-	mra_msg = (struct cm_mra_msg *)work->mad_recv_wc->recv_buf.mad;
+	mra_msg = (struct cm_mra_msg *)work->hdr.mad_recv_wc->recv_buf.mad;
 	cm_id_priv = cm_acquire_mraed_id(mra_msg);
 	if (!cm_id_priv)
 		return -EINVAL;
 
-	work->cm_event.private_data =
+	work->hdr.cm_event.private_data =
 		IBA_GET_MEM_PTR(CM_MRA_PRIVATE_DATA, mra_msg);
-	work->cm_event.param.mra_rcvd.service_timeout =
+	work->hdr.cm_event.param.mra_rcvd.service_timeout =
 		IBA_GET(CM_MRA_SERVICE_TIMEOUT, mra_msg);
 	timeout = cm_convert_to_ms(IBA_GET(CM_MRA_SERVICE_TIMEOUT, mra_msg)) +
 		  cm_convert_to_ms(cm_id_priv->av.timeout);
@@ -3210,7 +3216,7 @@ static int cm_mra_handler(struct cm_work *work)
 		    ib_modify_mad(cm_id_priv->msg, timeout)) {
 			if (cm_id_priv->id.lap_state == IB_CM_MRA_LAP_RCVD)
 				atomic_long_inc(
-					&work->port->counters[CM_RECV_DUPLICATES]
+					&work->hdr.port->counters[CM_RECV_DUPLICATES]
 							     [CM_MRA_COUNTER]);
 			goto out;
 		}
@@ -3218,7 +3224,7 @@ static int cm_mra_handler(struct cm_work *work)
 		break;
 	case IB_CM_MRA_REQ_RCVD:
 	case IB_CM_MRA_REP_RCVD:
-		atomic_long_inc(&work->port->counters[CM_RECV_DUPLICATES]
+		atomic_long_inc(&work->hdr.port->counters[CM_RECV_DUPLICATES]
 						     [CM_MRA_COUNTER]);
 		fallthrough;
 	default:
@@ -3295,33 +3301,33 @@ static int cm_lap_handler(struct cm_work *work)
 	/* Currently Alternate path messages are not supported for
 	 * RoCE link layer.
 	 */
-	if (rdma_protocol_roce(work->port->cm_dev->ib_device,
-			       work->port->port_num))
+	if (rdma_protocol_roce(work->hdr.port->cm_dev->ib_device,
+			       work->hdr.port->port_num))
 		return -EINVAL;
 
 	/* todo: verify LAP request and send reject APR if invalid. */
-	lap_msg = (struct cm_lap_msg *)work->mad_recv_wc->recv_buf.mad;
+	lap_msg = (struct cm_lap_msg *)work->hdr.mad_recv_wc->recv_buf.mad;
 	cm_id_priv = cm_acquire_id(
 		cpu_to_be32(IBA_GET(CM_LAP_REMOTE_COMM_ID, lap_msg)),
 		cpu_to_be32(IBA_GET(CM_LAP_LOCAL_COMM_ID, lap_msg)));
 	if (!cm_id_priv)
 		return -EINVAL;
 
-	param = &work->cm_event.param.lap_rcvd;
+	param = &work->hdr.cm_event.param.lap_rcvd;
 	memset(&work->path[0], 0, sizeof(work->path[1]));
-	cm_path_set_rec_type(work->port->cm_dev->ib_device,
-			     work->port->port_num, &work->path[0],
+	cm_path_set_rec_type(work->hdr.port->cm_dev->ib_device,
+			     work->hdr.port->port_num, &work->path[0],
 			     IBA_GET_MEM_PTR(CM_LAP_ALTERNATE_LOCAL_PORT_GID,
 					     lap_msg));
 	param->alternate_path = &work->path[0];
 	cm_format_path_from_lap(cm_id_priv, param->alternate_path, lap_msg);
-	work->cm_event.private_data =
+	work->hdr.cm_event.private_data =
 		IBA_GET_MEM_PTR(CM_LAP_PRIVATE_DATA, lap_msg);
 
-	ret = ib_init_ah_attr_from_wc(work->port->cm_dev->ib_device,
-				      work->port->port_num,
-				      work->mad_recv_wc->wc,
-				      work->mad_recv_wc->recv_buf.grh,
+	ret = ib_init_ah_attr_from_wc(work->hdr.port->cm_dev->ib_device,
+				      work->hdr.port->port_num,
+				      work->hdr.mad_recv_wc->wc,
+				      work->hdr.mad_recv_wc->recv_buf.grh,
 				      &ah_attr);
 	if (ret)
 		goto deref;
@@ -3333,7 +3339,7 @@ static int cm_lap_handler(struct cm_work *work)
 	}
 
 	spin_lock_irq(&cm_id_priv->lock);
-	cm_init_av_for_lap(work->port, work->mad_recv_wc->wc,
+	cm_init_av_for_lap(work->hdr.port, work->hdr.mad_recv_wc->wc,
 			   &ah_attr, &cm_id_priv->av);
 	cm_move_av_from_path(&cm_id_priv->alt_av, &alt_av);
 
@@ -3345,9 +3351,9 @@ static int cm_lap_handler(struct cm_work *work)
 	case IB_CM_LAP_IDLE:
 		break;
 	case IB_CM_MRA_LAP_SENT:
-		atomic_long_inc(&work->port->counters[CM_RECV_DUPLICATES]
+		atomic_long_inc(&work->hdr.port->counters[CM_RECV_DUPLICATES]
 						     [CM_LAP_COUNTER]);
-		msg = cm_alloc_response_msg_no_ah(work->port, work->mad_recv_wc,
+		msg = cm_alloc_response_msg_no_ah(work->hdr.port, work->hdr.mad_recv_wc,
 						  true);
 		if (IS_ERR(msg))
 			goto unlock;
@@ -3358,12 +3364,12 @@ static int cm_lap_handler(struct cm_work *work)
 			      cm_id_priv->private_data_len);
 		spin_unlock_irq(&cm_id_priv->lock);
 
-		if (cm_create_response_msg_ah(work->port, work->mad_recv_wc, msg) ||
+		if (cm_create_response_msg_ah(work->hdr.port, work->hdr.mad_recv_wc, msg) ||
 		    ib_post_send_mad(msg, NULL))
 			cm_free_msg(msg);
 		goto deref;
 	case IB_CM_LAP_RCVD:
-		atomic_long_inc(&work->port->counters[CM_RECV_DUPLICATES]
+		atomic_long_inc(&work->hdr.port->counters[CM_RECV_DUPLICATES]
 						     [CM_LAP_COUNTER]);
 		goto unlock;
 	default:
@@ -3388,24 +3394,24 @@ static int cm_apr_handler(struct cm_work *work)
 	/* Currently Alternate path messages are not supported for
 	 * RoCE link layer.
 	 */
-	if (rdma_protocol_roce(work->port->cm_dev->ib_device,
-			       work->port->port_num))
+	if (rdma_protocol_roce(work->hdr.port->cm_dev->ib_device,
+			       work->hdr.port->port_num))
 		return -EINVAL;
 
-	apr_msg = (struct cm_apr_msg *)work->mad_recv_wc->recv_buf.mad;
+	apr_msg = (struct cm_apr_msg *)work->hdr.mad_recv_wc->recv_buf.mad;
 	cm_id_priv = cm_acquire_id(
 		cpu_to_be32(IBA_GET(CM_APR_REMOTE_COMM_ID, apr_msg)),
 		cpu_to_be32(IBA_GET(CM_APR_LOCAL_COMM_ID, apr_msg)));
 	if (!cm_id_priv)
 		return -EINVAL; /* Unmatched reply. */
 
-	work->cm_event.param.apr_rcvd.ap_status =
+	work->hdr.cm_event.param.apr_rcvd.ap_status =
 		IBA_GET(CM_APR_AR_STATUS, apr_msg);
-	work->cm_event.param.apr_rcvd.apr_info =
+	work->hdr.cm_event.param.apr_rcvd.apr_info =
 		IBA_GET_MEM_PTR(CM_APR_ADDITIONAL_INFORMATION, apr_msg);
-	work->cm_event.param.apr_rcvd.info_len =
+	work->hdr.cm_event.param.apr_rcvd.info_len =
 		IBA_GET(CM_APR_ADDITIONAL_INFORMATION_LENGTH, apr_msg);
-	work->cm_event.private_data =
+	work->hdr.cm_event.private_data =
 		IBA_GET_MEM_PTR(CM_APR_PRIVATE_DATA, apr_msg);
 
 	spin_lock_irq(&cm_id_priv->lock);
@@ -3429,7 +3435,7 @@ static int cm_timewait_handler(struct cm_work *work)
 	struct cm_timewait_info *timewait_info;
 	struct cm_id_private *cm_id_priv;
 
-	timewait_info = container_of(work, struct cm_timewait_info, work);
+	timewait_info = container_of(&work->hdr, struct cm_timewait_info, work);
 	spin_lock_irq(&cm.lock);
 	list_del(&timewait_info->list);
 	spin_unlock_irq(&cm.lock);
@@ -3531,16 +3537,16 @@ static void cm_format_sidr_req_event(struct cm_work *work,
 	struct ib_cm_sidr_req_event_param *param;
 
 	sidr_req_msg = (struct cm_sidr_req_msg *)
-				work->mad_recv_wc->recv_buf.mad;
-	param = &work->cm_event.param.sidr_req_rcvd;
+				work->hdr.mad_recv_wc->recv_buf.mad;
+	param = &work->hdr.cm_event.param.sidr_req_rcvd;
 	param->pkey = IBA_GET(CM_SIDR_REQ_PARTITION_KEY, sidr_req_msg);
 	param->listen_id = listen_id;
 	param->service_id =
 		cpu_to_be64(IBA_GET(CM_SIDR_REQ_SERVICEID, sidr_req_msg));
 	param->bth_pkey = cm_get_bth_pkey(work);
-	param->port = work->port->port_num;
+	param->port = work->hdr.port->port_num;
 	param->sgid_attr = rx_cm_id->av.ah_attr.grh.sgid_attr;
-	work->cm_event.private_data =
+	work->hdr.cm_event.private_data =
 		IBA_GET_MEM_PTR(CM_SIDR_REQ_PRIVATE_DATA, sidr_req_msg);
 }
 
@@ -3552,13 +3558,13 @@ static int cm_sidr_req_handler(struct cm_work *work)
 	int ret;
 
 	cm_id_priv =
-		cm_alloc_id_priv(work->port->cm_dev->ib_device, NULL, NULL);
+		cm_alloc_id_priv(work->hdr.port->cm_dev->ib_device, NULL, NULL);
 	if (IS_ERR(cm_id_priv))
 		return PTR_ERR(cm_id_priv);
 
 	/* Record SGID/SLID and request ID for lookup. */
 	sidr_req_msg = (struct cm_sidr_req_msg *)
-				work->mad_recv_wc->recv_buf.mad;
+				work->hdr.mad_recv_wc->recv_buf.mad;
 
 	cm_id_priv->id.remote_id =
 		cpu_to_be32(IBA_GET(CM_SIDR_REQ_REQUESTID, sidr_req_msg));
@@ -3566,10 +3572,10 @@ static int cm_sidr_req_handler(struct cm_work *work)
 		cpu_to_be64(IBA_GET(CM_SIDR_REQ_SERVICEID, sidr_req_msg));
 	cm_id_priv->tid = sidr_req_msg->hdr.tid;
 
-	wc = work->mad_recv_wc->wc;
+	wc = work->hdr.mad_recv_wc->wc;
 	cm_id_priv->sidr_slid = wc->slid;
-	ret = cm_init_av_for_response(work->port, work->mad_recv_wc->wc,
-				      work->mad_recv_wc->recv_buf.grh,
+	ret = cm_init_av_for_response(work->hdr.port, work->hdr.mad_recv_wc->wc,
+				      work->hdr.mad_recv_wc->recv_buf.grh,
 				      &cm_id_priv->av);
 	if (ret)
 		goto out;
@@ -3578,7 +3584,7 @@ static int cm_sidr_req_handler(struct cm_work *work)
 	listen_cm_id_priv = cm_insert_remote_sidr(cm_id_priv);
 	if (listen_cm_id_priv) {
 		spin_unlock_irq(&cm.lock);
-		atomic_long_inc(&work->port->counters[CM_RECV_DUPLICATES]
+		atomic_long_inc(&work->hdr.port->counters[CM_RECV_DUPLICATES]
 						     [CM_SIDR_REQ_COUNTER]);
 		goto out; /* Duplicate message. */
 	}
@@ -3604,7 +3610,7 @@ static int cm_sidr_req_handler(struct cm_work *work)
 	 */
 
 	cm_format_sidr_req_event(work, cm_id_priv, &listen_cm_id_priv->id);
-	ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, &work->cm_event);
+	ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, &work->hdr.cm_event);
 	cm_free_work(work);
 	/*
 	 * A pointer to the listen_cm_id is held in the event, so this deref
@@ -3707,8 +3713,8 @@ static void cm_format_sidr_rep_event(struct cm_work *work,
 	struct ib_cm_sidr_rep_event_param *param;
 
 	sidr_rep_msg = (struct cm_sidr_rep_msg *)
-				work->mad_recv_wc->recv_buf.mad;
-	param = &work->cm_event.param.sidr_rep_rcvd;
+				work->hdr.mad_recv_wc->recv_buf.mad;
+	param = &work->hdr.cm_event.param.sidr_rep_rcvd;
 	param->status = IBA_GET(CM_SIDR_REP_STATUS, sidr_rep_msg);
 	param->qkey = IBA_GET(CM_SIDR_REP_Q_KEY, sidr_rep_msg);
 	param->qpn = IBA_GET(CM_SIDR_REP_QPN, sidr_rep_msg);
@@ -3717,7 +3723,7 @@ static void cm_format_sidr_rep_event(struct cm_work *work,
 	param->info_len = IBA_GET(CM_SIDR_REP_ADDITIONAL_INFORMATION_LENGTH,
 				  sidr_rep_msg);
 	param->sgid_attr = cm_id_priv->av.ah_attr.grh.sgid_attr;
-	work->cm_event.private_data =
+	work->hdr.cm_event.private_data =
 		IBA_GET_MEM_PTR(CM_SIDR_REP_PRIVATE_DATA, sidr_rep_msg);
 }
 
@@ -3727,7 +3733,7 @@ static int cm_sidr_rep_handler(struct cm_work *work)
 	struct cm_id_private *cm_id_priv;
 
 	sidr_rep_msg = (struct cm_sidr_rep_msg *)
-				work->mad_recv_wc->recv_buf.mad;
+				work->hdr.mad_recv_wc->recv_buf.mad;
 	cm_id_priv = cm_acquire_id(
 		cpu_to_be32(IBA_GET(CM_SIDR_REP_REQUESTID, sidr_rep_msg)), 0);
 	if (!cm_id_priv)
@@ -3839,10 +3845,10 @@ static void cm_send_handler(struct ib_mad_agent *mad_agent,
 
 static void cm_work_handler(struct work_struct *_work)
 {
-	struct cm_work *work = container_of(_work, struct cm_work, work.work);
+	struct cm_work *work = container_of(_work, struct cm_work, hdr.work.work);
 	int ret;
 
-	switch (work->cm_event.event) {
+	switch (work->hdr.cm_event.event) {
 	case IB_CM_REQ_RECEIVED:
 		ret = cm_req_handler(work);
 		break;
@@ -3883,7 +3889,7 @@ static void cm_work_handler(struct work_struct *_work)
 		ret = cm_timewait_handler(work);
 		break;
 	default:
-		trace_icm_handler_err(work->cm_event.event);
+		trace_icm_handler_err(work->hdr.cm_event.event);
 		ret = -EINVAL;
 		break;
 	}
@@ -3935,16 +3941,16 @@ static int cm_establish(struct ib_cm_id *cm_id)
 	 * we need to find the cm_id once we're in the context of the
 	 * worker thread, rather than holding a reference on it.
 	 */
-	INIT_DELAYED_WORK(&work->work, cm_work_handler);
-	work->local_id = cm_id->local_id;
-	work->remote_id = cm_id->remote_id;
-	work->mad_recv_wc = NULL;
-	work->cm_event.event = IB_CM_USER_ESTABLISHED;
+	INIT_DELAYED_WORK(&work->hdr.work, cm_work_handler);
+	work->hdr.local_id = cm_id->local_id;
+	work->hdr.remote_id = cm_id->remote_id;
+	work->hdr.mad_recv_wc = NULL;
+	work->hdr.cm_event.event = IB_CM_USER_ESTABLISHED;
 
 	/* Check if the device started its remove_one */
 	spin_lock_irqsave(&cm.lock, flags);
 	if (!cm_dev->going_down) {
-		queue_delayed_work(cm.wq, &work->work, 0);
+		queue_delayed_work(cm.wq, &work->hdr.work, 0);
 	} else {
 		kfree(work);
 		ret = -ENODEV;
@@ -4057,15 +4063,15 @@ static void cm_recv_handler(struct ib_mad_agent *mad_agent,
 		return;
 	}
 
-	INIT_DELAYED_WORK(&work->work, cm_work_handler);
-	work->cm_event.event = event;
-	work->mad_recv_wc = mad_recv_wc;
-	work->port = port;
+	INIT_DELAYED_WORK(&work->hdr.work, cm_work_handler);
+	work->hdr.cm_event.event = event;
+	work->hdr.mad_recv_wc = mad_recv_wc;
+	work->hdr.port = port;
 
 	/* Check if the device started its remove_one */
 	spin_lock_irq(&cm.lock);
 	if (!port->cm_dev->going_down)
-		queue_delayed_work(cm.wq, &work->work, 0);
+		queue_delayed_work(cm.wq, &work->hdr.work, 0);
 	else
 		going_down = 1;
 	spin_unlock_irq(&cm.lock);
-- 
2.43.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ