aboutsummaryrefslogtreecommitdiff
path: root/drivers/staging/zcache/ramster/ramster.h
blob: 12ae56f09ca4a1bb1948c0f6ea19b8f4f0e8a8cf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*
 * 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);
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 */