bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v2 1/3] vm: Make vm_object_coalesce return new object and off


From: Samuel Thibault
Subject: Re: [PATCH v2 1/3] vm: Make vm_object_coalesce return new object and offset
Date: Wed, 5 Jul 2023 20:49:52 +0200
User-agent: NeoMutt/20170609 (1.8.3)

Applied, thanks!

Sergey Bugaev, le mer. 05 juil. 2023 17:16:37 +0300, a ecrit:
> vm_object_coalesce() callers used to rely on the fact that it always
> merged the next_object into prev_object, potentially destroying
> next_object and leaving prev_object the result of the whole operation.
> 
> After ee65849bec5da261be90f565bee096abb4117bdd
> "vm: Allow coalescing null object with an internal object", this is no
> longer true, since in case of prev_object == VM_OBJECT_NULL and
> next_object != VM_OBJECT_NULL, the overall result is next_object, not
> prev_object. The current callers are prepared to deal with this since
> they handle this case seprately anyway, but the following commit will
> introduce another caller that handles both cases in the same code path.
> 
> So, declare the way vm_object_coalesce() coalesces the two objects its
> implementation detail, and make it return the resulting object and the
> offset into it explicitly. This simplifies the callers, too.
> ---
>  vm/vm_map.c    | 11 ++++++-----
>  vm/vm_object.c | 53 +++++++++++++++++++++++++++++++++++++-------------
>  vm/vm_object.h |  4 +++-
>  3 files changed, 49 insertions(+), 19 deletions(-)
> 
> diff --git a/vm/vm_map.c b/vm/vm_map.c
> index 97fc09ce..d147d4b2 100644
> --- a/vm/vm_map.c
> +++ b/vm/vm_map.c
> @@ -1089,7 +1089,9 @@ kern_return_t vm_map_enter(
>                               entry->offset,
>                               offset,
>                               (vm_size_t)(entry->vme_end - entry->vme_start),
> -                             size)) {
> +                             size,
> +                             &entry->object.vm_object,
> +                             &entry->offset)) {
>  
>                       /*
>                        *      Coalesced the two objects - can extend
> @@ -1099,7 +1101,6 @@ kern_return_t vm_map_enter(
>                       map->size += size;
>                       entry->vme_end = end;
>                       vm_map_gap_update(&map->hdr, entry);
> -                     vm_object_deallocate(object);
>                       RETURN(KERN_SUCCESS);
>               }
>       }
> @@ -1117,7 +1118,9 @@ kern_return_t vm_map_enter(
>                       offset,
>                       next_entry->offset,
>                       size,
> -                     (vm_size_t)(next_entry->vme_end - 
> next_entry->vme_start))) {
> +                     (vm_size_t)(next_entry->vme_end - 
> next_entry->vme_start),
> +                     &next_entry->object.vm_object,
> +                     &next_entry->offset)) {
>  
>                       /*
>                        *      Coalesced the two objects - can extend
> @@ -1126,9 +1129,7 @@ kern_return_t vm_map_enter(
>                        */
>                       map->size += size;
>                       next_entry->vme_start = start;
> -                     next_entry->offset -= size;
>                       vm_map_gap_update(&map->hdr, entry);
> -                     vm_object_deallocate(object);
>                       RETURN(KERN_SUCCESS);
>               }
>       }
> diff --git a/vm/vm_object.c b/vm/vm_object.c
> index e01c1856..c238cce4 100644
> --- a/vm/vm_object.c
> +++ b/vm/vm_object.c
> @@ -2687,15 +2687,16 @@ void vm_object_page_remove(
>  
>  /*
>   *   Routine:        vm_object_coalesce
> - *   Function:       Coalesces two objects backing up adjoining
> - *                   regions of memory into a single object.
> - *
> - *   returns TRUE if objects were combined.
> - *
> - *   NOTE:   Only works at the moment if one of the objects is NULL
> - *           or if the objects are the same - otherwise, which
> - *           object do we lock first?
> - *
> + *   Purpose:
> + *           Tries to coalesce two objects backing up adjoining
> + *           regions of memory into a single object.
> + *
> + *           NOTE: Only works at the moment if one of the objects
> + *           is NULL or if the objects are the same - otherwise,
> + *           which object do we lock first?
> + *   Returns:
> + *           TRUE    if objects have been coalesced.
> + *           FALSE   the objects could not be coalesced.
>   *   Parameters:
>   *           prev_object     First object to coalesce
>   *           prev_offset     Offset into prev_object
> @@ -2705,8 +2706,14 @@ void vm_object_page_remove(
>   *           prev_size       Size of reference to prev_object
>   *           next_size       Size of reference to next_object
>   *
> + *           new_object      Resulting colesced object
> + *           new_offset      Offset into the resulting object
>   *   Conditions:
> - *   The object must *not* be locked.
> + *           The objects must *not* be locked.
> + *
> + *           If the objects are coalesced successfully, the caller's
> + *           references for both objects are consumed, and the caller
> + *           gains a reference for the new object.
>   */
>  
>  boolean_t vm_object_coalesce(
> @@ -2715,7 +2722,9 @@ boolean_t vm_object_coalesce(
>       vm_offset_t     prev_offset,
>       vm_offset_t     next_offset,
>       vm_size_t       prev_size,
> -     vm_size_t       next_size)
> +     vm_size_t       next_size,
> +     vm_object_t     *new_object,    /* OUT */
> +     vm_offset_t     *new_offset)    /* OUT */
>  {
>       vm_object_t     object;
>       vm_size_t       newsize;
> @@ -2725,10 +2734,23 @@ boolean_t vm_object_coalesce(
>                *      If neither object actually exists,
>                *      the offsets don't matter.
>                */
> -             if (prev_object == VM_OBJECT_NULL)
> +             if (prev_object == VM_OBJECT_NULL) {
> +                     *new_object = VM_OBJECT_NULL;
> +                     *new_offset = 0;
>                       return TRUE;
> +             }
>  
> -             return prev_offset + prev_size == next_offset;
> +             if (prev_offset + prev_size == next_offset) {
> +                     *new_object = prev_object;
> +                     *new_offset = prev_offset;
> +                     /*
> +                      *      Deallocate one of the two references.
> +                      */
> +                     vm_object_deallocate(prev_object);
> +                     return TRUE;
> +             }
> +
> +             return FALSE;
>       }
>  
>       if (next_object != VM_OBJECT_NULL) {
> @@ -2785,6 +2807,8 @@ boolean_t vm_object_coalesce(
>               newsize = prev_offset + prev_size + next_size;
>               if (newsize > object->size)
>                       object->size = newsize;
> +
> +             *new_offset = prev_offset;
>       } else {
>               /*
>                *      Check if we have enough space in the object
> @@ -2802,9 +2826,12 @@ boolean_t vm_object_coalesce(
>               vm_object_page_remove(object,
>                       next_offset - prev_size,
>                       next_offset);
> +
> +             *new_offset = next_offset - prev_size;
>       }
>  
>       vm_object_unlock(object);
> +     *new_object = object;
>       return TRUE;
>  }
>  
> diff --git a/vm/vm_object.h b/vm/vm_object.h
> index 46328a38..9c17541f 100644
> --- a/vm/vm_object.h
> +++ b/vm/vm_object.h
> @@ -247,7 +247,9 @@ extern boolean_t vm_object_coalesce(
>     vm_offset_t prev_offset,
>     vm_offset_t next_offset,
>     vm_size_t   prev_size,
> -   vm_size_t   next_size);
> +   vm_size_t   next_size,
> +   vm_object_t *new_object,  /* OUT */
> +   vm_offset_t *new_offset); /* OUT */
>  
>  extern void vm_object_pager_wakeup(ipc_port_t  pager);
>  
> -- 
> 2.41.0
> 
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]