#define _OBD_SUPPORT
#include <libcfs/kp30.h>
+#include <lvfs.h>
+#include <lprocfs_status.h>
+#include <lustre/lustre_idl.h>
/* global variables */
-extern atomic_t obd_memory;
-extern int obd_memmax;
+extern struct lprocfs_stats *obd_memory;
+enum {
+ OBD_MEMORY_STAT = 0,
+ OBD_MEMORY_PAGES_STAT = 1,
+ OBD_STATS_NUM,
+};
+
extern unsigned int 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;
+/* obd_timeout should only be used for recovery, not for
+ networking / disk / timings affected by load (use Adaptive Timeouts) */
extern unsigned int obd_timeout; /* seconds */
-#define PING_INTERVAL max(obd_timeout / 4, 1U)
-#define RECONNECT_INTERVAL max(obd_timeout / 10, 10U)
-#define LDLM_TIMEOUT_DEFAULT 20
-extern unsigned int ldlm_timeout;
-extern unsigned int obd_health_check_timeout;
+extern unsigned int ldlm_timeout; /* seconds */
extern unsigned int obd_sync_filter;
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;
+
+/* Timeout definitions */
+#define OBD_TIMEOUT_DEFAULT 100
+#define LDLM_TIMEOUT_DEFAULT 20
+#ifdef CRAY_XT3
+ #define OBD_RECOVERY_MAX_TIME (obd_timeout * 18) /* b13079 */
+#endif
+/* Time to wait for all clients to reconnect during recovery */
+/* Should be very conservative; must catch the first reconnect after reboot */
+#define OBD_RECOVERY_FACTOR (5 / 2) /* times obd_timeout */
+/* Change recovery-small 26b time if you change this */
+#define PING_INTERVAL max(obd_timeout / 4, 1U)
+/* Client may skip 1 ping; wait for 2.5 */
+#define PING_EVICT_TIMEOUT (PING_INTERVAL * 5 / 2)
+#define DISK_TIMEOUT 50 /* Beyond this we warn about disk speed */
+#define CONNECTION_SWITCH_MIN 5U /* Connection switching rate limiter */
+ /* Max connect interval for nonresponsive servers; ~50s to avoid building up
+ connect requests in the LND queues, but within obd_timeout so we don't
+ miss the recovery window */
+#define CONNECTION_SWITCH_MAX min(50U, max(CONNECTION_SWITCH_MIN,obd_timeout))
+#define CONNECTION_SWITCH_INC 5 /* Connection timeout backoff */
+#ifndef CRAY_XT3
+/* In general this should be low to have quick detection of a system
+ running on a backup server. (If it's too low, import_select_connection
+ will increase the timeout anyhow.) */
+#define INITIAL_CONNECT_TIMEOUT max(CONNECTION_SWITCH_MIN,obd_timeout/20)
+#else
+/* ...but for very large systems (e.g. CRAY) we need to keep the initial
+ connect t.o. high (bz 10803), because they will nearly ALWAYS be doing the
+ connects for the first time (clients "reboot" after every process, so no
+ chance to generate adaptive timeout data. */
+#define INITIAL_CONNECT_TIMEOUT max(CONNECTION_SWITCH_MIN,obd_timeout/2)
+#endif
+#define LONG_UNLINK 300 /* Unlink should happen before now */
#define OBD_FAIL_MDS 0x100
#define OBD_FAIL_MDS_FS_SETUP 0x135
#define OBD_FAIL_MDS_RESEND 0x136
#define OBD_FAIL_MDS_LLOG_CREATE_FAILED 0x137
+#define OBD_FAIL_MDS_LOV_SYNC_RACE 0x138
+#define OBD_FAIL_MDS_OSC_PRECREATE 0x139
+#define OBD_FAIL_MDS_LLOG_SYNC_TIMEOUT 0x13a
+#define OBD_FAIL_MDS_CLOSE_NET_REP 0x13b
+#define OBD_FAIL_MDS_BLOCK_QUOTA_REQ 0x13c
+#define OBD_FAIL_MDS_DROP_QUOTA_REQ 0x13d
#define OBD_FAIL_OST 0x200
#define OBD_FAIL_OST_CONNECT_NET 0x201
#define OBD_FAIL_OST_BRW_READ_BULK 0x20f
#define OBD_FAIL_OST_SYNC_NET 0x210
#define OBD_FAIL_OST_ALL_REPLY_NET 0x211
-#define OBD_FAIL_OST_ALL_REQUESTS_NET 0x212
+#define OBD_FAIL_OST_ALL_REQUEST_NET 0x212
#define OBD_FAIL_OST_LDLM_REPLY_NET 0x213
#define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
#define OBD_FAIL_OST_ENOSPC 0x215
#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_PAUSE_CREATE 0x223
+#define OBD_FAIL_OST_BRW_PAUSE_PACK 0x224
+#define OBD_FAIL_OST_CONNECT_NET2 0x225
#define OBD_FAIL_LDLM 0x300
#define OBD_FAIL_LDLM_NAMESPACE_NEW 0x301
#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
#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_PTLRPC 0x500
#define OBD_FAIL_PTLRPC_ACK 0x501
#define OBD_FAIL_PTLRPC_DROP_RPC 0x505
#define OBD_FAIL_PTLRPC_DELAY_SEND 0x506
#define OBD_FAIL_PTLRPC_DELAY_RECOV 0x507
+#define OBD_FAIL_PTLRPC_CLIENT_BULK_CB 0x508
+#define OBD_FAIL_PTLRPC_PAUSE_REQ 0x50a
+#define OBD_FAIL_PTLRPC_PAUSE_REP 0x50c
#define OBD_FAIL_OBD_PING_NET 0x600
#define OBD_FAIL_OBD_LOG_CANCEL_NET 0x601
#define OBD_FAIL_MDC_REVALIDATE_PAUSE 0x800
#define OBD_FAIL_MDC_ENQUEUE_PAUSE 0x801
+#define OBD_FAIL_MDC_OLD_EXT_FLAGS 0x802
#define OBD_FAIL_MGS 0x900
#define OBD_FAIL_MGS_ALL_REQUEST_NET 0x901
#define OBD_FAIL_MGS_ALL_REPLY_NET 0x902
-#define OBD_FAIL_MGC_PROCESS_LOG 0x903
-#define OBD_FAIL_MGS_SLOW_REQUEST_NET 0x904
-#define OBD_FAIL_MGS_SLOW_TARGET_REG 0x905
+#define OBD_FAIL_MGC_PAUSE_PROCESS_LOG 0x903
+#define OBD_FAIL_MGS_PAUSE_REQ 0x904
+#define OBD_FAIL_MGS_PAUSE_TARGET_REG 0x905
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(1, 7, 0, 0)
#define OBD_FAIL_QUOTA_QD_COUNT_32BIT 0xA00
+#else
+#warning "remove quota code above for format obsolete in new release"
+#endif
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(1, 9, 0, 0)
+#define OBD_FAIL_QUOTA_WITHOUT_CHANGE_QS 0xA01
+#else
+#warning "remove quota code above for format obsolete in new release"
+#endif
+
+#define OBD_FAIL_QUOTA_RET_QDATA 0xA02
#define OBD_FAIL_LPROC_REMOVE 0xB00
-/* preparation for a more advanced failure testbed (not functional yet) */
+#define OBD_FAIL_GENERAL_ALLOC 0xC00
+
+/* Failure injection control */
#define OBD_FAIL_MASK_SYS 0x0000FF00
-#define OBD_FAIL_MASK_LOC (0x000000FF | OBD_FAIL_MASK_SYS)
+#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 (OBD_FAIL_CHECK(id)) { \
+/* The following flags aren't made to be combined */
+#define OBD_FAIL_SKIP 0x20000000 /* skip N then fail */
+#define OBD_FAIL_SOME 0x10000000 /* fail N times */
+#define OBD_FAIL_RAND 0x08000000 /* fail 1/N of the time */
+#define OBD_FAIL_USR1 0x04000000 /* user flag */
+
+int obd_fail_check(__u32 id);
+#define OBD_FAIL_CHECK(id) \
+({ \
+ int _ret_ = 0; \
+ if (unlikely(obd_fail_loc && (_ret_ = obd_fail_check(id)))) { \
CERROR("*** obd_fail_loc=%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_CHECK_QUIET(id) \
+ (unlikely(obd_fail_loc) ? obd_fail_check(id) : 0)
+
+/* deprecated - just use OBD_FAIL_CHECK */
+#define OBD_FAIL_CHECK_ONCE OBD_FAIL_CHECK
+
#define OBD_FAIL_RETURN(id, ret) \
do { \
- if (OBD_FAIL_CHECK_ONCE(id)) { \
+ if (unlikely(obd_fail_loc && obd_fail_check(id))) { \
+ CERROR("*** obd_fail_return=%x rc=%d ***\n", id, ret); \
RETURN(ret); \
} \
} while(0)
#define OBD_FAIL_TIMEOUT(id, secs) \
-do { \
- if (OBD_FAIL_CHECK_ONCE(id)) { \
+({ int _ret_ = 0; \
+ if (unlikely(obd_fail_loc && (_ret_ = obd_fail_check(id)))) { \
CERROR("obd_fail_timeout id %x sleeping for %d secs\n", \
(id), (secs)); \
set_current_state(TASK_UNINTERRUPTIBLE); \
cfs_time_seconds(secs)); \
set_current_state(TASK_RUNNING); \
CERROR("obd_fail_timeout id %x awake\n", (id)); \
- } \
-} while(0)
+ } \
+ _ret_; \
+})
+
+#define OBD_FAIL_TIMEOUT_MS(id, ms) \
+({ int _ret_ = 0; \
+ if (unlikely(obd_fail_loc && (_ret_ = obd_fail_check(id)))) { \
+ CERROR("obd_fail_timeout id %x sleeping for %d ms\n", \
+ (id), (ms)); \
+ set_current_state(TASK_UNINTERRUPTIBLE); \
+ cfs_schedule_timeout(CFS_TASK_UNINT, \
+ cfs_time_seconds(ms)/1000); \
+ set_current_state(TASK_RUNNING); \
+ CERROR("obd_fail_timeout id %x awake\n", (id)); \
+ } \
+ _ret_; \
+})
#ifdef __KERNEL__
/* The idea here is to synchronise two threads to force a race. The
* the first and continues. */
#define OBD_RACE(id) \
do { \
- if (OBD_FAIL_CHECK_ONCE(id)) { \
+ if (unlikely(obd_fail_loc && obd_fail_check(id))) { \
obd_race_state = 0; \
CERROR("obd_race id %x sleeping\n", (id)); \
OBD_SLEEP_ON(obd_race_waitq, obd_race_state != 0); \
extern atomic_t libcfs_kmemory;
+#ifdef RANDOM_FAIL_ALLOC
+#define HAS_FAIL_ALLOC_FLAG OBD_FAIL_CHECK_QUIET(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)
+
+#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(LUSTRE_UTILS) /* this version is for utils only */
#define OBD_ALLOC_GFP(ptr, size, gfp_mask) \
do { \
(ptr) = cfs_alloc(size, (gfp_mask)); \
- if ((ptr) == NULL) { \
- CERROR("kmalloc of '" #ptr "' (%d bytes) failed at %s:%d\n", \
- (int)(size), __FILE__, __LINE__); \
+ if (unlikely((ptr) == NULL)) { \
+ CERROR("kmalloc of '" #ptr "' (%d bytes) failed\n", \
+ (int)(size)); \
} else { \
memset(ptr, 0, size); \
CDEBUG(D_MALLOC, "kmalloced '" #ptr "': %d at %p\n", \
} \
} 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 ((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); \
- atomic_add(size, &obd_memory); \
- if (atomic_read(&obd_memory) > obd_memmax) \
- obd_memmax = atomic_read(&obd_memory); \
- CDEBUG(D_MALLOC, "kmalloced '" #ptr "': %d at %p (tot %d)\n", \
- (int)(size), ptr, atomic_read(&obd_memory)); \
+ obd_memory_add(size); \
+ CDEBUG(D_MALLOC, "kmalloced '" #ptr "': %d at %p.\n", \
+ (int)(size), ptr); \
} \
} while (0)
#endif
# define OBD_VMALLOC(ptr, size) \
do { \
(ptr) = cfs_alloc_large(size); \
- if ((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));\
+ if (unlikely((ptr) == NULL)) { \
+ 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); \
- atomic_add(size, &obd_memory); \
- if (atomic_read(&obd_memory) > obd_memmax) \
- obd_memmax = atomic_read(&obd_memory); \
- CDEBUG(D_MALLOC, "vmalloced '" #ptr "': %d at %p (tot %d)\n", \
- (int)(size), ptr, atomic_read(&obd_memory)); \
+ obd_memory_add(size); \
+ CDEBUG(D_MALLOC, "vmalloced '" #ptr "': %d at %p.\n", \
+ (int)(size), ptr); \
} \
} while (0)
#endif
#define OBD_FREE(ptr, size) \
do { \
LASSERT(ptr); \
- atomic_sub(size, &obd_memory); \
- CDEBUG(D_MALLOC, "kfreed '" #ptr "': %d at %p (tot %d).\n", \
- (int)(size), ptr, atomic_read(&obd_memory)); \
+ obd_memory_sub(size); \
+ CDEBUG(D_MALLOC, "kfreed '" #ptr "': %d at %p.\n", \
+ (int)(size), ptr); \
POISON(ptr, 0x5a, size); \
cfs_free(ptr); \
(ptr) = (void *)0xdeadbeef; \
# define OBD_VFREE(ptr, size) \
do { \
LASSERT(ptr); \
- atomic_sub(size, &obd_memory); \
- CDEBUG(D_MALLOC, "vfreed '" #ptr "': %d at %p (tot %d).\n", \
- (int)(size), ptr, atomic_read(&obd_memory)); \
+ obd_memory_sub(size); \
+ CDEBUG(D_MALLOC, "vfreed '" #ptr "': %d at %p.\n", \
+ (int)(size), ptr); \
POISON(ptr, 0x5a, size); \
cfs_free_large(ptr); \
(ptr) = (void *)0xdeadbeef; \
/* 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 ((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); \
- atomic_add(size, &obd_memory); \
- if (atomic_read(&obd_memory) > obd_memmax) \
- obd_memmax = atomic_read(&obd_memory); \
- CDEBUG(D_MALLOC, "slab-alloced '"#ptr"': %d at %p (tot %d)\n",\
- (int)(size), ptr, atomic_read(&obd_memory)); \
+ obd_memory_add(size); \
+ CDEBUG(D_MALLOC, "slab-alloced '"#ptr"': %d at %p.\n", \
+ (int)(size), ptr); \
} \
} while (0)
#define OBD_SLAB_FREE(ptr, slab, size) \
do { \
LASSERT(ptr); \
- CDEBUG(D_MALLOC, "slab-freed '" #ptr "': %d at %p (tot %d).\n", \
- (int)(size), ptr, atomic_read(&obd_memory)); \
- atomic_sub(size, &obd_memory); \
+ CDEBUG(D_MALLOC, "slab-freed '" #ptr "': %d at %p.\n", \
+ (int)(size), ptr); \
+ obd_memory_sub(size); \
POISON(ptr, 0x5a, size); \
cfs_mem_cache_free(slab, ptr); \
(ptr) = (void *)0xdeadbeef; \
} while (0)
-#define KEY_IS(str) (keylen >= strlen(key) && strcmp(key, str) == 0)
+#define OBD_SLAB_ALLOC_PTR(ptr, slab) \
+ OBD_SLAB_ALLOC((ptr), (slab), CFS_ALLOC_STD, sizeof *(ptr))
+#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)
+
+/* 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)
#if defined(__linux__)
#include <linux/obd_support.h>