Skip to content

Commit 97a16dc

Browse files
committed
mi: free endpoints on root destruction
The root_t object needs to persist through the lifetime of an endpoint, so close the endpoints on nvme_mi_free_root, and track allocated endpoints in the root->endpoints list. To do the destruction safely, we need a _safe variant of the endpoint iterator macro. Signed-off-by: Jeremy Kerr <[email protected]>
1 parent bb70b87 commit 97a16dc

3 files changed

Lines changed: 51 additions & 0 deletions

File tree

src/nvme/mi.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ nvme_root_t nvme_mi_create_root(FILE *fp, int log_level)
3939

4040
void nvme_mi_free_root(nvme_root_t root)
4141
{
42+
nvme_mi_ep_t ep, tmp;
43+
44+
nvme_mi_for_each_endpoint_safe(root, ep, tmp)
45+
nvme_mi_close(ep);
46+
4247
free(root);
4348
}
4449

@@ -50,6 +55,8 @@ struct nvme_mi_ep *nvme_mi_init_ep(nvme_root_t root)
5055
list_node_init(&ep->root_entry);
5156
ep->root = root;
5257

58+
list_add(&root->endpoints, &ep->root_entry);
59+
5360
return ep;
5461
}
5562

src/nvme/mi.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,18 @@ nvme_mi_ep_t nvme_mi_next_endpoint(nvme_root_t m, nvme_mi_ep_t e);
317317
for (e = nvme_mi_first_endpoint(m); e != NULL; \
318318
e = nvme_mi_next_endpoint(m, e))
319319

320+
/**
321+
* nvme_mi_for_each_endpoint_safe - Iterator for NVMe-MI endpoints, allowing
322+
* deletion during traversal
323+
* @m: &nvme_root_t containing endpoints
324+
* @e: &nvme_mi_ep_t object, set on each iteration
325+
* @_e: &nvme_mi_ep_t object used as temporary storage
326+
*/
327+
#define nvme_mi_for_each_endpoint_safe(m, e, _e) \
328+
for (e = nvme_mi_first_endpoint(m), _e = nvme_mi_next_endpoint(m, e); \
329+
e != NULL; \
330+
e = _e, _e = nvme_mi_next_endpoint(m, e))
331+
320332
struct nvme_mi_ctrl;
321333

322334
/**

test/mi.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,37 @@ nvme_mi_ep_t nvme_mi_open_test(nvme_root_t root)
121121
return ep;
122122
}
123123

124+
unsigned int count_root_eps(nvme_root_t root)
125+
{
126+
unsigned int i = 0;
127+
nvme_mi_ep_t ep;
128+
129+
nvme_mi_for_each_endpoint(root, ep)
130+
i++;
131+
132+
return i;
133+
}
134+
135+
/* test that the root->endpoints list is updated on endpoint
136+
* creation/destruction */
137+
static void test_endpoint_lifetime(nvme_mi_ep_t ep)
138+
{
139+
nvme_root_t root = ep->root;
140+
unsigned int count;
141+
nvme_mi_ep_t ep2;
142+
143+
count = count_root_eps(root);
144+
assert(count == 1);
145+
146+
ep2 = nvme_mi_open_test(root);
147+
count = count_root_eps(root);
148+
assert(count == 2);
149+
150+
nvme_mi_close(ep2);
151+
count = count_root_eps(root);
152+
assert(count == 1);
153+
}
154+
124155
/* test: basic read MI datastructure command */
125156
static int test_read_mi_data_cb(struct nvme_mi_ep *ep,
126157
struct nvme_mi_req *req,
@@ -357,6 +388,7 @@ struct test {
357388
const char *name;
358389
void (*fn)(nvme_mi_ep_t);
359390
} tests[] = {
391+
DEFINE_TEST(endpoint_lifetime),
360392
DEFINE_TEST(read_mi_data),
361393
DEFINE_TEST(transport_fail),
362394
DEFINE_TEST(transport_describe),

0 commit comments

Comments
 (0)