-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 <gustavo...@kernel.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


Reply via email to