Re: [RFC v3 05/15] mm, swap: add xswap cluster grow via VM_SPARSE vmalloc

Baoquan He <[email protected]>
Newsgroups org.kvack.linux-mm,org.kernel.vger.linux-kernel
Message-ID <aoJZ8QKMhFgwgUFz@MiWiFi-R3L-srv>
On 08/15/26 at 01:09am, Klara Modin wrote:
> Hi,
> 
> On 2026-08-13 18:48:44 +0800, Baoquan He wrote:
> > Implement dynamic cluster_info array growth for xswap devices using a
> > VM_SPARSE vmalloc area:
> > 
......snip....
> > @@ -3562,6 +3757,64 @@ static int setup_swap_clusters_info(struct swap_info_struct *si,
> >  	int err = -ENOMEM;
> >  	unsigned long i;
> >  
> > +#ifdef CONFIG_XSWAP
> > +	if (si->flags & SWP_XSWAP) {
> > +		unsigned long size = PAGE_ALIGN(nr_clusters * sizeof(*cluster_info));
> > +		struct vm_struct *vm;
> > +
> > +		vm = get_vm_area(size, VM_SPARSE);
> > +		if (!vm)
> > +			goto err;
> > +
> > +		cluster_info = vm->addr;
> > +		si->cluster_vm = vm;
> > +		si->nr_clusters = nr_clusters;
> > +		si->cluster_info = cluster_info;
> 
> Should probably initialise the mutex here instead since
> xswap_map_clusters() uses it?

Many thanks for reviewing, and you are absolutely right. A real bug is
caught, I will wrap up the fix in the next version as you suggested.

Thanks
Baoquan
> 
> > +
> > +		/* Map the initial chunk (at least cluster 0) */
> > +		if (xswap_map_clusters(si, 0, min_t(unsigned long,
> > +					XSWAP_GROW_CLUSTERS, nr_clusters)))
> > +			goto err_free_vm;
> 
> > +
> > +		/* xswap: only cluster 0 slot 0 is bad */
> > +		err = swap_cluster_setup_bad_slot(si, cluster_info, 0, false);
> > +		if (err)
> > +			goto err_unmap;
> > +
> > +		INIT_LIST_HEAD(&si->free_clusters);
> > +		INIT_LIST_HEAD(&si->full_clusters);
> > +		INIT_LIST_HEAD(&si->discard_clusters);
> > +		for (i = 0; i < SWAP_NR_ORDERS; i++) {
> > +			INIT_LIST_HEAD(&si->nonfull_clusters[i]);
> > +			INIT_LIST_HEAD(&si->frag_clusters[i]);
> > +		}
> > +
> > +		/* Mark mapped clusters: cluster 0 has 1 bad slot, rest free */
> > +		for (i = 0; i < si->nr_clusters_mapped; i++) {
> > +			struct swap_cluster_info *ci = &cluster_info[i];
> > +
> > +			if (i == 0) {
> > +				ci->flags = CLUSTER_FLAG_NONFULL;
> > +				list_add_tail(&ci->list, &si->nonfull_clusters[0]);
> > +			} else {
> > +				ci->flags = CLUSTER_FLAG_FREE;
> > +				list_add_tail(&ci->list, &si->free_clusters);
> > +			}
> > +		}
> > +
> > +		mutex_init(&si->xswap_lock);
> > +		return 0;
> > +
> > +err_unmap:
> > +		xswap_unmap_clusters(si, 0, si->nr_clusters_mapped);
> > +err_free_vm:
> > +		free_vm_area(si->cluster_vm);
> > +		si->cluster_vm = NULL;
> > +		si->cluster_info = NULL;
> > +		return err;
> > +	}
> > +#endif /* CONFIG_XSWAP */
> > +
> >  	cluster_info = kvzalloc_objs(*cluster_info, nr_clusters);
> >  	if (!cluster_info)
> >  		goto err;
> > -- 
> > 2.54.0
> > 
> 
> Regards,
> Klara Modin
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.