The branch main has been updated by jhb:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=cd567a22e28a68aebf12cc320d83648b5b68c274

commit cd567a22e28a68aebf12cc320d83648b5b68c274
Author:     John Baldwin <[email protected]>
AuthorDate: 2026-06-24 19:30:56 +0000
Commit:     John Baldwin <[email protected]>
CommitDate: 2026-06-24 19:30:56 +0000

    OFED: Various changes from Linux 4.18
    
    This contains changes from the following Linux commits:
    
    e822ff213fe6 IB/cm: Store and restore ah_attr during CM message processing
    0e225dcb7681 IB/cm: Store and restore ah_attr during LAP msg processing
    a5c57d327272 IB/cm: Avoid AV ah_attr overwriting during LAP message handling
    724631a9c6e9 IB/core: Introduce and use rdma_gid_table()
    25e62655c793 IB/core: Reduce the places that use zgid
    08bb558ac11a IB/core: Make testing MR flags for writability a static inline 
function
    
    Commit 0e225dcb7681 was partially merged previously as
    cm_init_av_for_lap() already existed in FreeBSD matching the version
    from the Linux commit.
    
    Tested by:      Wafa Hamzah <[email protected]> (mlx5_ib)
    Tested by:      John Baldwin <[email protected]> (iw_cxgbe)
    Sponsored by:   Chelsio Communications
---
 sys/dev/mlx4/mlx4_ib/mlx4_ib_main.c                |  5 ++-
 sys/dev/mlx4/mlx4_ib/mlx4_ib_qp.c                  |  2 +-
 sys/ofed/drivers/infiniband/core/ib_cache.c        | 44 ++++++++++++++--------
 sys/ofed/drivers/infiniband/core/ib_cm.c           | 35 +++++++++++------
 .../drivers/infiniband/core/ib_roce_gid_mgmt.c     |  2 +-
 sys/ofed/drivers/infiniband/core/ib_umem.c         | 11 +-----
 sys/ofed/include/rdma/ib_cache.h                   |  1 +
 7 files changed, 60 insertions(+), 40 deletions(-)

diff --git a/sys/dev/mlx4/mlx4_ib/mlx4_ib_main.c 
b/sys/dev/mlx4/mlx4_ib/mlx4_ib_main.c
index 9f51bac12d51..e7375d422abf 100644
--- a/sys/dev/mlx4/mlx4_ib/mlx4_ib_main.c
+++ b/sys/dev/mlx4/mlx4_ib/mlx4_ib_main.c
@@ -282,7 +282,7 @@ static int mlx4_ib_add_gid(const union ib_gid *gid,
                        found = i;
                        break;
                }
-               if (free < 0 && !memcmp(&port_gid_table->gids[i].gid, &zgid, 
sizeof(*gid)))
+               if (free < 0 && rdma_is_zero_gid(&port_gid_table->gids[i].gid))
                        free = i; /* HW has space */
        }
 
@@ -351,7 +351,8 @@ static int mlx4_ib_del_gid(const struct ib_gid_attr *attr, 
void **context)
                if (!ctx->refcount) {
                        unsigned int real_index = ctx->real_index;
 
-                       memcpy(&port_gid_table->gids[real_index].gid, &zgid, 
sizeof(zgid));
+                       memset(&port_gid_table->gids[real_index].gid, 0,
+                              sizeof(port_gid_table->gids[real_index].gid));
                        kfree(port_gid_table->gids[real_index].ctx);
                        port_gid_table->gids[real_index].ctx = NULL;
                        hw_update = 1;
diff --git a/sys/dev/mlx4/mlx4_ib/mlx4_ib_qp.c 
b/sys/dev/mlx4/mlx4_ib/mlx4_ib_qp.c
index 42606907a2e3..985980d206fe 100644
--- a/sys/dev/mlx4/mlx4_ib/mlx4_ib_qp.c
+++ b/sys/dev/mlx4/mlx4_ib/mlx4_ib_qp.c
@@ -2435,7 +2435,7 @@ static int fill_gid_by_hw_index(struct mlx4_ib_dev 
*ibdev, u8 port_num,
        memcpy(gid, &port_gid_table->gids[index].gid, sizeof(*gid));
        *gid_type = port_gid_table->gids[index].gid_type;
        spin_unlock_irqrestore(&iboe->lock, flags);
-       if (!memcmp(gid, &zgid, sizeof(*gid)))
+       if (rdma_is_zero_gid(gid))
                return -ENOENT;
 
        return 0;
diff --git a/sys/ofed/drivers/infiniband/core/ib_cache.c 
b/sys/ofed/drivers/infiniband/core/ib_cache.c
index 1b7f0dfd4761..bcc0a4315ee7 100644
--- a/sys/ofed/drivers/infiniband/core/ib_cache.c
+++ b/sys/ofed/drivers/infiniband/core/ib_cache.c
@@ -128,6 +128,16 @@ const char *ib_cache_gid_type_str(enum ib_gid_type 
gid_type)
 }
 EXPORT_SYMBOL(ib_cache_gid_type_str);
 
+/** rdma_is_zero_gid - Check if given GID is zero or not.
+ * @gid:       GID to check
+ * Returns true if given GID is zero, returns false otherwise.
+ */
+bool rdma_is_zero_gid(const union ib_gid *gid)
+{
+       return !memcmp(gid, &zgid, sizeof(*gid));
+}
+EXPORT_SYMBOL(rdma_is_zero_gid);
+
 int ib_cache_gid_parse_type_str(const char *buf)
 {
        unsigned int i;
@@ -152,6 +162,11 @@ int ib_cache_gid_parse_type_str(const char *buf)
 }
 EXPORT_SYMBOL(ib_cache_gid_parse_type_str);
 
+static struct ib_gid_table *rdma_gid_table(struct ib_device *device, u8 port)
+{
+       return device->cache.ports[port - rdma_start_port(device)].gid;
+}
+
 static void del_roce_gid(struct ib_device *device, u8 port_num,
                         struct ib_gid_table *table, int ix)
 {
@@ -234,7 +249,7 @@ static int add_modify_gid(struct ib_gid_table *table,
                 * So ignore such behavior for IB link layer and don't
                 * fail the call, but don't add such entry to GID cache.
                 */
-               if (!memcmp(gid, &zgid, sizeof(*gid)))
+               if (rdma_is_zero_gid(gid))
                        return 0;
        }
  
@@ -267,7 +282,7 @@ static void del_gid(struct ib_device *ib_dev, u8 port,
 
        if (rdma_protocol_roce(ib_dev, port))
                del_roce_gid(ib_dev, port, table, ix);
-       memcpy(&table->data_vec[ix].gid, &zgid, sizeof(zgid));
+       memset(&table->data_vec[ix].gid, 0, sizeof(table->data_vec[ix].gid));
        memset(&table->data_vec[ix].attr, 0, sizeof(table->data_vec[ix].attr));
        table->data_vec[ix].context = NULL;
 }
@@ -380,10 +395,10 @@ static int __ib_cache_gid_add(struct ib_device *ib_dev, 
u8 port,
         * IB spec version 1.3 section 4.1.1 point (6) and
         * section 12.7.10 and section 12.7.20
         */
-       if (!memcmp(gid, &zgid, sizeof(*gid)))
+       if (rdma_is_zero_gid(gid))
                return -EINVAL;
 
-       table = ib_dev->cache.ports[port - rdma_start_port(ib_dev)].gid;
+       table = rdma_gid_table(ib_dev, port);
 
        mutex_lock(&table->lock);
 
@@ -433,7 +448,7 @@ _ib_cache_gid_del(struct ib_device *ib_dev, u8 port,
        int ret = 0;
        int ix;
 
-       table = ib_dev->cache.ports[port - rdma_start_port(ib_dev)].gid;
+       table = rdma_gid_table(ib_dev, port);
 
        mutex_lock(&table->lock);
 
@@ -472,7 +487,7 @@ int ib_cache_gid_del_all_netdev_gids(struct ib_device 
*ib_dev, u8 port,
        int ix;
        bool deleted = false;
 
-       table = ib_dev->cache.ports[port - rdma_start_port(ib_dev)].gid;
+       table = rdma_gid_table(ib_dev, port);
 
        mutex_lock(&table->lock);
 
@@ -496,7 +511,7 @@ static int __ib_cache_gid_get(struct ib_device *ib_dev, u8 
port, int index,
 {
        struct ib_gid_table *table;
 
-       table = ib_dev->cache.ports[port - rdma_start_port(ib_dev)].gid;
+       table = rdma_gid_table(ib_dev, port);
 
        if (index < 0 || index >= table->sz)
                return -EINVAL;
@@ -594,7 +609,7 @@ int ib_find_cached_gid_by_port(struct ib_device *ib_dev,
        if (!rdma_is_port_valid(ib_dev, port))
                return -ENOENT;
 
-       table = ib_dev->cache.ports[port - rdma_start_port(ib_dev)].gid;
+       table = rdma_gid_table(ib_dev, port);
 
        if (ndev)
                mask |= GID_ATTR_FIND_MASK_NETDEV;
@@ -653,7 +668,7 @@ static int ib_cache_gid_find_by_filter(struct ib_device 
*ib_dev,
        if (!rdma_protocol_roce(ib_dev, port))
                return -EPROTONOSUPPORT;
 
-       table = ib_dev->cache.ports[port - rdma_start_port(ib_dev)].gid;
+       table = rdma_gid_table(ib_dev, port);
 
        read_lock_irqsave(&table->rwlock, flags);
        for (i = 0; i < table->sz; i++) {
@@ -730,8 +745,7 @@ static void cleanup_gid_table_port(struct ib_device 
*ib_dev, u8 port,
 
        mutex_lock(&table->lock);
        for (i = 0; i < table->sz; ++i) {
-               if (memcmp(&table->data_vec[i].gid, &zgid,
-                          sizeof(table->data_vec[i].gid))) {
+               if (!rdma_is_zero_gid(&table->data_vec[i].gid)) {
                        del_gid(ib_dev, port, table, i);
                        deleted = true;
                }
@@ -753,7 +767,7 @@ void ib_cache_gid_set_default_gid(struct ib_device *ib_dev, 
u8 port,
        unsigned int gid_type;
        unsigned long mask;
 
-       table = ib_dev->cache.ports[port - rdma_start_port(ib_dev)].gid;
+       table = rdma_gid_table(ib_dev, port);
 
        mask = GID_ATTR_FIND_MASK_GID_TYPE |
               GID_ATTR_FIND_MASK_DEFAULT |
@@ -907,7 +921,7 @@ int ib_get_cached_gid(struct ib_device *device,
        if (!rdma_is_port_valid(device, port_num))
                return -EINVAL;
 
-       table = device->cache.ports[port_num - rdma_start_port(device)].gid;
+       table = rdma_gid_table(device, port_num);
        read_lock_irqsave(&table->rwlock, flags);
        res = __ib_cache_gid_get(device, port_num, index, gid, gid_attr);
        read_unlock_irqrestore(&table->rwlock, flags);
@@ -1106,7 +1120,7 @@ static int config_non_roce_gid_cache(struct ib_device 
*device,
 
        gid_attr.device = device;
        gid_attr.port_num = port;
-       table = device->cache.ports[port - rdma_start_port(device)].gid;
+       table = rdma_gid_table(device, port);
 
        mutex_lock(&table->lock);
        for (i = 0; i < gid_tbl_len; ++i) {
@@ -1138,7 +1152,7 @@ static void ib_cache_update(struct ib_device *device,
        if (!rdma_is_port_valid(device, port))
                return;
 
-       table = device->cache.ports[port - rdma_start_port(device)].gid;
+       table = rdma_gid_table(device, port);
 
        tprops = kmalloc(sizeof *tprops, GFP_KERNEL);
        if (!tprops)
diff --git a/sys/ofed/drivers/infiniband/core/ib_cm.c 
b/sys/ofed/drivers/infiniband/core/ib_cm.c
index 05d2992a3dd3..4cd36910f030 100644
--- a/sys/ofed/drivers/infiniband/core/ib_cm.c
+++ b/sys/ofed/drivers/infiniband/core/ib_cm.c
@@ -541,6 +541,7 @@ static struct cm_port *get_cm_port_from_path(struct 
sa_path_rec *path)
 static int cm_init_av_by_path(struct sa_path_rec *path, struct cm_av *av,
                              struct cm_id_private *cm_id_priv)
 {
+       struct rdma_ah_attr new_ah_attr;
        struct cm_device *cm_dev;
        struct cm_port *port;
        int ret;
@@ -556,15 +557,26 @@ static int cm_init_av_by_path(struct sa_path_rec *path, 
struct cm_av *av,
                return ret;
 
        av->port = port;
-       ret = ib_init_ah_attr_from_path(cm_dev->ib_device, port->port_num,
-                                       path, &av->ah_attr);
+
+       /*
+        * av->ah_attr might be initialized based on wc or during
+        * request processing time. So initialize a new ah_attr on stack.
+        * If initialization fails, old ah_attr is used for sending any
+        * responses. If initialization is successful, than new ah_attr
+        * is used by overwriting the old one.
+        */
+       ret = ib_init_ah_attr_from_path(cm_dev->ib_device, port->port_num, path,
+                                       &new_ah_attr);
        if (ret)
                return ret;
 
        av->timeout = path->packet_life_time + 1;
 
        ret = add_cm_id_to_port_list(cm_id_priv, av, port);
-       return ret;
+       if (ret)
+               return ret;
+       memcpy(&av->ah_attr, &new_ah_attr, sizeof(new_ah_attr));
+       return 0;
 }
 
 static int cm_alloc_id(struct cm_id_private *cm_id_priv)
@@ -3177,12 +3189,6 @@ static int cm_lap_handler(struct cm_work *work)
        if (!cm_id_priv)
                return -EINVAL;
 
-       ret = cm_init_av_for_response(work->port, work->mad_recv_wc->wc,
-                                     work->mad_recv_wc->recv_buf.grh,
-                                     &cm_id_priv->av);
-       if (ret)
-               goto deref;
-
        param = &work->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,
@@ -3227,12 +3233,19 @@ static int cm_lap_handler(struct cm_work *work)
                goto unlock;
        }
 
-       cm_id_priv->id.lap_state = IB_CM_LAP_RCVD;
-       cm_id_priv->tid = lap_msg->hdr.tid;
+       ret = cm_init_av_for_lap(work->port, work->mad_recv_wc->wc,
+                                work->mad_recv_wc->recv_buf.grh,
+                                &cm_id_priv->av);
+       if (ret)
+               goto unlock;
+
        ret = cm_init_av_by_path(param->alternate_path, &cm_id_priv->alt_av,
                                 cm_id_priv);
        if (ret)
                goto unlock;
+
+       cm_id_priv->id.lap_state = IB_CM_LAP_RCVD;
+       cm_id_priv->tid = lap_msg->hdr.tid;
        ret = atomic_inc_and_test(&cm_id_priv->work_count);
        if (!ret)
                list_add_tail(&work->list, &cm_id_priv->work_list);
diff --git a/sys/ofed/drivers/infiniband/core/ib_roce_gid_mgmt.c 
b/sys/ofed/drivers/infiniband/core/ib_roce_gid_mgmt.c
index 50932d6ec675..8b119efad5f6 100644
--- a/sys/ofed/drivers/infiniband/core/ib_roce_gid_mgmt.c
+++ b/sys/ofed/drivers/infiniband/core/ib_roce_gid_mgmt.c
@@ -280,7 +280,7 @@ roce_gid_update_addr_callback(struct ib_device *device, u8 
port,
                dev_put(ndev);
 
                /* don't delete empty entries */
-               if (memcmp(&gid, &zgid, sizeof(zgid)) == 0)
+               if (rdma_is_zero_gid(&gid))
                        continue;
 
                /* zero default */
diff --git a/sys/ofed/drivers/infiniband/core/ib_umem.c 
b/sys/ofed/drivers/infiniband/core/ib_umem.c
index a72047075257..87325c480057 100644
--- a/sys/ofed/drivers/infiniband/core/ib_umem.c
+++ b/sys/ofed/drivers/infiniband/core/ib_umem.c
@@ -119,16 +119,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, 
unsigned long addr,
        umem->address    = addr;
        umem->page_shift = PAGE_SHIFT;
        umem->pid        = get_pid(task_pid(current));
-       /*
-        * We ask for writable memory if any of the following
-        * access flags are set.  "Local write" and "remote write"
-        * obviously require write access.  "Remote atomic" can do
-        * things like fetch and add, which will modify memory, and
-        * "MW bind" can change permissions by binding a window.
-        */
-       umem->writable  = !!(access &
-               (IB_ACCESS_LOCAL_WRITE   | IB_ACCESS_REMOTE_WRITE |
-                IB_ACCESS_REMOTE_ATOMIC | IB_ACCESS_MW_BIND));
+       umem->writable   = ib_access_writable(access);
 
        if (access & IB_ACCESS_ON_DEMAND) {
                put_pid(umem->pid);
diff --git a/sys/ofed/include/rdma/ib_cache.h b/sys/ofed/include/rdma/ib_cache.h
index 07ebea90be01..fbd9135ddab7 100644
--- a/sys/ofed/include/rdma/ib_cache.h
+++ b/sys/ofed/include/rdma/ib_cache.h
@@ -151,4 +151,5 @@ int ib_get_cached_port_state(struct ib_device *device,
                              u8                port_num,
                              enum ib_port_state *port_active);
 
+bool rdma_is_zero_gid(const union ib_gid *gid);
 #endif /* _IB_CACHE_H */

Reply via email to