Re: [PATCH rdma-next v4 06/17] RDMA/counter: Add "auto" configuration mode support
From: Jason Gunthorpe <hidden>
Date: 2019-06-30 00:32:14
Also in:
linux-rdma
On Tue, Jun 18, 2019 at 08:26:14PM +0300, Leon Romanovsky wrote:
+/**
+ * rdma_counter_bind_qp_auto - Check and bind the QP to a counter base on
+ * the auto-mode rule
+ */
+int rdma_counter_bind_qp_auto(struct ib_qp *qp, u8 port)
+{
+ struct rdma_port_counter *port_counter;
+ struct ib_device *dev = qp->device;
+ struct rdma_counter *counter;
+ int ret;
+
+ if (!rdma_is_port_valid(dev, port))
+ return -EINVAL;
+
+ port_counter = &dev->port_data[port].port_counter;
+ if (port_counter->mode.mode != RDMA_COUNTER_MODE_AUTO)
+ return 0;
+
+ counter = rdma_get_counter_auto_mode(qp, port);
+ if (counter) {
+ ret = __rdma_counter_bind_qp(counter, qp);
+ if (ret) {
+ rdma_restrack_put(&counter->res);
+ return ret;
+ }
+ kref_get(&counter->kref);The counter is left in the xarray while the kref is zero, this kref_get is wrong.. Using two kref like things at the same time is a bad idea, the 'rdma_get_counter_auto_mode' should return the kref held, not the restrack get. The restrack_del doesn't happen as long as the kref is positive, so we don't need the retrack thing here..
+ } else {
+ counter = rdma_counter_alloc(dev, port, RDMA_COUNTER_MODE_AUTO);
+ if (!counter)
+ return -ENOMEM;
+
+ auto_mode_init_counter(counter, qp, port_counter->mode.mask);
+
+ ret = __rdma_counter_bind_qp(counter, qp);
+ if (ret)
+ goto err_bind;
+
+ rdma_counter_res_add(counter, qp);
+ if (!rdma_restrack_get(&counter->res)) {
+ ret = -EINVAL;
+ goto err_get;
+ }and this shouldn't be needed as the kref is inited to 1 by the rdma_counter_alloc..
+ } + + return 0; + +err_get: + __rdma_counter_unbind_qp(qp); + __rdma_counter_dealloc(counter); +err_bind: + rdma_counter_free(counter); + return ret; +}
And then all this error unwind and all the twisty __ functions should just be a single kref_put and the release should handle everything. Jason