From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754593AbbESG0U (ORCPT ); Tue, 19 May 2015 02:26:20 -0400 Received: from mga02.intel.com ([134.134.136.20]:38315 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753966AbbESGZV (ORCPT ); Tue, 19 May 2015 02:25:21 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,456,1427785200"; d="scan'208";a="712268404" Subject: [PATCH 18/19] x86, mpx: do not count MPX VMAs as neighbors when unmapping To: linux-kernel@vger.kernel.org Cc: x86@kernel.org, tglx@linutronix.de, Dave Hansen , dave.hansen@linux.intel.com From: Dave Hansen Date: Mon, 18 May 2015 23:25:35 -0700 References: <20150519062528.E2D5DDFF@viggo.jf.intel.com> In-Reply-To: <20150519062528.E2D5DDFF@viggo.jf.intel.com> Message-Id: <20150519062535.DBAA3160@viggo.jf.intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Dave Hansen The comment pretty much says it all. I wrote a test program that does lots of random allocations and forces bounds tables to be created. It came up with a layout like this: .... | BOUNDS DIRECTORY ENTRY COVERS | .... | BOUNDS TABLE COVERS | | BOUNDS TABLE | REAL ALLOC | BOUNDS TABLE | Unmapping "REAL ALLOC" should have been able to free the bounds table "covering" the "REAL ALLOC" because it was the last real user. But, the neighboring VMA bounds tables were found, considered as real neighbors, and we declined to free the bounds table covering the area. Doing this over and over left a small but significant number of these orphans. Handling them is fairly straighforward. All we have to do is walk the VMAs and skip all of the MPX ones when looking for neighbors. Signed-off-by: Dave Hansen Reviewed-by: Thomas Gleixner --- b/arch/x86/mm/mpx.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff -puN arch/x86/mm/mpx.c~mpx-dont-count-mpx-vmas-as-neighbors arch/x86/mm/mpx.c --- a/arch/x86/mm/mpx.c~mpx-dont-count-mpx-vmas-as-neighbors 2015-05-18 17:49:04.791686927 -0700 +++ b/arch/x86/mm/mpx.c 2015-05-18 17:49:04.794687062 -0700 @@ -937,16 +937,30 @@ static int try_unmap_single_bt(struct mm void __user *bde_vaddr; int ret; /* + * We already unliked the VMAs from the mm's rbtree so 'start' + * is guaranteed to be in a hole. This gets us the first VMA + * before the hole in to 'prev' and the next VMA after the hole + * in to 'next'. + */ + next = find_vma_prev(mm, start, &prev); + /* + * Do not count other MPX bounds table VMAs as neighbors. + * Although theoretically possible, we do not allow bounds + * tables for bounds tables so our heads do not explode. + * If we count them as neighbors here, we may end up with + * lots of tables even though we have no actual table + * entries in use. + */ + while (next && is_mpx_vma(next)) + next = next->vm_next; + while (prev && is_mpx_vma(prev)) + prev = prev->vm_prev; + /* * We know 'start' and 'end' lie within an area controlled * by a single bounds table. See if there are any other * VMAs controlled by that bounds table. If there are not * then we can "expand" the are we are unmapping to possibly * cover the entire table. - * - * We already unliked the VMAs from the mm's rbtree so 'start' - * is guaranteed to be in a hole. This gets us the first VMA - * before the hole in to 'prev' and the next VMA after the hole - * in to 'next'. */ next = find_vma_prev(mm, start, &prev); if ((!prev || prev->vm_end <= bta_start_vaddr) && _