On (23/07/13 13:20), Hyeonggon Yoo wrote: > /* > @@ -264,6 +247,52 @@ struct mapping_area { > enum zs_mapmode vm_mm; /* mapping mode */ > }; > struct zspage already has a zsdesc member at this point, so I'd prefer to move struct zsdesc definition before struct zspage. > +/* > + * struct zsdesc - memory descriptor for zsmalloc memory > + * > + * This struct overlays struct page for now. Do not modify without a > + * good understanding of the issues. > + * > + * Usage of struct page flags on zsdesc: > + * PG_private: identifies the first component zsdesc > + */ > +struct zsdesc { > + unsigned long flags; > + > + /* > + * Although not used by zsmalloc, this field is used by non-LRU page migration > + * code. Leave it unused. > + */ > + struct list_head lru; > + > + /* Always points to zsmalloc_mops with PAGE_MAPPING_MOVABLE set */ > + struct movable_operations *mops; > + > + union { > + /* linked list of all zsdescs in a zspage */ > + struct zsdesc *next; > + /* for huge zspages */ > + unsigned long handle; > + }; > + struct zspage *zspage; > + unsigned int first_obj_offset; > + unsigned int _refcount; > +}; > + > +#define ZSDESC_MATCH(pg, zs) \ > + static_assert(offsetof(struct page, pg) == offsetof(struct zsdesc, zs)) > + > +ZSDESC_MATCH(flags, flags); > +ZSDESC_MATCH(lru, lru); > +ZSDESC_MATCH(mapping, mops); > +ZSDESC_MATCH(index, next); > +ZSDESC_MATCH(index, handle); > +ZSDESC_MATCH(private, zspage); > +ZSDESC_MATCH(page_type, first_obj_offset); > +ZSDESC_MATCH(_refcount, _refcount); > +#undef ZSDESC_MATCH > +static_assert(sizeof(struct zsdesc) <= sizeof(struct page)); > + > /* huge object: pages_per_zspage == 1 && maxobj_per_zspage == 1 */ > static void SetZsHugePage(struct zspage *zspage) > { > -- > 2.41.0 >