[rh7] mm/tcache: fix rcu_read_lock()/rcu_read_unlock() imbalance

Submitted by Andrey Ryabinin on May 22, 2018, 8:56 a.m.

Details

Message ID 20180522085607.30268-1-aryabinin@virtuozzo.com
State New
Series "mm/tcache: fix rcu_read_lock()/rcu_read_unlock() imbalance"
Headers show

Commit Message

Andrey Ryabinin May 22, 2018, 8:56 a.m.
tcache_detach_page()

	rcu_read_lock();
repeat:
	.....
	rcu_read_unlock();

	if (page) {
		...
		page = tcache_page_tree_delete(node, index, page);
		....
		if (!page)
			goto repeat; // <- will cause rcu_read_unlock() without lock

Take rcu lock before the last 'goto repeat;' in tcache_detach_page().

https://jira.sw.ru/browse/PSBM-81731
Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
---
 mm/tcache.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/mm/tcache.c b/mm/tcache.c
index 02fde409e691..9fc7cbf1c40b 100644
--- a/mm/tcache.c
+++ b/mm/tcache.c
@@ -864,8 +864,10 @@  out:
 		 * in __tcache_page_tree_delete() fails, and
 		 * we have to repeat the cycle.
 		 */
-		if (!page)
+		if (!page) {
+			rcu_read_lock();
 			goto repeat;
+		}
 	}
 
 	return page;

Comments

Kirill Tkhai May 22, 2018, 8:59 a.m.
On 22.05.2018 11:56, Andrey Ryabinin wrote:
> tcache_detach_page()
> 
> 	rcu_read_lock();
> repeat:
> 	.....
> 	rcu_read_unlock();
> 
> 	if (page) {
> 		...
> 		page = tcache_page_tree_delete(node, index, page);
> 		....
> 		if (!page)
> 			goto repeat; // <- will cause rcu_read_unlock() without lock
> 
> Take rcu lock before the last 'goto repeat;' in tcache_detach_page().
> 
> https://jira.sw.ru/browse/PSBM-81731
> Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>

Acked-by: Kirill Tkhai <ktkhai@virtuozzo.com>

> ---
>  mm/tcache.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/mm/tcache.c b/mm/tcache.c
> index 02fde409e691..9fc7cbf1c40b 100644
> --- a/mm/tcache.c
> +++ b/mm/tcache.c
> @@ -864,8 +864,10 @@ out:
>  		 * in __tcache_page_tree_delete() fails, and
>  		 * we have to repeat the cycle.
>  		 */
> -		if (!page)
> +		if (!page) {
> +			rcu_read_lock();
>  			goto repeat;
> +		}
>  	}
>  
>  	return page;
>