From 6a25a121131cc41ea0530c0e73b602d07e1a3e14 Mon Sep 17 00:00:00 2001 From: "rgr22@boulderdash.cl.cam.ac.uk" Date: Tue, 10 Jun 2003 15:18:45 +0000 Subject: bitkeeper revision 1.255 (3ee5f6d5vkkWKWqCJgu8yj_PRuBcLQ) adding resource usage accounting for network usage --- xen/common/network.c | 63 ++++++++++++++++--- xen/include/hypervisor-ifs/network.h | 15 ++++- xen/include/xeno/vif.h | 6 ++ xen/net/dev.c | 8 +++ .../arch/xeno/drivers/dom0/dom0_core.c | 70 +++++++++++++++++----- 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(¤t->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 = { -- cgit v1.2.3