static int ip_av_insert_addr(struct util_av *av, const void *addr, fi_addr_t *fi_addr, void *context) { int ret, index = -1; if (ip_av_valid_addr(av, addr)) { ret = ofi_av_insert_addr(av, addr, ip_av_slot(av, addr), &index); } else { ret = -FI_EADDRNOTAVAIL; FI_WARN(av->prov, FI_LOG_AV, "invalid address\n"); } if (fi_addr) *fi_addr = !ret ? index : FI_ADDR_NOTAVAIL; return ret; }
int rxd_av_insert_check(struct rxd_av *av, const void *addr, size_t count, fi_addr_t *fi_addr, uint64_t flags, void *context) { int i, success_cnt = 0; int ret, index; void *curr_addr; uint64_t dg_av_idx; for (i = 0; i < count; i++) { curr_addr = (char *) addr + av->addrlen * i; ret = rxd_av_dg_reverse_lookup(av, i, curr_addr, av->addrlen, &dg_av_idx); if (ret == -FI_ENODATA) { ret = fi_av_insert(av->dg_av, curr_addr, 1, &dg_av_idx, flags, context); if (ret <= 0) { if (av->util_av.eq) ofi_av_write_event(&av->util_av, i, (ret == 0) ? FI_EINVAL : -ret, context); if (fi_addr) fi_addr[i] = FI_ADDR_NOTAVAIL; continue; } } ret = ofi_av_insert_addr(&av->util_av, &dg_av_idx, dg_av_idx, &index); if (ret) { if (av->util_av.eq) ofi_av_write_event(&av->util_av, i, -ret, context); } else { success_cnt++; } if (fi_addr) fi_addr[i] = (ret == 0) ? index : FI_ADDR_NOTAVAIL; } av->dg_av_used += success_cnt; if (av->util_av.eq) { ofi_av_write_event(&av->util_av, success_cnt, 0, context); ret = 0; } else { ret = success_cnt; } return ret; }
int rxd_av_insert_fast(struct rxd_av *av, const void *addr, size_t count, fi_addr_t *fi_addr, uint64_t flags, void *context) { int i, num, ret, success_cnt = 0; int index; fi_addr_t *fi_addrs; fi_addrs = calloc(count, sizeof(fi_addr_t)); if (!fi_addrs) return -FI_ENOMEM; num = fi_av_insert(av->dg_av, addr, count, fi_addrs, flags, context); if (num != count) { free(fi_addrs); return rxd_av_insert_check(av, addr, count, fi_addr, flags, context); } for (i = 0; i < num; i++) { ret = ofi_av_insert_addr(&av->util_av, &fi_addrs[i], fi_addrs[i], &index); if (ret) { if (av->util_av.eq) ofi_av_write_event(&av->util_av, i, -ret, context); } else { success_cnt++; } if (fi_addr) fi_addr[i] = (ret == 0) ? index : FI_ADDR_NOTAVAIL; } free(fi_addrs); av->dg_av_used += success_cnt; if (av->util_av.eq) { ofi_av_write_event(&av->util_av, success_cnt, 0, context); ret = 0; } else { ret = success_cnt; } return ret; }
static int rxd_av_insert(struct fid_av *av_fid, const void *addr, size_t count, fi_addr_t *fi_addr, uint64_t flags, void *context) { struct rxd_av *av; int i = 0, index, ret = 0, success_cnt = 0, lookup = 1; uint64_t dg_fiaddr; av = container_of(av_fid, struct rxd_av, util_av.av_fid); fastlock_acquire(&av->util_av.lock); if (!av->dg_addrlen) { ret = rxd_av_set_addrlen(av, addr); if (ret) goto out; /* Skip lookups if this is the first insertion call. */ lookup = 0; } for (; i < count; i++, addr = (uint8_t *) addr + av->dg_addrlen) { ret = lookup ? rxd_av_dg_reverse_lookup(av, i, addr, &dg_fiaddr) : -FI_ENODATA; if (ret) { ret = fi_av_insert(av->dg_av, addr, 1, &dg_fiaddr, flags, context); if (ret != 1) break; } ret = ofi_av_insert_addr(&av->util_av, &dg_fiaddr, dg_fiaddr, &index); if (ret) break; success_cnt++; if (fi_addr) fi_addr[i] = index; } if (ret) { FI_WARN(&rxd_prov, FI_LOG_AV, "failed to insert address %d: %d (%s)\n", i, -ret, fi_strerror(-ret)); if (av->util_av.eq) ofi_av_write_event(&av->util_av, i, -ret, context); if (fi_addr) fi_addr[i] = FI_ADDR_NOTAVAIL; i++; } out: av->dg_av_used += success_cnt; fastlock_release(&av->util_av.lock); for (; i < count; i++) { if (av->util_av.eq) ofi_av_write_event(&av->util_av, i, FI_ECANCELED, context); if (fi_addr) fi_addr[i] = FI_ADDR_NOTAVAIL; } if (av->util_av.eq) { ofi_av_write_event(&av->util_av, success_cnt, 0, context); return 0; } return success_cnt; }