xseg: Add some perf counters (request rtt/latency)
authorStratos Psomadakis <psomas@grnet.gr>
Wed, 16 May 2012 23:01:01 +0000 (02:01 +0300)
committerStratos Psomadakis <psomas@grnet.gr>
Wed, 6 Jun 2012 11:52:33 +0000 (14:52 +0300)
xseg/sys/kernel/_sysutil.h
xseg/sys/kernel/xsegmod.c
xseg/sys/user/_sysutil.h
xseg/sys/user/xseg_user.c
xseg/xseg/domain.h
xseg/xseg/xseg.c
xseg/xseg/xseg.h

index d55921b..7042642 100644 (file)
@@ -4,5 +4,6 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/slab.h>
+#include <linux/time.h>
 
 #endif
index 299b1a1..de15fdc 100644 (file)
@@ -2,6 +2,7 @@
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/time.h>
 
 #include <sys/domain.h>
 #include <xq/domain.h>
@@ -56,6 +57,11 @@ void xq_mfree(void *ptr)
        return kfree(ptr);
 }
 
+void __get_current_time(struct timeval *tv)
+{
+       do_gettimeofday(tv);
+}
+
 static int __init xsegmod_init(void)
 {
        printk(KERN_INFO "xseg loaded");
index 8f192c6..aad5def 100644 (file)
@@ -5,5 +5,6 @@
 #include <stdlib.h>
 #include <stdint.h>
 #include <string.h>
+#include <sys/time.h>
 
 #endif
index 9036077..ef501d0 100644 (file)
@@ -7,6 +7,7 @@
 #include <sys/syscall.h>
 #include <errno.h>
 #include <sys/util.h>
+#include <sys/time.h>
 
 #include <sys/domain.h>
 #include <xq/domain.h>
@@ -78,3 +79,8 @@ void xq_mfree(void *ptr)
 {
        free(ptr);
 }
+
+void __get_current_time(struct timeval *tv) {
+       gettimeofday(tv, NULL);
+}
+
index 3f3ee87..d231a27 100644 (file)
@@ -7,5 +7,6 @@ void __unlock_domain(void);
 void __load_plugin(const char *name);
 int __xseg_preinit(void);
 uint64_t __get_id(void);
+void __get_current_time(struct timeval *tv);
 
 #endif
index ff5b3ba..5f3d9b0 100644 (file)
@@ -271,10 +271,12 @@ int xseg_register_peer(struct xseg_peer *peer_type)
                r -= 1;
                goto out;
        }
+
        peer_type->name[XSEG_TNAMESIZE-1] = 0;
        __peer_types[__nr_peer_types] = peer_type;
        __nr_peer_types += 1;
        r = 0;
+
 out:
        __unlock_domain();
        return r;
@@ -506,6 +508,10 @@ static long initialize_segment(struct xseg *xseg, struct xseg_config *cfg)
 
        xseg->segment_size = size;
        memcpy(&xseg->config, cfg, sizeof(struct xseg_config));
+
+       xseg->counters.req_cnt = 0;
+       xseg->counters.avg_req_lat = 0;
+
        return 0;
 }
 
@@ -551,6 +557,7 @@ int xseg_create(struct xseg_config *cfg)
                goto out_deallocate;
        }
 
+
        return 0;
 
 out_deallocate:
@@ -811,6 +818,10 @@ struct xseg_request *xseg_get_request(struct xseg *xseg, uint32_t portno)
 
        req = &xseg->requests[xqi];
        req->portno = portno;
+
+       req->elapsed = 0;
+       req->timestamp.tv_sec = 0;
+
        return req;
 }
 
@@ -823,6 +834,17 @@ int xseg_put_request (  struct xseg *xseg,
        xreq->datalen = xreq->bufferlen;
        xreq->target = NULL;
        xreq->targetlen = 0;
+
+#ifdef DEBUG_PERF
+       XSEGLOG("request's @%p rtt is: %llu usecs\n", xreq, xreq->elapsed);
+#endif
+       if (xreq->elapsed != 0) {
+               __lock_segment(xseg);
+               ++(xseg->counters.req_cnt);
+               xseg->counters.avg_req_lat += xreq->elapsed;
+               __unlock_segment(xseg);
+       }
+
        return xq_append_head(&xseg->ports[portno].free_queue, xqi) == None;
 }
 
@@ -839,6 +861,23 @@ int xseg_prep_request ( struct xseg_request *req,
        return 0;
 }
 
+static void __update_timestamp(struct xseg_request *xreq)
+{
+       struct timeval tv;
+
+       __get_current_time(&tv);
+       if (xreq->timestamp.tv_sec != 0)
+               /*
+                * FIXME: Make xreq->elapsed timeval/timespec again to avoid the
+                *                multiplication?
+                */
+               xreq->elapsed += (tv.tv_sec - xreq->timestamp.tv_sec) * 1000000 
+                                               + (tv.tv_usec - xreq->timestamp.tv_usec);
+
+       xreq->timestamp.tv_sec = tv.tv_sec;
+       xreq->timestamp.tv_usec = tv.tv_usec;
+}
+
 xserial xseg_submit (  struct xseg *xseg, uint32_t portno,
                        struct xseg_request *xreq       )
 {
@@ -848,6 +887,8 @@ xserial xseg_submit (       struct xseg *xseg, uint32_t portno,
        if (!__validate_port(xseg, portno))
                goto out;
 
+       __update_timestamp(xreq);
+
        port = &xseg->ports[portno];
        xqi = xreq - xseg->requests;
        serial = xq_append_tail(&port->request_queue, xqi);
@@ -867,6 +908,8 @@ struct xseg_request *xseg_receive(struct xseg *xseg, uint32_t portno)
        if (xqi == None)
                return NULL;
 
+       __update_timestamp(&xseg->requests[xqi]);
+
        return xseg->requests + xqi;
 }
 
@@ -882,6 +925,8 @@ struct xseg_request *xseg_accept(struct xseg *xseg, uint32_t portno)
        if (xqi == None)
                return NULL;
 
+       __update_timestamp(&xseg->requests[xqi]);
+
        return xseg->requests + xqi;
 }
 
@@ -894,6 +939,8 @@ xserial xseg_respond (  struct xseg *xseg, uint32_t portno,
        if (!__validate_port(xseg, portno))
                goto out;
 
+       __update_timestamp(xreq);
+
        port = &xseg->ports[portno];
        xqi = xreq - xseg->requests;
        serial = xq_append_tail(&port->reply_queue, xqi);
index eeefb38..aa6b010 100644 (file)
@@ -170,6 +170,8 @@ struct xseg_request {
        uint64_t bufferlen;
        xqindex task;
        uint64_t priv;
+       struct timeval timestamp;
+       uint64_t elapsed;
 };
 
 struct xseg_shared {
@@ -186,6 +188,11 @@ struct xseg_private {
        void (*wakeup)(struct xseg *xseg, uint32_t portno);
 };
 
+struct xseg_counters {
+       uint64_t avg_req_lat;
+       uint64_t req_cnt;
+};
+
 struct xseg {
        uint64_t version;
        uint64_t segment_size;
@@ -199,6 +206,7 @@ struct xseg {
        struct xseg_private *priv;
        uint32_t max_peer_types;
        struct xseg_config config;
+       struct xseg_counters counters;
 };
 
 #define XSEG_F_LOCK 0x1