The following patch-set proposes an efficient mechanism for handing freed memory between the guest and the host. This approach has some different trade-offs compared to ballooning: -For guests with DAX (no page cache) it rapidly hands back all free memory to the host. -Resolves the complexity of ballooning policy as the whole process is transparent and occurs automatically. -More frequent hypercalls than ballooning. More efficient memory use at the cost of higher CPU use. -Guest can quickly re-use memory if it is needed again, with MADV_FREE use on the host side. This patch set is divided into three parts and this is just the first part which contains the implementation used for preparing the list of guest free pages which will be sent to the host via hypercall. The patch-set leverages the existing arch_free_page() and arch_alloc_page() to add this functionality. It uses two lists one cpu-local and other cpu-global. Whenever a page is freed it is added to the respective cpu-local list until it is full. Once the list is full a seqlock is taken to prevent any further page allocations and the per cpu-local list is traversed in order to check for any fragmentation due to reallocations. If present those entries are defragmented and are added to the cpu-global list until it is full. Once the cpu-global list is full it is parsed and compressed. A hypercall is made only if the total number of entries are above the specified threshold value. A hypercall may affect the performance if done frequently and hence it needs to be minimized. This is the primary reason for compression, as it ensures replacement of multiple consecutive entries to a single one and removal of all duplicate entries causing frequent exhaustion of cpu-global list. After compressing the hyperlist there could be three following possibilities: *If the number of entries in this cpu-global list is greater than the threshold required for hypercall value then a hypercall is issued. *If the parsing of the cpu-local list is complete but the number of cpu-global list entries is less than the threshold then they are copied to a cpu-local list. *In case the parsing of the cpu-local list is yet not complete and the number of entries in the cpu-global list is less than the threshold then the parsing of the cpu-local list is continued and entries in the cpu-global list are added from the newly available index acquired after compression. - Regards Nitesh