aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrgr22@boulderdash.cl.cam.ac.uk <rgr22@boulderdash.cl.cam.ac.uk>2003-06-10 15:18:45 +0000
committerrgr22@boulderdash.cl.cam.ac.uk <rgr22@boulderdash.cl.cam.ac.uk>2003-06-10 15:18:45 +0000
commit6a25a121131cc41ea0530c0e73b602d07e1a3e14 (patch)
tree57a675a7cf2195e769cb74b910c009964819517f
parent06bbc9e0ab74904cb9067e9a3f5232f0edfd5611 (diff)
downloadxen-6a25a121131cc41ea0530c0e73b602d07e1a3e14.tar.gz
xen-6a25a121131cc41ea0530c0e73b602d07e1a3e14.tar.bz2
xen-6a25a121131cc41ea0530c0e73b602d07e1a3e14.zip
bitkeeper revision 1.255 (3ee5f6d5vkkWKWqCJgu8yj_PRuBcLQ)
adding resource usage accounting for network usage
-rw-r--r--xen/common/network.c63
-rw-r--r--xen/include/hypervisor-ifs/network.h15
-rw-r--r--xen/include/xeno/vif.h6
-rw-r--r--xen/net/dev.c8
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_core.c70
5 files changed, 137 insertions, 25 deletions
diff --git a/xen/common/network.c b/xen/common/network.c
index 242f6ccadf..30cdf81441 100644
--- a/xen/common/network.c
+++ b/xen/common/network.c
@@ -211,29 +211,67 @@ void unlink_net_vif(net_vif_t *vif)
/* vif_query - Call from the proc file system to get a list of indexes
* in use by a particular domain.
*/
-void vif_query(vif_query_t *vq)
+int vif_query(vif_query_t *vq)
{
net_vif_t *vif;
struct task_struct *p;
- char buf[128];
+ int buf[32];
int i;
+ int count = 0;
- if ( !(p = find_domain_by_id(vq->domain)) )
- return;
-
- *buf = '\0';
+ if ( !(p = find_domain_by_id(vq->domain)) ) {
+ buf[0] = -1;
+ copy_to_user(vq->buf, buf, sizeof(int));
+ return -ENOSYS;
+ }
for ( i = 0; i < MAX_DOMAIN_VIFS; i++ )
{
vif = p->net_vif_list[i];
if ( vif == NULL ) continue;
- sprintf(buf + strlen(buf), "%d\n", i);
+ buf[++count] = i;
}
- copy_to_user(vq->buf, buf, strlen(buf) + 1);
+ buf[0] = count;
+
+ copy_to_user(vq->buf, buf, (buf[0] + 1) * sizeof(int));
put_task_struct(p);
+
+ return 0;
}
+
+/* vif_getinfo - Call from the proc file system to get info about a specific
+ * vif in use by a particular domain.
+ */
+int vif_getinfo(vif_getinfo_t *info)
+{
+ struct task_struct *p;
+ net_vif_t *vif;
+
+ info->total_bytes_sent =
+ info->total_bytes_received =
+ info->total_packets_sent =
+ info->total_packets_received = -1;
+
+ if ( !(p = find_domain_by_id(info->domain)) )
+ return -ENOSYS;
+
+ vif = p->net_vif_list[info->vif];
+
+ if(vif == NULL)
+ return -ENOSYS;
+
+ info->total_bytes_sent = vif->total_bytes_sent;
+ info->total_bytes_received = vif->total_bytes_received;
+ info->total_packets_sent = vif->total_packets_sent;
+ info->total_packets_received = vif->total_packets_received;
+
+ put_task_struct(p);
+
+ return 0;
+}
+
/* ----[ Net Rule Functions ]-----------------------------------------------*/
@@ -517,9 +555,16 @@ long do_network_op(network_op_t *u_network_op)
}
break;
+ case NETWORK_OP_VIFGETINFO:
+ {
+ ret = vif_getinfo(&op.u.vif_getinfo);
+ copy_to_user(u_network_op, &op, sizeof(op));
+ }
+ break;
+
case NETWORK_OP_VIFQUERY:
{
- vif_query(&op.u.vif_query);
+ ret = vif_query(&op.u.vif_query);
}
default:
diff --git a/xen/include/hypervisor-ifs/network.h b/xen/include/hypervisor-ifs/network.h
index fa8a365f21..09703df925 100644
--- a/xen/include/hypervisor-ifs/network.h
+++ b/xen/include/hypervisor-ifs/network.h
@@ -123,9 +123,20 @@ typedef struct net_rule_st
typedef struct vif_query_st
{
unsigned int domain;
- char *buf; /* reply buffer -- guest virtual address */
+ int *buf; /* reply buffer -- guest virtual address */
} vif_query_t;
+typedef struct vif_getinfo_st
+{
+ unsigned int domain;
+ unsigned int vif;
+ /* domain & vif are supplied by dom0, the rest are response fields */
+ long long total_bytes_sent;
+ long long total_bytes_received;
+ long long total_packets_sent;
+ long long total_packets_received;
+} vif_getinfo_t;
+
/* Network trap operations and associated structure.
* This presently just handles rule insertion and deletion, but will
* evenually have code to add and remove interfaces.
@@ -135,6 +146,7 @@ typedef struct vif_query_st
#define NETWORK_OP_DELETERULE 1
#define NETWORK_OP_GETRULELIST 2
#define NETWORK_OP_VIFQUERY 3
+#define NETWORK_OP_VIFGETINFO 4
typedef struct network_op_st
{
@@ -143,6 +155,7 @@ typedef struct network_op_st
{
net_rule_t net_rule;
vif_query_t vif_query;
+ vif_getinfo_t vif_getinfo;
}
u;
} network_op_t;
diff --git a/xen/include/xeno/vif.h b/xen/include/xeno/vif.h
index 8e4fcab444..3c38668bd6 100644
--- a/xen/include/xeno/vif.h
+++ b/xen/include/xeno/vif.h
@@ -66,6 +66,12 @@ typedef struct net_vif_st {
unsigned int tx_req_cons;
unsigned int tx_resp_prod; /* private version of shared variable */
+ /* Usage accounting */
+ long long total_bytes_sent;
+ long long total_bytes_received;
+ long long total_packets_sent;
+ long long total_packets_received;
+
/* Miscellaneous private stuff. */
struct task_struct *domain;
unsigned int idx; /* index within domain */
diff --git a/xen/net/dev.c b/xen/net/dev.c
index ce2795f3a0..7619fa5361 100644
--- a/xen/net/dev.c
+++ b/xen/net/dev.c
@@ -1882,6 +1882,10 @@ long do_net_update(void)
make_tx_response(vif, tx.id, RING_STATUS_OK);
}
+ /* record the transmission so they can be billed */
+ vif->total_packets_sent++;
+ vif->total_bytes_sent += tx.size;
+
tx_unmap_and_continue:
unmap_domain_mem(g_data);
spin_unlock_irq(&current->page_lock);
@@ -2037,6 +2041,10 @@ static void make_rx_response(net_vif_t *vif,
guest_event_notify(cpu_mask);
}
spin_unlock_irqrestore(&vif->rx_lock, flags);
+
+ /* record this so they can be billed */
+ vif->total_packets_received++;
+ vif->total_bytes_received += size;
}
diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_core.c b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_core.c
index 3dadd5cebd..b42abc45e4 100644
--- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_core.c
+++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_core.c
@@ -82,7 +82,8 @@ static int cmd_read_proc(char *page, char **start, off_t off,
static ssize_t dom_vif_read(struct file * file, char * buff, size_t size, loff_t * off)
{
- char hyp_buf[128];
+ int hyp_buf[32];
+ char buf[128];
network_op_t op;
static int finished = 0;
@@ -93,20 +94,30 @@ static ssize_t dom_vif_read(struct file * file, char * buff, size_t size, loff_t
}
op.cmd = NETWORK_OP_VIFQUERY;
- op.u.vif_query.domain = (unsigned int) ((struct proc_dir_entry *)file->f_dentry->d_inode->u.generic_ip)->data;
+ op.u.vif_query.domain = (unsigned int)
+ ((struct proc_dir_entry *)file->f_dentry->d_inode->u.generic_ip)->data;
op.u.vif_query.buf = hyp_buf;
- strcpy(hyp_buf, "Error getting domain's vif list from hypervisor.\n"); // This will be replaced if everything works.
+ (void) HYPERVISOR_network_op(&op);
+
+ if(hyp_buf[0] < 0) {
+ strcpy(buf, "Error getting domain's vif list from hypervisor.\n");
+ } else {
+ int i;
+ int len = 0;
+ strcpy(buf, "No vif found");
- (void)HYPERVISOR_network_op(&op);
+ for(i = 1; i <= hyp_buf[0] && len < 127; i++)
+ len += snprintf(buf + len, 127 - len, "%d\n", hyp_buf[i]);
+ }
- if (*off >= (strlen(hyp_buf)+1)) return 0;
+ if (*off >= (strlen(buf)+1)) return 0;
- copy_to_user(buff, hyp_buf, strlen(hyp_buf));
+ copy_to_user(buff, buf, strlen(buf));
finished = 1;
- return strlen(hyp_buf)+1;
+ return strlen(buf)+1;
}
struct file_operations dom_vif_ops = {
@@ -115,8 +126,12 @@ struct file_operations dom_vif_ops = {
static ssize_t dom_usage_read(struct file * file, char * buff, size_t size, loff_t * off)
{
- char hyp_buf[128];
+ char str[256];
+ int vifs[32];
dom0_op_t op;
+ network_op_t netop;
+ int i, end;
+ unsigned int domain;
static int finished = 0;
if ( finished )
@@ -125,21 +140,46 @@ static ssize_t dom_usage_read(struct file * file, char * buff, size_t size, loff
return 0;
}
- op.cmd = DOM0_GETDOMAININFO;
- op.u.getdominfo.domain = (unsigned int)
+ domain = (unsigned int)
((struct proc_dir_entry *)file->f_dentry->d_inode->u.generic_ip)->data;
+ op.cmd = DOM0_GETDOMAININFO;
- (void)HYPERVISOR_dom0_op(&op);
+ op.u.getdominfo.domain = domain;
- snprintf(hyp_buf, 128, "cpu: %lld\n", op.u.getdominfo.cpu_time);
+ (void) HYPERVISOR_dom0_op(&op);
+
+ end = snprintf(str, 256, "cpu: %lld\n", op.u.getdominfo.cpu_time);
+
+ netop.cmd = NETWORK_OP_VIFQUERY;
+ netop.u.vif_query.domain = domain;
+ netop.u.vif_query.buf = vifs;
+
+ (void) HYPERVISOR_network_op(&netop);
+
+ for(i = 1; i <= vifs[0]; i++) {
+ netop.cmd = NETWORK_OP_VIFGETINFO;
+ netop.u.vif_getinfo.domain = domain;
+ netop.u.vif_getinfo.vif = vifs[i];
+
+ (void) HYPERVISOR_network_op(&netop);
+
+ end += snprintf(str + end, 255 - end,
+ "vif%d: sent %lld bytes (%lld packets) "
+ "received %lld bytes (%lld packets)\n",
+ vifs[i],
+ netop.u.vif_getinfo.total_bytes_sent,
+ netop.u.vif_getinfo.total_packets_sent,
+ netop.u.vif_getinfo.total_bytes_received,
+ netop.u.vif_getinfo.total_packets_received);
+ }
- if (*off >= (strlen(hyp_buf) + 1)) return 0;
+ if (*off >= end + 1) return 0;
- copy_to_user(buff, hyp_buf, strlen(hyp_buf));
+ copy_to_user(buff, str, end);
finished = 1;
- return strlen(hyp_buf) + 1;
+ return end + 1;
}
struct file_operations dom_usage_ops = {