rpc: add method for listing PCI devices

This RPC lists all PCI devices attached to an SPDK application.  Each
device is identified by a BDF and contains a buffer with a copy of its
config space.

Signed-off-by: Konrad Sztyber <konrad.sztyber@intel.com>
Change-Id: I852f421fde105d975458f8e63b8da4f92ed2c69b
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/10652
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Community-CI: Mellanox Build Bot
This commit is contained in:
Konrad Sztyber 2021-12-12 11:19:00 +01:00 committed by Tomasz Zawadzki
parent 2c9895dee6
commit 9647fd4e8d
4 changed files with 107 additions and 0 deletions

View File

@ -9095,3 +9095,47 @@ Example response:
}
}
~~
### framework_get_pci_devices
List PCIe devices attached to an SPDK application and the contents of their config space.
#### Parameters
This method has no parameters.
#### Response
The response is an array of attached PCIe devices.
#### Example
Example request:
~~
{
"jsonrpc": "2.0",
"id": 1,
"method": "framework_get_pci_devices"
}
~~
Example response:
Note that the config space buffer was trimmed.
~~
{
"jsonrpc": "2.0",
"id": 1,
"result": {
[
{
"address": "0000:00:04.0",
"config_space": "8680455807051000...0000000000000000"
},
{
"address": "0000:00:03.0",
"config_space": "8680455807051000...0000000000000000"
}
]
}
}
~~

View File

@ -35,6 +35,7 @@
#include "spdk/string.h"
#include "spdk/util.h"
#include "spdk/env.h"
#include "spdk/log.h"
#include "spdk_internal/init.h"
@ -119,3 +120,55 @@ rpc_framework_get_config(struct spdk_jsonrpc_request *request,
SPDK_RPC_REGISTER("framework_get_config", rpc_framework_get_config, SPDK_RPC_RUNTIME)
SPDK_RPC_REGISTER_ALIAS_DEPRECATED(framework_get_config, get_subsystem_config)
static void
dump_pci_device(void *ctx, struct spdk_pci_device *dev)
{
struct spdk_json_write_ctx *w = ctx;
struct spdk_pci_addr addr;
char config[4096], bdf[14];
int rc;
addr = spdk_pci_device_get_addr(dev);
spdk_pci_addr_fmt(bdf, sizeof(bdf), &addr);
rc = spdk_pci_device_cfg_read(dev, config, sizeof(config), 0);
if (rc != 0) {
SPDK_ERRLOG("Failed to read config space of device: %s\n", bdf);
return;
}
spdk_json_write_object_begin(w);
spdk_json_write_named_string(w, "address", bdf);
/* Don't write the extended config space if it's all zeroes */
if (spdk_mem_all_zero(&config[256], sizeof(config) - 256)) {
spdk_json_write_named_bytearray(w, "config_space", config, 256);
} else {
spdk_json_write_named_bytearray(w, "config_space", config, sizeof(config));
}
spdk_json_write_object_end(w);
}
static void
rpc_framework_get_pci_devices(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct spdk_json_write_ctx *w;
if (params != NULL) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"framework_get_pci_devices doesn't accept any parameters.\n");
return;
}
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_array_begin(w);
spdk_pci_for_each_device(w, dump_pci_device);
spdk_json_write_array_end(w);
spdk_jsonrpc_end_result(request, w);
}
SPDK_RPC_REGISTER("framework_get_pci_devices", rpc_framework_get_pci_devices, SPDK_RPC_RUNTIME)

View File

@ -2690,6 +2690,12 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse
p.add_argument('-i', '--impl', help='Socket implementation name, e.g. posix', required=True)
p.set_defaults(func=sock_set_default_impl)
def framework_get_pci_devices(args):
print_json(rpc.subsystem.framework_get_pci_devices(args.client))
p = subparsers.add_parser('framework_get_pci_devices', help='''Get a list of attached PCI devices''')
p.set_defaults(func=framework_get_pci_devices)
def check_called_name(name):
if name in deprecated_aliases:
print("{} is deprecated, use {} instead.".format(name, deprecated_aliases[name]), file=sys.stderr)

View File

@ -10,3 +10,7 @@ def framework_get_subsystems(client):
def framework_get_config(client, name):
params = {'name': name}
return client.call('framework_get_config', params)
def framework_get_pci_devices(client):
return client.call('framework_get_pci_devices')