Received: by 10.223.185.116 with SMTP id b49csp2483100wrg; Mon, 12 Feb 2018 10:15:07 -0800 (PST) X-Google-Smtp-Source: AH8x224d9RFmIZ8lJtLosnCXzhRVsRiXumuAUY45jofwiz6ltkL3S3yAGRsIUYxV720PYeFBSXNY X-Received: by 10.101.82.1 with SMTP id o1mr9826342pgp.259.1518459307873; Mon, 12 Feb 2018 10:15:07 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1518459307; cv=none; d=google.com; s=arc-20160816; b=FM1Px8Up8udalI6oE2RspRqwTF8VXibHmlXk7zaoPdjm4DHjPku2abVkQB9mFQaTLp gnqzwYJ/tygiy39BGjukoW/4y9zFeO2KK4LLtzLFjbOIHXt9vuVQP//PC7Ae9oCNCGiM sekphKbOtyiKmnHGj0kkgLnfyfHJlf62H16QYedWzh/Supjt5TN/dMP2WdRsbdmW/L2n eK4VR2S6R8FffRSuvu+MgnposSzO2cHMGY8FN72OBuTFQnbttbWvGmJKeBF0ZvYXfGsh LGX0rqdo8WBjubcC7NRQGpeXIEHIpw0p6rWkspRs9g4eBumYSSxGLm/ns9aWPGZYOvMs rhOQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:date:cc:to:subject:from:references :in-reply-to:message-id:arc-authentication-results; bh=RRch98hga8rTIFYTd2dBSoSJ9lcpx/WrjIotlbQaREw=; b=g0GrgQF8HcUtnQOAAc1uHH76VG9Moz0YGMV0BinZuraXYrYLR9VNeYfrao29Jn6k9u HdP1a5RcChjEsXvaCY8yUayt4jQNkXfdR6ut7pn8Ib8gTWVNrbUGec6hUkGo0VzytNGx +NhO1f1y2wsCzbTJ/ZKP0nHhgZ6x2UQPkEoDCLjD9mmmxysj3BGMdsmFxEA7cFlzRywf IarnsXSGvKGfNABC3fPC59081qweWFuMvTe9vlTBv5c9kMskAfilpJ79E47j0B0Fecfz 7uh6q9zB4ekk7HjSM9hWbM9oJoPodNmWtK6TUupsNOHHGYSWOX7IaGLnk2LU3KRvOxia cwbQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u136si590772pgc.481.2018.02.12.10.14.53; Mon, 12 Feb 2018 10:15:07 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753899AbeBLSNq (ORCPT + 99 others); Mon, 12 Feb 2018 13:13:46 -0500 Received: from pegase1.c-s.fr ([93.17.236.30]:10429 "EHLO pegase1.c-s.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753349AbeBLSM2 (ORCPT ); Mon, 12 Feb 2018 13:12:28 -0500 Received: from localhost (mailhub1-int [192.168.12.234]) by localhost (Postfix) with ESMTP id 3zgDKJ4mtXz9tvMt; Mon, 12 Feb 2018 19:12:20 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at c-s.fr Received: from pegase1.c-s.fr ([192.168.12.234]) by localhost (pegase1.c-s.fr [192.168.12.234]) (amavisd-new, port 10024) with ESMTP id yEitY_gwlfGB; Mon, 12 Feb 2018 19:12:20 +0100 (CET) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase1.c-s.fr (Postfix) with ESMTP id 3zgDKJ4Gc5z9tvMh; Mon, 12 Feb 2018 19:12:20 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id DACAA8B96C; Mon, 12 Feb 2018 19:12:26 +0100 (CET) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id ALNiLQ0b_TWX; Mon, 12 Feb 2018 19:12:26 +0100 (CET) Received: from po15720vm.idsi0.si.c-s.fr (unknown [192.168.232.3]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 9BAEC8B962; Mon, 12 Feb 2018 19:12:26 +0100 (CET) Received: by po15720vm.idsi0.si.c-s.fr (Postfix, from userid 0) id 7683767B0B; Mon, 12 Feb 2018 19:12:26 +0100 (CET) Message-Id: In-Reply-To: <02a62db83282b5ef3e0e8281fdc46fa91beffc86.1518382747.git.christophe.leroy@c-s.fr> References: <02a62db83282b5ef3e0e8281fdc46fa91beffc86.1518382747.git.christophe.leroy@c-s.fr> From: Christophe Leroy Subject: [RFC REBASED 3/5] powerpc/mm/slice: implement slice_check_range_fits To: Nicholas Piggin Cc: linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Date: Mon, 12 Feb 2018 19:12:26 +0100 (CET) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Rather than build slice masks from a range then use that to check for fit in a candidate mask, implement slice_check_range_fits that checks if a range fits in a mask directly. This allows several structures to be removed from stacks, and also we don't expect a huge range in a lot of these cases, so building and comparing a full mask is going to be more expensive than testing just one or two bits of the range. Signed-off-by: Nicholas Piggin Signed-off-by: Christophe Leroy --- arch/powerpc/mm/slice.c | 68 ++++++++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c index ddf015d2d05b..311168ca3939 100644 --- a/arch/powerpc/mm/slice.c +++ b/arch/powerpc/mm/slice.c @@ -233,22 +233,36 @@ static const struct slice_mask *slice_mask_for_size(struct mm_struct *mm, int ps #error "Must define the slice masks for page sizes supported by the platform" #endif -static int slice_check_fit(struct mm_struct *mm, - const struct slice_mask *mask, - const struct slice_mask *available) +static bool slice_check_range_fits(struct mm_struct *mm, + const struct slice_mask *available, + unsigned long start, unsigned long len) { - DECLARE_BITMAP(result, SLICE_NUM_HIGH); - /* - * Make sure we just do bit compare only to the max - * addr limit and not the full bit map size. - */ - unsigned long slice_count = GET_HIGH_SLICE_INDEX(mm->context.slb_addr_limit); + unsigned long end = start + len - 1; + u64 low_slices = 0; + + if (start < SLICE_LOW_TOP) { + unsigned long mend = min(end, + (unsigned long)(SLICE_LOW_TOP - 1)); + + low_slices = (1u << (GET_LOW_SLICE_INDEX(mend) + 1)) + - (1u << GET_LOW_SLICE_INDEX(start)); + } + if ((low_slices & available->low_slices) != low_slices) + return false; + + if ((start + len) > SLICE_LOW_TOP) { + unsigned long start_index = GET_HIGH_SLICE_INDEX(start); + unsigned long align_end = ALIGN(end, (1UL << SLICE_HIGH_SHIFT)); + unsigned long count = GET_HIGH_SLICE_INDEX(align_end) - start_index; + unsigned long i; - slice_bitmap_and(result, mask->high_slices, available->high_slices, - slice_count); + for (i = start_index; i < start_index + count; i++) { + if (!test_bit(i, available->high_slices)) + return false; + } + } - return (mask->low_slices & available->low_slices) == mask->low_slices && - slice_bitmap_equal(result, mask->high_slices, slice_count); + return true; } static void slice_flush_segments(void *parm) @@ -519,12 +533,6 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len, on_each_cpu(slice_flush_segments, mm, 1); } - /* - * init different masks - */ - mask.low_slices = 0; - slice_bitmap_zero(mask.high_slices, SLICE_NUM_HIGH); - /* silence stupid warning */; potential_mask.low_slices = 0; slice_bitmap_zero(potential_mask.high_slices, SLICE_NUM_HIGH); @@ -586,15 +594,11 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len, #endif /* First check hint if it's valid or if we have MAP_FIXED */ - if (addr != 0 || fixed) { - /* Build a mask for the requested range */ - slice_range_to_mask(addr, len, &mask); - slice_print_mask(" mask", &mask); - + if (addr || fixed) { /* Check if we fit in the good mask. If we do, we just return, * nothing else to do */ - if (slice_check_fit(mm, &mask, &good_mask)) { + if (slice_check_range_fits(mm, &good_mask, addr, len)) { slice_dbg(" fits good !\n"); return addr; } @@ -620,10 +624,11 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len, slice_or_mask(&potential_mask, &good_mask); slice_print_mask(" potential", &potential_mask); - if ((addr != 0 || fixed) && - slice_check_fit(mm, &mask, &potential_mask)) { - slice_dbg(" fits potential !\n"); - goto convert; + if (addr || fixed) { + if (slice_check_range_fits(mm, &potential_mask, addr, len)) { + slice_dbg(" fits potential !\n"); + goto convert; + } } /* If we have MAP_FIXED and failed the above steps, then error out */ @@ -829,13 +834,12 @@ void slice_set_range_psize(struct mm_struct *mm, unsigned long start, int is_hugepage_only_range(struct mm_struct *mm, unsigned long addr, unsigned long len) { - struct slice_mask mask, available; + struct slice_mask available; unsigned int psize = mm->context.user_psize; if (radix_enabled()) return 0; - slice_range_to_mask(addr, len, &mask); available = *slice_mask_for_size(mm, psize); #ifdef CONFIG_PPC_64K_PAGES /* We need to account for 4k slices too */ @@ -852,6 +856,6 @@ int is_hugepage_only_range(struct mm_struct *mm, unsigned long addr, slice_print_mask(" mask", &mask); slice_print_mask(" available", &available); #endif - return !slice_check_fit(mm, &mask, &available); + return !slice_check_range_fits(mm, &available, addr, len); } #endif -- 2.13.3