From 84fdc85b514f93a178e6925a599d1ebbf5721e93 Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Tue, 25 Sep 2018 08:00:22 -0700 Subject: [PATCH] fabric: Add ability to duplicate a fid_nic Add a function that will allocated/duplicate a struct fid_nic. This may be used by providers to copy a fid_nic. Signed-off-by: Sean Hefty --- include/ofi.h | 1 + include/ofi_mem.h | 11 +++++++ src/fabric.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 92 insertions(+), 1 deletion(-) diff --git a/include/ofi.h b/include/ofi.h index 69c918eb5cd..db7660149ba 100644 --- a/include/ofi.h +++ b/include/ofi.h @@ -118,6 +118,7 @@ void ofi_free_filter(struct fi_filter *filter); int ofi_apply_filter(struct fi_filter *filter, const char *name); int ofi_nic_close(struct fid *fid); +struct fid_nic *ofi_nic_dup(const struct fid_nic *nic); void fi_log_init(void); void fi_log_fini(void); diff --git a/include/ofi_mem.h b/include/ofi_mem.h index 3099ccb18e3..aa268c8deec 100644 --- a/include/ofi_mem.h +++ b/include/ofi_mem.h @@ -63,6 +63,17 @@ static inline void *mem_dup(const void *src, size_t size) return dest; } +static inline int str_dup(const char *src, char **dst) +{ + if (src) { + *dst = strdup(src); + if (!*dst) + return -FI_ENOMEM; + } else { + *dst = NULL; + } + return 0; +} /* * Buffer pool (free stack) template diff --git a/src/fabric.c b/src/fabric.c index fbf28ebf614..ad0e20549ee 100644 --- a/src/fabric.c +++ b/src/fabric.c @@ -512,6 +512,86 @@ int ofi_nic_close(struct fid *fid) return 0; } +struct fi_ops default_nic_ops = { + .size = sizeof(struct fi_ops), + .close = ofi_nic_close, +}; + +static int ofi_dup_dev_attr(const struct fi_device_attr *attr, + struct fi_device_attr *dup_attr) +{ + if (str_dup(attr->name, &dup_attr->name) || + str_dup(attr->device_id, &dup_attr->device_id) || + str_dup(attr->device_version, &dup_attr->device_version) || + str_dup(attr->vendor_id, &dup_attr->vendor_id) || + str_dup(attr->driver, &dup_attr->driver) || + str_dup(attr->firmware, &dup_attr->firmware)) + return -FI_ENOMEM; + + return 0; +} + +static int ofi_dup_link_attr(const struct fi_link_attr *attr, + struct fi_link_attr *dup_attr) +{ + if (str_dup(attr->address, &dup_attr->address) || + str_dup(attr->network_type, &dup_attr->network_type)) + return -FI_ENOMEM; + + dup_attr->mtu = attr->mtu; + dup_attr->speed = attr->speed; + dup_attr->state = attr->state; + return 0; +} + +struct fid_nic *ofi_nic_dup(const struct fid_nic *nic) +{ + struct fid_nic *dup_nic; + int ret; + + dup_nic = calloc(1, sizeof(*dup_nic)); + if (!dup_nic) + return NULL; + + dup_nic->device_attr = calloc(1, sizeof(*dup_nic->device_attr)); + dup_nic->bus_attr = calloc(1, sizeof(*dup_nic->bus_attr)); + dup_nic->link_attr = calloc(1, sizeof(*dup_nic->link_attr)); + + if (!dup_nic->device_attr || !dup_nic->bus_attr || !dup_nic->link_attr) + goto fail; + + if (!nic) { + dup_nic->fid.fclass = FI_CLASS_NIC; + dup_nic->fid.ops = &default_nic_ops; + return dup_nic; + } + + assert(nic->fid.fclass == FI_CLASS_NIC); + dup_nic->fid = nic->fid; + + if (nic->device_attr) { + ret = ofi_dup_dev_attr(nic->device_attr, dup_nic->device_attr); + if (ret) + goto fail; + } + + if (nic->bus_attr) + *dup_nic->bus_attr = *nic->bus_attr; + + if (nic->link_attr) { + ret = ofi_dup_link_attr(nic->link_attr, dup_nic->link_attr); + if (ret) + goto fail; + } + + return dup_nic; + +fail: + ofi_nic_close(&dup_nic->fid); + return NULL; + +} + __attribute__((visibility ("default"),EXTERNALLY_VISIBLE)) void DEFAULT_SYMVER_PRE(fi_freeinfo)(struct fi_info *info) { @@ -796,7 +876,6 @@ struct fi_info *ofi_allocinfo_internal(void) return NULL; } - __attribute__((visibility ("default"),EXTERNALLY_VISIBLE)) struct fi_info *DEFAULT_SYMVER_PRE(fi_dupinfo)(const struct fi_info *info) {