Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

IB/core: Create get_perf_mad function in sysfs.c

Create a new function to retrieve performance management
data from the existing code in get_pma_counter().

Reviewed-by: Hal Rosenstock <hal@mellanox.com>
Signed-off-by: Christoph Lameter <cl@linux.com>
Reviewed-by: Ira Weiny <ira.weiny@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>

authored by

Christoph Lameter and committed by
Doug Ledford
35c4cbb1 c09befcb

+40 -22
+40 -22
drivers/infiniband/core/sysfs.c
··· 398 398 .index = (_offset) | ((_width) << 16) | ((_counter) << 24) \ 399 399 } 400 400 401 - static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr, 402 - char *buf) 401 + /* 402 + * Get a Perfmgmt MAD block of data. 403 + * Returns error code or the number of bytes retrieved. 404 + */ 405 + static int get_perf_mad(struct ib_device *dev, int port_num, int attr, 406 + void *data, int offset, size_t size) 403 407 { 404 - struct port_table_attribute *tab_attr = 405 - container_of(attr, struct port_table_attribute, attr); 406 - int offset = tab_attr->index & 0xffff; 407 - int width = (tab_attr->index >> 16) & 0xff; 408 - struct ib_mad *in_mad = NULL; 409 - struct ib_mad *out_mad = NULL; 408 + struct ib_mad *in_mad; 409 + struct ib_mad *out_mad; 410 410 size_t mad_size = sizeof(*out_mad); 411 411 u16 out_mad_pkey_index = 0; 412 412 ssize_t ret; 413 413 414 - if (!p->ibdev->process_mad) 415 - return sprintf(buf, "N/A (no PMA)\n"); 414 + if (!dev->process_mad) 415 + return -ENOSYS; 416 416 417 417 in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL); 418 418 out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); ··· 425 425 in_mad->mad_hdr.mgmt_class = IB_MGMT_CLASS_PERF_MGMT; 426 426 in_mad->mad_hdr.class_version = 1; 427 427 in_mad->mad_hdr.method = IB_MGMT_METHOD_GET; 428 - in_mad->mad_hdr.attr_id = cpu_to_be16(0x12); /* PortCounters */ 428 + in_mad->mad_hdr.attr_id = attr; 429 429 430 - in_mad->data[41] = p->port_num; /* PortSelect field */ 430 + in_mad->data[41] = port_num; /* PortSelect field */ 431 431 432 - if ((p->ibdev->process_mad(p->ibdev, IB_MAD_IGNORE_MKEY, 433 - p->port_num, NULL, NULL, 432 + if ((dev->process_mad(dev, IB_MAD_IGNORE_MKEY, 433 + port_num, NULL, NULL, 434 434 (const struct ib_mad_hdr *)in_mad, mad_size, 435 435 (struct ib_mad_hdr *)out_mad, &mad_size, 436 436 &out_mad_pkey_index) & ··· 439 439 ret = -EINVAL; 440 440 goto out; 441 441 } 442 + memcpy(data, out_mad->data + offset, size); 443 + ret = size; 444 + out: 445 + kfree(in_mad); 446 + kfree(out_mad); 447 + return ret; 448 + } 449 + 450 + static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr, 451 + char *buf) 452 + { 453 + struct port_table_attribute *tab_attr = 454 + container_of(attr, struct port_table_attribute, attr); 455 + int offset = tab_attr->index & 0xffff; 456 + int width = (tab_attr->index >> 16) & 0xff; 457 + ssize_t ret; 458 + u8 data[8]; 459 + 460 + ret = get_perf_mad(p->ibdev, p->port_num, cpu_to_be16(0x12), &data, 461 + 40 + offset / 8, sizeof(data)); 462 + if (ret < 0) 463 + return sprintf(buf, "N/A (no PMA)\n"); 442 464 443 465 switch (width) { 444 466 case 4: 445 - ret = sprintf(buf, "%u\n", (out_mad->data[40 + offset / 8] >> 467 + ret = sprintf(buf, "%u\n", (*data >> 446 468 (4 - (offset % 8))) & 0xf); 447 469 break; 448 470 case 8: 449 - ret = sprintf(buf, "%u\n", out_mad->data[40 + offset / 8]); 471 + ret = sprintf(buf, "%u\n", *data); 450 472 break; 451 473 case 16: 452 474 ret = sprintf(buf, "%u\n", 453 - be16_to_cpup((__be16 *)(out_mad->data + 40 + offset / 8))); 475 + be16_to_cpup((__be16 *)data)); 454 476 break; 455 477 case 32: 456 478 ret = sprintf(buf, "%u\n", 457 - be32_to_cpup((__be32 *)(out_mad->data + 40 + offset / 8))); 479 + be32_to_cpup((__be32 *)data)); 458 480 break; 459 481 default: 460 482 ret = 0; 461 483 } 462 - 463 - out: 464 - kfree(in_mad); 465 - kfree(out_mad); 466 484 467 485 return ret; 468 486 }