pmdk icon indicating copy to clipboard operation
pmdk copied to clipboard

FEAT: transaction metadata suballocator

Open pbalcer opened this issue 7 years ago • 1 comments

Transaction metadata suballocator

Description

User currently has no control over the persistent allocations happening inside of a transaction. They happen automatically and from the global pool - this might interfere with users allocation classes and induce additional fragmentation. The initial idea I had was to simply allow the user to remap the entire internal allocation classes map so that it would be possible to simply substitute custom ones for metadata allocations. That had two problems: a) allocation classes map is common for all allocations, meaning that having custom classes only for metadata might be difficult, and b) the user never really knows what are the sizes of metadata allocations - it would force applications to fill the entire alloc class map, which might not be needed for anything else.

The new idea is to allow the user to substitute metadata allocator for a transaction. Each transaction would take an optional argument - instance of transaction metadata suballocator. If provided, each allocation/deallocation would go through it. This includes pvector arrays, snapshot caches and huge snapshots.

The simplest suballocator would be passthrough to pmalloc with custom allocation class (and other flags), where a little bit more complicated and useful one would be a fixed-size linear allocator that resets when the transaction ends.

API Changes

There would be a new structure that defines the suballocator:


struct pobj_tx_alloc {
   int (*alloc)(struct pobj_tx_alloc *alloc, uint64_t *offset, size_t size);
   void (*dealloc)(struct pobj_tx_alloc *alloc, uint64_t *offset);
   void (*on_tx_begin)(struct pobj_tx_alloc *alloc);
   void (*on_tx_end)(struct pobj_tx_alloc *alloc);
};

It could include a type of the thing being allocated and/or a constructor. TBD

The user would be responsible for instantiating the allocator, which can be then passed to pmemobj_tx_begin as one of the varargs, like so:

struct my_super_tx_allocator *mallocator = ...;
pmemobj_tx_begin(pop, NULL, POBJ_PARAM_ALLOCATOR, mallocator);

The user structure must include struct pobj_tx_alloc at offset 0:


struct my_super_tx_allocator {
  struct pobj_tx_alloc base;
  uint64_t *offset;
  char *data;
}

Implementation details

There's a problem with the fact that we internally do not use PMEMoids, which means that the user would not be able to simply implement the alloc function as pmemobj_xalloc(..., &oid, ...);, but would need to use the reserve/publish API and use the pmemobj_set_value() function to set the offset. Not sure if this is a big issue.

pbalcer avatar Jan 15 '18 10:01 pbalcer

This partially solves pmem/issues#553

pbalcer avatar Jan 15 '18 10:01 pbalcer

If you consider this question still important to you please reopen the issue and provide more context for your request so we can reassess its priority.

janekmi avatar Aug 30 '23 16:08 janekmi