[Codefragments-commits] bryce commits r8 - trunk/bufferheads

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Thu Jan 31 09:16:52 PST 2008


Author: bryce
Date: 2008-01-31 09:16:52 -0800 (Thu, 31 Jan 2008)
New Revision: 8

Added:
   trunk/bufferheads/buffer.stp
Log:
Wenji Huang's systemtap version



Added: trunk/bufferheads/buffer.stp
===================================================================
--- trunk/bufferheads/buffer.stp	                        (rev 0)
+++ trunk/bufferheads/buffer.stp	2008-01-31 17:16:52 UTC (rev 8)
@@ -0,0 +1,148 @@
+#!/usr/bin/env stap
+#
+# Copyright (C) 2007 Oracle Corp.
+#
+# TEST script for buffer allocation;
+# Originally from oss.oracle.com/projects/codefragments/src/chunk
+# by Philip Copeland <Philip.Copeland at oracle.com>
+#
+# Adapt it to stap script by Wenji Huang <wenji.huang at oracle.com>
+#
+# GPL License
+#
+# Instruction: (need to disable oom-killer)
+#  
+# old_val =`cat /proc/sys/vm/overcommit_memory`
+# echo 2 > /proc/sys/vm/overcommit_memory 
+# stap -g buffer.stp 1234
+# echo $old_val >/proc/sysvm/overcommit_memory
+#
+#
+
+global result
+
+%{
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/stat.h>
+
+// This is where we get alloc_buffer_head from
+#include <linux/buffer_head.h>
+
+// structure thats going to be burried in linked list hell
+typedef struct node *node_p;
+
+struct node
+{
+  int idx;			// node number
+  struct buffer_head *new_bh;	// some memory allocated by alloc_buffer_head
+  struct list_head list;	// kernel's list structure
+} node;
+
+struct list_head *pos, *q;
+
+/* Allocate buffer_head stuff -------------------- */
+int allocation (int requested)
+{
+  // Note: we don't care about taking note of tracking the nodes
+  // all we care about is that alloc_buffer_head() is called and stored
+
+  int x = 0;
+  int loop = 0;
+  int diff = 0;
+  struct node *tmp = NULL;
+
+  // how many items are there in the list?
+  list_for_each (pos, &node.list) loop++;
+
+  // do we need to add more records?
+  if (loop < requested)
+    {
+      // how many more do we need?
+      diff = (requested - loop);
+      for (x = 0; x < diff; x++)
+	{
+	  // malloc some space for the struct
+	  // __GPF flags,  NORETRY 
+	  // add | GFP_NOWARN if you dont like the memory stats dump when
+	  // kmalloc fails
+	  tmp =
+	    (struct node *) kmalloc (sizeof (struct node),
+			     GFP_KERNEL | __GFP_NORETRY |__GFP_THISNODE);
+	  if (tmp == NULL)
+	    {
+	      // abandon loop, we've all the memory
+	      return   x;
+	    } 
+
+	  // track what number this node is
+	  tmp->idx = loop + x;
+
+	  // Finally we get to do the one line of code we actually
+	  // truely care about...
+	 tmp->new_bh = alloc_buffer_head (GFP_NOFS | __GFP_NOFAIL);
+
+	  if ((tmp->new_bh) == NULL)
+	    {
+		// abandon routine
+		return  x;
+	    }
+
+	  // add to the end of the list
+	  list_add_tail (&(tmp->list), &(node.list));
+	} //end for
+   }  //end if
+  return (x);
+}
+
+/* Entry and Exit -------------------------------- */
+
+int test_init (void)
+{
+  // Create a start record
+  INIT_LIST_HEAD (&node.list);
+
+  return 0;
+}
+
+
+int test_exit (void)
+{
+  struct node *tmp;
+  int loop = 0;
+
+  // Clear out the list
+
+  list_for_each_safe (pos, q, &node.list)
+  {
+    tmp = list_entry (pos, struct node, list);
+    list_del (pos);
+    kfree (tmp->new_bh);
+    kfree (tmp);
+    loop++;
+  }
+  return loop;
+  }
+%}
+
+function start:long(val:long)
+%{ /* pure */
+	test_init();
+	THIS->__retvalue = allocation(THIS->val);
+%}
+
+function exit:long()
+%{ /* pure */
+	THIS->__retvalue = test_exit();
+%}
+
+probe begin{
+       loops = $1
+       printf("Kernel Test: Allocate %d amount of buffer_heads \n",loops)
+       result = start(loops)
+       printf("Allocated %d elements\n",result)
+}
+
+probe end{
+	printf("Freed %d elements\n",exit())
+}




More information about the Codefragments-commits mailing list