From patchwork Thu Jan 24 01:29:50 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michel Lespinasse X-Patchwork-Id: 2027521 Return-Path: X-Original-To: patchwork-linux-parisc@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 5A1C9E0207 for ; Thu, 24 Jan 2013 01:31:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753405Ab3AXBan (ORCPT ); Wed, 23 Jan 2013 20:30:43 -0500 Received: from mail-pb0-f49.google.com ([209.85.160.49]:32904 "EHLO mail-pb0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753024Ab3AXBaK (ORCPT ); Wed, 23 Jan 2013 20:30:10 -0500 Received: by mail-pb0-f49.google.com with SMTP id un15so5087321pbc.36 for ; Wed, 23 Jan 2013 17:30:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=dWIUm/SyxXLUhYlZuQzTqqQF2lew0qh9lmcRnCVmde0=; b=gVuYUSS+e6/SwDx4UB60cdGsutiIApOHCAOBZWfAcgzQm5g6iDZpfOGkiVrvgMg0ZT +8FHplnKZ/1UKUbu0gqlV+iJABizwdzS5UNvkD6o6Ad5E9fC3hhHX7UDnt/hGiF8kOPi O4tJ497jmjFSqx5qDegEXWhsQfmBCe5LfXL0awjhRXIL0BFE4TRMVt+K6Pb6tuCD/6Ng 5/umPBWpSHBvzjyu6AFmlqfg1UnwHmxBLqmvLgHdGJK0Ot7dudNq7Sia4NymK2yjfArP OMkafeU0A8sOdJ+xYDRr4BiSRPolA2fQe5NfPoIZQ1lv4f71saLLbVOPjS3UoAHKFD0x niSA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:x-gm-message-state; bh=dWIUm/SyxXLUhYlZuQzTqqQF2lew0qh9lmcRnCVmde0=; b=R15GSTriVUHP/JMBxthb8sOr2kPDuO0eXN5D+lp8vSKCWAEab2asE6CLtb1yDkEumk lTGbOfPHjNysY2RpkCBUvpJ2KEDmksfbJuJyzKPIgy9JN1H6ky7cgyNqt4BcnzTa83kt vDOB0u5rcdkdbQZYUSHlfVWyV5koh7F9MYGhVsHmn4XiHXYabTHyDeLKj8zHGaMfRQBT 2SoUqiSdKabYHB6wtUnL6s9ruF2HSpM5126QX/SgsXERG/TqlONVy1tsRK+v1vBhYopG nHd3Dfvs8cGjuJ3O3sFmczX2vT6DiNjojz8tcvdTg+EN59X2cWuVdpbAGQ55FwJfEQhL 22AQ== X-Received: by 10.68.253.161 with SMTP id ab1mr494409pbd.97.1358991009623; Wed, 23 Jan 2013 17:30:09 -0800 (PST) Received: from studio.mtv.corp.google.com (studio.mtv.corp.google.com [172.17.131.106]) by mx.google.com with ESMTPS id kc4sm13786285pbc.23.2013.01.23.17.30.07 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 23 Jan 2013 17:30:08 -0800 (PST) From: Michel Lespinasse To: Benjamin Herrenschmidt , Paul Mackerras , "James E.J. Bottomley" , Helge Deller , Richard Henderson , Ivan Kokshaysky , Matt Turner , David Howells , Tony Luck , Fenghua Yu Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org, Andrew Morton , linuxppc-dev@lists.ozlabs.org, linux-parisc@vger.kernel.org, linux-alpha@vger.kernel.org, linux-ia64@vger.kernel.org Subject: [PATCH 7/8] mm: use vm_unmapped_area() on powerpc architecture Date: Wed, 23 Jan 2013 17:29:50 -0800 Message-Id: <1358990991-21316-8-git-send-email-walken@google.com> X-Mailer: git-send-email 1.8.1 In-Reply-To: <1358990991-21316-1-git-send-email-walken@google.com> References: <1358990991-21316-1-git-send-email-walken@google.com> X-Gm-Message-State: ALoCoQlGptVnqRwawGRFHGMGaknZB2eWf/kqLJNQEeBVL15dNFjkYyO+GuSlx3N7z3hG022FeVmOJRAkL9IYTNe2hpi1CPRoVxRGEraLx5xVDUpNyOStDpljS32HOT5QS6fEbuzxZKu8Qydw5q0Ng1pXYLPcW/gJWNvwnWlo2Mz6IeEs5fta+HGRzD0+td3wBWuOAn5oqMlYSxUR+5r6jt6CcgFKj1uSyQ== Sender: linux-parisc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-parisc@vger.kernel.org Update the powerpc slice_get_unmapped_area function to make use of vm_unmapped_area() instead of implementing a brute force search. Signed-off-by: Michel Lespinasse --- arch/powerpc/mm/slice.c | 123 ++++++++++++++++++++++++++++++----------------- 1 files changed, 78 insertions(+), 45 deletions(-) diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c index 999a74f25ebe..3e99c149271a 100644 --- a/arch/powerpc/mm/slice.c +++ b/arch/powerpc/mm/slice.c @@ -237,36 +237,69 @@ static void slice_convert(struct mm_struct *mm, struct slice_mask mask, int psiz #endif } +/* + * Compute which slice addr is part of; + * set *boundary_addr to the start or end boundary of that slice + * (depending on 'end' parameter); + * return boolean indicating if the slice is marked as available in the + * 'available' slice_mark. + */ +static bool slice_scan_available(unsigned long addr, + struct slice_mask available, + int end, + unsigned long *boundary_addr) +{ + unsigned long slice; + if (addr < SLICE_LOW_TOP) { + slice = GET_LOW_SLICE_INDEX(addr); + *boundary_addr = (slice + end) << SLICE_LOW_SHIFT; + return !!(available.low_slices & (1u << slice)); + } else { + slice = GET_HIGH_SLICE_INDEX(addr); + *boundary_addr = (slice + end) ? + ((slice + end) << SLICE_HIGH_SHIFT) : SLICE_LOW_TOP; + return !!(available.high_slices & (1u << slice)); + } +} + static unsigned long slice_find_area_bottomup(struct mm_struct *mm, unsigned long len, struct slice_mask available, int psize) { - struct vm_area_struct *vma; - unsigned long addr; - struct slice_mask mask; int pshift = max_t(int, mmu_psize_defs[psize].shift, PAGE_SHIFT); + unsigned long addr, found, next_end; + struct vm_unmapped_area_info info; - addr = TASK_UNMAPPED_BASE; - - for (;;) { - addr = _ALIGN_UP(addr, 1ul << pshift); - if ((TASK_SIZE - len) < addr) - break; - vma = find_vma(mm, addr); - BUG_ON(vma && (addr >= vma->vm_end)); + info.flags = 0; + info.length = len; + info.align_mask = PAGE_MASK & ((1ul << pshift) - 1); + info.align_offset = 0; - mask = slice_range_to_mask(addr, len); - if (!slice_check_fit(mask, available)) { - if (addr < SLICE_LOW_TOP) - addr = _ALIGN_UP(addr + 1, 1ul << SLICE_LOW_SHIFT); - else - addr = _ALIGN_UP(addr + 1, 1ul << SLICE_HIGH_SHIFT); + addr = TASK_UNMAPPED_BASE; + while (addr < TASK_SIZE) { + info.low_limit = addr; + if (!slice_scan_available(addr, available, 1, &addr)) continue; + + next_slice: + /* + * At this point [info.low_limit; addr) covers + * available slices only and ends at a slice boundary. + * Check if we need to reduce the range, or if we can + * extend it to cover the next available slice. + */ + if (addr >= TASK_SIZE) + addr = TASK_SIZE; + else if (slice_scan_available(addr, available, 1, &next_end)) { + addr = next_end; + goto next_slice; } - if (!vma || addr + len <= vma->vm_start) - return addr; - addr = vma->vm_end; + info.high_limit = addr; + + found = vm_unmapped_area(&info); + if (!(found & ~PAGE_MASK)) + return found; } return -ENOMEM; @@ -277,39 +310,39 @@ static unsigned long slice_find_area_topdown(struct mm_struct *mm, struct slice_mask available, int psize) { - struct vm_area_struct *vma; - unsigned long addr; - struct slice_mask mask; int pshift = max_t(int, mmu_psize_defs[psize].shift, PAGE_SHIFT); + unsigned long addr, found, prev; + struct vm_unmapped_area_info info; - addr = mm->mmap_base; - while (addr > len) { - /* Go down by chunk size */ - addr = _ALIGN_DOWN(addr - len, 1ul << pshift); + info.flags = VM_UNMAPPED_AREA_TOPDOWN; + info.length = len; + info.align_mask = PAGE_MASK & ((1ul << pshift) - 1); + info.align_offset = 0; - /* Check for hit with different page size */ - mask = slice_range_to_mask(addr, len); - if (!slice_check_fit(mask, available)) { - if (addr < SLICE_LOW_TOP) - addr = _ALIGN_DOWN(addr, 1ul << SLICE_LOW_SHIFT); - else if (addr < (1ul << SLICE_HIGH_SHIFT)) - addr = SLICE_LOW_TOP; - else - addr = _ALIGN_DOWN(addr, 1ul << SLICE_HIGH_SHIFT); + addr = mm->mmap_base; + while (addr > PAGE_SIZE) { + info.high_limit = addr; + if (!slice_scan_available(addr - 1, available, 0, &addr)) continue; - } + prev_slice: /* - * Lookup failure means no vma is above this address, - * else if new region fits below vma->vm_start, - * return with success: + * At this point [addr; info.high_limit) covers + * available slices only and starts at a slice boundary. + * Check if we need to reduce the range, or if we can + * extend it to cover the previous available slice. */ - vma = find_vma(mm, addr); - if (!vma || (addr + len) <= vma->vm_start) - return addr; + if (addr < PAGE_SIZE) + addr = PAGE_SIZE; + else if (slice_scan_available(addr - 1, available, 0, &prev)) { + addr = prev; + goto prev_slice; + } + info.low_limit = addr; - /* try just below the current vma->vm_start */ - addr = vma->vm_start; + found = vm_unmapped_area(&info); + if (!(found & ~PAGE_MASK)) + return found; } /*