segdev_put(segdev);
}
-static void segdev_callback(struct segdev *dev)
+static void segdev_callback(struct segdev *dev, xport portno)
{
struct xseg *xseg;
struct segpriv *priv = dev->priv;
struct xseg_private *xpriv;
- uint32_t portno;
+ struct xseg_port *port;
if (priv->segno >= nr_xsegments)
return;
+ /* temporarily disabling this
+
if (dev->buffer_index != sizeof(uint32_t)) {
WARN_ON(1);
return;
}
+ */
xseg = xsegments[priv->segno];
xpriv = xseg->priv;
+ port = xseg_get_port(xseg, portno);
+ if (!port || !port->waitcue)
+ return;
+
if (xpriv->wakeup) {
- portno = *(uint32_t *)dev->buffer;
xpriv->wakeup(xseg, portno);
}
}
static int segdev_prepare_wait(struct xseg *xseg, uint32_t portno)
{
- return -1;
+ struct xseg_port *port = xseg_get_port(xseg, portno);
+ if (!port)
+ return -1;
+ /* true/false value */
+ port->waitcue = 1;
+ return 0;
}
static int segdev_cancel_wait(struct xseg *xseg, uint32_t portno)
{
- return -1;
+ struct xseg_port *port = xseg_get_port(xseg, portno);
+ if (!port)
+ return -1;
+ /* true/false value */
+ port->waitcue = 0;
+ return -0;
}
static int segdev_wait_signal(struct xseg *xseg, uint32_t timeout)
mk_chardev
load_all
spawn_filed ${IMAGES} 1
-# map_volume xsegvol 0 1
+ sleep 1
+ map_volume xsegvol 0 1
;;
stop)
pkill -f peers/user/filed
sleep 0.5
-# unmap_device 0
+ unmap_device 0
rm ${CHRDEV_NAME}
unload_all
;;
//maybe put this in loop start, and on break,
//just do xseg_get_req_data
- spin_lock(&xsegbd_dev->reqdatalock);
- r = xseg_set_req_data(xsegbd_dev->xseg, xreq, (void *) blkreq_idx);
- spin_unlock(&xsegbd_dev->reqdatalock);
- BUG_ON(r < 0);
+ //r = xseg_set_req_data(xsegbd_dev->xseg, xreq, (void *) blkreq_idx);
+ //BUG_ON(r < 0);
+ xreq->priv = (void *) blkreq_idx;
//XSEGLOG("xreq: %lx size: %llu offset: %llu, blkreq_idx: %llu set req data",
// xreq, xreq->size, xreq->offset, blkreq_idx);
pending->comp = ∁
- spin_lock(&xsegbd_dev->reqdatalock);
- r = xseg_set_req_data(xsegbd_dev->xseg, xreq, (void *) blkreq_idx);
- spin_unlock(&xsegbd_dev->reqdatalock);
- if (r < 0)
- goto out_queue;
+// r = xseg_set_req_data(xsegbd_dev->xseg, xreq, (void *) blkreq_idx);
+// if (r < 0)
+// goto out_queue;
+ xreq->priv = (void *) blkreq_idx;
//XSEGLOG("for req: %lx, set data %llu (lx: %lx)", xreq, blkreq_idx, (void *) blkreq_idx);
target = xseg_get_target(xsegbd_dev->xseg, xreq);
xsegbd_dev->src_portno, X_ALLOC);
BUG_ON(p == NoPort);
if ( p == NoPort) {
- goto out_data;
+ //goto out_data;
+ goto out_queue;
}
WARN_ON(xseg_signal(xsegbd_dev->xseg, p) < 0);
BUG_ON(xseg_put_request(xsegbd_dev->xseg, xreq, xsegbd_dev->src_portno) < 0);
return ret;
-out_data:
- spin_lock(&xsegbd_dev->reqdatalock);
- r = xseg_get_req_data(xsegbd_dev->xseg, xreq, &data);
- spin_unlock(&xsegbd_dev->reqdatalock);
+//out_data:
+// r = xseg_get_req_data(xsegbd_dev->xseg, xreq, &data);
out_queue:
xq_append_head(&xsegbd_dev->blk_queue_pending, blkreq_idx, 1);
}
for (;;) {
+ xseg_prepare_wait(xsegbd_dev->xseg, xsegbd_dev->src_portno);
xreq = xseg_receive(xsegbd_dev->xseg, portno);
if (!xreq)
break;
- spin_lock(&xsegbd_dev->reqdatalock);
- err = xseg_get_req_data(xsegbd_dev->xseg, xreq, &data);
- spin_unlock(&xsegbd_dev->reqdatalock);
+ xseg_cancel_wait(xsegbd_dev->xseg, xsegbd_dev->src_portno);
+
+// err = xseg_get_req_data(xsegbd_dev->xseg, xreq, &data);
//XSEGLOG("for req: %lx, got data %llu (lx %lx)", xreq, (xqindex) data, data);
- if (err < 0) {
- WARN_ON(1);
+// if (err < 0) {
+// WARN_ON(1);
//maybe put request?
- continue;
- }
-
- blkreq_idx = (xqindex) data;
+// continue;
+// }
+
+ blkreq_idx = (xqindex) xreq->priv;
if (blkreq_idx >= xsegbd_dev->nr_requests) {
WARN_ON(1);
//maybe put request?
goto out;
spin_lock_init(&xsegbd_dev->rqlock);
- spin_lock_init(&xsegbd_dev->reqdatalock);
INIT_LIST_HEAD(&xsegbd_dev->node);
/* parse cmd */
if (ret)
goto out_xseg;
+ xseg_prepare_wait(xsegbd_dev->xseg, xseg_portno(xsegbd_dev->xseg, port));
return count;
out_xseg:
struct xsegbd_device {
struct xseg *xseg;
spinlock_t rqlock;
- spinlock_t reqdatalock;
struct request_queue *blk_queue;
struct gendisk *gd;
int id;
{
struct segdev_file *vf = file->private_data;
struct segdev *dev = segdev_get(vf->minor);
+ char buffer[SEGDEV_BUFSIZE];
+ uint32_t portno;
int ret = -ENODEV;
if (!dev)
goto out;
if (count > SEGDEV_BUFSIZE)
count = SEGDEV_BUFSIZE;
- ret = copy_from_user(dev->buffer, buf, count);
+ ret = copy_from_user(buffer, buf, count);
if (ret < 0)
goto out;
- dev->buffer_index = count - ret;
+ if((count - ret) != sizeof(uint32_t))
+ goto out;
+
+ portno = *(uint32_t *)buffer;
ret = 0;
if (dev->callback)
- dev->callback(dev);
+ dev->callback(dev, portno);
else
ret = -ENOSYS;
#define SEGDEV_READY 1
#define SEGDEV_RESERVED 2
-#define SEGDEV_BUFSIZE 1024
+#define SEGDEV_BUFSIZE 512
struct segdev {
int minor;
char *segment;
struct cdev cdev;
unsigned long flags;
- void (*callback)(struct segdev *dev);
+ void (*callback)(struct segdev *dev, uint32_t portno);
void *priv;
spinlock_t lock;
priv->req_data = xhash_new(3); //FIXME should be relative to XSEG_DEF_REQS
if (!priv->req_data)
goto err_priv;
+ xlock_release(&priv->reqdatalock);
xseg->max_peer_types = __xseg->max_peer_types;
int xseg_set_req_data(struct xseg *xseg, struct xseg_request *xreq, void *data)
{
int r;
- xhash_t *req_data = xseg->priv->req_data;
+ xhash_t *req_data;
+
+ xlock_acquire(&xseg->priv->reqdatalock, 1);
+
+ req_data = xseg->priv->req_data;
r = xhash_insert(req_data, (ul_t) xreq, (ul_t) data);
if (r == -XHASH_ERESIZE) {
req_data = xhash_resize(req_data, grow_size_shift(req_data), NULL);
r = xhash_insert(req_data, (ul_t) xreq, (ul_t) data);
}
}
+
+ xlock_release(&xseg->priv->reqdatalock);
return r;
}
int xseg_get_req_data(struct xseg *xseg, struct xseg_request *xreq, void **data)
{
- //FIXME
- int r1, r;
+ int r;
ul_t val;
- xhash_t *req_data = xseg->priv->req_data;
- r1 = xhash_lookup(req_data, (ul_t) xreq, &val);
+ xhash_t *req_data;
+
+ xlock_acquire(&xseg->priv->reqdatalock, 1);
+
+ req_data = xseg->priv->req_data;
+ //maybe we need a xhash_delete with lookup...
+ //maybe we also need a delete that doesn't shrink xhash
+ r = xhash_lookup(req_data, (ul_t) xreq, &val);
*data = (void *) val;
- if (r1 >= 0) {
- // delete or update to NULL ?
+ if (r >= 0) {
r = xhash_delete(req_data, (ul_t) xreq);
if (r == -XHASH_ERESIZE) {
req_data = xhash_resize(req_data, shrink_size_shift(req_data), NULL);
}
}
}
- return r1;
+
+ xlock_release(&xseg->priv->reqdatalock);
+ return r;
}
/*
uint32_t max_peer_types;
void (*wakeup)(struct xseg *xseg, uint32_t portno);
xhash_t *req_data;
+ struct xlock reqdatalock;
};
struct xseg_counters {