From fe80b9f0646e9456337ca79778c74c7bb3cb10de Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Fri, 27 Apr 2018 04:42:47 -0700 Subject: TAP memory leaks: 1 - use bit-map to re-use ID values and thus VLIB nodes 2 - free vrings 3 - free hw_address on HW interface delete (a HW * struct is memset on pool_get) 4 - free temporary node names during TX node setup Change-Id: Id114c8bb9c844fd4ceb02fbbeb4b511ecfeb61ce Signed-off-by: Neale Ranns --- src/vnet/devices/tap/tap.c | 37 +++++++++++++------------------------ src/vnet/devices/tap/tap.h | 4 ++-- 2 files changed, 15 insertions(+), 26 deletions(-) (limited to 'src/vnet/devices/tap') diff --git a/src/vnet/devices/tap/tap.c b/src/vnet/devices/tap/tap.c index 8005b347391..12150df6d43 100644 --- a/src/vnet/devices/tap/tap.c +++ b/src/vnet/devices/tap/tap.c @@ -75,6 +75,7 @@ open_netns_fd (char *netns) return fd; } +#define TAP_MAX_INSTANCE 1024 void tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args) @@ -92,12 +93,10 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args) struct vhost_memory *vhost_mem = 0; virtio_if_t *vif = 0; clib_error_t *err = 0; - uword *p; if (args->id != ~0) { - p = hash_get (tm->dev_instance_by_interface_id, args->id); - if (p) + if (clib_bitmap_get (tm->tap_ids, args->id)) { args->rv = VNET_API_ERROR_INVALID_INTERFACE; args->error = clib_error_return (0, "interface already exists"); @@ -106,22 +105,14 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args) } else { - int tries = 1000; - while (--tries) - { - args->id = tm->last_used_interface_id++; - p = hash_get (tm->dev_instance_by_interface_id, args->id); - if (!p) - break; - } + args->id = clib_bitmap_first_clear (tm->tap_ids); + } - if (!tries) - { - args->rv = VNET_API_ERROR_UNSPECIFIED; - args->error = - clib_error_return (0, "cannot find free interface id"); - return; - } + if (args->id > TAP_MAX_INSTANCE) + { + args->rv = VNET_API_ERROR_UNSPECIFIED; + args->error = clib_error_return (0, "cannot find free interface id"); + return; } memset (&ifr, 0, sizeof (ifr)); @@ -381,8 +372,7 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args) goto error; } - hash_set (tm->dev_instance_by_interface_id, vif->id, vif->dev_instance); - + tm->tap_ids = clib_bitmap_set (tm->tap_ids, vif->id, 1); sw = vnet_get_hw_sw_interface (vnm, vif->hw_if_index); vif->sw_if_index = sw->sw_if_index; args->sw_if_index = vif->sw_if_index; @@ -414,6 +404,7 @@ error: if (vif->fd != -1) close (vif->fd); vec_foreach_index (i, vif->vrings) virtio_vring_free (vm, vif, i); + vec_free (vif->vrings); memset (vif, 0, sizeof (virtio_if_t)); pool_put (vim->interfaces, vif); @@ -456,7 +447,7 @@ tap_delete_if (vlib_main_t * vm, u32 sw_if_index) vec_foreach_index (i, vif->vrings) virtio_vring_free (vm, vif, i); vec_free (vif->vrings); - hash_unset (tm->dev_instance_by_interface_id, vif->id); + tm->tap_ids = clib_bitmap_set (tm->tap_ids, vif->id, 0); clib_spinlock_free (&vif->lockp); memset (vif, 0, sizeof (*vif)); pool_put (mm->interfaces, vif); @@ -522,9 +513,7 @@ tap_dump_ifs (tap_interface_details_t ** out_tapids) static clib_error_t * tap_init (vlib_main_t * vm) { - tap_main_t *tm = &tap_main; - tm->dev_instance_by_interface_id = hash_create (0, sizeof (uword)); - return 0; + return NULL; } VLIB_INIT_FUNCTION (tap_init); diff --git a/src/vnet/devices/tap/tap.h b/src/vnet/devices/tap/tap.h index 98af0d8f3ab..7f6190335c4 100644 --- a/src/vnet/devices/tap/tap.h +++ b/src/vnet/devices/tap/tap.h @@ -67,8 +67,8 @@ typedef struct typedef struct { - u32 last_used_interface_id; - uword *dev_instance_by_interface_id; + /* bit-map of in-use IDs */ + uword *tap_ids; } tap_main_t; void tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args); -- cgit