]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Merge commit '6bb992cb04926895be57dc97e7d569ea15a07db1' into thread-next
authorMaria Matejka <mq@ucw.cz>
Tue, 24 Jan 2023 08:44:43 +0000 (09:44 +0100)
committerMaria Matejka <mq@ucw.cz>
Tue, 24 Jan 2023 08:44:43 +0000 (09:44 +0100)
1  2 
sysdep/unix/alloc.c

index 030fb9c1501d2b68822f107186a0b0eda525ae8f,d625cd38ff22f3c2ce1d0e3849370ec981b547d0..04cf7498c1ff22fba170eb096d2b400113aafee3
@@@ -245,25 -179,26 +245,23 @@@ page_cleanup(void *_ UNUSED
    if (shutting_down)
      return;
  
 -  struct free_pages *fps = &global_free_pages;
 +  struct free_page *stack = atomic_exchange_explicit(&page_stack, NULL, memory_order_acq_rel);
 +  if (!stack)
 +    return;
  
-   /* Cleanup gets called when hot free page cache is too big.
-    * Moving some pages to the cold free page cache. */
 -  /* Cleanup may get called when hot free page cache is short of pages. Replenishing. */
 -  while (fps->cnt / 2 < fps->min)
 -    free_page(alloc_cold_page());
  
 -  /* Or the hot free page cache is too big. Moving some pages to the cold free page cache. */
 -  for (int limit = CLEANUP_PAGES_BULK; limit && (fps->cnt > fps->max / 2); fps->cnt--, limit--)
 -  {
 -    struct free_page *fp = SKIP_BACK(struct free_page, n, TAIL(fps->pages));
 -    rem_node(&fp->n);
 +  do {
 +    synchronize_rcu();
 +    struct free_page *fp = stack;
 +    stack = atomic_load_explicit(&fp->next, memory_order_acquire);
  
 +    LOCK_DOMAIN(resource, empty_pages_domain);
      /* Empty pages are stored as pointers. To store them, we need a pointer block. */
 -    struct empty_pages *ep;
 -    if (EMPTY_LIST(fps->empty) || ((ep = HEAD(fps->empty))->pos == EP_POS_MAX))
 +    if (!empty_pages || (empty_pages->pos == EP_POS_MAX))
      {
        /* There is either no pointer block or the last block is full. We use this block as a pointer block. */
 -      ep = (struct empty_pages *) fp;
 -      *ep = (struct empty_pages) {};
 -      add_head(&fps->empty, &ep->n);
 +      empty_pages = (struct empty_pages *) fp;
 +      *empty_pages = (struct empty_pages) {};
      }
      else
      {