1d9a5a644SRaed Salem // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2d9a5a644SRaed Salem /* 3d9a5a644SRaed Salem * Copyright (c) 2018, Mellanox Technologies inc. All rights reserved. 4d9a5a644SRaed Salem * 5d9a5a644SRaed Salem * This software is available to you under a choice of one of two 6d9a5a644SRaed Salem * licenses. You may choose to be licensed under the terms of the GNU 7d9a5a644SRaed Salem * General Public License (GPL) Version 2, available from the file 8d9a5a644SRaed Salem * COPYING in the main directory of this source tree, or the 9d9a5a644SRaed Salem * OpenIB.org BSD license below: 10d9a5a644SRaed Salem * 11d9a5a644SRaed Salem * Redistribution and use in source and binary forms, with or 12d9a5a644SRaed Salem * without modification, are permitted provided that the following 13d9a5a644SRaed Salem * conditions are met: 14d9a5a644SRaed Salem * 15d9a5a644SRaed Salem * - Redistributions of source code must retain the above 16d9a5a644SRaed Salem * copyright notice, this list of conditions and the following 17d9a5a644SRaed Salem * disclaimer. 18d9a5a644SRaed Salem * 19d9a5a644SRaed Salem * - Redistributions in binary form must reproduce the above 20d9a5a644SRaed Salem * copyright notice, this list of conditions and the following 21d9a5a644SRaed Salem * disclaimer in the documentation and/or other materials 22d9a5a644SRaed Salem * provided with the distribution. 23d9a5a644SRaed Salem * 24d9a5a644SRaed Salem * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25d9a5a644SRaed Salem * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26d9a5a644SRaed Salem * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27d9a5a644SRaed Salem * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 28d9a5a644SRaed Salem * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 29d9a5a644SRaed Salem * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 30d9a5a644SRaed Salem * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31d9a5a644SRaed Salem * SOFTWARE. 32d9a5a644SRaed Salem */ 33d9a5a644SRaed Salem 340080aed4SBart Van Assche #include "rdma_core.h" 35d9a5a644SRaed Salem #include "uverbs.h" 36d9a5a644SRaed Salem #include <rdma/uverbs_std_types.h> 37d9a5a644SRaed Salem 38d9a5a644SRaed Salem static int uverbs_free_counters(struct ib_uobject *uobject, 39a6a3797dSShamir Rabinovitch enum rdma_remove_reason why, 40a6a3797dSShamir Rabinovitch struct uverbs_attr_bundle *attrs) 41d9a5a644SRaed Salem { 42d9a5a644SRaed Salem struct ib_counters *counters = uobject->object; 431c77483eSYishai Hadas int ret; 44d9a5a644SRaed Salem 451c77483eSYishai Hadas ret = ib_destroy_usecnt(&counters->usecnt, why, uobject); 461c77483eSYishai Hadas if (ret) 471c77483eSYishai Hadas return ret; 48d9a5a644SRaed Salem 493023a1e9SKamal Heib return counters->device->ops.destroy_counters(counters); 50d9a5a644SRaed Salem } 51d9a5a644SRaed Salem 52e83f0ecdSJason Gunthorpe static int UVERBS_HANDLER(UVERBS_METHOD_COUNTERS_CREATE)( 5315a1b4beSJason Gunthorpe struct uverbs_attr_bundle *attrs) 54d9a5a644SRaed Salem { 55e83f0ecdSJason Gunthorpe struct ib_uobject *uobj = uverbs_attr_get_uobject( 56e83f0ecdSJason Gunthorpe attrs, UVERBS_ATTR_CREATE_COUNTERS_HANDLE); 57feec576aSJason Gunthorpe struct ib_device *ib_dev = attrs->context->device; 58d9a5a644SRaed Salem struct ib_counters *counters; 59d9a5a644SRaed Salem int ret; 60d9a5a644SRaed Salem 61d9a5a644SRaed Salem /* 62d9a5a644SRaed Salem * This check should be removed once the infrastructure 63d9a5a644SRaed Salem * have the ability to remove methods from parse tree once 64d9a5a644SRaed Salem * such condition is met. 65d9a5a644SRaed Salem */ 663023a1e9SKamal Heib if (!ib_dev->ops.create_counters) 67d9a5a644SRaed Salem return -EOPNOTSUPP; 68d9a5a644SRaed Salem 693023a1e9SKamal Heib counters = ib_dev->ops.create_counters(ib_dev, attrs); 70d9a5a644SRaed Salem if (IS_ERR(counters)) { 71d9a5a644SRaed Salem ret = PTR_ERR(counters); 72d9a5a644SRaed Salem goto err_create_counters; 73d9a5a644SRaed Salem } 74d9a5a644SRaed Salem 75d9a5a644SRaed Salem counters->device = ib_dev; 76d9a5a644SRaed Salem counters->uobject = uobj; 77d9a5a644SRaed Salem uobj->object = counters; 78d9a5a644SRaed Salem atomic_set(&counters->usecnt, 0); 79d9a5a644SRaed Salem 80d9a5a644SRaed Salem return 0; 81d9a5a644SRaed Salem 82d9a5a644SRaed Salem err_create_counters: 83d9a5a644SRaed Salem return ret; 84d9a5a644SRaed Salem } 85d9a5a644SRaed Salem 86e83f0ecdSJason Gunthorpe static int UVERBS_HANDLER(UVERBS_METHOD_COUNTERS_READ)( 8715a1b4beSJason Gunthorpe struct uverbs_attr_bundle *attrs) 88ebb6796bSRaed Salem { 89ebb6796bSRaed Salem struct ib_counters_read_attr read_attr = {}; 90ebb6796bSRaed Salem const struct uverbs_attr *uattr; 91ebb6796bSRaed Salem struct ib_counters *counters = 92ebb6796bSRaed Salem uverbs_attr_get_obj(attrs, UVERBS_ATTR_READ_COUNTERS_HANDLE); 93ebb6796bSRaed Salem int ret; 94ebb6796bSRaed Salem 953023a1e9SKamal Heib if (!counters->device->ops.read_counters) 96ebb6796bSRaed Salem return -EOPNOTSUPP; 97ebb6796bSRaed Salem 98ebb6796bSRaed Salem if (!atomic_read(&counters->usecnt)) 99ebb6796bSRaed Salem return -EINVAL; 100ebb6796bSRaed Salem 101bccd0622SJason Gunthorpe ret = uverbs_get_flags32(&read_attr.flags, attrs, 102bccd0622SJason Gunthorpe UVERBS_ATTR_READ_COUNTERS_FLAGS, 103bccd0622SJason Gunthorpe IB_UVERBS_READ_COUNTERS_PREFER_CACHED); 104ebb6796bSRaed Salem if (ret) 105ebb6796bSRaed Salem return ret; 106ebb6796bSRaed Salem 107ebb6796bSRaed Salem uattr = uverbs_attr_get(attrs, UVERBS_ATTR_READ_COUNTERS_BUFF); 108ebb6796bSRaed Salem read_attr.ncounters = uattr->ptr_attr.len / sizeof(u64); 109b61815e2SJason Gunthorpe read_attr.counters_buff = uverbs_zalloc( 110b61815e2SJason Gunthorpe attrs, array_size(read_attr.ncounters, sizeof(u64))); 111b61815e2SJason Gunthorpe if (IS_ERR(read_attr.counters_buff)) 112b61815e2SJason Gunthorpe return PTR_ERR(read_attr.counters_buff); 113ebb6796bSRaed Salem 1143023a1e9SKamal Heib ret = counters->device->ops.read_counters(counters, &read_attr, attrs); 115ebb6796bSRaed Salem if (ret) 116b61815e2SJason Gunthorpe return ret; 117ebb6796bSRaed Salem 118b61815e2SJason Gunthorpe return uverbs_copy_to(attrs, UVERBS_ATTR_READ_COUNTERS_BUFF, 119ebb6796bSRaed Salem read_attr.counters_buff, 120ebb6796bSRaed Salem read_attr.ncounters * sizeof(u64)); 121ebb6796bSRaed Salem } 122ebb6796bSRaed Salem 1239a119cd5SJason Gunthorpe DECLARE_UVERBS_NAMED_METHOD( 1249a119cd5SJason Gunthorpe UVERBS_METHOD_COUNTERS_CREATE, 1259a119cd5SJason Gunthorpe UVERBS_ATTR_IDR(UVERBS_ATTR_CREATE_COUNTERS_HANDLE, 126d9a5a644SRaed Salem UVERBS_OBJECT_COUNTERS, 127d9a5a644SRaed Salem UVERBS_ACCESS_NEW, 12883bb4442SJason Gunthorpe UA_MANDATORY)); 129d9a5a644SRaed Salem 1309a119cd5SJason Gunthorpe DECLARE_UVERBS_NAMED_METHOD_DESTROY( 1319a119cd5SJason Gunthorpe UVERBS_METHOD_COUNTERS_DESTROY, 1329a119cd5SJason Gunthorpe UVERBS_ATTR_IDR(UVERBS_ATTR_DESTROY_COUNTERS_HANDLE, 133d9a5a644SRaed Salem UVERBS_OBJECT_COUNTERS, 134d9a5a644SRaed Salem UVERBS_ACCESS_DESTROY, 13583bb4442SJason Gunthorpe UA_MANDATORY)); 136d9a5a644SRaed Salem 1379a119cd5SJason Gunthorpe DECLARE_UVERBS_NAMED_METHOD( 1389a119cd5SJason Gunthorpe UVERBS_METHOD_COUNTERS_READ, 1399a119cd5SJason Gunthorpe UVERBS_ATTR_IDR(UVERBS_ATTR_READ_COUNTERS_HANDLE, 140ebb6796bSRaed Salem UVERBS_OBJECT_COUNTERS, 141ebb6796bSRaed Salem UVERBS_ACCESS_READ, 14283bb4442SJason Gunthorpe UA_MANDATORY), 1439a119cd5SJason Gunthorpe UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_READ_COUNTERS_BUFF, 144540cd692SJason Gunthorpe UVERBS_ATTR_MIN_SIZE(0), 14583bb4442SJason Gunthorpe UA_MANDATORY), 146bccd0622SJason Gunthorpe UVERBS_ATTR_FLAGS_IN(UVERBS_ATTR_READ_COUNTERS_FLAGS, 147bccd0622SJason Gunthorpe enum ib_uverbs_read_counters_flags)); 148ebb6796bSRaed Salem 149d9a5a644SRaed Salem DECLARE_UVERBS_NAMED_OBJECT(UVERBS_OBJECT_COUNTERS, 1509a119cd5SJason Gunthorpe UVERBS_TYPE_ALLOC_IDR(uverbs_free_counters), 151d9a5a644SRaed Salem &UVERBS_METHOD(UVERBS_METHOD_COUNTERS_CREATE), 152ebb6796bSRaed Salem &UVERBS_METHOD(UVERBS_METHOD_COUNTERS_DESTROY), 153ebb6796bSRaed Salem &UVERBS_METHOD(UVERBS_METHOD_COUNTERS_READ)); 1540bd01f3dSJason Gunthorpe 1550bd01f3dSJason Gunthorpe const struct uapi_definition uverbs_def_obj_counters[] = { 1560bd01f3dSJason Gunthorpe UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_COUNTERS, 1570bd01f3dSJason Gunthorpe UAPI_DEF_OBJ_NEEDS_FN(destroy_counters)), 1580bd01f3dSJason Gunthorpe {} 1590bd01f3dSJason Gunthorpe }; 160