Whamcloud - gitweb
libcfs: add cfs_mem_is_in_cache() checking that a given pointer points at the object...
authornikita <nikita>
Fri, 8 Aug 2008 13:51:27 +0000 (13:51 +0000)
committernikita <nikita>
Fri, 8 Aug 2008 13:51:27 +0000 (13:51 +0000)
libcfs/include/libcfs/linux/linux-mem.h
libcfs/include/libcfs/user-mem.h
libcfs/libcfs/linux/linux-mem.c
libcfs/libcfs/user-mem.c

index d5cf0d3..19dec15 100644 (file)
@@ -47,7 +47,7 @@
 
 #ifndef __KERNEL__
 #error This include is only for kernel use.
-#endif 
+#endif
 
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
@@ -129,6 +129,7 @@ extern cfs_mem_cache_t * cfs_mem_cache_create (const char *, size_t, size_t, uns
 extern int cfs_mem_cache_destroy ( cfs_mem_cache_t * );
 extern void *cfs_mem_cache_alloc ( cfs_mem_cache_t *, int);
 extern void cfs_mem_cache_free ( cfs_mem_cache_t *, void *);
+extern int cfs_mem_is_in_cache(const void *addr, const cfs_mem_cache_t *kmem);
 
 /*
  */
index 3b0a606..701d8f8 100644 (file)
@@ -86,6 +86,7 @@ cfs_mem_cache_create(const char *, size_t, size_t, unsigned long);
 int cfs_mem_cache_destroy(cfs_mem_cache_t *c);
 void *cfs_mem_cache_alloc(cfs_mem_cache_t *c, int gfp);
 void cfs_mem_cache_free(cfs_mem_cache_t *c, void *addr);
+int cfs_mem_is_in_cache(const void *addr, const cfs_mem_cache_t *kmem);
 
 /*
  * Copy to/from user
index 04ccd4e..20f3667 100644 (file)
@@ -148,6 +148,28 @@ cfs_mem_cache_free(cfs_mem_cache_t *cachep, void *objp)
         return kmem_cache_free(cachep, objp);
 }
 
+/**
+ * Returns true if \a addr is an address of an allocated object in a slab \a
+ * kmem. Used in assertions. This check is optimistically imprecise, i.e., it
+ * occasionally returns true for the incorrect addresses, but if it returns
+ * false, then the addresses is guaranteed to be incorrect.
+ */
+int cfs_mem_is_in_cache(const void *addr, const cfs_mem_cache_t *kmem)
+{
+        struct page *page;
+
+        /*
+         * XXX Copy of mm/slab.c:virt_to_cache(). It won't work with other
+         * allocators, like slub and slob.
+         */
+        page = virt_to_page(addr);
+        if (unlikely(PageCompound(page)))
+                page = (struct page *)page_private(page);
+        return PageSlab(page) && ((void *)page->lru.next) == kmem;
+}
+EXPORT_SYMBOL(cfs_mem_is_in_cache);
+
+
 EXPORT_SYMBOL(cfs_alloc);
 EXPORT_SYMBOL(cfs_free);
 EXPORT_SYMBOL(cfs_alloc_large);
index f1c44f5..7c2cc4d 100644 (file)
@@ -153,3 +153,14 @@ void cfs_mem_cache_free(cfs_mem_cache_t *c, void *addr)
 {
         cfs_free(addr);
 }
+
+/**
+ * Returns true if \a addr is an address of an allocated object in a slab \a
+ * kmem. Used in assertions. This check is optimistically imprecise, i.e., it
+ * occasionally returns true for the incorrect addresses, but if it returns
+ * false, then the addresses is guaranteed to be incorrect.
+ */
+int cfs_mem_is_in_cache(const void *addr, const cfs_mem_cache_t *kmem)
+{
+        return 1;
+}