From: Samuel Thibault <samuel.thibault@ens-lyon.org>
To: Juergen Gross <jgross@suse.com>
Cc: minios-devel@lists.xenproject.org,
xen-devel@lists.xenproject.org, wl@xen.org
Subject: Re: [PATCH 3/4] mini-os: mm: reduce buddy allocator list administration data
Date: Mon, 22 Jul 2024 23:34:53 +0200 [thread overview]
Message-ID: <20240722213453.2seamcvsig5zkff3@begin> (raw)
In-Reply-To: <20240722150141.31391-4-jgross@suse.com>
Juergen Gross, le lun. 22 juil. 2024 17:01:40 +0200, a ecrit:
> Today the administration data for the buddy allocator's lists consists
> of 2 arrays: one pointer array and one list element array for easier
> handling of the lists' tails.
>
> Those arrays can be combined into one by dropping the pointer array and
> using a different list end indicator.
>
> Add enqueue and dequeue helpers for better readability.
>
> Change the level member type to unsigned int.
>
> Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
> ---
> mm.c | 73 ++++++++++++++++++++++++++++--------------------------------
> 1 file changed, 34 insertions(+), 39 deletions(-)
>
> diff --git a/mm.c b/mm.c
> index 2cc49e94..96686a5c 100644
> --- a/mm.c
> +++ b/mm.c
> @@ -125,16 +125,30 @@ static void map_free(unsigned long first_page, unsigned long nr_pages)
> typedef struct chunk_head_st chunk_head_t;
>
> struct chunk_head_st {
> - chunk_head_t *next;
> - chunk_head_t **pprev;
> - int level;
> + chunk_head_t *next;
> + chunk_head_t *prev;
> + unsigned int level;
> };
>
> /* Linked lists of free chunks of different powers-of-two in size. */
> #define FREELIST_SIZE ((sizeof(void *) << 3) - PAGE_SHIFT)
> -static chunk_head_t *free_head[FREELIST_SIZE];
> -static chunk_head_t free_tail[FREELIST_SIZE];
> -#define FREELIST_EMPTY(_l) ((_l)->next == NULL)
> +static chunk_head_t free_list[FREELIST_SIZE];
> +#define FREELIST_EMPTY(_l) ((_l)->level == FREELIST_SIZE)
> +
> +static void enqueue_elem(chunk_head_t *elem, unsigned int level)
> +{
> + elem->level = level;
> + elem->next = free_list[level].next;
> + elem->prev = &free_list[level];
> + elem->next->prev = elem;
> + free_list[level].next = elem;
> +}
> +
> +static void dequeue_elem(chunk_head_t *elem)
> +{
> + elem->prev->next = elem->next;
> + elem->next->prev = elem->prev;
> +}
>
> /*
> * Initialise allocator, placing addresses [@min,@max] in free pool.
> @@ -151,9 +165,9 @@ static void init_page_allocator(unsigned long min, unsigned long max)
> (u_long)to_virt(min), min, (u_long)to_virt(max), max);
> for ( i = 0; i < FREELIST_SIZE; i++ )
> {
> - free_head[i] = &free_tail[i];
> - free_tail[i].pprev = &free_head[i];
> - free_tail[i].next = NULL;
> + free_list[i].next = &free_list[i];
> + free_list[i].prev = &free_list[i];
> + free_list[i].level = FREELIST_SIZE;
> }
>
> min = round_pgup(min);
> @@ -209,12 +223,7 @@ static void init_page_allocator(unsigned long min, unsigned long max)
> ch = (chunk_head_t *)r_min;
> r_min += 1UL << i;
> range -= 1UL << i;
> - i -= PAGE_SHIFT;
> - ch->level = i;
> - ch->next = free_head[i];
> - ch->pprev = &free_head[i];
> - ch->next->pprev = &ch->next;
> - free_head[i] = ch;
> + enqueue_elem(ch, i - PAGE_SHIFT);
> }
> }
>
> @@ -233,17 +242,16 @@ unsigned long alloc_pages(int order)
> /* Find smallest order which can satisfy the request. */
> for ( i = order; i < FREELIST_SIZE; i++ )
> {
> - if ( !FREELIST_EMPTY(free_head[i]) )
> + if ( !FREELIST_EMPTY(free_list[i].next) )
> break;
> }
>
> - if ( i == FREELIST_SIZE )
> + if ( i >= FREELIST_SIZE )
> goto no_memory;
>
> /* Unlink a chunk. */
> - alloc_ch = free_head[i];
> - free_head[i] = alloc_ch->next;
> - alloc_ch->next->pprev = alloc_ch->pprev;
> + alloc_ch = free_list[i].next;
> + dequeue_elem(alloc_ch);
>
> /* We may have to break the chunk a number of times. */
> while ( i != order )
> @@ -254,13 +262,7 @@ unsigned long alloc_pages(int order)
> (1UL << (i + PAGE_SHIFT)));
>
> /* Create new header for spare chunk. */
> - spare_ch->level = i;
> - spare_ch->next = free_head[i];
> - spare_ch->pprev = &free_head[i];
> -
> - /* Link in the spare chunk. */
> - spare_ch->next->pprev = &spare_ch->next;
> - free_head[i] = spare_ch;
> + enqueue_elem(spare_ch, i);
> }
>
> map_alloc(PHYS_PFN(to_phys(alloc_ch)), 1UL << order);
> @@ -308,18 +310,13 @@ void free_pages(void *pointer, int order)
> }
>
> /* We are committed to merging, unlink the chunk */
> - *(to_merge_ch->pprev) = to_merge_ch->next;
> - to_merge_ch->next->pprev = to_merge_ch->pprev;
> + dequeue_elem(to_merge_ch);
>
> order++;
> }
>
> /* Link the new chunk */
> - freed_ch->level = order;
> - freed_ch->next = free_head[order];
> - freed_ch->pprev = &free_head[order];
> - freed_ch->next->pprev = &freed_ch->next;
> - free_head[order] = freed_ch;
> + enqueue_elem(freed_ch, order);
>
> }
> EXPORT_SYMBOL(free_pages);
> @@ -405,13 +402,11 @@ void sanity_check(void)
>
> for ( x = 0; x < FREELIST_SIZE; x++ )
> {
> - for ( head = free_head[x]; !FREELIST_EMPTY(head); head = head->next )
> + for ( head = free_list[x].next; !FREELIST_EMPTY(head);
> + head = head->next )
> {
> ASSERT(!allocated_in_map(virt_to_pfn(head)));
> - if ( head->next )
> - ASSERT(head->next->pprev == &head->next);
> + ASSERT(head->next->prev == head);
> }
> - if ( free_head[x] )
> - ASSERT(free_head[x]->pprev == &free_head[x]);
> }
> }
> --
> 2.43.0
>
--
Samuel
/*
* [...] Note that 120 sec is defined in the protocol as the maximum
* possible RTT. I guess we'll have to use something other than TCP
* to talk to the University of Mars.
* PAWS allows us longer timeouts and large windows, so once implemented
* ftp to mars will work nicely.
*/
(from /usr/src/linux/net/inet/tcp.c, concerning RTT [retransmission timeout])
next prev parent reply other threads:[~2024-07-22 21:35 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-07-22 15:01 [PATCH 0/4] mini-os: cleanup of mm.c Juergen Gross
2024-07-22 15:01 ` [PATCH 1/4] mini-os: make mm.c coding style compliant Juergen Gross
2024-07-22 21:30 ` Samuel Thibault
2024-07-22 15:01 ` [PATCH 2/4] mini-os: mm: remove not needed struct chunk_tail_st Juergen Gross
2024-07-22 21:30 ` Samuel Thibault
2024-07-22 15:01 ` [PATCH 3/4] mini-os: mm: reduce buddy allocator list administration data Juergen Gross
2024-07-22 21:34 ` Samuel Thibault [this message]
2024-07-22 15:01 ` [PATCH 4/4] mini-os: remove sanity_check() Juergen Gross
2024-07-22 21:35 ` Samuel Thibault
2024-07-23 6:36 ` Jürgen Groß
2024-07-24 22:44 ` Samuel Thibault
2024-07-25 6:25 ` Jürgen Groß
2024-07-25 6:29 ` Samuel Thibault
2024-07-25 6:40 ` Juergen Gross
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240722213453.2seamcvsig5zkff3@begin \
--to=samuel.thibault@ens-lyon.org \
--cc=jgross@suse.com \
--cc=minios-devel@lists.xenproject.org \
--cc=wl@xen.org \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.