1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2 /* 3 * Copyright (c) 2019 Mellanox Technologies. All rights reserved. 4 */ 5 #include <rdma/ib_verbs.h> 6 #include <rdma/rdma_counter.h> 7 8 #include "core_priv.h" 9 #include "restrack.h" 10 11 #define ALL_AUTO_MODE_MASKS (RDMA_COUNTER_MASK_QP_TYPE) 12 13 static int __counter_set_mode(struct rdma_counter_mode *curr, 14 enum rdma_nl_counter_mode new_mode, 15 enum rdma_nl_counter_mask new_mask) 16 { 17 if ((new_mode == RDMA_COUNTER_MODE_AUTO) && 18 ((new_mask & (~ALL_AUTO_MODE_MASKS)) || 19 (curr->mode != RDMA_COUNTER_MODE_NONE))) 20 return -EINVAL; 21 22 curr->mode = new_mode; 23 curr->mask = new_mask; 24 return 0; 25 } 26 27 /** 28 * rdma_counter_set_auto_mode() - Turn on/off per-port auto mode 29 * 30 * When @on is true, the @mask must be set; When @on is false, it goes 31 * into manual mode if there's any counter, so that the user is able to 32 * manually access them. 33 */ 34 int rdma_counter_set_auto_mode(struct ib_device *dev, u8 port, 35 bool on, enum rdma_nl_counter_mask mask) 36 { 37 struct rdma_port_counter *port_counter; 38 int ret; 39 40 port_counter = &dev->port_data[port].port_counter; 41 if (!port_counter->hstats) 42 return -EOPNOTSUPP; 43 44 mutex_lock(&port_counter->lock); 45 if (on) { 46 ret = __counter_set_mode(&port_counter->mode, 47 RDMA_COUNTER_MODE_AUTO, mask); 48 } else { 49 if (port_counter->mode.mode != RDMA_COUNTER_MODE_AUTO) { 50 ret = -EINVAL; 51 goto out; 52 } 53 54 if (port_counter->num_counters) 55 ret = __counter_set_mode(&port_counter->mode, 56 RDMA_COUNTER_MODE_MANUAL, 0); 57 else 58 ret = __counter_set_mode(&port_counter->mode, 59 RDMA_COUNTER_MODE_NONE, 0); 60 } 61 62 out: 63 mutex_unlock(&port_counter->lock); 64 return ret; 65 } 66 67 static struct rdma_counter *rdma_counter_alloc(struct ib_device *dev, u8 port, 68 enum rdma_nl_counter_mode mode) 69 { 70 struct rdma_port_counter *port_counter; 71 struct rdma_counter *counter; 72 int ret; 73 74 if (!dev->ops.counter_dealloc || !dev->ops.counter_alloc_stats) 75 return NULL; 76 77 counter = kzalloc(sizeof(*counter), GFP_KERNEL); 78 if (!counter) 79 return NULL; 80 81 counter->device = dev; 82 counter->port = port; 83 counter->res.type = RDMA_RESTRACK_COUNTER; 84 counter->stats = dev->ops.counter_alloc_stats(counter); 85 if (!counter->stats) 86 goto err_stats; 87 88 port_counter = &dev->port_data[port].port_counter; 89 mutex_lock(&port_counter->lock); 90 if (mode == RDMA_COUNTER_MODE_MANUAL) { 91 ret = __counter_set_mode(&port_counter->mode, 92 RDMA_COUNTER_MODE_MANUAL, 0); 93 if (ret) 94 goto err_mode; 95 } 96 97 port_counter->num_counters++; 98 mutex_unlock(&port_counter->lock); 99 100 counter->mode.mode = mode; 101 kref_init(&counter->kref); 102 mutex_init(&counter->lock); 103 104 return counter; 105 106 err_mode: 107 mutex_unlock(&port_counter->lock); 108 kfree(counter->stats); 109 err_stats: 110 kfree(counter); 111 return NULL; 112 } 113 114 static void rdma_counter_free(struct rdma_counter *counter) 115 { 116 struct rdma_port_counter *port_counter; 117 118 port_counter = &counter->device->port_data[counter->port].port_counter; 119 mutex_lock(&port_counter->lock); 120 port_counter->num_counters--; 121 if (!port_counter->num_counters && 122 (port_counter->mode.mode == RDMA_COUNTER_MODE_MANUAL)) 123 __counter_set_mode(&port_counter->mode, RDMA_COUNTER_MODE_NONE, 124 0); 125 126 mutex_unlock(&port_counter->lock); 127 128 rdma_restrack_del(&counter->res); 129 kfree(counter->stats); 130 kfree(counter); 131 } 132 133 static void auto_mode_init_counter(struct rdma_counter *counter, 134 const struct ib_qp *qp, 135 enum rdma_nl_counter_mask new_mask) 136 { 137 struct auto_mode_param *param = &counter->mode.param; 138 139 counter->mode.mode = RDMA_COUNTER_MODE_AUTO; 140 counter->mode.mask = new_mask; 141 142 if (new_mask & RDMA_COUNTER_MASK_QP_TYPE) 143 param->qp_type = qp->qp_type; 144 } 145 146 static bool auto_mode_match(struct ib_qp *qp, struct rdma_counter *counter, 147 enum rdma_nl_counter_mask auto_mask) 148 { 149 struct auto_mode_param *param = &counter->mode.param; 150 bool match = true; 151 152 /* Ensure that counter belongs to the right PID */ 153 if (task_pid_nr(counter->res.task) != task_pid_nr(qp->res.task)) 154 return false; 155 156 if (auto_mask & RDMA_COUNTER_MASK_QP_TYPE) 157 match &= (param->qp_type == qp->qp_type); 158 159 return match; 160 } 161 162 static int __rdma_counter_bind_qp(struct rdma_counter *counter, 163 struct ib_qp *qp) 164 { 165 int ret; 166 167 if (qp->counter) 168 return -EINVAL; 169 170 if (!qp->device->ops.counter_bind_qp) 171 return -EOPNOTSUPP; 172 173 mutex_lock(&counter->lock); 174 ret = qp->device->ops.counter_bind_qp(counter, qp); 175 mutex_unlock(&counter->lock); 176 177 return ret; 178 } 179 180 static int __rdma_counter_unbind_qp(struct ib_qp *qp) 181 { 182 struct rdma_counter *counter = qp->counter; 183 int ret; 184 185 if (!qp->device->ops.counter_unbind_qp) 186 return -EOPNOTSUPP; 187 188 mutex_lock(&counter->lock); 189 ret = qp->device->ops.counter_unbind_qp(qp); 190 mutex_unlock(&counter->lock); 191 192 return ret; 193 } 194 195 static void counter_history_stat_update(const struct rdma_counter *counter) 196 { 197 struct ib_device *dev = counter->device; 198 struct rdma_port_counter *port_counter; 199 int i; 200 201 port_counter = &dev->port_data[counter->port].port_counter; 202 if (!port_counter->hstats) 203 return; 204 205 for (i = 0; i < counter->stats->num_counters; i++) 206 port_counter->hstats->value[i] += counter->stats->value[i]; 207 } 208 209 /** 210 * rdma_get_counter_auto_mode - Find the counter that @qp should be bound 211 * with in auto mode 212 * 213 * Return: The counter (with ref-count increased) if found 214 */ 215 static struct rdma_counter *rdma_get_counter_auto_mode(struct ib_qp *qp, 216 u8 port) 217 { 218 struct rdma_port_counter *port_counter; 219 struct rdma_counter *counter = NULL; 220 struct ib_device *dev = qp->device; 221 struct rdma_restrack_entry *res; 222 struct rdma_restrack_root *rt; 223 unsigned long id = 0; 224 225 port_counter = &dev->port_data[port].port_counter; 226 rt = &dev->res[RDMA_RESTRACK_COUNTER]; 227 xa_lock(&rt->xa); 228 xa_for_each(&rt->xa, id, res) { 229 counter = container_of(res, struct rdma_counter, res); 230 if ((counter->device != qp->device) || (counter->port != port)) 231 goto next; 232 233 if (auto_mode_match(qp, counter, port_counter->mode.mask)) 234 break; 235 next: 236 counter = NULL; 237 } 238 239 if (counter && !kref_get_unless_zero(&counter->kref)) 240 counter = NULL; 241 242 xa_unlock(&rt->xa); 243 return counter; 244 } 245 246 static void rdma_counter_res_add(struct rdma_counter *counter, 247 struct ib_qp *qp) 248 { 249 if (rdma_is_kernel_res(&qp->res)) { 250 rdma_restrack_set_task(&counter->res, qp->res.kern_name); 251 rdma_restrack_kadd(&counter->res); 252 } else { 253 rdma_restrack_attach_task(&counter->res, qp->res.task); 254 rdma_restrack_uadd(&counter->res); 255 } 256 } 257 258 static void counter_release(struct kref *kref) 259 { 260 struct rdma_counter *counter; 261 262 counter = container_of(kref, struct rdma_counter, kref); 263 counter_history_stat_update(counter); 264 counter->device->ops.counter_dealloc(counter); 265 rdma_counter_free(counter); 266 } 267 268 /** 269 * rdma_counter_bind_qp_auto - Check and bind the QP to a counter base on 270 * the auto-mode rule 271 */ 272 int rdma_counter_bind_qp_auto(struct ib_qp *qp, u8 port) 273 { 274 struct rdma_port_counter *port_counter; 275 struct ib_device *dev = qp->device; 276 struct rdma_counter *counter; 277 int ret; 278 279 if (!rdma_is_port_valid(dev, port)) 280 return -EINVAL; 281 282 port_counter = &dev->port_data[port].port_counter; 283 if (port_counter->mode.mode != RDMA_COUNTER_MODE_AUTO) 284 return 0; 285 286 counter = rdma_get_counter_auto_mode(qp, port); 287 if (counter) { 288 ret = __rdma_counter_bind_qp(counter, qp); 289 if (ret) { 290 kref_put(&counter->kref, counter_release); 291 return ret; 292 } 293 } else { 294 counter = rdma_counter_alloc(dev, port, RDMA_COUNTER_MODE_AUTO); 295 if (!counter) 296 return -ENOMEM; 297 298 auto_mode_init_counter(counter, qp, port_counter->mode.mask); 299 300 ret = __rdma_counter_bind_qp(counter, qp); 301 if (ret) { 302 rdma_counter_free(counter); 303 return ret; 304 } 305 306 rdma_counter_res_add(counter, qp); 307 } 308 309 return 0; 310 } 311 312 /** 313 * rdma_counter_unbind_qp - Unbind a qp from a counter 314 * @force: 315 * true - Decrease the counter ref-count anyway (e.g., qp destroy) 316 */ 317 int rdma_counter_unbind_qp(struct ib_qp *qp, bool force) 318 { 319 struct rdma_counter *counter = qp->counter; 320 int ret; 321 322 if (!counter) 323 return -EINVAL; 324 325 ret = __rdma_counter_unbind_qp(qp); 326 if (ret && !force) 327 return ret; 328 329 kref_put(&counter->kref, counter_release); 330 return 0; 331 } 332 333 int rdma_counter_query_stats(struct rdma_counter *counter) 334 { 335 struct ib_device *dev = counter->device; 336 int ret; 337 338 if (!dev->ops.counter_update_stats) 339 return -EINVAL; 340 341 mutex_lock(&counter->lock); 342 ret = dev->ops.counter_update_stats(counter); 343 mutex_unlock(&counter->lock); 344 345 return ret; 346 } 347 348 static u64 get_running_counters_hwstat_sum(struct ib_device *dev, 349 u8 port, u32 index) 350 { 351 struct rdma_restrack_entry *res; 352 struct rdma_restrack_root *rt; 353 struct rdma_counter *counter; 354 unsigned long id = 0; 355 u64 sum = 0; 356 357 rt = &dev->res[RDMA_RESTRACK_COUNTER]; 358 xa_lock(&rt->xa); 359 xa_for_each(&rt->xa, id, res) { 360 if (!rdma_restrack_get(res)) 361 continue; 362 363 xa_unlock(&rt->xa); 364 365 counter = container_of(res, struct rdma_counter, res); 366 if ((counter->device != dev) || (counter->port != port) || 367 rdma_counter_query_stats(counter)) 368 goto next; 369 370 sum += counter->stats->value[index]; 371 372 next: 373 xa_lock(&rt->xa); 374 rdma_restrack_put(res); 375 } 376 377 xa_unlock(&rt->xa); 378 return sum; 379 } 380 381 /** 382 * rdma_counter_get_hwstat_value() - Get the sum value of all counters on a 383 * specific port, including the running ones and history data 384 */ 385 u64 rdma_counter_get_hwstat_value(struct ib_device *dev, u8 port, u32 index) 386 { 387 struct rdma_port_counter *port_counter; 388 u64 sum; 389 390 port_counter = &dev->port_data[port].port_counter; 391 if (!port_counter->hstats) 392 return 0; 393 394 sum = get_running_counters_hwstat_sum(dev, port, index); 395 sum += port_counter->hstats->value[index]; 396 397 return sum; 398 } 399 400 static struct ib_qp *rdma_counter_get_qp(struct ib_device *dev, u32 qp_num) 401 { 402 struct rdma_restrack_entry *res = NULL; 403 struct ib_qp *qp = NULL; 404 405 res = rdma_restrack_get_byid(dev, RDMA_RESTRACK_QP, qp_num); 406 if (IS_ERR(res)) 407 return NULL; 408 409 qp = container_of(res, struct ib_qp, res); 410 if (qp->qp_type == IB_QPT_RAW_PACKET && !capable(CAP_NET_RAW)) 411 goto err; 412 413 return qp; 414 415 err: 416 rdma_restrack_put(res); 417 return NULL; 418 } 419 420 static int rdma_counter_bind_qp_manual(struct rdma_counter *counter, 421 struct ib_qp *qp) 422 { 423 if ((counter->device != qp->device) || (counter->port != qp->port)) 424 return -EINVAL; 425 426 return __rdma_counter_bind_qp(counter, qp); 427 } 428 429 static struct rdma_counter *rdma_get_counter_by_id(struct ib_device *dev, 430 u32 counter_id) 431 { 432 struct rdma_restrack_entry *res; 433 struct rdma_counter *counter; 434 435 res = rdma_restrack_get_byid(dev, RDMA_RESTRACK_COUNTER, counter_id); 436 if (IS_ERR(res)) 437 return NULL; 438 439 counter = container_of(res, struct rdma_counter, res); 440 kref_get(&counter->kref); 441 rdma_restrack_put(res); 442 443 return counter; 444 } 445 446 /** 447 * rdma_counter_bind_qpn() - Bind QP @qp_num to counter @counter_id 448 */ 449 int rdma_counter_bind_qpn(struct ib_device *dev, u8 port, 450 u32 qp_num, u32 counter_id) 451 { 452 struct rdma_port_counter *port_counter; 453 struct rdma_counter *counter; 454 struct ib_qp *qp; 455 int ret; 456 457 port_counter = &dev->port_data[port].port_counter; 458 if (port_counter->mode.mode == RDMA_COUNTER_MODE_AUTO) 459 return -EINVAL; 460 461 qp = rdma_counter_get_qp(dev, qp_num); 462 if (!qp) 463 return -ENOENT; 464 465 counter = rdma_get_counter_by_id(dev, counter_id); 466 if (!counter) { 467 ret = -ENOENT; 468 goto err; 469 } 470 471 if (counter->res.task != qp->res.task) { 472 ret = -EINVAL; 473 goto err_task; 474 } 475 476 ret = rdma_counter_bind_qp_manual(counter, qp); 477 if (ret) 478 goto err_task; 479 480 rdma_restrack_put(&qp->res); 481 return 0; 482 483 err_task: 484 kref_put(&counter->kref, counter_release); 485 err: 486 rdma_restrack_put(&qp->res); 487 return ret; 488 } 489 490 /** 491 * rdma_counter_bind_qpn_alloc() - Alloc a counter and bind QP @qp_num to it 492 * The id of new counter is returned in @counter_id 493 */ 494 int rdma_counter_bind_qpn_alloc(struct ib_device *dev, u8 port, 495 u32 qp_num, u32 *counter_id) 496 { 497 struct rdma_port_counter *port_counter; 498 struct rdma_counter *counter; 499 struct ib_qp *qp; 500 int ret; 501 502 if (!rdma_is_port_valid(dev, port)) 503 return -EINVAL; 504 505 port_counter = &dev->port_data[port].port_counter; 506 if (!port_counter->hstats) 507 return -EOPNOTSUPP; 508 509 if (port_counter->mode.mode == RDMA_COUNTER_MODE_AUTO) 510 return -EINVAL; 511 512 qp = rdma_counter_get_qp(dev, qp_num); 513 if (!qp) 514 return -ENOENT; 515 516 if (rdma_is_port_valid(dev, qp->port) && (qp->port != port)) { 517 ret = -EINVAL; 518 goto err; 519 } 520 521 counter = rdma_counter_alloc(dev, port, RDMA_COUNTER_MODE_MANUAL); 522 if (!counter) { 523 ret = -ENOMEM; 524 goto err; 525 } 526 527 ret = rdma_counter_bind_qp_manual(counter, qp); 528 if (ret) 529 goto err_bind; 530 531 if (counter_id) 532 *counter_id = counter->id; 533 534 rdma_counter_res_add(counter, qp); 535 536 rdma_restrack_put(&qp->res); 537 return ret; 538 539 err_bind: 540 rdma_counter_free(counter); 541 err: 542 rdma_restrack_put(&qp->res); 543 return ret; 544 } 545 546 /** 547 * rdma_counter_unbind_qpn() - Unbind QP @qp_num from a counter 548 */ 549 int rdma_counter_unbind_qpn(struct ib_device *dev, u8 port, 550 u32 qp_num, u32 counter_id) 551 { 552 struct rdma_port_counter *port_counter; 553 struct ib_qp *qp; 554 int ret; 555 556 if (!rdma_is_port_valid(dev, port)) 557 return -EINVAL; 558 559 qp = rdma_counter_get_qp(dev, qp_num); 560 if (!qp) 561 return -ENOENT; 562 563 if (rdma_is_port_valid(dev, qp->port) && (qp->port != port)) { 564 ret = -EINVAL; 565 goto out; 566 } 567 568 port_counter = &dev->port_data[port].port_counter; 569 if (!qp->counter || qp->counter->id != counter_id || 570 port_counter->mode.mode != RDMA_COUNTER_MODE_MANUAL) { 571 ret = -EINVAL; 572 goto out; 573 } 574 575 ret = rdma_counter_unbind_qp(qp, false); 576 577 out: 578 rdma_restrack_put(&qp->res); 579 return ret; 580 } 581 582 int rdma_counter_get_mode(struct ib_device *dev, u8 port, 583 enum rdma_nl_counter_mode *mode, 584 enum rdma_nl_counter_mask *mask) 585 { 586 struct rdma_port_counter *port_counter; 587 588 port_counter = &dev->port_data[port].port_counter; 589 *mode = port_counter->mode.mode; 590 *mask = port_counter->mode.mask; 591 592 return 0; 593 } 594 595 void rdma_counter_init(struct ib_device *dev) 596 { 597 struct rdma_port_counter *port_counter; 598 u32 port, i; 599 600 if (!dev->port_data) 601 return; 602 603 rdma_for_each_port(dev, port) { 604 port_counter = &dev->port_data[port].port_counter; 605 port_counter->mode.mode = RDMA_COUNTER_MODE_NONE; 606 mutex_init(&port_counter->lock); 607 608 if (!dev->ops.alloc_hw_stats) 609 continue; 610 611 port_counter->hstats = dev->ops.alloc_hw_stats(dev, port); 612 if (!port_counter->hstats) 613 goto fail; 614 } 615 616 return; 617 618 fail: 619 for (i = port; i >= rdma_start_port(dev); i--) { 620 port_counter = &dev->port_data[port].port_counter; 621 kfree(port_counter->hstats); 622 port_counter->hstats = NULL; 623 mutex_destroy(&port_counter->lock); 624 } 625 } 626 627 void rdma_counter_release(struct ib_device *dev) 628 { 629 struct rdma_port_counter *port_counter; 630 u32 port; 631 632 rdma_for_each_port(dev, port) { 633 port_counter = &dev->port_data[port].port_counter; 634 kfree(port_counter->hstats); 635 mutex_destroy(&port_counter->lock); 636 } 637 } 638