sock: add function spdk_sock_get_optimal_sock_group
Also add the mapping table and the operations between placement_id and sock_group Change-Id: I31868e241fdd20252c2d79792ff1239e6d23afb8 Signed-off-by: Ziye Yang <ziye.yang@intel.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/454537 Reviewed-by: Changpeng Liu <changpeng.liu@intel.com> Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
parent
bdb90726ee
commit
8bb174f87d
@ -69,6 +69,14 @@ the ring.
|
||||
A new API `spdk_mempool_lookup` has been added to lookup the memory pool created
|
||||
by the primary process.
|
||||
|
||||
### sock
|
||||
|
||||
Add spdk_sock_get_optimal_sock_group(), which returns the optimal sock group for
|
||||
this socket. When a socket is created, it is often assigned to a sock group using
|
||||
spdk_sock_group_add_sock so that a set of sockets can be polled more efficiently.
|
||||
For some network devices, it is optimal to assign particular sockets to specific
|
||||
sock groups. This API is intended to provide the user with that information.
|
||||
|
||||
## v19.04:
|
||||
|
||||
### nvme
|
||||
|
@ -252,6 +252,16 @@ int spdk_sock_group_poll_count(struct spdk_sock_group *group, int max_events);
|
||||
*/
|
||||
int spdk_sock_group_close(struct spdk_sock_group **group);
|
||||
|
||||
/**
|
||||
* Get the optimal sock group for this sock.
|
||||
*
|
||||
* \param sock The socket
|
||||
* \param group Returns the optimal sock group. If there is no optimal sock group, returns NULL.
|
||||
*
|
||||
* \return 0 on success. Negated errno on failure.
|
||||
*/
|
||||
int spdk_sock_get_optimal_sock_group(struct spdk_sock *sock, struct spdk_sock_group **group);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
135
lib/sock/sock.c
135
lib/sock/sock.c
@ -40,6 +40,123 @@
|
||||
|
||||
static STAILQ_HEAD(, spdk_net_impl) g_net_impls = STAILQ_HEAD_INITIALIZER(g_net_impls);
|
||||
|
||||
struct spdk_sock_placement_id_entry {
|
||||
int placement_id;
|
||||
uint32_t ref;
|
||||
struct spdk_sock_group *group;
|
||||
STAILQ_ENTRY(spdk_sock_placement_id_entry) link;
|
||||
};
|
||||
|
||||
static STAILQ_HEAD(, spdk_sock_placement_id_entry) g_placement_id_map = STAILQ_HEAD_INITIALIZER(
|
||||
g_placement_id_map);
|
||||
static pthread_mutex_t g_map_table_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* Insert a group into the placement map.
|
||||
* If the group is already in the map, take a reference.
|
||||
*/
|
||||
static int
|
||||
spdk_sock_map_insert(int placement_id, struct spdk_sock_group *group)
|
||||
{
|
||||
struct spdk_sock_placement_id_entry *entry;
|
||||
|
||||
pthread_mutex_lock(&g_map_table_mutex);
|
||||
STAILQ_FOREACH(entry, &g_placement_id_map, link) {
|
||||
if (placement_id == entry->placement_id) {
|
||||
/* The mapping already exists, it means that different sockets have
|
||||
* the same placement_ids.
|
||||
*/
|
||||
entry->ref++;
|
||||
pthread_mutex_unlock(&g_map_table_mutex);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
entry = calloc(1, sizeof(*entry));
|
||||
if (!entry) {
|
||||
SPDK_ERRLOG("Cannot allocate an entry for placement_id=%u\n", placement_id);
|
||||
pthread_mutex_unlock(&g_map_table_mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
entry->placement_id = placement_id;
|
||||
entry->group = group;
|
||||
entry->ref++;
|
||||
|
||||
STAILQ_INSERT_TAIL(&g_placement_id_map, entry, link);
|
||||
pthread_mutex_unlock(&g_map_table_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Release a reference to the group for a given placement_id.
|
||||
* If the reference count is 0, remove the group.
|
||||
*/
|
||||
static void
|
||||
spdk_sock_map_release(int placement_id)
|
||||
{
|
||||
struct spdk_sock_placement_id_entry *entry;
|
||||
|
||||
pthread_mutex_lock(&g_map_table_mutex);
|
||||
STAILQ_FOREACH(entry, &g_placement_id_map, link) {
|
||||
if (placement_id == entry->placement_id) {
|
||||
assert(entry->ref > 0);
|
||||
entry->ref--;
|
||||
if (!entry->ref) {
|
||||
STAILQ_REMOVE(&g_placement_id_map, entry, spdk_sock_placement_id_entry, link);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&g_map_table_mutex);
|
||||
}
|
||||
|
||||
/* Look up the group for a placement_id. */
|
||||
static void
|
||||
spdk_sock_map_lookup(int placement_id, struct spdk_sock_group **group)
|
||||
{
|
||||
struct spdk_sock_placement_id_entry *entry;
|
||||
|
||||
*group = NULL;
|
||||
pthread_mutex_lock(&g_map_table_mutex);
|
||||
STAILQ_FOREACH(entry, &g_placement_id_map, link) {
|
||||
if (placement_id == entry->placement_id) {
|
||||
assert(entry->group != NULL);
|
||||
*group = entry->group;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&g_map_table_mutex);
|
||||
}
|
||||
|
||||
/* Remove the socket group from the map table */
|
||||
static void
|
||||
spdk_sock_remove_sock_group_from_map_table(struct spdk_sock_group *group)
|
||||
{
|
||||
struct spdk_sock_placement_id_entry *entry;
|
||||
|
||||
pthread_mutex_lock(&g_map_table_mutex);
|
||||
STAILQ_FOREACH(entry, &g_placement_id_map, link) {
|
||||
STAILQ_REMOVE(&g_placement_id_map, entry, spdk_sock_placement_id_entry, link);
|
||||
}
|
||||
pthread_mutex_unlock(&g_map_table_mutex);
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
spdk_sock_get_optimal_sock_group(struct spdk_sock *sock, struct spdk_sock_group **group)
|
||||
{
|
||||
int placement_id = 0, rc;
|
||||
|
||||
rc = sock->net_impl->get_placement_id(sock, &placement_id);
|
||||
if (!rc && (placement_id != 0)) {
|
||||
spdk_sock_map_lookup(placement_id, group);
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
spdk_sock_getaddr(struct spdk_sock *sock, char *saddr, int slen, uint16_t *sport,
|
||||
char *caddr, int clen, uint16_t *cport)
|
||||
@ -212,7 +329,7 @@ spdk_sock_group_add_sock(struct spdk_sock_group *group, struct spdk_sock *sock,
|
||||
spdk_sock_cb cb_fn, void *cb_arg)
|
||||
{
|
||||
struct spdk_sock_group_impl *group_impl = NULL;
|
||||
int rc;
|
||||
int rc, placement_id = 0;
|
||||
|
||||
if (cb_fn == NULL) {
|
||||
errno = EINVAL;
|
||||
@ -228,6 +345,14 @@ spdk_sock_group_add_sock(struct spdk_sock_group *group, struct spdk_sock *sock,
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = sock->net_impl->get_placement_id(sock, &placement_id);
|
||||
if (!rc && (placement_id != 0)) {
|
||||
rc = spdk_sock_map_insert(placement_id, group);
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
STAILQ_FOREACH_FROM(group_impl, &group->group_impls, link) {
|
||||
if (sock->net_impl == group_impl->net_impl) {
|
||||
break;
|
||||
@ -253,7 +378,7 @@ int
|
||||
spdk_sock_group_remove_sock(struct spdk_sock_group *group, struct spdk_sock *sock)
|
||||
{
|
||||
struct spdk_sock_group_impl *group_impl = NULL;
|
||||
int rc;
|
||||
int rc, placement_id = 0;
|
||||
|
||||
STAILQ_FOREACH_FROM(group_impl, &group->group_impls, link) {
|
||||
if (sock->net_impl == group_impl->net_impl) {
|
||||
@ -266,6 +391,11 @@ spdk_sock_group_remove_sock(struct spdk_sock_group *group, struct spdk_sock *soc
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = sock->net_impl->get_placement_id(sock, &placement_id);
|
||||
if (!rc && (placement_id != 0)) {
|
||||
spdk_sock_map_release(placement_id);
|
||||
}
|
||||
|
||||
rc = group_impl->net_impl->group_impl_remove_sock(group_impl, sock);
|
||||
if (rc == 0) {
|
||||
TAILQ_REMOVE(&group_impl->socks, sock, link);
|
||||
@ -366,6 +496,7 @@ spdk_sock_group_close(struct spdk_sock_group **group)
|
||||
free(group_impl);
|
||||
}
|
||||
|
||||
spdk_sock_remove_sock_group_from_map_table(*group);
|
||||
free(*group);
|
||||
*group = NULL;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user