> Subject: [bug report] RDMA/mana_ib: Add a driver for Microsoft Azure > Network Adapter > > Hello Long Li, > > The patch 6dce3468a04c: "RDMA/mana_ib: Add a driver for Microsoft Azure > Network Adapter" from Sep 20, 2022, leads to the following Smatch static > checker warning: > > drivers/infiniband/hw/mana/qp.c:240 mana_ib_create_qp_rss() > warn: 'mana_ind_table' was already freed. > > drivers/infiniband/hw/mana/qp.c > 91 static int mana_ib_create_qp_rss(struct ib_qp *ibqp, struct ib_pd *pd, > 92 struct ib_qp_init_attr *attr, > 93 struct ib_udata *udata) > 94 { > 95 struct mana_ib_qp *qp = container_of(ibqp, struct mana_ib_qp, > ibqp); > 96 struct mana_ib_dev *mdev = > 97 container_of(pd->device, struct mana_ib_dev, ib_dev); > 98 struct ib_rwq_ind_table *ind_tbl = attr->rwq_ind_tbl; > 99 struct mana_ib_create_qp_rss_resp resp = {}; > 100 struct mana_ib_create_qp_rss ucmd = {}; > 101 struct gdma_dev *gd = mdev->gdma_dev; > 102 mana_handle_t *mana_ind_table; > 103 struct mana_port_context *mpc; > 104 struct mana_context *mc; > 105 struct net_device *ndev; > 106 struct mana_ib_cq *cq; > 107 struct mana_ib_wq *wq; > 108 struct ib_cq *ibcq; > 109 struct ib_wq *ibwq; > 110 int i = 0, ret; > 111 u32 port; > 112 > 113 mc = gd->driver_data; > 114 > 115 if (udata->inlen < sizeof(ucmd)) > 116 return -EINVAL; > 117 > 118 ret = ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), > udata->inlen)); > 119 if (ret) { > 120 ibdev_dbg(&mdev->ib_dev, > 121 "Failed copy from udata for create rss-qp, err %d\n", > 122 ret); > 123 return -EFAULT; > 124 } > 125 > 126 if (attr->cap.max_recv_wr > MAX_SEND_BUFFERS_PER_QUEUE) { > 127 ibdev_dbg(&mdev->ib_dev, > 128 "Requested max_recv_wr %d exceeding limit.\n", > 129 attr->cap.max_recv_wr); > 130 return -EINVAL; > 131 } > 132 > 133 if (attr->cap.max_recv_sge > MAX_RX_WQE_SGL_ENTRIES) { > 134 ibdev_dbg(&mdev->ib_dev, > 135 "Requested max_recv_sge %d exceeding limit.\n", > 136 attr->cap.max_recv_sge); > 137 return -EINVAL; > 138 } > 139 > 140 if (ucmd.rx_hash_function != > MANA_IB_RX_HASH_FUNC_TOEPLITZ) { > 141 ibdev_dbg(&mdev->ib_dev, > 142 "RX Hash function is not supported, %d\n", > 143 ucmd.rx_hash_function); > 144 return -EINVAL; > 145 } > 146 > 147 /* IB ports start with 1, MANA start with 0 */ > 148 port = ucmd.port; > 149 if (port < 1 || port > mc->num_ports) { > 150 ibdev_dbg(&mdev->ib_dev, "Invalid port %u in creating qp\n", > 151 port); > 152 return -EINVAL; > 153 } > 154 ndev = mc->ports[port - 1]; > 155 mpc = netdev_priv(ndev); > 156 > 157 ibdev_dbg(&mdev->ib_dev, "rx_hash_function %d port %d\n", > 158 ucmd.rx_hash_function, port); > 159 > 160 mana_ind_table = kzalloc(sizeof(mana_handle_t) * > 161 (1 << ind_tbl->log_ind_tbl_size), > 162 GFP_KERNEL); > 163 if (!mana_ind_table) { > 164 ret = -ENOMEM; > 165 goto fail; > 166 } > 167 > 168 qp->port = port; > 169 > 170 for (i = 0; i < (1 << ind_tbl->log_ind_tbl_size); i++) { > 171 struct mana_obj_spec wq_spec = {}; > 172 struct mana_obj_spec cq_spec = {}; > 173 > 174 ibwq = ind_tbl->ind_tbl[i]; > 175 wq = container_of(ibwq, struct mana_ib_wq, ibwq); > 176 > 177 ibcq = ibwq->cq; > 178 cq = container_of(ibcq, struct mana_ib_cq, ibcq); > 179 > 180 wq_spec.gdma_region = wq->gdma_region; > 181 wq_spec.queue_size = wq->wq_buf_size; > 182 > 183 cq_spec.gdma_region = cq->gdma_region; > 184 cq_spec.queue_size = cq->cqe * COMP_ENTRY_SIZE; > 185 cq_spec.modr_ctx_id = 0; > 186 cq_spec.attached_eq = GDMA_CQ_NO_EQ; > 187 > 188 ret = mana_create_wq_obj(mpc, mpc->port_handle, > GDMA_RQ, > 189 &wq_spec, &cq_spec, &wq->rx_object); > 190 if (ret) > 191 goto fail; > 192 > 193 /* The GDMA regions are now owned by the WQ object */ > 194 wq->gdma_region = GDMA_INVALID_DMA_REGION; > 195 cq->gdma_region = GDMA_INVALID_DMA_REGION; > 196 > 197 wq->id = wq_spec.queue_index; > 198 cq->id = cq_spec.queue_index; > 199 > 200 ibdev_dbg(&mdev->ib_dev, > 201 "ret %d rx_object 0x%llx wq id %llu cq id %llu\n", > 202 ret, wq->rx_object, wq->id, cq->id); > 203 > 204 resp.entries[i].cqid = cq->id; > 205 resp.entries[i].wqid = wq->id; > 206 > 207 mana_ind_table[i] = wq->rx_object; > 208 } > 209 resp.num_entries = i; > 210 > 211 ret = mana_ib_cfg_vport_steering(mdev, ndev, wq->rx_object, > 212 mana_ind_table, > 213 ind_tbl->log_ind_tbl_size, > 214 ucmd.rx_hash_key_len, > 215 ucmd.rx_hash_key); > 216 if (ret) > 217 goto fail; > 218 > 219 kfree(mana_ind_table); > > Freed here. > > 220 > 221 if (udata) { > 222 ret = ib_copy_to_udata(udata, &resp, sizeof(resp)); > 223 if (ret) { > 224 ibdev_dbg(&mdev->ib_dev, > 225 "Failed to copy to udata create rss-qp, %d\n", > 226 ret); > 227 goto fail; > > Goto. > > 228 } > 229 } > 230 > 231 return 0; > 232 > 233 fail: > 234 while (i-- > 0) { > 235 ibwq = ind_tbl->ind_tbl[i]; > 236 wq = container_of(ibwq, struct mana_ib_wq, ibwq); > 237 mana_destroy_wq_obj(mpc, GDMA_RQ, wq->rx_object); > 238 } > 239 > --> 240 kfree(mana_ind_table); > > Double freed. > > 241 > 242 return ret; > 243 } > > regards, > dan carpenter Thank you, will fix this. Long