From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1Lg5PW-0007aA-HO for mharc-grub-devel@gnu.org; Sat, 07 Mar 2009 17:54:26 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Lg5PT-0007YU-Hd for grub-devel@gnu.org; Sat, 07 Mar 2009 17:54:23 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Lg5PS-0007YI-UN for grub-devel@gnu.org; Sat, 07 Mar 2009 17:54:23 -0500 Received: from [199.232.76.173] (port=48361 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Lg5PS-0007YF-Ou for grub-devel@gnu.org; Sat, 07 Mar 2009 17:54:22 -0500 Received: from fg-out-1718.google.com ([72.14.220.156]:49279) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1Lg5PS-0004iX-5M for grub-devel@gnu.org; Sat, 07 Mar 2009 17:54:22 -0500 Received: by fg-out-1718.google.com with SMTP id l27so673830fgb.30 for ; Sat, 07 Mar 2009 14:54:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from :user-agent:mime-version:to:subject:content-type; bh=1k/BFB8gvPOk4ft98kK3Gt2J794C7sgaiaLOALz6xIE=; b=T48USfNT6tnTQCdfzjSHbHqhcj2AhbqAtBKKXmZ0sRcmL5rXv1pF/OVk0yMerWOfDn 9eOptMUEDQMa9m6Oy5vBSqTU6G+73CxbQX0SRnQtc41tNvuBH+dEQAYSCq5AyB3LI0Kc 135XwA5YT86KzPhEkAElVPIZlYtwkF3QMppdE= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:subject :content-type; b=NFK+nskiXlZPklC/3i8oJy6tz2PfwTy+rOYDCCSrRjNj1EJfPtS6AlNnRDsYbBnPpg 9QGHOXGu9+9nw9zN1xwY4LjemOFlkjzltQAfY0CJB01NFdOy9SfU+kUutPKDLoUFz/R3 umD8WSoC75SJF5hMDd9tC0pYk+KyulN4moB3Q= Received: by 10.86.82.16 with SMTP id f16mr2937890fgb.32.1236466460523; Sat, 07 Mar 2009 14:54:20 -0800 (PST) Received: from ?192.168.1.25? (181-74.0-85.cust.bluewin.ch [85.0.74.181]) by mx.google.com with ESMTPS id l19sm1594669fgb.7.2009.03.07.14.54.19 (version=SSLv3 cipher=RC4-MD5); Sat, 07 Mar 2009 14:54:20 -0800 (PST) Message-ID: <49B2FB1A.9040208@gmail.com> Date: Sat, 07 Mar 2009 23:54:18 +0100 From: phcoder User-Agent: Thunderbird 2.0.0.19 (X11/20090105) MIME-Version: 1.0 To: The development of GRUB 2 Content-Type: multipart/mixed; boundary="------------020404060006010903060402" X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 2) Subject: [PATCH] dynamic cache allocation X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GRUB 2 List-Id: The development of GRUB 2 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 07 Mar 2009 22:54:24 -0000 This is a multi-part message in MIME format. --------------020404060006010903060402 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hello. Discussing with Robert Millan and Bean on IRC we noticed that disk cache index is statically allocated. Here is a proposal to change it to dynamic allocation proportional to the size of available memory. -- Regards Vladimir 'phcoder' Serbinenko --------------020404060006010903060402 Content-Type: text/x-patch; name="cache.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="cache.diff" Index: kern/disk.c =================================================================== --- kern/disk.c (revision 2021) +++ kern/disk.c (working copy) @@ -41,7 +41,8 @@ struct grub_disk_cache int lock; }; -static struct grub_disk_cache grub_disk_cache_table[GRUB_DISK_CACHE_NUM]; +static struct grub_disk_cache *grub_disk_cache_table = 0; +static int grub_disk_cache_num = 0; void (*grub_disk_firmware_fini) (void); int grub_disk_firmware_is_tainted; @@ -68,7 +69,7 @@ grub_disk_cache_get_index (unsigned long dev_id, u { return ((dev_id * 524287UL + disk_id * 2606459UL + ((unsigned) (sector >> GRUB_DISK_CACHE_BITS))) - % GRUB_DISK_CACHE_NUM); + % grub_disk_cache_num); } static void @@ -78,6 +79,9 @@ grub_disk_cache_invalidate (unsigned long dev_id, unsigned index; struct grub_disk_cache *cache; + if (!grub_disk_cache_table) + return; + sector &= ~(GRUB_DISK_CACHE_SIZE - 1); index = grub_disk_cache_get_index (dev_id, disk_id, sector); cache = grub_disk_cache_table + index; @@ -97,7 +101,10 @@ grub_disk_cache_invalidate_all (void) { unsigned i; - for (i = 0; i < GRUB_DISK_CACHE_NUM; i++) + if (!grub_disk_cache_table) + return; + + for (i = 0; i < grub_disk_cache_num; i++) { struct grub_disk_cache *cache = grub_disk_cache_table + i; @@ -116,6 +123,14 @@ grub_disk_cache_fetch (unsigned long dev_id, unsig struct grub_disk_cache *cache; unsigned index; + if (!grub_disk_cache_table) + { +#if 0 + grub_disk_cache_misses++; +#endif + return 0; + } + index = grub_disk_cache_get_index (dev_id, disk_id, sector); cache = grub_disk_cache_table + index; @@ -143,6 +158,9 @@ grub_disk_cache_unlock (unsigned long dev_id, unsi struct grub_disk_cache *cache; unsigned index; + if (!grub_disk_cache_table) + return ; + index = grub_disk_cache_get_index (dev_id, disk_id, sector); cache = grub_disk_cache_table + index; @@ -157,7 +175,22 @@ grub_disk_cache_store (unsigned long dev_id, unsig { unsigned index; struct grub_disk_cache *cache; - + + if (!grub_disk_cache_table) + { +#ifdef GRUB_UTIL + grub_disk_cache_num = GRUB_UTIL_CACHE_NUM; +#else + grub_disk_cache_num = grub_mm_get_free () / GRUB_DISK_CACHE_DIVIDE; +#endif + grub_disk_cache_table = (struct grub_disk_cache *) + grub_malloc (grub_disk_cache_num * sizeof (struct grub_disk_cache)); + } + + if (!grub_disk_cache_table) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "couldn't allocate space for cache index"); + grub_disk_cache_invalidate (dev_id, disk_id, sector); index = grub_disk_cache_get_index (dev_id, disk_id, sector); Index: kern/mm.c =================================================================== --- kern/mm.c (revision 2021) +++ kern/mm.c (working copy) @@ -449,6 +449,33 @@ grub_realloc (void *ptr, grub_size_t size) return q; } +grub_size_t +grub_mm_get_free (void) +{ + grub_mm_region_t r; + grub_size_t ret = 0; + + for (r = base; r; r = r->next) + { + grub_mm_header_t p; + + /* Follow the free list. */ + p = r->first; + do + { + if (p->magic != GRUB_MM_FREE_MAGIC) + grub_fatal ("free magic is broken at %p: 0x%x", p, p->magic); + + ret += p->size << GRUB_MM_ALIGN_LOG2; + p = p->next; + } + while (p != r->first); + } + + return ret; +} + + #ifdef MM_DEBUG int grub_mm_debug = 0; Index: include/grub/disk.h =================================================================== --- include/grub/disk.h (revision 2021) +++ include/grub/disk.h (working copy) @@ -129,9 +129,14 @@ typedef struct grub_disk_memberlist *grub_disk_mem #define GRUB_DISK_SECTOR_SIZE 0x200 #define GRUB_DISK_SECTOR_BITS 9 -/* The maximum number of disk caches. */ -#define GRUB_DISK_CACHE_NUM 1021 +/* Allocate one cache entry per N bytes. + By default use up to one quarter of memory available for allocation */ +#define GRUB_DISK_CACHE_DIVIDE 16536 +/* On grub-util we can't know the available memory size and since host OS + already caches data we don't need a big cache*/ +#define GRUB_UTIL_CACHE_NUM 100 + /* The size of a disk cache in sector units. */ #define GRUB_DISK_CACHE_SIZE 8 #define GRUB_DISK_CACHE_BITS 3 Index: include/grub/mm.h =================================================================== --- include/grub/mm.h (revision 2021) +++ include/grub/mm.h (working copy) @@ -33,6 +33,7 @@ void *EXPORT_FUNC(grub_malloc) (grub_size_t size); void EXPORT_FUNC(grub_free) (void *ptr); void *EXPORT_FUNC(grub_realloc) (void *ptr, grub_size_t size); void *EXPORT_FUNC(grub_memalign) (grub_size_t align, grub_size_t size); +grub_size_t EXPORT_FUNC(grub_mm_get_free) (void); /* For debugging. */ #if defined(MM_DEBUG) && !defined(GRUB_UTIL) Index: ChangeLog =================================================================== --- ChangeLog (revision 2021) +++ ChangeLog (working copy) @@ -1,3 +1,17 @@ +2009-03-07 Vladimir Serbinenko + + Dynamic cache allocation + + * kern/disk.c (grub_disk_cache_table): changed declaration as pointer + instead of array. All users updated + * include/grub/disk.h (GRUB_DISK_CACHE_NUM): changed to ... + (grub_disk_cache_num): ... a variable. All users updated + * kern/disk.c (grub_disk_cache_store): allocate cache index + * kern/mm.c (grub_mm_get_free): new function + * include/grub/disk.h (GRUB_DISK_CACHE_DIVIDE): new declaration + (GRUB_UTIL_CACHE_NUM): likewise + * include/grub/mm.h (grub_mm_get_free): likewise + 2009-03-07 Bean * loader/i386/efi/linux.c (grub_rescue_cmd_initrd): Fix a bug in initrd --------------020404060006010903060402--