[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] linux/xenoprof: dynamic buffer array allocation



The recent change to locally define MAX_VIRT_CPUS wasn't really
appropriate - with there not being a hard limit on the number of
vCPU-s anymore, these arrays should be allocated dynamically.

As usual, written against 2.6.32.2 and made apply to the 2.6.18
tree without further testing.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>

--- head-2010-01-04.orig/drivers/xen/xenoprof/xenoprofile.c     2010-01-04 
13:31:29.000000000 +0100
+++ head-2010-01-04/drivers/xen/xenoprof/xenoprofile.c  2010-01-04 
16:51:11.000000000 +0100
@@ -32,15 +32,14 @@
 #include "../../../drivers/oprofile/event_buffer.h"
 
 #define MAX_XENOPROF_SAMPLES 16
-#define MAX_VIRT_CPUS 128
 
 /* sample buffers shared with Xen */
-static xenoprof_buf_t *xenoprof_buf[MAX_VIRT_CPUS];
+static xenoprof_buf_t **__read_mostly xenoprof_buf;
 /* Shared buffer area */
 static struct xenoprof_shared_buffer shared_buffer;
 
 /* Passive sample buffers shared with Xen */
-static xenoprof_buf_t *p_xenoprof_buf[MAX_OPROF_DOMAINS][MAX_VIRT_CPUS];
+static xenoprof_buf_t **__read_mostly p_xenoprof_buf[MAX_OPROF_DOMAINS];
 /* Passive shared buffer area */
 static struct xenoprof_shared_buffer p_shared_buffer[MAX_OPROF_DOMAINS];
 
@@ -250,11 +249,32 @@ static int bind_virq(void)
 }
 
 
+static xenoprof_buf_t **get_buffer_array(unsigned int nbuf)
+{
+       size_t size = nbuf * sizeof(xenoprof_buf_t);
+
+       if (size <= PAGE_SIZE)
+               return kmalloc(size, GFP_KERNEL);
+       return vmalloc(size);
+}
+
+static void release_buffer_array(xenoprof_buf_t **buf, unsigned int nbuf)
+{
+       if (nbuf * sizeof(xenoprof_buf_t) <= PAGE_SIZE)
+               kfree(buf);
+       else
+               vfree(buf);
+}
+
+
 static void unmap_passive_list(void)
 {
        int i;
-       for (i = 0; i < pdomains; i++)
+       for (i = 0; i < pdomains; i++) {
                xenoprof_arch_unmap_shared_buffer(&p_shared_buffer[i]);
+               release_buffer_array(p_xenoprof_buf[i],
+                                    passive_domains[i].nbuf);
+       }
        pdomains = 0;
 }
 
@@ -274,10 +294,16 @@ static int map_xenoprof_buffer(int max_s
                return ret;
        nbuf = get_buffer.nbuf;
 
+       xenoprof_buf = get_buffer_array(nbuf);
+       if (!xenoprof_buf) {
+               xenoprof_arch_unmap_shared_buffer(&shared_buffer);
+               return -ENOMEM;
+       }
+
        for (i=0; i< nbuf; i++) {
                buf = (struct xenoprof_buf*) 
                        &shared_buffer.buffer[i * get_buffer.bufsize];
-               BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS);
+               BUG_ON(buf->vcpu_id >= nbuf);
                xenoprof_buf[buf->vcpu_id] = buf;
        }
 
@@ -292,8 +318,10 @@ static int xenoprof_setup(void)
        if ( (ret = map_xenoprof_buffer(MAX_XENOPROF_SAMPLES)) )
                return ret;
 
-       if ( (ret = bind_virq()) )
+       if ( (ret = bind_virq()) ) {
+               release_buffer_array(xenoprof_buf, nbuf);
                return ret;
+       }
 
        if (xenoprof_is_primary) {
                /* Define dom0 as an active domain if not done yet */
@@ -336,6 +364,7 @@ static int xenoprof_setup(void)
        return 0;
  err:
        unbind_virq();
+       release_buffer_array(xenoprof_buf, nbuf);
        return ret;
 }
 
@@ -357,6 +386,7 @@ static void xenoprof_shutdown(void)
        xenoprof_arch_unmap_shared_buffer(&shared_buffer);
        if (xenoprof_is_primary)
                unmap_passive_list();
+       release_buffer_array(xenoprof_buf, nbuf);
 }
 
 
@@ -449,11 +479,19 @@ static int xenoprof_set_passive(int * p_
                                                &p_shared_buffer[i]);
                if (ret)
                        goto out;
+
+               p_xenoprof_buf[i] = get_buffer_array(passive_domains[i].nbuf);
+               if (!p_xenoprof_buf[i]) {
+                       ++i;
+                       ret = -ENOMEM;
+                       goto out;
+               }
+
                for (j = 0; j < passive_domains[i].nbuf; j++) {
                        buf = (struct xenoprof_buf *)
                                &p_shared_buffer[i].buffer[
                                j * passive_domains[i].bufsize];
-                       BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS);
+                       BUG_ON(buf->vcpu_id >= passive_domains[i].nbuf);
                        p_xenoprof_buf[i][buf->vcpu_id] = buf;
                }
        }
@@ -462,8 +500,11 @@ static int xenoprof_set_passive(int * p_
        return 0;
 
 out:
-       for (j = 0; j < i; j++)
+       for (j = 0; j < i; j++) {
                xenoprof_arch_unmap_shared_buffer(&p_shared_buffer[i]);
+               release_buffer_array(p_xenoprof_buf[i],
+                                    passive_domains[i].nbuf);
+       }
 
        return ret;
 }


Attachment: xenlinux-oprofile-buffer-alloc.patch
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.