@@ -1891,9 +1891,33 @@ static inline void mark_objexts_empty(struct slabobj_ext *obj_exts)
18911891 }
18921892}
18931893
1894+ static inline void mark_failed_objexts_alloc (struct slab * slab )
1895+ {
1896+ slab -> obj_exts = OBJEXTS_ALLOC_FAIL ;
1897+ }
1898+
1899+ static inline void handle_failed_objexts_alloc (unsigned long obj_exts ,
1900+ struct slabobj_ext * vec , unsigned int objects )
1901+ {
1902+ /*
1903+ * If vector previously failed to allocate then we have live
1904+ * objects with no tag reference. Mark all references in this
1905+ * vector as empty to avoid warnings later on.
1906+ */
1907+ if (obj_exts & OBJEXTS_ALLOC_FAIL ) {
1908+ unsigned int i ;
1909+
1910+ for (i = 0 ; i < objects ; i ++ )
1911+ set_codetag_empty (& vec [i ].ref );
1912+ }
1913+ }
1914+
18941915#else /* CONFIG_MEM_ALLOC_PROFILING_DEBUG */
18951916
18961917static inline void mark_objexts_empty (struct slabobj_ext * obj_exts ) {}
1918+ static inline void mark_failed_objexts_alloc (struct slab * slab ) {}
1919+ static inline void handle_failed_objexts_alloc (unsigned long obj_exts ,
1920+ struct slabobj_ext * vec , unsigned int objects ) {}
18971921
18981922#endif /* CONFIG_MEM_ALLOC_PROFILING_DEBUG */
18991923
@@ -1909,29 +1933,37 @@ static int alloc_slab_obj_exts(struct slab *slab, struct kmem_cache *s,
19091933 gfp_t gfp , bool new_slab )
19101934{
19111935 unsigned int objects = objs_per_slab (s , slab );
1912- unsigned long obj_exts ;
1913- void * vec ;
1936+ unsigned long new_exts ;
1937+ unsigned long old_exts ;
1938+ struct slabobj_ext * vec ;
19141939
19151940 gfp &= ~OBJCGS_CLEAR_MASK ;
19161941 /* Prevent recursive extension vector allocation */
19171942 gfp |= __GFP_NO_OBJ_EXT ;
19181943 vec = kcalloc_node (objects , sizeof (struct slabobj_ext ), gfp ,
19191944 slab_nid (slab ));
1920- if (!vec )
1945+ if (!vec ) {
1946+ /* Mark vectors which failed to allocate */
1947+ if (new_slab )
1948+ mark_failed_objexts_alloc (slab );
1949+
19211950 return - ENOMEM ;
1951+ }
19221952
1923- obj_exts = (unsigned long )vec ;
1953+ new_exts = (unsigned long )vec ;
19241954#ifdef CONFIG_MEMCG
1925- obj_exts |= MEMCG_DATA_OBJEXTS ;
1955+ new_exts |= MEMCG_DATA_OBJEXTS ;
19261956#endif
1957+ old_exts = slab -> obj_exts ;
1958+ handle_failed_objexts_alloc (old_exts , vec , objects );
19271959 if (new_slab ) {
19281960 /*
19291961 * If the slab is brand new and nobody can yet access its
19301962 * obj_exts, no synchronization is required and obj_exts can
19311963 * be simply assigned.
19321964 */
1933- slab -> obj_exts = obj_exts ;
1934- } else if (cmpxchg (& slab -> obj_exts , 0 , obj_exts ) ) {
1965+ slab -> obj_exts = new_exts ;
1966+ } else if (cmpxchg (& slab -> obj_exts , old_exts , new_exts ) != old_exts ) {
19351967 /*
19361968 * If the slab is already in use, somebody can allocate and
19371969 * assign slabobj_exts in parallel. In this case the existing
0 commit comments