diff for duplicates of <20111222155212.GA21486@ca-server1.us.oracle.com> diff --git a/a/1.txt b/N1/1.txt index 8b13789..cb24c64 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -1 +1,600 @@ +>From 3a84584164119d3c08b2857fe45313cbd4df9a00 Mon Sep 17 00:00:00 2001 +From: Dan Magenheimer <dan.magenheimer@oracle.com> +Date: Wed, 21 Dec 2011 14:02:01 -0700 +Subject: [PATCH V2 5/6] drivers/staging/ramster: ramster-specific new files +New files for ramster support: The file ramster.h declares externs +and some pampd bitfield manipulation. The file zcache.h declares +some zcache functions that now must be accessed from the ramster +glue code. The file ramster_o2net.c is the glue between +zcache and the o2net messaging code, providing routines called +from zcache that initiate messages, and routines that handle +messages by calling zcache. + +Signed-off-by: Dan Magenheimer <dan.magenheimer@oracle.com> + +--- + + drivers/staging/ramster/ramster.h | 117 +++++++++ + drivers/staging/ramster/ramster_o2net.c | 419 +++++++++++++++++++++++++++++++ + drivers/staging/ramster/zcache.h | 22 ++ + 3 files changed, 558 insertions(+), 0 deletions(-) + +diff --git a/drivers/staging/ramster/ramster.h b/drivers/staging/ramster/ramster.h +new file mode 100644 +index 0000000..3293512 +--- /dev/null ++++ b/drivers/staging/ramster/ramster.h +@@ -0,0 +1,117 @@ ++/* ++ * ramster.h ++ * ++ * Peer-to-peer transcendent memory ++ * ++ * Copyright (c) 2009-2012, Dan Magenheimer, Oracle Corp. ++ */ ++ ++#ifndef _RAMSTER_H_ ++#define _RAMSTER_H_ ++ ++/* ++ * format of remote pampd: ++ * bit 0 == intransit ++ * bit 1 == is_remote... if this bit is set, then ++ * bit 2-9 == remotenode ++ * bit 10-22 == size ++ * bit 23-30 == 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 0 ++#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 ramster_remote_async_get(struct tmem_xhandle *, ++ bool, int, size_t, uint8_t, void *extra); ++extern int ramster_remote_put(struct tmem_xhandle *, char *, size_t, ++ bool, int *); ++extern int ramster_remote_flush(struct tmem_xhandle *, int); ++extern int ramster_remote_flush_object(struct tmem_xhandle *, int); ++extern int ramster_o2net_register_handlers(void); ++ ++#endif /* _TMEM_H */ +diff --git a/drivers/staging/ramster/ramster_o2net.c b/drivers/staging/ramster/ramster_o2net.c +new file mode 100644 +index 0000000..ee6a9ed +--- /dev/null ++++ b/drivers/staging/ramster/ramster_o2net.c +@@ -0,0 +1,419 @@ ++/* ++ * ramster_o2net.c ++ * ++ * Copyright (c) 2011, Dan Magenheimer, Oracle Corp. ++ * ++ * Ramster_o2net provides an interface between zcache and o2net. ++ * ++ * FIXME: support more than two nodes ++ */ ++ ++#include <linux/list.h> ++#include "cluster/tcp.h" ++#include "cluster/nodemanager.h" ++#include "tmem.h" ++#include "zcache.h" ++#include "ramster.h" ++ ++#define RMSTR_KEY 0x77347734 ++ ++enum { ++ RMSTR_TMEM_PUT_EPH = 100, ++ RMSTR_TMEM_PUT_PERS, ++ RMSTR_TMEM_ASYNC_GET_REQUEST, ++ RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST, ++ RMSTR_TMEM_ASYNC_GET_REPLY, ++ RMSTR_TMEM_FLUSH, ++ RMSTR_TMEM_FLOBJ, ++ RMSTR_TMEM_DESTROY_POOL, ++}; ++ ++#define RMSTR_O2NET_MAX_LEN \ ++ (O2NET_MAX_PAYLOAD_BYTES - sizeof(struct tmem_xhandle)) ++ ++#include "cluster/tcp_internal.h" ++ ++static struct o2nm_node *ramster_choose_node(int *nodenum, ++ struct tmem_xhandle *xh) ++{ ++ struct o2nm_node *node = NULL; ++ int i; ++ ++/* FIXME reproducibly pick a node based on xh that is NOT this node */ ++ i = o2nm_this_node(); ++ i = !i; /* FIXME ONLY FOR TWO NODES */ ++ node = o2nm_get_node_by_num(i); ++ /* WARNING: THIS DOES NOT CHECK TO ENSURE CONNECTED */ ++ if (node != NULL) ++ *nodenum = i; ++ return node; ++} ++ ++static void ramster_put_node(struct o2nm_node *node) ++{ ++ o2nm_node_put(node); ++} ++ ++/* FIXME following buffer should be per-cpu, protected by preempt_disable */ ++static char ramster_async_get_buf[O2NET_MAX_PAYLOAD_BYTES]; ++ ++static int ramster_remote_async_get_request_handler(struct o2net_msg *msg, ++ u32 len, void *data, void **ret_data) ++{ ++ char *pdata; ++ struct tmem_xhandle xh; ++ int found; ++ size_t size = RMSTR_O2NET_MAX_LEN; ++ u16 msgtype = be16_to_cpu(msg->msg_type); ++ bool get_and_free = (msgtype == RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST); ++ unsigned long flags; ++ ++ xh = *(struct tmem_xhandle *)msg->buf; ++ if (xh.xh_data_size > RMSTR_O2NET_MAX_LEN) ++ BUG(); ++ pdata = ramster_async_get_buf; ++ *(struct tmem_xhandle *)pdata = xh; ++ pdata += sizeof(struct tmem_xhandle); ++ local_irq_save(flags); ++ found = zcache_get(xh.client_id, xh.pool_id, &xh.oid, xh.index, ++ pdata, &size, 1, get_and_free ? 1 : -1); ++ local_irq_restore(flags); ++ if (found < 0) { ++#if 0 ++static unsigned long cnt; ++cnt++; ++if (!(cnt&(cnt-1))) ++pr_err("TESTING ArrgREQ zcache_get %s failed, assuming is this OK? cnt=%lu\n", ++ (get_and_free) ? "eph" : "pers", cnt); ++#endif ++ /* a zero size indicates the get failed */ ++ size = 0; ++ } ++ if (size > RMSTR_O2NET_MAX_LEN) ++ BUG(); ++#if 0 ++if (size != 0) { ++/* DOH! RMSTR_O2NET_MAX_LEN==4032... means zcache_get is returning failure ++ which means maybe a race with a flush? */ ++unsigned char cksum; ++int i; ++char *tmp; ++for (tmp = pdata, cksum = 0, i = 0; i < size; i++) ++ cksum += *tmp; ++if ((xh.xh_data_size != size) || (xh.xh_data_cksum != cksum)) ++pr_err("TESTING ArrgREQ, HUH xh_data_size=%d, exp=%d, cksum=%d, exp=%d," ++ "xh=(%d,0x%llx.0x%llx.0x%llx,%x), %s\n", ++ (int)xh.xh_data_size, (int)size, xh.xh_data_cksum, cksum, ++ xh.pool_id, xh.oid.oid[0], xh.oid.oid[1], xh.oid.oid[2], ++ xh.index, (get_and_free ? "eph" : "pers")); ++else { ++#if 0 ++static unsigned long cnt; ++cnt++; ++if (!(cnt&(cnt-1))) ++pr_err("TESTING ArrgREQ cnt=%lu, xh_data_size=%d, exp=%d, cksum=%d, exp=%d\n", ++ cnt, (int)xh.xh_data_size, (int)size, xh.xh_data_cksum, cksum); ++#endif ++} ++} ++#endif ++ *ret_data = pdata - sizeof(struct tmem_xhandle); ++ /* now make caller (o2net_process_message) handle specially */ ++ o2net_force_data_magic(msg, RMSTR_TMEM_ASYNC_GET_REPLY, RMSTR_KEY); ++ return size + sizeof(struct tmem_xhandle); ++} ++ ++static int ramster_remote_async_get_reply_handler(struct o2net_msg *msg, ++ u32 len, void *data, void **ret_data) ++{ ++ char *in = (char *)msg->buf; ++ int datalen = len - sizeof(struct o2net_msg); ++ int ret = -1; ++ struct tmem_xhandle *xh = (struct tmem_xhandle *)in; ++ ++ in += sizeof(struct tmem_xhandle); ++ datalen -= sizeof(struct tmem_xhandle); ++ BUG_ON(datalen < 0 || datalen > PAGE_SIZE); ++ ret = zcache_localify(xh->pool_id, &xh->oid, xh->index, ++ in, datalen, xh->extra); ++#if 1 ++if (ret == -EEXIST) ++pr_err("TESTING ArrgREP, aborted overwrite on racy put\n"); ++#endif ++ return ret; ++} ++ ++int ramster_remote_put_handler(struct o2net_msg *msg, ++ u32 len, void *data, void **ret_data) ++{ ++ struct tmem_xhandle *xh; ++ char *p = (char *)msg->buf; ++ int datalen = len - sizeof(struct o2net_msg) - ++ sizeof(struct tmem_xhandle); ++ u16 msgtype = be16_to_cpu(msg->msg_type); ++ bool ephemeral = (msgtype == RMSTR_TMEM_PUT_EPH); ++ unsigned long flags; ++ int ret; ++ ++ xh = (struct tmem_xhandle *)p; ++ p += sizeof(struct tmem_xhandle); ++ zcache_autocreate_pool(xh->client_id, xh->pool_id, ephemeral); ++ local_irq_save(flags); ++ ret = zcache_put(xh->client_id, xh->pool_id, &xh->oid, xh->index, ++ p, datalen, 1, ephemeral ? 1 : -1); ++ local_irq_restore(flags); ++ return ret; ++} ++ ++int ramster_remote_flush_handler(struct o2net_msg *msg, ++ u32 len, void *data, void **ret_data) ++{ ++ struct tmem_xhandle *xh; ++ char *p = (char *)msg->buf; ++ ++ xh = (struct tmem_xhandle *)p; ++ p += sizeof(struct tmem_xhandle); ++ (void)zcache_flush(xh->client_id, xh->pool_id, &xh->oid, xh->index); ++ return 0; ++} ++ ++int ramster_remote_flobj_handler(struct o2net_msg *msg, ++ u32 len, void *data, void **ret_data) ++{ ++ struct tmem_xhandle *xh; ++ char *p = (char *)msg->buf; ++ ++ xh = (struct tmem_xhandle *)p; ++ p += sizeof(struct tmem_xhandle); ++ (void)zcache_flush_object(xh->client_id, xh->pool_id, &xh->oid); ++ return 0; ++} ++ ++int ramster_remote_async_get(struct tmem_xhandle *xh, bool free, int remotenode, ++ size_t expect_size, uint8_t expect_cksum, ++ void *extra) ++{ ++ int ret = -1, status; ++ struct o2nm_node *node = NULL; ++ struct kvec vec[1]; ++ size_t veclen = 1; ++ u32 msg_type; ++ ++ node = o2nm_get_node_by_num(remotenode); ++ if (node == NULL) ++ goto out; ++ xh->client_id = o2nm_this_node(); /* which node is getting */ ++ xh->xh_data_cksum = expect_cksum; ++ xh->xh_data_size = expect_size; ++ xh->extra = extra; ++ vec[0].iov_len = sizeof(*xh); ++ vec[0].iov_base = xh; ++ if (free) ++ msg_type = RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST; ++ else ++ msg_type = RMSTR_TMEM_ASYNC_GET_REQUEST; ++ ret = o2net_send_message_vec(msg_type, RMSTR_KEY, ++ vec, veclen, remotenode, &status); ++ ramster_put_node(node); ++ if (ret < 0) { ++ /* FIXME handle bad message possibilities here? */ ++ pr_err("UNTESTED ret<0 in ramster_remote_async_get\n"); ++ } ++ ret = status; ++out: ++ return ret; ++} ++ ++int ramster_remote_put(struct tmem_xhandle *xh, char *data, size_t size, ++ bool ephemeral, int *remotenode) ++{ ++ int nodenum, ret = -1, status; ++ struct o2nm_node *node = NULL; ++ struct kvec vec[2]; ++ size_t veclen = 2; ++ u32 msg_type; ++ ++ BUG_ON(size > RMSTR_O2NET_MAX_LEN); ++ xh->client_id = o2nm_this_node(); /* which node is putting */ ++ vec[0].iov_len = sizeof(*xh); ++ vec[0].iov_base = xh; ++ vec[1].iov_len = size; ++ vec[1].iov_base = data; ++ node = ramster_choose_node(&nodenum, xh); ++ if (!node) ++ goto out; ++ ++#if 1 ++{ ++ extern struct o2net_node *o2net_nn_from_num(u8); ++ struct o2net_node *nn = o2net_nn_from_num(nodenum); ++ WARN_ON_ONCE(nn->nn_persistent_error || !nn->nn_sc_valid); ++} ++#endif ++ ++ if (ephemeral) ++ msg_type = RMSTR_TMEM_PUT_EPH; ++ else ++ msg_type = RMSTR_TMEM_PUT_PERS; ++#if 1 ++/* leave me here to see if it catches a weird crash I've seen a couple times */ ++{ ++static int last_hardirq_cnt, last_softirq_cnt, last_preempt_cnt; ++int cur_hardirq_cnt, cur_softirq_cnt, cur_preempt_cnt; ++cur_hardirq_cnt = hardirq_count() >> HARDIRQ_SHIFT; ++if (cur_hardirq_cnt > last_hardirq_cnt) { ++ last_hardirq_cnt = cur_hardirq_cnt; ++ if (!(last_hardirq_cnt&(last_hardirq_cnt-1))) ++ pr_err("TESTING RRP hardirq_count=%d\n", last_hardirq_cnt); ++} ++cur_softirq_cnt = softirq_count() >> SOFTIRQ_SHIFT; ++if (cur_softirq_cnt > last_softirq_cnt) { ++ last_softirq_cnt = cur_softirq_cnt; ++ if (!(last_softirq_cnt&(last_softirq_cnt-1))) ++ pr_err("TESTING RRP softirq_count=%d\n", last_softirq_cnt); ++} ++cur_preempt_cnt = preempt_count() & PREEMPT_MASK; ++if (cur_preempt_cnt > last_preempt_cnt) { ++ last_preempt_cnt = cur_preempt_cnt; ++ if (!(last_preempt_cnt&(last_preempt_cnt-1))) ++ pr_err("TESTING RRP preempt_count=%d\n", last_preempt_cnt); ++} ++} ++#endif ++ ++ ret = o2net_send_message_vec(msg_type, RMSTR_KEY, ++ vec, veclen, nodenum, &status); ++#if 1 ++ if (ret != 0) { ++ pr_err("UNTESTED case in ramster_remote_put\n"); ++ ret = -1; ++ } ++#endif ++ if (ret < 0) ++ ret = -1; ++ else { ++ ret = status; ++ *remotenode = nodenum; ++ } ++ ++ ramster_put_node(node); ++out: ++ return ret; ++} ++ ++int ramster_remote_flush(struct tmem_xhandle *xh, int remotenode) ++{ ++ int ret = -1, status; ++ struct o2nm_node *node = NULL; ++ struct kvec vec[1]; ++ size_t veclen = 1; ++ ++ node = o2nm_get_node_by_num(remotenode); ++ BUG_ON(node == NULL); ++ xh->client_id = o2nm_this_node(); /* which node is flushing */ ++ vec[0].iov_len = sizeof(*xh); ++ vec[0].iov_base = xh; ++ BUG_ON(irqs_disabled()); ++ BUG_ON(in_softirq()); ++ ret = o2net_send_message_vec(RMSTR_TMEM_FLUSH, RMSTR_KEY, ++ vec, veclen, remotenode, &status); ++ ramster_put_node(node); ++ return ret; ++} ++ ++int ramster_remote_flush_object(struct tmem_xhandle *xh, int remotenode) ++{ ++ int ret = -1, status; ++ struct o2nm_node *node = NULL; ++ struct kvec vec[1]; ++ size_t veclen = 1; ++ ++ node = o2nm_get_node_by_num(remotenode); ++ BUG_ON(node == NULL); ++ xh->client_id = o2nm_this_node(); /* which node is flobjing */ ++ vec[0].iov_len = sizeof(*xh); ++ vec[0].iov_base = xh; ++ ret = o2net_send_message_vec(RMSTR_TMEM_FLOBJ, RMSTR_KEY, ++ vec, veclen, remotenode, &status); ++ ramster_put_node(node); ++ return ret; ++} ++ ++/* ++ * Handler registration ++ */ ++ ++static LIST_HEAD(ramster_o2net_unreg_list); ++ ++static void ramster_o2net_unregister_handlers(void) ++{ ++ o2net_unregister_handler_list(&ramster_o2net_unreg_list); ++} ++ ++int ramster_o2net_register_handlers(void) ++{ ++ int status; ++ ++ status = o2net_register_handler(RMSTR_TMEM_PUT_EPH, RMSTR_KEY, ++ RMSTR_O2NET_MAX_LEN, ++ ramster_remote_put_handler, ++ NULL, NULL, &ramster_o2net_unreg_list); ++ if (status) ++ goto bail; ++ ++ status = o2net_register_handler(RMSTR_TMEM_PUT_PERS, RMSTR_KEY, ++ RMSTR_O2NET_MAX_LEN, ++ ramster_remote_put_handler, ++ NULL, NULL, &ramster_o2net_unreg_list); ++ if (status) ++ goto bail; ++ ++ status = o2net_register_handler(RMSTR_TMEM_ASYNC_GET_REQUEST, RMSTR_KEY, ++ RMSTR_O2NET_MAX_LEN, ++ ramster_remote_async_get_request_handler, ++ NULL, NULL, ++ &ramster_o2net_unreg_list); ++ if (status) ++ goto bail; ++ ++ status = o2net_register_handler(RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST, ++ RMSTR_KEY, RMSTR_O2NET_MAX_LEN, ++ ramster_remote_async_get_request_handler, ++ NULL, NULL, ++ &ramster_o2net_unreg_list); ++ if (status) ++ goto bail; ++ ++ status = o2net_register_handler(RMSTR_TMEM_ASYNC_GET_REPLY, RMSTR_KEY, ++ RMSTR_O2NET_MAX_LEN, ++ ramster_remote_async_get_reply_handler, ++ NULL, NULL, ++ &ramster_o2net_unreg_list); ++ if (status) ++ goto bail; ++ ++ status = o2net_register_handler(RMSTR_TMEM_FLUSH, RMSTR_KEY, ++ RMSTR_O2NET_MAX_LEN, ++ ramster_remote_flush_handler, ++ NULL, NULL, ++ &ramster_o2net_unreg_list); ++ if (status) ++ goto bail; ++ ++ status = o2net_register_handler(RMSTR_TMEM_FLOBJ, RMSTR_KEY, ++ RMSTR_O2NET_MAX_LEN, ++ ramster_remote_flobj_handler, ++ NULL, NULL, ++ &ramster_o2net_unreg_list); ++ if (status) ++ goto bail; ++ ++ pr_info("ramster_o2net: handlers registered\n"); ++ ++bail: ++ if (status) { ++ ramster_o2net_unregister_handlers(); ++ pr_err("ramster_o2net: couldn't register handlers\n"); ++ } ++ return status; ++} +diff --git a/drivers/staging/ramster/zcache.h b/drivers/staging/ramster/zcache.h +new file mode 100644 +index 0000000..250b121 +--- /dev/null ++++ b/drivers/staging/ramster/zcache.h +@@ -0,0 +1,22 @@ ++/* ++ * zcache.h ++ * ++ * External zcache functions ++ * ++ * Copyright (c) 2009-2012, Dan Magenheimer, Oracle Corp. ++ */ ++ ++#ifndef _ZCACHE_H_ ++#define _ZCACHE_H_ ++ ++extern int zcache_put(int, int, struct tmem_oid *, uint32_t, ++ char *, size_t, bool, int); ++extern int zcache_autocreate_pool(int, int, bool); ++extern int zcache_get(int, int, struct tmem_oid *, uint32_t, ++ char *, size_t *, bool, int); ++extern int zcache_flush(int, int, struct tmem_oid *, uint32_t); ++extern int zcache_flush_object(int, int, struct tmem_oid *); ++extern int zcache_localify(int, struct tmem_oid *, uint32_t, ++ char *, size_t, void *); ++ ++#endif /* _ZCACHE_H */ +-- +1.7.1 diff --git a/a/content_digest b/N1/content_digest index 2640ad1..ce3f21b 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -13,5 +13,605 @@ " dan.magenheimer@oracle.com\0" "\00:1\0" "b\0" + ">From 3a84584164119d3c08b2857fe45313cbd4df9a00 Mon Sep 17 00:00:00 2001\n" + "From: Dan Magenheimer <dan.magenheimer@oracle.com>\n" + "Date: Wed, 21 Dec 2011 14:02:01 -0700\n" + "Subject: [PATCH V2 5/6] drivers/staging/ramster: ramster-specific new files\n" + "\n" + "New files for ramster support: The file ramster.h declares externs\n" + "and some pampd bitfield manipulation. The file zcache.h declares\n" + "some zcache functions that now must be accessed from the ramster\n" + "glue code. The file ramster_o2net.c is the glue between\n" + "zcache and the o2net messaging code, providing routines called\n" + "from zcache that initiate messages, and routines that handle\n" + "messages by calling zcache.\n" + "\n" + "Signed-off-by: Dan Magenheimer <dan.magenheimer@oracle.com>\n" + "\n" + "---\n" + "\n" + " drivers/staging/ramster/ramster.h | 117 +++++++++\n" + " drivers/staging/ramster/ramster_o2net.c | 419 +++++++++++++++++++++++++++++++\n" + " drivers/staging/ramster/zcache.h | 22 ++\n" + " 3 files changed, 558 insertions(+), 0 deletions(-)\n" + "\n" + "diff --git a/drivers/staging/ramster/ramster.h b/drivers/staging/ramster/ramster.h\n" + "new file mode 100644\n" + "index 0000000..3293512\n" + "--- /dev/null\n" + "+++ b/drivers/staging/ramster/ramster.h\n" + "@@ -0,0 +1,117 @@\n" + "+/*\n" + "+ * ramster.h\n" + "+ *\n" + "+ * Peer-to-peer transcendent memory\n" + "+ *\n" + "+ * Copyright (c) 2009-2012, Dan Magenheimer, Oracle Corp.\n" + "+ */\n" + "+\n" + "+#ifndef _RAMSTER_H_\n" + "+#define _RAMSTER_H_\n" + "+\n" + "+/*\n" + "+ * format of remote pampd:\n" + "+ * bit 0 == intransit\n" + "+ * bit 1 == is_remote... if this bit is set, then\n" + "+ * bit 2-9 == remotenode\n" + "+ * bit 10-22 == size\n" + "+ * bit 23-30 == cksum\n" + "+ */\n" + "+#define FAKE_PAMPD_INTRANSIT_BITS\t1\n" + "+#define FAKE_PAMPD_ISREMOTE_BITS\t1\n" + "+#define FAKE_PAMPD_REMOTENODE_BITS\t8\n" + "+#define FAKE_PAMPD_REMOTESIZE_BITS\t13\n" + "+#define FAKE_PAMPD_CHECKSUM_BITS\t8\n" + "+\n" + "+#define FAKE_PAMPD_INTRANSIT_SHIFT\t0\n" + "+#define FAKE_PAMPD_ISREMOTE_SHIFT\t(FAKE_PAMPD_INTRANSIT_SHIFT + \\\n" + "+\t\t\t\t\t FAKE_PAMPD_INTRANSIT_BITS)\n" + "+#define FAKE_PAMPD_REMOTENODE_SHIFT\t(FAKE_PAMPD_ISREMOTE_SHIFT + \\\n" + "+\t\t\t\t\t FAKE_PAMPD_ISREMOTE_BITS)\n" + "+#define FAKE_PAMPD_REMOTESIZE_SHIFT\t(FAKE_PAMPD_REMOTENODE_SHIFT + \\\n" + "+\t\t\t\t\t FAKE_PAMPD_REMOTENODE_BITS)\n" + "+#define FAKE_PAMPD_CHECKSUM_SHIFT\t(FAKE_PAMPD_REMOTESIZE_SHIFT + \\\n" + "+\t\t\t\t\t FAKE_PAMPD_REMOTESIZE_BITS)\n" + "+\n" + "+#define FAKE_PAMPD_MASK(x)\t\t((1UL << (x)) - 1)\n" + "+\n" + "+static inline void *pampd_make_remote(int remotenode, size_t size,\n" + "+\t\t\t\t\tunsigned char cksum)\n" + "+{\n" + "+\tunsigned long fake_pampd = 0;\n" + "+\tfake_pampd |= 1UL << FAKE_PAMPD_ISREMOTE_SHIFT;\n" + "+\tfake_pampd |= ((unsigned long)remotenode &\n" + "+\t\t\tFAKE_PAMPD_MASK(FAKE_PAMPD_REMOTENODE_BITS)) <<\n" + "+\t\t\t\tFAKE_PAMPD_REMOTENODE_SHIFT;\n" + "+\tfake_pampd |= ((unsigned long)size &\n" + "+\t\t\tFAKE_PAMPD_MASK(FAKE_PAMPD_REMOTESIZE_BITS)) <<\n" + "+\t\t\t\tFAKE_PAMPD_REMOTESIZE_SHIFT;\n" + "+\tfake_pampd |= ((unsigned long)cksum &\n" + "+\t\t\tFAKE_PAMPD_MASK(FAKE_PAMPD_CHECKSUM_BITS)) <<\n" + "+\t\t\t\tFAKE_PAMPD_CHECKSUM_SHIFT;\n" + "+\treturn (void *)fake_pampd;\n" + "+}\n" + "+\n" + "+static inline unsigned int pampd_remote_node(void *pampd)\n" + "+{\n" + "+\tunsigned long fake_pampd = (unsigned long)pampd;\n" + "+\treturn (fake_pampd >> FAKE_PAMPD_REMOTENODE_SHIFT) &\n" + "+\t\tFAKE_PAMPD_MASK(FAKE_PAMPD_REMOTENODE_BITS);\n" + "+}\n" + "+\n" + "+static inline unsigned int pampd_remote_size(void *pampd)\n" + "+{\n" + "+\tunsigned long fake_pampd = (unsigned long)pampd;\n" + "+\treturn (fake_pampd >> FAKE_PAMPD_REMOTESIZE_SHIFT) &\n" + "+\t\tFAKE_PAMPD_MASK(FAKE_PAMPD_REMOTESIZE_BITS);\n" + "+}\n" + "+\n" + "+static inline unsigned char pampd_remote_cksum(void *pampd)\n" + "+{\n" + "+\tunsigned long fake_pampd = (unsigned long)pampd;\n" + "+\treturn (fake_pampd >> FAKE_PAMPD_CHECKSUM_SHIFT) &\n" + "+\t\tFAKE_PAMPD_MASK(FAKE_PAMPD_CHECKSUM_BITS);\n" + "+}\n" + "+\n" + "+static inline bool pampd_is_remote(void *pampd)\n" + "+{\n" + "+\tunsigned long fake_pampd = (unsigned long)pampd;\n" + "+\treturn (fake_pampd >> FAKE_PAMPD_ISREMOTE_SHIFT) &\n" + "+\t\tFAKE_PAMPD_MASK(FAKE_PAMPD_ISREMOTE_BITS);\n" + "+}\n" + "+\n" + "+static inline bool pampd_is_intransit(void *pampd)\n" + "+{\n" + "+\tunsigned long fake_pampd = (unsigned long)pampd;\n" + "+\treturn (fake_pampd >> FAKE_PAMPD_INTRANSIT_SHIFT) &\n" + "+\t\tFAKE_PAMPD_MASK(FAKE_PAMPD_INTRANSIT_BITS);\n" + "+}\n" + "+\n" + "+/* note that it is a BUG for intransit to be set without isremote also set */\n" + "+static inline void *pampd_mark_intransit(void *pampd)\n" + "+{\n" + "+\tunsigned long fake_pampd = (unsigned long)pampd;\n" + "+\n" + "+\tfake_pampd |= 1UL << FAKE_PAMPD_ISREMOTE_SHIFT;\n" + "+\tfake_pampd |= 1UL << FAKE_PAMPD_INTRANSIT_SHIFT;\n" + "+\treturn (void *)fake_pampd;\n" + "+}\n" + "+\n" + "+static inline void *pampd_mask_intransit_and_remote(void *marked_pampd)\n" + "+{\n" + "+\tunsigned long pampd = (unsigned long)marked_pampd;\n" + "+\n" + "+\tpampd &= ~(1UL << FAKE_PAMPD_INTRANSIT_SHIFT);\n" + "+\tpampd &= ~(1UL << FAKE_PAMPD_ISREMOTE_SHIFT);\n" + "+\treturn (void *)pampd;\n" + "+}\n" + "+\n" + "+extern int ramster_remote_async_get(struct tmem_xhandle *,\n" + "+\t\t\t\tbool, int, size_t, uint8_t, void *extra);\n" + "+extern int ramster_remote_put(struct tmem_xhandle *, char *, size_t,\n" + "+\t\t\t\tbool, int *);\n" + "+extern int ramster_remote_flush(struct tmem_xhandle *, int);\n" + "+extern int ramster_remote_flush_object(struct tmem_xhandle *, int);\n" + "+extern int ramster_o2net_register_handlers(void);\n" + "+\n" + "+#endif /* _TMEM_H */\n" + "diff --git a/drivers/staging/ramster/ramster_o2net.c b/drivers/staging/ramster/ramster_o2net.c\n" + "new file mode 100644\n" + "index 0000000..ee6a9ed\n" + "--- /dev/null\n" + "+++ b/drivers/staging/ramster/ramster_o2net.c\n" + "@@ -0,0 +1,419 @@\n" + "+/*\n" + "+ * ramster_o2net.c\n" + "+ *\n" + "+ * Copyright (c) 2011, Dan Magenheimer, Oracle Corp.\n" + "+ *\n" + "+ * Ramster_o2net provides an interface between zcache and o2net.\n" + "+ *\n" + "+ * FIXME: support more than two nodes\n" + "+ */\n" + "+\n" + "+#include <linux/list.h>\n" + "+#include \"cluster/tcp.h\"\n" + "+#include \"cluster/nodemanager.h\"\n" + "+#include \"tmem.h\"\n" + "+#include \"zcache.h\"\n" + "+#include \"ramster.h\"\n" + "+\n" + "+#define RMSTR_KEY\t0x77347734\n" + "+\n" + "+enum {\n" + "+\tRMSTR_TMEM_PUT_EPH = 100,\n" + "+\tRMSTR_TMEM_PUT_PERS,\n" + "+\tRMSTR_TMEM_ASYNC_GET_REQUEST,\n" + "+\tRMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST,\n" + "+\tRMSTR_TMEM_ASYNC_GET_REPLY,\n" + "+\tRMSTR_TMEM_FLUSH,\n" + "+\tRMSTR_TMEM_FLOBJ,\n" + "+\tRMSTR_TMEM_DESTROY_POOL,\n" + "+};\n" + "+\n" + "+#define RMSTR_O2NET_MAX_LEN \\\n" + "+\t\t(O2NET_MAX_PAYLOAD_BYTES - sizeof(struct tmem_xhandle))\n" + "+\n" + "+#include \"cluster/tcp_internal.h\"\n" + "+\n" + "+static struct o2nm_node *ramster_choose_node(int *nodenum,\n" + "+\t\t\t\t\t\tstruct tmem_xhandle *xh)\n" + "+{\n" + "+\tstruct o2nm_node *node = NULL;\n" + "+\tint i;\n" + "+\n" + "+/* FIXME reproducibly pick a node based on xh that is NOT this node */\n" + "+\ti = o2nm_this_node();\n" + "+\ti = !i;\t\t/* FIXME ONLY FOR TWO NODES */\n" + "+\tnode = o2nm_get_node_by_num(i);\n" + "+\t\t/* WARNING: THIS DOES NOT CHECK TO ENSURE CONNECTED */\n" + "+\tif (node != NULL)\n" + "+\t\t*nodenum = i;\n" + "+\treturn node;\n" + "+}\n" + "+\n" + "+static void ramster_put_node(struct o2nm_node *node)\n" + "+{\n" + "+\to2nm_node_put(node);\n" + "+}\n" + "+\n" + "+/* FIXME following buffer should be per-cpu, protected by preempt_disable */\n" + "+static char ramster_async_get_buf[O2NET_MAX_PAYLOAD_BYTES];\n" + "+\n" + "+static int ramster_remote_async_get_request_handler(struct o2net_msg *msg,\n" + "+\t\t\t\tu32 len, void *data, void **ret_data)\n" + "+{\n" + "+\tchar *pdata;\n" + "+\tstruct tmem_xhandle xh;\n" + "+\tint found;\n" + "+\tsize_t size = RMSTR_O2NET_MAX_LEN;\n" + "+\tu16 msgtype = be16_to_cpu(msg->msg_type);\n" + "+\tbool get_and_free = (msgtype == RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST);\n" + "+\tunsigned long flags;\n" + "+\n" + "+\txh = *(struct tmem_xhandle *)msg->buf;\n" + "+\tif (xh.xh_data_size > RMSTR_O2NET_MAX_LEN)\n" + "+\t\tBUG();\n" + "+\tpdata = ramster_async_get_buf;\n" + "+\t*(struct tmem_xhandle *)pdata = xh;\n" + "+\tpdata += sizeof(struct tmem_xhandle);\n" + "+\tlocal_irq_save(flags);\n" + "+\tfound = zcache_get(xh.client_id, xh.pool_id, &xh.oid, xh.index,\n" + "+\t\t\t\tpdata, &size, 1, get_and_free ? 1 : -1);\n" + "+\tlocal_irq_restore(flags);\n" + "+\tif (found < 0) {\n" + "+#if 0\n" + "+static unsigned long cnt;\n" + "+cnt++;\n" + "+if (!(cnt&(cnt-1)))\n" + "+pr_err(\"TESTING ArrgREQ zcache_get %s failed, assuming is this OK? cnt=%lu\\n\",\n" + "+\t(get_and_free) ? \"eph\" : \"pers\", cnt);\n" + "+#endif\n" + "+\t\t/* a zero size indicates the get failed */\n" + "+\t\tsize = 0;\n" + "+\t}\n" + "+\tif (size > RMSTR_O2NET_MAX_LEN)\n" + "+\t\tBUG();\n" + "+#if 0\n" + "+if (size != 0) {\n" + "+/* DOH! RMSTR_O2NET_MAX_LEN==4032... means zcache_get is returning failure\n" + "+ which means maybe a race with a flush? */\n" + "+unsigned char cksum;\n" + "+int i;\n" + "+char *tmp;\n" + "+for (tmp = pdata, cksum = 0, i = 0; i < size; i++)\n" + "+\tcksum += *tmp;\n" + "+if ((xh.xh_data_size != size) || (xh.xh_data_cksum != cksum))\n" + "+pr_err(\"TESTING ArrgREQ, HUH xh_data_size=%d, exp=%d, cksum=%d, exp=%d,\"\n" + "+\t\"xh=(%d,0x%llx.0x%llx.0x%llx,%x), %s\\n\",\n" + "+\t(int)xh.xh_data_size, (int)size, xh.xh_data_cksum, cksum,\n" + "+\txh.pool_id, xh.oid.oid[0], xh.oid.oid[1], xh.oid.oid[2],\n" + "+\txh.index, (get_and_free ? \"eph\" : \"pers\"));\n" + "+else {\n" + "+#if 0\n" + "+static unsigned long cnt;\n" + "+cnt++;\n" + "+if (!(cnt&(cnt-1)))\n" + "+pr_err(\"TESTING ArrgREQ cnt=%lu, xh_data_size=%d, exp=%d, cksum=%d, exp=%d\\n\",\n" + "+\tcnt, (int)xh.xh_data_size, (int)size, xh.xh_data_cksum, cksum);\n" + "+#endif\n" + "+}\n" + "+}\n" + "+#endif\n" + "+\t*ret_data = pdata - sizeof(struct tmem_xhandle);\n" + "+\t/* now make caller (o2net_process_message) handle specially */\n" + "+\to2net_force_data_magic(msg, RMSTR_TMEM_ASYNC_GET_REPLY, RMSTR_KEY);\n" + "+\treturn size + sizeof(struct tmem_xhandle);\n" + "+}\n" + "+\n" + "+static int ramster_remote_async_get_reply_handler(struct o2net_msg *msg,\n" + "+\t\t\t\tu32 len, void *data, void **ret_data)\n" + "+{\n" + "+\tchar *in = (char *)msg->buf;\n" + "+\tint datalen = len - sizeof(struct o2net_msg);\n" + "+\tint ret = -1;\n" + "+\tstruct tmem_xhandle *xh = (struct tmem_xhandle *)in;\n" + "+\n" + "+\tin += sizeof(struct tmem_xhandle);\n" + "+\tdatalen -= sizeof(struct tmem_xhandle);\n" + "+\tBUG_ON(datalen < 0 || datalen > PAGE_SIZE);\n" + "+\tret = zcache_localify(xh->pool_id, &xh->oid, xh->index,\n" + "+\t\t\t\tin, datalen, xh->extra);\n" + "+#if 1\n" + "+if (ret == -EEXIST)\n" + "+pr_err(\"TESTING ArrgREP, aborted overwrite on racy put\\n\");\n" + "+#endif\n" + "+\treturn ret;\n" + "+}\n" + "+\n" + "+int ramster_remote_put_handler(struct o2net_msg *msg,\n" + "+\t\t\t\tu32 len, void *data, void **ret_data)\n" + "+{\n" + "+\tstruct tmem_xhandle *xh;\n" + "+\tchar *p = (char *)msg->buf;\n" + "+\tint datalen = len - sizeof(struct o2net_msg) -\n" + "+\t\t\t\tsizeof(struct tmem_xhandle);\n" + "+\tu16 msgtype = be16_to_cpu(msg->msg_type);\n" + "+\tbool ephemeral = (msgtype == RMSTR_TMEM_PUT_EPH);\n" + "+\tunsigned long flags;\n" + "+\tint ret;\n" + "+\n" + "+\txh = (struct tmem_xhandle *)p;\n" + "+\tp += sizeof(struct tmem_xhandle);\n" + "+\tzcache_autocreate_pool(xh->client_id, xh->pool_id, ephemeral);\n" + "+\tlocal_irq_save(flags);\n" + "+\tret = zcache_put(xh->client_id, xh->pool_id, &xh->oid, xh->index,\n" + "+\t\t\t\tp, datalen, 1, ephemeral ? 1 : -1);\n" + "+\tlocal_irq_restore(flags);\n" + "+\treturn ret;\n" + "+}\n" + "+\n" + "+int ramster_remote_flush_handler(struct o2net_msg *msg,\n" + "+\t\t\t\tu32 len, void *data, void **ret_data)\n" + "+{\n" + "+\tstruct tmem_xhandle *xh;\n" + "+\tchar *p = (char *)msg->buf;\n" + "+\n" + "+\txh = (struct tmem_xhandle *)p;\n" + "+\tp += sizeof(struct tmem_xhandle);\n" + "+\t(void)zcache_flush(xh->client_id, xh->pool_id, &xh->oid, xh->index);\n" + "+\treturn 0;\n" + "+}\n" + "+\n" + "+int ramster_remote_flobj_handler(struct o2net_msg *msg,\n" + "+\t\t\t\tu32 len, void *data, void **ret_data)\n" + "+{\n" + "+\tstruct tmem_xhandle *xh;\n" + "+\tchar *p = (char *)msg->buf;\n" + "+\n" + "+\txh = (struct tmem_xhandle *)p;\n" + "+\tp += sizeof(struct tmem_xhandle);\n" + "+\t(void)zcache_flush_object(xh->client_id, xh->pool_id, &xh->oid);\n" + "+\treturn 0;\n" + "+}\n" + "+\n" + "+int ramster_remote_async_get(struct tmem_xhandle *xh, bool free, int remotenode,\n" + "+\t\t\t\tsize_t expect_size, uint8_t expect_cksum,\n" + "+\t\t\t\tvoid *extra)\n" + "+{\n" + "+\tint ret = -1, status;\n" + "+\tstruct o2nm_node *node = NULL;\n" + "+\tstruct kvec vec[1];\n" + "+\tsize_t veclen = 1;\n" + "+\tu32 msg_type;\n" + "+\n" + "+\tnode = o2nm_get_node_by_num(remotenode);\n" + "+\tif (node == NULL)\n" + "+\t\tgoto out;\n" + "+\txh->client_id = o2nm_this_node(); /* which node is getting */\n" + "+\txh->xh_data_cksum = expect_cksum;\n" + "+\txh->xh_data_size = expect_size;\n" + "+\txh->extra = extra;\n" + "+\tvec[0].iov_len = sizeof(*xh);\n" + "+\tvec[0].iov_base = xh;\n" + "+\tif (free)\n" + "+\t\tmsg_type = RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST;\n" + "+\telse\n" + "+\t\tmsg_type = RMSTR_TMEM_ASYNC_GET_REQUEST;\n" + "+\tret = o2net_send_message_vec(msg_type, RMSTR_KEY,\n" + "+\t\t\t\t\tvec, veclen, remotenode, &status);\n" + "+\tramster_put_node(node);\n" + "+\tif (ret < 0) {\n" + "+\t\t/* FIXME handle bad message possibilities here? */\n" + "+\t\tpr_err(\"UNTESTED ret<0 in ramster_remote_async_get\\n\");\n" + "+\t}\n" + "+\tret = status;\n" + "+out:\n" + "+\treturn ret;\n" + "+}\n" + "+\n" + "+int ramster_remote_put(struct tmem_xhandle *xh, char *data, size_t size,\n" + "+\t\t\t\tbool ephemeral, int *remotenode)\n" + "+{\n" + "+\tint nodenum, ret = -1, status;\n" + "+\tstruct o2nm_node *node = NULL;\n" + "+\tstruct kvec vec[2];\n" + "+\tsize_t veclen = 2;\n" + "+\tu32 msg_type;\n" + "+\n" + "+\tBUG_ON(size > RMSTR_O2NET_MAX_LEN);\n" + "+\txh->client_id = o2nm_this_node(); /* which node is putting */\n" + "+\tvec[0].iov_len = sizeof(*xh);\n" + "+\tvec[0].iov_base = xh;\n" + "+\tvec[1].iov_len = size;\n" + "+\tvec[1].iov_base = data;\n" + "+\tnode = ramster_choose_node(&nodenum, xh);\n" + "+\tif (!node)\n" + "+\t\tgoto out;\n" + "+\n" + "+#if 1\n" + "+{\n" + "+\textern struct o2net_node *o2net_nn_from_num(u8);\n" + "+\tstruct o2net_node *nn = o2net_nn_from_num(nodenum);\n" + "+\tWARN_ON_ONCE(nn->nn_persistent_error || !nn->nn_sc_valid);\n" + "+}\n" + "+#endif\n" + "+\n" + "+\tif (ephemeral)\n" + "+\t\tmsg_type = RMSTR_TMEM_PUT_EPH;\n" + "+\telse\n" + "+\t\tmsg_type = RMSTR_TMEM_PUT_PERS;\n" + "+#if 1\n" + "+/* leave me here to see if it catches a weird crash I've seen a couple times */\n" + "+{\n" + "+static int last_hardirq_cnt, last_softirq_cnt, last_preempt_cnt;\n" + "+int cur_hardirq_cnt, cur_softirq_cnt, cur_preempt_cnt;\n" + "+cur_hardirq_cnt = hardirq_count() >> HARDIRQ_SHIFT;\n" + "+if (cur_hardirq_cnt > last_hardirq_cnt) {\n" + "+\tlast_hardirq_cnt = cur_hardirq_cnt;\n" + "+\tif (!(last_hardirq_cnt&(last_hardirq_cnt-1)))\n" + "+\t\tpr_err(\"TESTING RRP hardirq_count=%d\\n\", last_hardirq_cnt);\n" + "+}\n" + "+cur_softirq_cnt = softirq_count() >> SOFTIRQ_SHIFT;\n" + "+if (cur_softirq_cnt > last_softirq_cnt) {\n" + "+\tlast_softirq_cnt = cur_softirq_cnt;\n" + "+\tif (!(last_softirq_cnt&(last_softirq_cnt-1)))\n" + "+\t\tpr_err(\"TESTING RRP softirq_count=%d\\n\", last_softirq_cnt);\n" + "+}\n" + "+cur_preempt_cnt = preempt_count() & PREEMPT_MASK;\n" + "+if (cur_preempt_cnt > last_preempt_cnt) {\n" + "+\tlast_preempt_cnt = cur_preempt_cnt;\n" + "+\tif (!(last_preempt_cnt&(last_preempt_cnt-1)))\n" + "+\t\tpr_err(\"TESTING RRP preempt_count=%d\\n\", last_preempt_cnt);\n" + "+}\n" + "+}\n" + "+#endif\n" + "+\n" + "+\tret = o2net_send_message_vec(msg_type, RMSTR_KEY,\n" + "+\t\t\t\t\t\tvec, veclen, nodenum, &status);\n" + "+#if 1\n" + "+\tif (ret != 0) {\n" + "+\t\tpr_err(\"UNTESTED case in ramster_remote_put\\n\");\n" + "+\t\tret = -1;\n" + "+\t}\n" + "+#endif\n" + "+\tif (ret < 0)\n" + "+\t\tret = -1;\n" + "+\telse {\n" + "+\t\tret = status;\n" + "+\t\t*remotenode = nodenum;\n" + "+\t}\n" + "+\n" + "+\tramster_put_node(node);\n" + "+out:\n" + "+\treturn ret;\n" + "+}\n" + "+\n" + "+int ramster_remote_flush(struct tmem_xhandle *xh, int remotenode)\n" + "+{\n" + "+\tint ret = -1, status;\n" + "+\tstruct o2nm_node *node = NULL;\n" + "+\tstruct kvec vec[1];\n" + "+\tsize_t veclen = 1;\n" + "+\n" + "+\tnode = o2nm_get_node_by_num(remotenode);\n" + "+\tBUG_ON(node == NULL);\n" + "+\txh->client_id = o2nm_this_node(); /* which node is flushing */\n" + "+\tvec[0].iov_len = sizeof(*xh);\n" + "+\tvec[0].iov_base = xh;\n" + "+\tBUG_ON(irqs_disabled());\n" + "+\tBUG_ON(in_softirq());\n" + "+\tret = o2net_send_message_vec(RMSTR_TMEM_FLUSH, RMSTR_KEY,\n" + "+\t\t\t\t\tvec, veclen, remotenode, &status);\n" + "+\tramster_put_node(node);\n" + "+\treturn ret;\n" + "+}\n" + "+\n" + "+int ramster_remote_flush_object(struct tmem_xhandle *xh, int remotenode)\n" + "+{\n" + "+\tint ret = -1, status;\n" + "+\tstruct o2nm_node *node = NULL;\n" + "+\tstruct kvec vec[1];\n" + "+\tsize_t veclen = 1;\n" + "+\n" + "+\tnode = o2nm_get_node_by_num(remotenode);\n" + "+\tBUG_ON(node == NULL);\n" + "+\txh->client_id = o2nm_this_node(); /* which node is flobjing */\n" + "+\tvec[0].iov_len = sizeof(*xh);\n" + "+\tvec[0].iov_base = xh;\n" + "+\tret = o2net_send_message_vec(RMSTR_TMEM_FLOBJ, RMSTR_KEY,\n" + "+\t\t\t\t\tvec, veclen, remotenode, &status);\n" + "+\tramster_put_node(node);\n" + "+\treturn ret;\n" + "+}\n" + "+\n" + "+/*\n" + "+ * Handler registration\n" + "+ */\n" + "+\n" + "+static LIST_HEAD(ramster_o2net_unreg_list);\n" + "+\n" + "+static void ramster_o2net_unregister_handlers(void)\n" + "+{\n" + "+\to2net_unregister_handler_list(&ramster_o2net_unreg_list);\n" + "+}\n" + "+\n" + "+int ramster_o2net_register_handlers(void)\n" + "+{\n" + "+\tint status;\n" + "+\n" + "+\tstatus = o2net_register_handler(RMSTR_TMEM_PUT_EPH, RMSTR_KEY,\n" + "+\t\t\t\tRMSTR_O2NET_MAX_LEN,\n" + "+\t\t\t\tramster_remote_put_handler,\n" + "+\t\t\t\tNULL, NULL, &ramster_o2net_unreg_list);\n" + "+\tif (status)\n" + "+\t\tgoto bail;\n" + "+\n" + "+\tstatus = o2net_register_handler(RMSTR_TMEM_PUT_PERS, RMSTR_KEY,\n" + "+\t\t\t\tRMSTR_O2NET_MAX_LEN,\n" + "+\t\t\t\tramster_remote_put_handler,\n" + "+\t\t\t\tNULL, NULL, &ramster_o2net_unreg_list);\n" + "+\tif (status)\n" + "+\t\tgoto bail;\n" + "+\n" + "+\tstatus = o2net_register_handler(RMSTR_TMEM_ASYNC_GET_REQUEST, RMSTR_KEY,\n" + "+\t\t\t\tRMSTR_O2NET_MAX_LEN,\n" + "+\t\t\t\tramster_remote_async_get_request_handler,\n" + "+\t\t\t\tNULL, NULL,\n" + "+\t\t\t\t&ramster_o2net_unreg_list);\n" + "+\tif (status)\n" + "+\t\tgoto bail;\n" + "+\n" + "+\tstatus = o2net_register_handler(RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST,\n" + "+\t\t\t\tRMSTR_KEY, RMSTR_O2NET_MAX_LEN,\n" + "+\t\t\t\tramster_remote_async_get_request_handler,\n" + "+\t\t\t\tNULL, NULL,\n" + "+\t\t\t\t&ramster_o2net_unreg_list);\n" + "+\tif (status)\n" + "+\t\tgoto bail;\n" + "+\n" + "+\tstatus = o2net_register_handler(RMSTR_TMEM_ASYNC_GET_REPLY, RMSTR_KEY,\n" + "+\t\t\t\tRMSTR_O2NET_MAX_LEN,\n" + "+\t\t\t\tramster_remote_async_get_reply_handler,\n" + "+\t\t\t\tNULL, NULL,\n" + "+\t\t\t\t&ramster_o2net_unreg_list);\n" + "+\tif (status)\n" + "+\t\tgoto bail;\n" + "+\n" + "+\tstatus = o2net_register_handler(RMSTR_TMEM_FLUSH, RMSTR_KEY,\n" + "+\t\t\t\tRMSTR_O2NET_MAX_LEN,\n" + "+\t\t\t\tramster_remote_flush_handler,\n" + "+\t\t\t\tNULL, NULL,\n" + "+\t\t\t\t&ramster_o2net_unreg_list);\n" + "+\tif (status)\n" + "+\t\tgoto bail;\n" + "+\n" + "+\tstatus = o2net_register_handler(RMSTR_TMEM_FLOBJ, RMSTR_KEY,\n" + "+\t\t\t\tRMSTR_O2NET_MAX_LEN,\n" + "+\t\t\t\tramster_remote_flobj_handler,\n" + "+\t\t\t\tNULL, NULL,\n" + "+\t\t\t\t&ramster_o2net_unreg_list);\n" + "+\tif (status)\n" + "+\t\tgoto bail;\n" + "+\n" + "+\tpr_info(\"ramster_o2net: handlers registered\\n\");\n" + "+\n" + "+bail:\n" + "+\tif (status) {\n" + "+\t\tramster_o2net_unregister_handlers();\n" + "+\t\tpr_err(\"ramster_o2net: couldn't register handlers\\n\");\n" + "+\t}\n" + "+\treturn status;\n" + "+}\n" + "diff --git a/drivers/staging/ramster/zcache.h b/drivers/staging/ramster/zcache.h\n" + "new file mode 100644\n" + "index 0000000..250b121\n" + "--- /dev/null\n" + "+++ b/drivers/staging/ramster/zcache.h\n" + "@@ -0,0 +1,22 @@\n" + "+/*\n" + "+ * zcache.h\n" + "+ *\n" + "+ * External zcache functions\n" + "+ *\n" + "+ * Copyright (c) 2009-2012, Dan Magenheimer, Oracle Corp.\n" + "+ */\n" + "+\n" + "+#ifndef _ZCACHE_H_\n" + "+#define _ZCACHE_H_\n" + "+\n" + "+extern int zcache_put(int, int, struct tmem_oid *, uint32_t,\n" + "+\t\t\tchar *, size_t, bool, int);\n" + "+extern int zcache_autocreate_pool(int, int, bool);\n" + "+extern int zcache_get(int, int, struct tmem_oid *, uint32_t,\n" + "+\t\t\tchar *, size_t *, bool, int);\n" + "+extern int zcache_flush(int, int, struct tmem_oid *, uint32_t);\n" + "+extern int zcache_flush_object(int, int, struct tmem_oid *);\n" + "+extern int zcache_localify(int, struct tmem_oid *, uint32_t,\n" + "+\t\t\tchar *, size_t, void *);\n" + "+\n" + "+#endif /* _ZCACHE_H */\n" + "-- \n" + 1.7.1 -1c9373857f7e247d87a108efe2a2a79ad02dd1a3a1d2fa10c20823bfd975a4fe +1f612b970982819a5a77fe7feacaa239b2afe1909d00564648940677d1170eb8
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.