]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.14/net-rds-fix-memory-leak-in-rds_ib_flush_mr_pool.patch
Linux 4.19.50
[thirdparty/kernel/stable-queue.git] / queue-4.14 / net-rds-fix-memory-leak-in-rds_ib_flush_mr_pool.patch
1 From foo@baz Sun 09 Jun 2019 09:44:19 AM CEST
2 From: Zhu Yanjun <yanjun.zhu@oracle.com>
3 Date: Thu, 6 Jun 2019 04:00:03 -0400
4 Subject: net: rds: fix memory leak in rds_ib_flush_mr_pool
5
6 From: Zhu Yanjun <yanjun.zhu@oracle.com>
7
8 [ Upstream commit 85cb928787eab6a2f4ca9d2a798b6f3bed53ced1 ]
9
10 When the following tests last for several hours, the problem will occur.
11
12 Server:
13 rds-stress -r 1.1.1.16 -D 1M
14 Client:
15 rds-stress -r 1.1.1.14 -s 1.1.1.16 -D 1M -T 30
16
17 The following will occur.
18
19 "
20 Starting up....
21 tsks tx/s rx/s tx+rx K/s mbi K/s mbo K/s tx us/c rtt us cpu
22 %
23 1 0 0 0.00 0.00 0.00 0.00 0.00 -1.00
24 1 0 0 0.00 0.00 0.00 0.00 0.00 -1.00
25 1 0 0 0.00 0.00 0.00 0.00 0.00 -1.00
26 1 0 0 0.00 0.00 0.00 0.00 0.00 -1.00
27 "
28 >From vmcore, we can find that clean_list is NULL.
29
30 >From the source code, rds_mr_flushd calls rds_ib_mr_pool_flush_worker.
31 Then rds_ib_mr_pool_flush_worker calls
32 "
33 rds_ib_flush_mr_pool(pool, 0, NULL);
34 "
35 Then in function
36 "
37 int rds_ib_flush_mr_pool(struct rds_ib_mr_pool *pool,
38 int free_all, struct rds_ib_mr **ibmr_ret)
39 "
40 ibmr_ret is NULL.
41
42 In the source code,
43 "
44 ...
45 list_to_llist_nodes(pool, &unmap_list, &clean_nodes, &clean_tail);
46 if (ibmr_ret)
47 *ibmr_ret = llist_entry(clean_nodes, struct rds_ib_mr, llnode);
48
49 /* more than one entry in llist nodes */
50 if (clean_nodes->next)
51 llist_add_batch(clean_nodes->next, clean_tail, &pool->clean_list);
52 ...
53 "
54 When ibmr_ret is NULL, llist_entry is not executed. clean_nodes->next
55 instead of clean_nodes is added in clean_list.
56 So clean_nodes is discarded. It can not be used again.
57 The workqueue is executed periodically. So more and more clean_nodes are
58 discarded. Finally the clean_list is NULL.
59 Then this problem will occur.
60
61 Fixes: 1bc144b62524 ("net, rds, Replace xlist in net/rds/xlist.h with llist")
62 Signed-off-by: Zhu Yanjun <yanjun.zhu@oracle.com>
63 Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
64 Signed-off-by: David S. Miller <davem@davemloft.net>
65 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
66 ---
67 net/rds/ib_rdma.c | 10 ++++++----
68 1 file changed, 6 insertions(+), 4 deletions(-)
69
70 --- a/net/rds/ib_rdma.c
71 +++ b/net/rds/ib_rdma.c
72 @@ -416,12 +416,14 @@ int rds_ib_flush_mr_pool(struct rds_ib_m
73 wait_clean_list_grace();
74
75 list_to_llist_nodes(pool, &unmap_list, &clean_nodes, &clean_tail);
76 - if (ibmr_ret)
77 + if (ibmr_ret) {
78 *ibmr_ret = llist_entry(clean_nodes, struct rds_ib_mr, llnode);
79 -
80 + clean_nodes = clean_nodes->next;
81 + }
82 /* more than one entry in llist nodes */
83 - if (clean_nodes->next)
84 - llist_add_batch(clean_nodes->next, clean_tail, &pool->clean_list);
85 + if (clean_nodes)
86 + llist_add_batch(clean_nodes, clean_tail,
87 + &pool->clean_list);
88
89 }
90