Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / include / obd_support.h
index f6717a1..6765019 100644 (file)
 #ifndef _OBD_SUPPORT
 #define _OBD_SUPPORT
 
-#include <libcfs/kp30.h>
+#include <libcfs/libcfs.h>
+#include <lvfs.h>
+#include <lprocfs_status.h>
+
+#if defined(__linux__)
+#include <linux/obd_support.h>
+#elif defined(__APPLE__)
+#include <darwin/obd_support.h>
+#elif defined(__WINNT__)
+#include <winnt/obd_support.h>
+#else
+#error Unsupported operating system.
+#endif
 
 /* global variables */
-extern atomic_t obd_memory;
-extern int obd_memmax;
-extern unsigned int obd_fail_loc;
+extern struct lprocfs_stats *obd_memory;
+enum {
+        OBD_MEMORY_STAT = 0,
+        OBD_MEMORY_PAGES_STAT = 1,
+        OBD_STATS_NUM,
+};
+
+enum {
+        OBD_FAIL_LOC_NOSET      = 0,
+        OBD_FAIL_LOC_ORSET      = 1,
+        OBD_FAIL_LOC_RESET      = 2
+};
+
+extern unsigned long obd_fail_loc;
+extern unsigned int obd_fail_val;
 extern unsigned int obd_debug_peer_on_timeout;
 extern unsigned int obd_dump_on_timeout;
 extern unsigned int obd_dump_on_eviction;
@@ -42,6 +66,13 @@ extern unsigned int obd_max_dirty_pages;
 extern atomic_t obd_dirty_pages;
 extern cfs_waitq_t obd_race_waitq;
 extern int obd_race_state;
+extern unsigned int obd_alloc_fail_rate;
+
+int __obd_fail_check_set(__u32 id, __u32 value, int set);
+
+/* lvfs.c */
+int obd_alloc_fail(const void *ptr, const char *name, const char *type,
+                   size_t size, const char *file, int line);
 
 /* Timeout definitions */
 #define LDLM_TIMEOUT_DEFAULT 20
@@ -112,6 +143,9 @@ extern int obd_race_state;
 #define OBD_FAIL_MDS_WRITEPAGE_PACK      0x13b
 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x13c
 #define OBD_FAIL_MDS_OSC_PRECREATE       0x13d
+#define OBD_FAIL_MDS_LOV_SYNC_RACE       0x13e
+#define OBD_FAIL_MDS_CLOSE_NET_REP       0x13f
+#define OBD_FAIL_MDS_LLOG_SYNC_TIMEOUT   0x140
 
 #define OBD_FAIL_OST                     0x200
 #define OBD_FAIL_OST_CONNECT_NET         0x201
@@ -145,6 +179,10 @@ extern int obd_race_state;
 #define OBD_FAIL_OST_DROP_REQ            0x21d
 #define OBD_FAIL_OST_SETATTR_CREDITS     0x21e
 #define OBD_FAIL_OST_HOLD_WRITE_RPC      0x21f
+#define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
+#define OBD_FAIL_OST_LLOG_RECOVERY_TIMEOUT 0x221
+#define OBD_FAIL_OST_CANCEL_COOKIE_TIMEOUT 0x222
+#define OBD_FAIL_OST_CONNECT_NET2        0x225
 
 #define OBD_FAIL_LDLM                    0x300
 #define OBD_FAIL_LDLM_NAMESPACE_NEW      0x301
@@ -164,6 +202,11 @@ extern int obd_race_state;
 #define OBD_FAIL_LDLM_GLIMPSE            0x30f
 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
 #define OBD_FAIL_LDLM_CANCEL_EVICT_RACE  0x311
+/* 
+#define OBD_FAIL_LDLM_PAUSE_CANCEL       0x312
+*/
+#define OBD_FAIL_LDLM_CLOSE_THREAD       0x313
+#define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE  0x314
 
 #define OBD_FAIL_OSC                     0x400
 #define OBD_FAIL_OSC_BRW_READ_BULK       0x401
@@ -175,6 +218,10 @@ extern int obd_race_state;
 #define OBD_FAIL_OSC_SHUTDOWN            0x407
 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
+#define OBD_FAIL_OSC_BRW_PREP_REQ2       0x40a
+#define OBD_FAIL_OSC_CONNECT_CKSUM       0x40b
+#define OBD_FAIL_OSC_CKSUM_ADLER_ONLY    0x40c
+#define OBD_FAIL_OSC_DIO_PAUSE           0x40d
 
 #define OBD_FAIL_PTLRPC                  0x500
 #define OBD_FAIL_PTLRPC_ACK              0x501
@@ -197,9 +244,11 @@ extern int obd_race_state;
 #define OBD_FAIL_TGT_DELAY_CONNECT       0x703
 #define OBD_FAIL_TGT_DELAY_RECONNECT     0x704
 #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
+#define OBD_FAIL_TGT_TOOMANY_THREADS     0x706
 
 #define OBD_FAIL_MDC_REVALIDATE_PAUSE    0x800
 #define OBD_FAIL_MDC_ENQUEUE_PAUSE       0x801
+#define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
 
 #define OBD_FAIL_MGS                     0x900
 #define OBD_FAIL_MGS_ALL_REQUEST_NET     0x901
@@ -212,6 +261,8 @@ extern int obd_race_state;
 
 #define OBD_FAIL_LPROC_REMOVE            0xb00
 
+#define OBD_FAIL_GENERAL_ALLOC           0xc00
+
 #define OBD_FAIL_SEQ                     0x1000
 #define OBD_FAIL_SEQ_QUERY_NET           0x1001
 
@@ -223,68 +274,112 @@ extern int obd_race_state;
 #define OBD_FAIL_SEC_CTX_INIT_CONT_NET   0x1202
 #define OBD_FAIL_SEC_CTX_FINI_NET        0x1203
 
-/* preparation for a more advanced failure testbed (not functional yet) */
+/* Failure injection control */
 #define OBD_FAIL_MASK_SYS    0x0000FF00
-#define OBD_FAIL_MASK_LOC    (0x000000FF | OBD_FAIL_MASK_SYS)
-#define OBD_FAIL_ONCE        0x80000000
-#define OBD_FAILED           0x40000000
-
-#define OBD_FAIL_CHECK(id)   (((obd_fail_loc & OBD_FAIL_MASK_LOC) ==           \
-                              ((id) & OBD_FAIL_MASK_LOC)) &&                   \
-                              ((obd_fail_loc & (OBD_FAILED | OBD_FAIL_ONCE))!= \
-                                (OBD_FAILED | OBD_FAIL_ONCE)))
-
-#define OBD_FAIL_CHECK_ONCE(id)                                              \
-({      int _ret_ = 0;                                                       \
-        if (unlikely(OBD_FAIL_CHECK(id))) {                                  \
-                CERROR("*** obd_fail_loc=0x%x ***\n", id);                   \
-                obd_fail_loc |= OBD_FAILED;                                  \
-                if ((id) & OBD_FAIL_ONCE)                                    \
-                        obd_fail_loc |= OBD_FAIL_ONCE;                       \
-                _ret_ = 1;                                                   \
-        }                                                                    \
-        _ret_;                                                               \
-})
+#define OBD_FAIL_MASK_LOC   (0x000000FF | OBD_FAIL_MASK_SYS)
 
-#define OBD_FAIL_RETURN(id, ret)                                             \
-do {                                                                         \
-        if (unlikely(OBD_FAIL_CHECK_ONCE(id))) {                             \
-                RETURN(ret);                                                 \
-        }                                                                    \
-} while(0)
+#define OBD_FAILED_BIT       30
+/* OBD_FAILED is 0x40000000 */
+#define OBD_FAILED          (1 << OBD_FAILED_BIT)
 
-#define OBD_FAIL_TIMEOUT(id, secs)                                           \
-do {                                                                         \
-        if (unlikely(OBD_FAIL_CHECK_ONCE(id))) {                             \
-                CERROR("obd_fail_timeout id %x sleeping for %d secs\n",      \
-                       (id), (secs));                                        \
-                set_current_state(TASK_UNINTERRUPTIBLE);                     \
-                cfs_schedule_timeout(CFS_TASK_UNINT,                         \
-                                    cfs_time_seconds(secs));                 \
-                set_current_state(TASK_RUNNING);                             \
-                CERROR("obd_fail_timeout id %x awake\n", (id));              \
-       }                                                                     \
-} while(0)
+#define OBD_FAIL_ONCE_BIT    31
+/* OBD_FAIL_ONCE is 0x80000000 */
+#define OBD_FAIL_ONCE       (1 << OBD_FAIL_ONCE_BIT)
+
+/* The following flags aren't made to be combined */
+#define OBD_FAIL_SKIP        0x20000000 /* skip N times then fail */
+#define OBD_FAIL_SOME        0x10000000 /* only fail N times */
+#define OBD_FAIL_RAND        0x08000000 /* fail 1/N of the times */
+#define OBD_FAIL_USR1        0x04000000 /* user flag */
+
+#define OBD_FAIL_PRECHECK(id) (obd_fail_loc &&                                \
+                              (obd_fail_loc & OBD_FAIL_MASK_LOC) ==           \
+                              ((id) & OBD_FAIL_MASK_LOC))
+
+static inline int obd_fail_check_set(__u32 id, __u32 value, int set)
+{
+        int ret = 0;
+        if (unlikely(OBD_FAIL_PRECHECK(id) &&
+            (ret = __obd_fail_check_set(id, value, set)))) {
+                CERROR("*** obd_fail_loc=%x ***\n", id);
+        }
+        return ret;
+}
+
+/* If id hit obd_fail_loc, return 1, otherwise return 0 */
+#define OBD_FAIL_CHECK(id) \
+        obd_fail_check_set(id, 0, OBD_FAIL_LOC_NOSET)
+
+/* If id hit obd_fail_loc, obd_fail_loc |= value and return 1,
+ * otherwise return 0 */
+#define OBD_FAIL_CHECK_ORSET(id, value) \
+        obd_fail_check_set(id, value, OBD_FAIL_LOC_ORSET)
+
+/* If id hit obd_fail_loc, obd_fail_loc = value and return 1,
+ * otherwise return 0 */
+#define OBD_FAIL_CHECK_RESET(id, value) \
+        obd_fail_check_set(id, value, OBD_FAIL_LOC_RESET)
+
+
+static inline int obd_fail_timeout_set(__u32 id, __u32 value, int secs, int set)
+{
+        int ret = 0;
+        if (unlikely(OBD_FAIL_PRECHECK(id) &&
+            (ret = __obd_fail_check_set(id, value, set)))) {
+                CERROR("obd_fail_timeout id %x sleeping for %d secs\n",
+                       id, secs);
+                set_current_state(TASK_UNINTERRUPTIBLE);
+                cfs_schedule_timeout(CFS_TASK_UNINT,  cfs_time_seconds(secs));
+                set_current_state(TASK_RUNNING);
+                CERROR("obd_fail_timeout id %x awake\n", id);
+        }
+        return ret;
+}
+
+/* If id hit obd_fail_loc, sleep secs */
+#define OBD_FAIL_TIMEOUT(id, secs) \
+        obd_fail_timeout_set(id, 0, secs, OBD_FAIL_LOC_NOSET)
+
+/* If id hit obd_fail_loc, obd_fail_loc |= value and sleep secs */
+#define OBD_FAIL_TIMEOUT_ORSET(id, value, secs) \
+        obd_fail_timeout_set(id, value, secs, OBD_FAIL_LOC_ORSET)
 
 #ifdef __KERNEL__
+static inline void obd_fail_write(int id, struct super_block *sb)
+{
+        /* We set FAIL_ONCE because we never "un-fail" a device */
+        if (OBD_FAIL_CHECK_ORSET(id & ~OBD_FAIL_ONCE, OBD_FAIL_ONCE)) {
+#ifdef LIBCFS_DEBUG
+                BDEVNAME_DECLARE_STORAGE(tmp);
+                CERROR("obd_fail_loc=%x, fail write operation on %s\n",
+                       id, ll_bdevname(sb, tmp));
+#endif
+                /* TODO-CMD: fix getting jdev */
+                __lvfs_set_rdonly(lvfs_sbdev(sb), (lvfs_sbdev_type)0);
+        }
+}
+#define OBD_FAIL_WRITE(id, sb) obd_fail_write(id, sb)
+
 /* The idea here is to synchronise two threads to force a race. The
  * first thread that calls this with a matching fail_loc is put to
  * sleep. The next thread that calls with the same fail_loc wakes up
  * the first and continues. */
-#define OBD_RACE(id)                                                         \
-do {                                                                         \
-        if (unlikely(OBD_FAIL_CHECK_ONCE(id))) {                             \
-                obd_race_state = 0;                                          \
-                CERROR("obd_race id %x sleeping\n", (id));                   \
-                OBD_SLEEP_ON(obd_race_waitq, obd_race_state != 0);           \
-                CERROR("obd_fail_race id %x awake\n", (id));                 \
-        } else if ((obd_fail_loc & OBD_FAIL_MASK_LOC) ==                     \
-                    ((id) & OBD_FAIL_MASK_LOC)) {                            \
-                CERROR("obd_fail_race id %x waking\n", (id));                \
-                obd_race_state = 1;                                          \
-                wake_up(&obd_race_waitq);                                    \
-        }                                                                    \
-} while(0)
+static inline void obd_race(__u32 id)
+{
+        if (OBD_FAIL_PRECHECK(id)) {
+                if (unlikely(__obd_fail_check_set(id, 0, OBD_FAIL_LOC_NOSET))) {
+                        obd_race_state = 0;
+                        CERROR("obd_race id %x sleeping\n", id);
+                        OBD_SLEEP_ON(obd_race_waitq, obd_race_state != 0);
+                        CERROR("obd_fail_race id %x awake\n", id);
+                } else {
+                        CERROR("obd_fail_race id %x waking\n", id);
+                        obd_race_state = 1;
+                        wake_up(&obd_race_waitq);
+                }
+        }
+}
+#define OBD_RACE(id) obd_race(id)
 #else
 /* sigh.  an expedient fix until OBD_RACE is fixed up */
 #define OBD_RACE(foo) do {} while(0)
@@ -294,6 +389,68 @@ do {                                                                         \
 
 extern atomic_t libcfs_kmemory;
 
+#ifdef LPROCFS
+#define obd_memory_add(size)                                                  \
+        lprocfs_counter_add(obd_memory, OBD_MEMORY_STAT, (long)(size))
+#define obd_memory_sub(size)                                                  \
+        lprocfs_counter_sub(obd_memory, OBD_MEMORY_STAT, (long)(size))
+#define obd_memory_sum()                                                      \
+        lprocfs_stats_collector(obd_memory, OBD_MEMORY_STAT,                  \
+                                LPROCFS_FIELDS_FLAGS_SUM)
+#define obd_pages_add(order)                                                  \
+        lprocfs_counter_add(obd_memory, OBD_MEMORY_PAGES_STAT,                \
+                            (long)(1 << (order)))
+#define obd_pages_sub(order)                                                  \
+        lprocfs_counter_sub(obd_memory, OBD_MEMORY_PAGES_STAT,                \
+                            (long)(1 << (order)))
+#define obd_pages_sum()                                                       \
+        lprocfs_stats_collector(obd_memory, OBD_MEMORY_PAGES_STAT,            \
+                                LPROCFS_FIELDS_FLAGS_SUM)
+
+extern void obd_update_maxusage(void);
+extern __u64 obd_memory_max(void);
+extern __u64 obd_pages_max(void);
+
+#else
+
+extern __u64 obd_alloc;
+extern __u64 obd_pages;
+
+extern __u64 obd_max_alloc;
+extern __u64 obd_max_pages;
+
+static inline void obd_memory_add(long size)
+{
+        obd_alloc += size;
+        if (obd_alloc > obd_max_alloc)
+                obd_max_alloc = obd_alloc;
+}
+
+static inline void obd_memory_sub(long size)
+{
+        obd_alloc -= size;
+}
+
+static inline void obd_pages_add(int order)
+{
+        obd_pages += 1<< order;
+        if (obd_pages > obd_max_pages)
+                obd_max_pages = obd_pages;
+}
+
+static inline void obd_pages_sub(int order)
+{
+        obd_pages -= 1<< order;
+}
+
+#define obd_memory_sum() (obd_alloc)
+#define obd_pages_sum()  (obd_pages)
+
+#define obd_memory_max() (obd_max_alloc)
+#define obd_pages_max() (obd_max_pages)
+
+#endif
+
 #if defined (CONFIG_DEBUG_MEMORY) && defined(__KERNEL__)
 
 #define OBD_MT_WRONG_SIZE    (1 << 0)
@@ -409,19 +566,17 @@ __put_mem_track(void *ptr, int size,
 
 #if OBD_DEBUG_MEMUSAGE
 #define OBD_ALLOC_POST(ptr, size, name)                                 \
-                atomic_add(size, &obd_memory);                          \
-                if (atomic_read(&obd_memory) > obd_memmax)              \
-                        obd_memmax = atomic_read(&obd_memory);          \
+                obd_memory_add(size);                                   \
                 get_mem_track((ptr), (size), __FILE__, __LINE__);       \
-                CDEBUG(D_MALLOC, name " '" #ptr "': %d at %p (tot %d)\n", \
-                       (int)(size), ptr, atomic_read(&obd_memory))
+                CDEBUG(D_MALLOC, name " '" #ptr "': %d at %p.\n",       \
+                       (int)(size), ptr)
 
 #define OBD_FREE_PRE(ptr, size, name)                                   \
         LASSERT(ptr);                                                   \
         put_mem_track((ptr), (size), __FILE__, __LINE__);               \
-        atomic_sub(size, &obd_memory);                                  \
-        CDEBUG(D_MALLOC, name " '" #ptr "': %d at %p (tot %d).\n",      \
-               (int)(size), ptr, atomic_read(&obd_memory));             \
+        obd_memory_sub(size);                                           \
+        CDEBUG(D_MALLOC, name " '" #ptr "': %d at %p.\n",               \
+               (int)(size), ptr);                                       \
         POISON(ptr, 0x5a, size)
 
 #else /* !OBD_DEBUG_MEMUSAGE */
@@ -431,6 +586,16 @@ __put_mem_track(void *ptr, int size,
 
 #endif /* !OBD_DEBUG_MEMUSAGE */
 
+#ifdef RANDOM_FAIL_ALLOC
+#define HAS_FAIL_ALLOC_FLAG OBD_FAIL_CHECK(OBD_FAIL_GENERAL_ALLOC)
+#else
+#define HAS_FAIL_ALLOC_FLAG 0
+#endif
+
+#define OBD_ALLOC_FAIL_BITS 24
+#define OBD_ALLOC_FAIL_MASK ((1 << OBD_ALLOC_FAIL_BITS) - 1)
+#define OBD_ALLOC_FAIL_MULT (OBD_ALLOC_FAIL_MASK / 100)
+
 #if defined(LUSTRE_UTILS) /* this version is for utils only */
 #define OBD_ALLOC_GFP(ptr, size, gfp_mask)                                    \
 do {                                                                          \
@@ -445,15 +610,20 @@ do {                                                                          \
         }                                                                     \
 } while (0)
 #else /* this version is for the kernel and liblustre */
+#define OBD_FREE_RTN0(ptr)                                                    \
+({                                                                            \
+        cfs_free(ptr);                                                        \
+        (ptr) = NULL;                                                         \
+        0;                                                                    \
+})
 #define OBD_ALLOC_GFP(ptr, size, gfp_mask)                                    \
 do {                                                                          \
         (ptr) = cfs_alloc(size, (gfp_mask));                                  \
-        if (unlikely((ptr) == NULL)) {                                        \
-                CERROR("kmalloc of '" #ptr "' (%d bytes) failed at %s:%d\n",  \
-                       (int)(size), __FILE__, __LINE__);                      \
-                CERROR("%d total bytes allocated by Lustre, %d by Portals\n", \
-                       atomic_read(&obd_memory), atomic_read(&libcfs_kmemory));\
-        } else {                                                              \
+        if (likely((ptr) != NULL &&                                           \
+                   (!HAS_FAIL_ALLOC_FLAG || obd_alloc_fail_rate == 0 ||       \
+                    !obd_alloc_fail(ptr, #ptr, "km", size,                    \
+                                    __FILE__, __LINE__) ||                    \
+                    OBD_FREE_RTN0(ptr)))){                                    \
                 memset(ptr, 0, size);                                         \
                 OBD_ALLOC_POST(ptr, size, "kmalloced");                       \
         }                                                                     \
@@ -476,10 +646,10 @@ do {                                                                          \
 do {                                                                          \
         (ptr) = cfs_alloc_large(size);                                        \
         if (unlikely((ptr) == NULL)) {                                        \
-                CERROR("vmalloc of '" #ptr "' (%d bytes) failed at %s:%d\n",  \
-                       (int)(size), __FILE__, __LINE__);                      \
-                CERROR("%d total bytes allocated by Lustre, %d by Portals\n", \
-                       atomic_read(&obd_memory), atomic_read(&libcfs_kmemory));\
+                CERROR("vmalloc of '" #ptr "' (%d bytes) failed\n",           \
+                       (int)(size));                                          \
+                CERROR(LPU64" total bytes allocated by Lustre, %d by LNET\n", \
+                       obd_memory_sum(), atomic_read(&libcfs_kmemory));       \
         } else {                                                              \
                 memset(ptr, 0, size);                                         \
                 OBD_ALLOC_POST(ptr, size, "vmalloced");                       \
@@ -553,16 +723,21 @@ do {                                                                          \
 /* we memset() the slab object to 0 when allocation succeeds, so DO NOT
  * HAVE A CTOR THAT DOES ANYTHING.  its work will be cleared here.  we'd
  * love to assert on that, but slab.c keeps kmem_cache_s all to itself. */
+#define OBD_SLAB_FREE_RTN0(ptr, slab)                                         \
+({                                                                            \
+        cfs_mem_cache_free((slab), (ptr));                                    \
+        (ptr) = NULL;                                                         \
+        0;                                                                    \
+})
 #define OBD_SLAB_ALLOC(ptr, slab, type, size)                                 \
 do {                                                                          \
         LASSERT(!in_interrupt());                                             \
         (ptr) = cfs_mem_cache_alloc(slab, (type));                            \
-        if (unlikely((ptr) == NULL)) {                                        \
-                CERROR("slab-alloc of '"#ptr"' (%d bytes) failed at %s:%d\n", \
-                       (int)(size), __FILE__, __LINE__);                      \
-                CERROR("%d total bytes allocated by Lustre, %d by Portals\n", \
-                       atomic_read(&obd_memory), atomic_read(&libcfs_kmemory));\
-        } else {                                                              \
+        if (likely((ptr) != NULL &&                                           \
+                   (!HAS_FAIL_ALLOC_FLAG || obd_alloc_fail_rate == 0 ||       \
+                    !obd_alloc_fail(ptr, #ptr, "slab-", size,                 \
+                                    __FILE__, __LINE__) ||                    \
+                    OBD_SLAB_FREE_RTN0(ptr, slab)))) {                        \
                 memset(ptr, 0, size);                                         \
                 OBD_ALLOC_POST(ptr, size, "slab-alloced");                    \
         }                                                                     \
@@ -582,16 +757,48 @@ do {                                                                          \
 #define OBD_SLAB_FREE_PTR(ptr, slab)                                          \
         OBD_SLAB_FREE((ptr), (slab), sizeof *(ptr))
 
-#define KEY_IS(str) (keylen >= strlen(str) && strcmp(key, str) == 0)
+#define KEY_IS(str) \
+        (keylen >= (sizeof(str)-1) && memcmp(key, str, (sizeof(str)-1)) == 0)
 
-#if defined(__linux__)
-#include <linux/obd_support.h>
-#elif defined(__APPLE__)
-#include <darwin/obd_support.h>
-#elif defined(__WINNT__)
-#include <winnt/obd_support.h>
-#else
-#error Unsupported operating system.
-#endif
+/* Wrapper for contiguous page frame allocation */
+#define OBD_PAGES_ALLOC(ptr, order, gfp_mask)                                 \
+do {                                                                          \
+        (ptr) = cfs_alloc_pages(gfp_mask, order);                             \
+        if (unlikely((ptr) == NULL)) {                                        \
+                CERROR("alloc_pages of '" #ptr "' %d page(s) / "LPU64" bytes "\
+                       "failed\n", (int)(1 << (order)),                       \
+                       (__u64)((1 << (order)) << CFS_PAGE_SHIFT));            \
+                CERROR(LPU64" total bytes and "LPU64" total pages "           \
+                       "("LPU64" bytes) allocated by Lustre, "                \
+                       "%d total bytes by LNET\n",                            \
+                       obd_memory_sum(),                                      \
+                       obd_pages_sum() << CFS_PAGE_SHIFT,                     \
+                       obd_pages_sum(),                                       \
+                       atomic_read(&libcfs_kmemory));                         \
+        } else {                                                              \
+                obd_pages_add(order);                                         \
+                CDEBUG(D_MALLOC, "alloc_pages '" #ptr "': %d page(s) / "      \
+                       LPU64" bytes at %p.\n",                                \
+                       (int)(1 << (order)),                                   \
+                       (__u64)((1 << (order)) << CFS_PAGE_SHIFT), ptr);       \
+        }                                                                     \
+} while (0)
+
+#define OBD_PAGE_ALLOC(ptr, gfp_mask)                                         \
+        OBD_PAGES_ALLOC(ptr, 0, gfp_mask)
+
+#define OBD_PAGES_FREE(ptr, order)                                            \
+do {                                                                          \
+        LASSERT(ptr);                                                         \
+        obd_pages_sub(order);                                                 \
+        CDEBUG(D_MALLOC, "free_pages '" #ptr "': %d page(s) / "LPU64" bytes " \
+               "at %p.\n",                                                    \
+               (int)(1 << (order)), (__u64)((1 << (order)) << CFS_PAGE_SHIFT),\
+               ptr);                                                          \
+        __cfs_free_pages(ptr, order);                                         \
+        (ptr) = (void *)0xdeadbeef;                                           \
+} while (0)
+
+#define OBD_PAGE_FREE(ptr) OBD_PAGES_FREE(ptr, 0)
 
 #endif