fix xsegbd to use req->priv pointer instead of xseg_{get,set} req data
authorUser <user@snf-1286.(none)>
Fri, 7 Sep 2012 15:22:39 +0000 (18:22 +0300)
committerUser <user@snf-1286.(none)>
Fri, 7 Sep 2012 15:22:39 +0000 (18:22 +0300)
xseg/drivers/kernel/xseg_segdev.c
xseg/launch
xseg/peers/kernel/xsegbd.c
xseg/peers/kernel/xsegbd.h
xseg/sys/kernel/segdev.c
xseg/sys/kernel/segdev.h
xseg/xseg/xseg.c
xseg/xseg/xseg.h

index 5b52c89..3abda3a 100644 (file)
@@ -145,24 +145,30 @@ out:
        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);
        }
 }
@@ -219,12 +225,22 @@ static void segdev_signal_quit(void)
 
 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)
index f379fb2..e7f8c7e 100755 (executable)
@@ -144,12 +144,13 @@ filed)
                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
                ;;
index 883aabb..25704bb 100644 (file)
@@ -427,10 +427,9 @@ static void xseg_request_fn(struct request_queue *rq)
 
                //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);
 
@@ -502,11 +501,10 @@ static int xsegbd_get_size(struct xsegbd_device *xsegbd_dev)
        pending->comp = &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);
@@ -526,7 +524,8 @@ static int xsegbd_get_size(struct xsegbd_device *xsegbd_dev)
                                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);
 
@@ -538,10 +537,8 @@ out:
        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);
        
@@ -566,21 +563,22 @@ static void xseg_callback(struct xseg *xseg, xport portno)
        }
 
        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?
@@ -825,7 +823,6 @@ static ssize_t xsegbd_add(struct bus_type *bus, const char *buf, size_t count)
                goto out;
 
        spin_lock_init(&xsegbd_dev->rqlock);
-       spin_lock_init(&xsegbd_dev->reqdatalock);
        INIT_LIST_HEAD(&xsegbd_dev->node);
 
        /* parse cmd */
@@ -901,6 +898,7 @@ static ssize_t xsegbd_add(struct bus_type *bus, const char *buf, size_t count)
        if (ret)
                goto out_xseg;
 
+       xseg_prepare_wait(xsegbd_dev->xseg, xseg_portno(xsegbd_dev->xseg, port));
        return count;
 
 out_xseg:
index aa9a75e..dc0c7b1 100644 (file)
@@ -28,7 +28,6 @@ struct xsegbd {
 struct xsegbd_device {
        struct xseg *xseg;
        spinlock_t rqlock;
-       spinlock_t reqdatalock;
        struct request_queue *blk_queue;
        struct gendisk *gd;
        int id;
index fa75992..022372e 100644 (file)
@@ -214,6 +214,8 @@ static ssize_t segdev_write(struct file *file, const char __user *buf,
 {
        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;
@@ -221,15 +223,18 @@ static ssize_t segdev_write(struct file *file, const char __user *buf,
        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;
 
index 671b71b..1b39edd 100644 (file)
@@ -15,7 +15,7 @@
 
 #define SEGDEV_READY           1
 #define SEGDEV_RESERVED                2
-#define SEGDEV_BUFSIZE         1024
+#define SEGDEV_BUFSIZE         512
 
 struct segdev {
        int minor;
@@ -23,7 +23,7 @@ struct segdev {
        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;
index b3c257d..e91c5f0 100644 (file)
@@ -701,6 +701,7 @@ struct xseg *xseg_join(     char *segtypename,
        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;
 
@@ -1369,7 +1370,11 @@ xport xseg_getandset_dstgw(struct xseg *xseg, xport portno, xport dstgw)
 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);
@@ -1378,19 +1383,25 @@ int xseg_set_req_data(struct xseg *xseg, struct xseg_request *xreq, void *data)
                        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);
@@ -1400,7 +1411,9 @@ int xseg_get_req_data(struct xseg *xseg, struct xseg_request *xreq, void **data)
                        }
                }
        }
-       return r1;
+
+       xlock_release(&xseg->priv->reqdatalock);
+       return r;
 }
 
 /*
index 184fce0..08b6196 100644 (file)
@@ -221,6 +221,7 @@ struct xseg_private {
        uint32_t max_peer_types;
        void (*wakeup)(struct xseg *xseg, uint32_t portno);
        xhash_t *req_data;
+       struct xlock reqdatalock;
 };
 
 struct xseg_counters {