1 /*
2 * ramster.h
3 *
4 * Peer-to-peer transcendent memory
5 *
6 * Copyright (c) 2009-2012, Dan Magenheimer, Oracle Corp.
7 */
8
9 #ifndef _RAMSTER_RAMSTER_H_
10 #define _RAMSTER_RAMSTER_H_
11
12 #include "../tmem.h"
13
14 enum ramster_remotify_op {
15 RAMSTER_REMOTIFY_FLUSH_PAGE,
16 RAMSTER_REMOTIFY_FLUSH_OBJ,
17 };
18
19 struct ramster_remotify_hdr {
20 enum ramster_remotify_op op;
21 struct list_head list;
22 };
23
24 struct flushlist_node {
25 struct ramster_remotify_hdr rem_op;
26 struct tmem_xhandle xh;
27 };
28
29 struct ramster_preload {
30 struct flushlist_node *flnode;
31 };
32
33 union remotify_list_node {
34 struct ramster_remotify_hdr rem_op;
35 struct {
36 struct ramster_remotify_hdr rem_op;
37 struct tmem_handle th;
38 } zbud_hdr;
39 struct flushlist_node flist;
40 };
41
42 /*
43 * format of remote pampd:
44 * bit 0 is reserved for zbud (in-page buddy selection)
45 * bit 1 == intransit
46 * bit 2 == is_remote... if this bit is set, then
47 * bit 3-10 == remotenode
48 * bit 11-23 == size
49 * bit 24-31 == cksum
50 */
51 #define FAKE_PAMPD_INTRANSIT_BITS 1
52 #define FAKE_PAMPD_ISREMOTE_BITS 1
53 #define FAKE_PAMPD_REMOTENODE_BITS 8
54 #define FAKE_PAMPD_REMOTESIZE_BITS 13
55 #define FAKE_PAMPD_CHECKSUM_BITS 8
56
57 #define FAKE_PAMPD_INTRANSIT_SHIFT 1
58 #define FAKE_PAMPD_ISREMOTE_SHIFT (FAKE_PAMPD_INTRANSIT_SHIFT + \
59 FAKE_PAMPD_INTRANSIT_BITS)
60 #define FAKE_PAMPD_REMOTENODE_SHIFT (FAKE_PAMPD_ISREMOTE_SHIFT + \
61 FAKE_PAMPD_ISREMOTE_BITS)
62 #define FAKE_PAMPD_REMOTESIZE_SHIFT (FAKE_PAMPD_REMOTENODE_SHIFT + \
63 FAKE_PAMPD_REMOTENODE_BITS)
64 #define FAKE_PAMPD_CHECKSUM_SHIFT (FAKE_PAMPD_REMOTESIZE_SHIFT + \
65 FAKE_PAMPD_REMOTESIZE_BITS)
66
67 #define FAKE_PAMPD_MASK(x) ((1UL << (x)) - 1)
68
pampd_make_remote(int remotenode,size_t size,unsigned char cksum)69 static inline void *pampd_make_remote(int remotenode, size_t size,
70 unsigned char cksum)
71 {
72 unsigned long fake_pampd = 0;
73 fake_pampd |= 1UL << FAKE_PAMPD_ISREMOTE_SHIFT;
74 fake_pampd |= ((unsigned long)remotenode &
75 FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTENODE_BITS)) <<
76 FAKE_PAMPD_REMOTENODE_SHIFT;
77 fake_pampd |= ((unsigned long)size &
78 FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTESIZE_BITS)) <<
79 FAKE_PAMPD_REMOTESIZE_SHIFT;
80 fake_pampd |= ((unsigned long)cksum &
81 FAKE_PAMPD_MASK(FAKE_PAMPD_CHECKSUM_BITS)) <<
82 FAKE_PAMPD_CHECKSUM_SHIFT;
83 return (void *)fake_pampd;
84 }
85
pampd_remote_node(void * pampd)86 static inline unsigned int pampd_remote_node(void *pampd)
87 {
88 unsigned long fake_pampd = (unsigned long)pampd;
89 return (fake_pampd >> FAKE_PAMPD_REMOTENODE_SHIFT) &
90 FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTENODE_BITS);
91 }
92
pampd_remote_size(void * pampd)93 static inline unsigned int pampd_remote_size(void *pampd)
94 {
95 unsigned long fake_pampd = (unsigned long)pampd;
96 return (fake_pampd >> FAKE_PAMPD_REMOTESIZE_SHIFT) &
97 FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTESIZE_BITS);
98 }
99
pampd_remote_cksum(void * pampd)100 static inline unsigned char pampd_remote_cksum(void *pampd)
101 {
102 unsigned long fake_pampd = (unsigned long)pampd;
103 return (fake_pampd >> FAKE_PAMPD_CHECKSUM_SHIFT) &
104 FAKE_PAMPD_MASK(FAKE_PAMPD_CHECKSUM_BITS);
105 }
106
pampd_is_remote(void * pampd)107 static inline bool pampd_is_remote(void *pampd)
108 {
109 unsigned long fake_pampd = (unsigned long)pampd;
110 return (fake_pampd >> FAKE_PAMPD_ISREMOTE_SHIFT) &
111 FAKE_PAMPD_MASK(FAKE_PAMPD_ISREMOTE_BITS);
112 }
113
pampd_is_intransit(void * pampd)114 static inline bool pampd_is_intransit(void *pampd)
115 {
116 unsigned long fake_pampd = (unsigned long)pampd;
117 return (fake_pampd >> FAKE_PAMPD_INTRANSIT_SHIFT) &
118 FAKE_PAMPD_MASK(FAKE_PAMPD_INTRANSIT_BITS);
119 }
120
121 /* note that it is a BUG for intransit to be set without isremote also set */
pampd_mark_intransit(void * pampd)122 static inline void *pampd_mark_intransit(void *pampd)
123 {
124 unsigned long fake_pampd = (unsigned long)pampd;
125
126 fake_pampd |= 1UL << FAKE_PAMPD_ISREMOTE_SHIFT;
127 fake_pampd |= 1UL << FAKE_PAMPD_INTRANSIT_SHIFT;
128 return (void *)fake_pampd;
129 }
130
pampd_mask_intransit_and_remote(void * marked_pampd)131 static inline void *pampd_mask_intransit_and_remote(void *marked_pampd)
132 {
133 unsigned long pampd = (unsigned long)marked_pampd;
134
135 pampd &= ~(1UL << FAKE_PAMPD_INTRANSIT_SHIFT);
136 pampd &= ~(1UL << FAKE_PAMPD_ISREMOTE_SHIFT);
137 return (void *)pampd;
138 }
139
140 extern int r2net_remote_async_get(struct tmem_xhandle *,
141 bool, int, size_t, uint8_t, void *extra);
142 extern int r2net_remote_put(struct tmem_xhandle *, char *, size_t,
143 bool, int *);
144 extern int r2net_remote_flush(struct tmem_xhandle *, int);
145 extern int r2net_remote_flush_object(struct tmem_xhandle *, int);
146 extern int r2net_register_handlers(void);
147 extern int r2net_remote_target_node_set(int);
148
149 extern int ramster_remotify_pageframe(bool);
150 extern void ramster_init(bool, bool, bool, bool);
151 extern void ramster_register_pamops(struct tmem_pamops *);
152 extern int ramster_localify(int, struct tmem_oid *oidp, uint32_t, char *,
153 unsigned int, void *);
154 extern void *ramster_pampd_free(void *, struct tmem_pool *, struct tmem_oid *,
155 uint32_t, bool);
156 extern void ramster_count_foreign_pages(bool, int);
157 extern int ramster_do_preload_flnode(struct tmem_pool *);
158 extern void ramster_cpu_up(int);
159 extern void ramster_cpu_down(int);
160
161 #endif /* _RAMSTER_RAMSTER_H */
162