[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] RE: [PATCH 2/3] Add Lazy slab initialization
-----Original Message----- From: win-pv-devel <win-pv-devel-bounces@xxxxxxxxxxxxxxxxxxxx> On Behalf Of Paul Durrant Sent: Monday, July 19, 2021 11:54 AM To: win-pv-devel@xxxxxxxxxxxxxxxxxxxx Subject: Re: [PATCH 2/3] Add Lazy slab initialization [CAUTION - EXTERNAL EMAIL] DO NOT reply, click links, or open attachments unless you have verified the sender and know the content is safe. On 19/07/2021 11:03, Owen Smith wrote: > Only initialize 1/4 of a slab initially, unless a reservation is defined. > Allocate and initialize each slab object once this initial allocation > has been exceeded. > > This is to decrease the overall resource usage when each cache > object's constructor allocates additional memory. > Whilst I understand the motivation, I don't think this is the right solution. If the resource consumption is too great to justify the performance benefit of using the slab constructor to allocate additional memory then the owner of the cache should simply refrain from doing so and defer that work until the point it actually allocates the object from the cache. There should be no need for a global change such as this. Paul Its possible that this is not need when the 3rd patch (Remove MINIMUM_OBJECT_SIZE) is used. In XenVbd, the bounce buffers had a reservation of 32 objects (each object will allocate a page of memory). This unfortunately currently results in 2 slabs of 31 objects, which is far more than used in a relatively unused VM (experimentally, 16 bounce buffers are used at any one time). This does leave the possibility of consuming significant memory when a new slab is required. At worse this can be (PAGE_SIZE - sizeof(XENBUS_CACHE_SLAB)) / sizeof(PVOID) objects allocating a single page, or less objects allocating multiple pages. I will look at making users of the cache interface attempt to avoid preallocation of pages during the constructor call. Owen > Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx> > --- > src/xenbus/cache.c | 27 +++++++++++++++++++++++++-- > 1 file changed, 25 insertions(+), 2 deletions(-) > > diff --git a/src/xenbus/cache.c b/src/xenbus/cache.c index > 247f244..d695ee3 100644 > --- a/src/xenbus/cache.c > +++ b/src/xenbus/cache.c > @@ -61,6 +61,7 @@ typedef struct _XENBUS_CACHE_SLAB { > LIST_ENTRY ListEntry; > USHORT MaximumOccupancy; > USHORT CurrentOccupancy; > + USHORT CurrentAllocated; > ULONG *Mask; > UCHAR Buffer[1]; > } XENBUS_CACHE_SLAB, *PXENBUS_CACHE_SLAB; @@ -301,6 +302,7 @@ > CacheCreateSlab( > ULONG Size; > LONG Index; > LONG SlabCount; > + LONG ObjectsToAllocate; > NTSTATUS status; > > NumberOfBytes = P2ROUNDUP(FIELD_OFFSET(XENBUS_CACHE_SLAB, > Buffer) + @@ -326,6 +328,7 @@ CacheCreateSlab( > Slab->Magic = XENBUS_CACHE_SLAB_MAGIC; > Slab->Cache = Cache; > Slab->MaximumOccupancy = (USHORT)Count; > + Slab->CurrentAllocated = 0; > > Size = P2ROUNDUP(Count, BITS_PER_ULONG); > Size /= 8; > @@ -334,12 +337,18 @@ CacheCreateSlab( > if (Slab->Mask == NULL) > goto fail3; > > - for (Index = 0; Index < (LONG)Slab->MaximumOccupancy; Index++) { > + ObjectsToAllocate = (Cache->Reservation == 0) ? > + (LONG)Count / 4 : > + min((LONG)Cache->Reservation, (LONG)Count); > + > + for (Index = 0; Index < ObjectsToAllocate; Index++) { > PVOID Object = (PVOID)&Slab->Buffer[Index * Cache->Size]; > > status = __CacheCtor(Cache, Object); > if (!NT_SUCCESS(status)) > goto fail4; > + > + Slab->CurrentAllocated++; > } > > CacheInsertSlab(Cache, Slab); > @@ -402,7 +411,7 @@ CacheDestroySlab( > ASSERT(Cache->Cursor != &Cache->SlabList || > IsListEmpty(&Cache->SlabList)); > > - Index = Slab->MaximumOccupancy; > + Index = Slab->CurrentAllocated; > while (--Index >= 0) { > PVOID Object = (PVOID)&Slab->Buffer[Index * Cache->Size]; > > @@ -493,6 +502,20 @@ CacheGetObjectFromSlab( > if (Slab->CurrentOccupancy == Slab->MaximumOccupancy) > return NULL; > > + ASSERT3U(Slab->CurrentOccupancy, <=, Slab->CurrentAllocated); > + ASSERT3U(Slab->CurrentAllocated, <=, Slab->MaximumOccupancy); > + if (Slab->CurrentOccupancy == Slab->CurrentAllocated) { > + NTSTATUS status; > + > + Object = (PVOID)&Slab->Buffer[Slab->CurrentAllocated * > + Cache->Size]; > + > + status = __CacheCtor(Cache, Object); > + if (!NT_SUCCESS(status)) > + return NULL; > + > + Slab->CurrentAllocated++; > + } > + > Index = __CacheMaskScan(Slab->Mask, Slab->MaximumOccupancy); > BUG_ON(Index >= Slab->MaximumOccupancy); > >
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |