Kernel  |  3.10

下载     查看原文件
C++程序  |  162行  |  4.67 KB
/*
 * ramster.h
 *
 * Peer-to-peer transcendent memory
 *
 * Copyright (c) 2009-2012, Dan Magenheimer, Oracle Corp.
 */

#ifndef _RAMSTER_RAMSTER_H_
#define _RAMSTER_RAMSTER_H_

#include "../tmem.h"

enum ramster_remotify_op {
	RAMSTER_REMOTIFY_FLUSH_PAGE,
	RAMSTER_REMOTIFY_FLUSH_OBJ,
};

struct ramster_remotify_hdr {
	enum ramster_remotify_op op;
	struct list_head list;
};

struct flushlist_node {
	struct ramster_remotify_hdr rem_op;
	struct tmem_xhandle xh;
};

struct ramster_preload {
	struct flushlist_node *flnode;
};

union remotify_list_node {
	struct ramster_remotify_hdr rem_op;
	struct {
		struct ramster_remotify_hdr rem_op;
		struct tmem_handle th;
	} zbud_hdr;
	struct flushlist_node flist;
};

/*
 * format of remote pampd:
 *   bit 0 is reserved for zbud (in-page buddy selection)
 *   bit 1 == intransit
 *   bit 2 == is_remote... if this bit is set, then
 *   bit 3-10 == remotenode
 *   bit 11-23 == size
 *   bit 24-31 == cksum
 */
#define FAKE_PAMPD_INTRANSIT_BITS	1
#define FAKE_PAMPD_ISREMOTE_BITS	1
#define FAKE_PAMPD_REMOTENODE_BITS	8
#define FAKE_PAMPD_REMOTESIZE_BITS	13
#define FAKE_PAMPD_CHECKSUM_BITS	8

#define FAKE_PAMPD_INTRANSIT_SHIFT	1
#define FAKE_PAMPD_ISREMOTE_SHIFT	(FAKE_PAMPD_INTRANSIT_SHIFT + \
					 FAKE_PAMPD_INTRANSIT_BITS)
#define FAKE_PAMPD_REMOTENODE_SHIFT	(FAKE_PAMPD_ISREMOTE_SHIFT + \
					 FAKE_PAMPD_ISREMOTE_BITS)
#define FAKE_PAMPD_REMOTESIZE_SHIFT	(FAKE_PAMPD_REMOTENODE_SHIFT + \
					 FAKE_PAMPD_REMOTENODE_BITS)
#define FAKE_PAMPD_CHECKSUM_SHIFT	(FAKE_PAMPD_REMOTESIZE_SHIFT + \
					 FAKE_PAMPD_REMOTESIZE_BITS)

#define FAKE_PAMPD_MASK(x)		((1UL << (x)) - 1)

static inline void *pampd_make_remote(int remotenode, size_t size,
					unsigned char cksum)
{
	unsigned long fake_pampd = 0;
	fake_pampd |= 1UL << FAKE_PAMPD_ISREMOTE_SHIFT;
	fake_pampd |= ((unsigned long)remotenode &
			FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTENODE_BITS)) <<
				FAKE_PAMPD_REMOTENODE_SHIFT;
	fake_pampd |= ((unsigned long)size &
			FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTESIZE_BITS)) <<
				FAKE_PAMPD_REMOTESIZE_SHIFT;
	fake_pampd |= ((unsigned long)cksum &
			FAKE_PAMPD_MASK(FAKE_PAMPD_CHECKSUM_BITS)) <<
				FAKE_PAMPD_CHECKSUM_SHIFT;
	return (void *)fake_pampd;
}

static inline unsigned int pampd_remote_node(void *pampd)
{
	unsigned long fake_pampd = (unsigned long)pampd;
	return (fake_pampd >> FAKE_PAMPD_REMOTENODE_SHIFT) &
		FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTENODE_BITS);
}

static inline unsigned int pampd_remote_size(void *pampd)
{
	unsigned long fake_pampd = (unsigned long)pampd;
	return (fake_pampd >> FAKE_PAMPD_REMOTESIZE_SHIFT) &
		FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTESIZE_BITS);
}

static inline unsigned char pampd_remote_cksum(void *pampd)
{
	unsigned long fake_pampd = (unsigned long)pampd;
	return (fake_pampd >> FAKE_PAMPD_CHECKSUM_SHIFT) &
		FAKE_PAMPD_MASK(FAKE_PAMPD_CHECKSUM_BITS);
}

static inline bool pampd_is_remote(void *pampd)
{
	unsigned long fake_pampd = (unsigned long)pampd;
	return (fake_pampd >> FAKE_PAMPD_ISREMOTE_SHIFT) &
		FAKE_PAMPD_MASK(FAKE_PAMPD_ISREMOTE_BITS);
}

static inline bool pampd_is_intransit(void *pampd)
{
	unsigned long fake_pampd = (unsigned long)pampd;
	return (fake_pampd >> FAKE_PAMPD_INTRANSIT_SHIFT) &
		FAKE_PAMPD_MASK(FAKE_PAMPD_INTRANSIT_BITS);
}

/* note that it is a BUG for intransit to be set without isremote also set */
static inline void *pampd_mark_intransit(void *pampd)
{
	unsigned long fake_pampd = (unsigned long)pampd;

	fake_pampd |= 1UL << FAKE_PAMPD_ISREMOTE_SHIFT;
	fake_pampd |= 1UL << FAKE_PAMPD_INTRANSIT_SHIFT;
	return (void *)fake_pampd;
}

static inline void *pampd_mask_intransit_and_remote(void *marked_pampd)
{
	unsigned long pampd = (unsigned long)marked_pampd;

	pampd &= ~(1UL << FAKE_PAMPD_INTRANSIT_SHIFT);
	pampd &= ~(1UL << FAKE_PAMPD_ISREMOTE_SHIFT);
	return (void *)pampd;
}

extern int r2net_remote_async_get(struct tmem_xhandle *,
				bool, int, size_t, uint8_t, void *extra);
extern int r2net_remote_put(struct tmem_xhandle *, char *, size_t,
				bool, int *);
extern int r2net_remote_flush(struct tmem_xhandle *, int);
extern int r2net_remote_flush_object(struct tmem_xhandle *, int);
extern int r2net_register_handlers(void);
extern int r2net_remote_target_node_set(int);

extern int ramster_remotify_pageframe(bool);
extern void ramster_init(bool, bool, bool, bool);
extern void ramster_register_pamops(struct tmem_pamops *);
extern int ramster_localify(int, struct tmem_oid *oidp, uint32_t, char *,
				unsigned int, void *);
extern void *ramster_pampd_free(void *, struct tmem_pool *, struct tmem_oid *,
				uint32_t, bool);
extern void ramster_count_foreign_pages(bool, int);
extern int ramster_do_preload_flnode(struct tmem_pool *);
extern void ramster_cpu_up(int);
extern void ramster_cpu_down(int);

#endif /* _RAMSTER_RAMSTER_H */