From: Subrata <sub...@us...> - 2008-04-30 07:19:33
|
Update of /cvsroot/ltp/ltp/testcases/kernel/controllers/memctl In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27811/ltp/testcases/kernel/controllers/memctl Added Files: Makefile memctl_test01.c myfunctions.sh run_memctl_test.sh Log Message: Initial Set of MEMORY CONTROLLER Test Cases Added to LTP by Sudhir Kumar. Signed-off-by: Sudhir Kumar <sk...@li...>, Acked-by: Balbir Singh <ba...@li...>. --- NEW FILE: Makefile --- CFLAGS += -Wall CPPFLAGS += -I../../../../include -I../libcontrollers LDLIBS += -lm -L../../../../lib/ -L../libcontrollers -lcontrollers -lltp SRCS = $(wildcard *.c) TARGETS = $(patsubst %.c,%,$(SRCS)) all: $(TARGETS) clean: rm -f $(TARGETS) *.o install: @set -e; for i in $(TARGETS) run_memctl_test.sh myfunctions.sh; do ln -f $$i ../../../bin/$$i ; chmod +x $$i ; done --- NEW FILE: memctl_test01.c --- /******************************************************************************/ /* */ /* Copyright (c) International Business Machines Corp., 2008 */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* This program is distributed in the hope that it will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ /* the GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with this program; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* */ /******************************************************************************/ /******************************************************************************/ /* */ /* File: memctl_test01.c */ /* */ /* Description: This is a c program that allocates memory in chunks of size */ /* as given by the calling script. The program touches all the */ /* allocated pages by writing a string on each page. */ /* */ /* Total Tests: 1 */ /* */ /* Test Name: mem_controller_test01 */ /* */ /* */ /* Test Assertion */ /* Please refer to the file memctl_testplan.txt */ /* */ /* Author: Sudhir Kumar sk...@li... */ /* */ /* History: */ /* Created 12/03/2008 Sudhir Kumar <sk...@li...> */ /* */ /******************************************************************************/ /* Standard Include Files */ #include <stdio.h> #include <string.h> #include <unistd.h> #include "libcontrollers.h" #include "test.h" extern int Tst_count; char *TCID = "memory_controller_test01"; int TST_TOTAL = 1; pid_t scriptpid; typedef size_t record_t; record_t **array_of_chunks; record_t tmp; int num_of_chunks, chunk_size, test_num, limit; extern void cleanup(); void signal_handler_sigusr1 (int signal); void signal_handler_sigusr2 (int signal); int allocate_memory(void); int main(int argc, char *argv[]) { int ret; char mygroup[FILENAME_MAX], mytaskfile[FILENAME_MAX]; char *mygroup_p, *script_pid_p, *test_num_p, *chunk_size_p, *num_chunks_p; struct sigaction newaction1, newaction2, oldaction1, oldaction2; /* Signal handling for SIGUSR1 recieved from script */ sigemptyset (&newaction1.sa_mask); newaction1.sa_handler = signal_handler_sigusr1; newaction1.sa_flags=0; sigaction (SIGUSR1, &newaction1, &oldaction1); /* Signal handling for SIGUSR2 recieved from script */ sigemptyset (&newaction2.sa_mask); newaction2.sa_handler = signal_handler_sigusr2; newaction2.sa_flags=0; sigaction (SIGUSR2, &newaction2, &oldaction2); /* *Capture variables from the script environment */ test_num_p = getenv("TEST_NUM"); mygroup_p = getenv("MYGROUP"); script_pid_p = getenv("SCRIPT_PID"); chunk_size_p = getenv("CHUNK_SIZE"); num_chunks_p = getenv("NUM_CHUNKS"); if ((test_num_p != NULL) && (mygroup_p != NULL) && (script_pid_p != NULL) && \ (chunk_size_p != NULL) && (num_chunks_p != NULL)) { scriptpid = atoi(script_pid_p); test_num = atoi(test_num_p); chunk_size = atoi(chunk_size_p); num_of_chunks = atoi(num_chunks_p); sprintf(mygroup,"%s", mygroup_p); } else { tst_brkm (TBROK, cleanup, "Invalid parameters recieved from script\n"); } sprintf(mytaskfile, "%s", mygroup); strcat (mytaskfile,"/tasks"); /* Assign the task to it's group */ write_to_file (mytaskfile, "a", getpid()); /* Assign the task to it's group*/ ret = allocate_memory(); /*should i check ret?*/ return 0; } /* * Function: cleanup() * signals for system cleanup in case test breaks */ void cleanup() { kill (scriptpid, SIGUSR1);/* Inform the shell to do cleanup*/ tst_exit (); /* Report exit status*/ } /* * Function: signal_handler_sigusr1() * signal handler for the new action */ void signal_handler_sigusr1 (int signal) { int i; for (i=0; i< num_of_chunks; ++i) free(array_of_chunks[i]); free(array_of_chunks); exit (0); } /* * Function: signal_handler_sigusr2() * signal handler for the new action */ void signal_handler_sigusr2 (int signal) { int i; for (i=0; i< num_of_chunks; ++i) free(array_of_chunks[i]); free(array_of_chunks); allocate_memory(); } int allocate_memory() { int i, j; /* * Allocate array which contains base addresses of all chunks */ array_of_chunks = (record_t *) malloc(sizeof(record_t *) * num_of_chunks); if (array_of_chunks == NULL) tst_brkm (TBROK, cleanup, "Memory allocation failed for array_of_chunks"); /* * Allocate chunks of memory */ for (i=0; i< num_of_chunks; ++i) { array_of_chunks[i] = (record_t *) malloc(chunk_size); if (array_of_chunks[i] == NULL) tst_brkm (TBROK, cleanup, "Memory allocation failed for chunks. Try smaller chunk size"); } /* * Touch all the pages of allocated memory by writing some string */ limit = chunk_size / sizeof(record_t); for (i=0; i< num_of_chunks; ++i) for (j=0; j< limit; ++j) array_of_chunks[i][j] = 0xaa; /* * Just keep on accessing the allocated pages and do nothing relevant */ while (1) { for (i=0; i< num_of_chunks; ++i) for (j=0; j< limit; ++j) tmp = array_of_chunks[i][j]; } return 0; } --- NEW FILE: run_memctl_test.sh --- #!/bin/bash # usage ./runmemctl_test.sh test_num ################################################################################# # Copyright (c) International Business Machines Corp., 2008 # # # # This program is free software; you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation; either version 2 of the License, or # # (at your option) any later version. # # # # This program is distributed in the hope that it will be useful, # # but WITHOUT ANY WARRANTY; without even the implied warranty of # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See # # the GNU General Public License for more details. # # # # You should have received a copy of the GNU General Public License # # along with this program; if not, write to the Free Software # # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # # ################################################################################# # Name Of File: run_memctl_test.sh # # # # Description: This file runs the setup for testing different memory resource # # controller features. After setup it runs diff test cases in diff # # setup. # # # # Test 01: Tests group memory usage on task migration # # # # Precaution: Avoid system use by other applications/users to get fair and # # appropriate results (avoid unnecessary killing of applicatio) # # # # Author: Sudhir Kumar <sk...@li...> # # # # History: # # # # DATE NAME EMAIL DESC # # # # 12/03/08 Sudhir Kumar <sk...@li...> Created this test # # # ################################################################################# export TCID="memctl_test01"; export TST_TOTAL=1; export TST_COUNT=1; TEST_NUM=$1; SCRIPT_PID=$$; RC=0; PWD=`pwd`; cd $LTPROOT/testcases/bin/ . myfunctions.sh ################################################################################# # ****************************** WARNING ********************************* # # User can change the parameters in different cases below but before doing # # any change user is supposed to know what he is doing. At any point when # # memory usage of a group becomes more than the group limit OOM Killer will # # be invoked and some of the tasks will be killed. Need to add code to handle # # the OOM Killer issues. # ################################################################################# # First of all check if the system has sufficient memory # Checking Inactive memory is sufficient. Is'nt it?? MEM_AVAIL=`cat /proc/meminfo | grep Inactive | tr -s [:space:] | cut -d" " -f2`; if [ $MEM_AVAIL -lt 262144 ] # 256MB(as test requires some ~200MB) then echo System does not have sufficient free memory.; echo Skipping execution of memory controller tests.; exit; fi case ${TEST_NUM} in "1" | "2" ) NUM_GROUPS=2; MEMLIMIT_GROUP_1=100M; MEMLIMIT_GROUP_2=132M; CHUNK_SIZE=6291456; # malloc n chunks of size m(6M) NUM_CHUNKS=10; # (say)60 MB memory(6*10) TOTAL_TASKS=1; # num of tasks in a group(1) NUM_MIG_TASKS=$TOTAL_TASKS # num of tasks to migrate MEM_TASK=`expr $CHUNK_SIZE \* $NUM_CHUNKS`; # memory allocated by a task MEM_TOTAL=`expr $MEM_TASK \* $TOTAL_TASKS`; # total memory allocated in a group TEST_NAME=" TASK MIGRATION TEST:"; ;; * ) usage; exit -1 ;; esac echo "TEST $TEST_NUM: MEMORY CONTROLLER TESTING"; echo "RUNNING SETUP....."; setup; # Trap the signal from any abnormaly terminated task # and kill all others and let cleanup be called trap 'echo "signal caught from task"; killall memctl_task_*;\ cleanup; exit -1;' SIGUSR1;#??? may need changes here echo "TEST STARTED: Please avoid using system while this test executes"; #Check if C source file has been compiled and then run it in different groups case $TEST_NUM in "1" | "2" ) setmemlimits; if [ -f memctl_test01 ] then for i in $(seq 1 $TOTAL_TASKS) do MYGROUP=/dev/memctl/group_1; cp memctl_test01 memctl_task_$i # 2>/dev/null; chmod +x memctl_task_$i; TEST_NUM=$TEST_NUM MYGROUP=$MYGROUP SCRIPT_PID=$SCRIPT_PID CHUNK_SIZE=$CHUNK_SIZE \ NUM_CHUNKS=$NUM_CHUNKS ./memctl_task_$i & if [ $? -ne 0 ] then echo "Error: Could not run ./memctl_task_$i" cleanup; exit -1; else PID[$i]=$!; fi done; # tasks are now running in group1 # Wait untill tasks allocate memory from group1 while [ 1 -gt 0 ] do sleep 1; GRP1_MEMUSAGE=`cat /dev/memctl/group_1/memory.usage_in_bytes`; if [ $GRP1_MEMUSAGE -gt $MEM_TOTAL ] then break; fi done GRP2_MEMUSAGE_OLD=`cat /dev/memctl/group_2/memory.usage_in_bytes`; echo Before task migration to group2 echo group2 memory usage: $GRP2_MEMUSAGE_OLD Bytes # Now migrate the tasks to another group for i in $(seq 1 $NUM_MIG_TASKS) do echo ${PID[$i]} >>/dev/memctl/group_2/tasks; if [ $? -ne 0 ] then echo "TFAIL Task migration failed from group_1 to group_2"; fi done # double check GRP2_TASKS=`cat /dev/memctl/group_2/tasks|wc -l`; if [ $GRP2_TASKS -ne $NUM_MIG_TASKS ] then echo "TFAIL Task Migration failed for some of the tasks"; fi; # Wait for some time to check if memory usage of group_2 increases # This is not the right approach however working. ??? thoughts??? sleep 10; # Decision formula: decides PASS or FAIL case $TEST_NUM in "1" ) GRP2_MEMUSAGE_NEW=`cat /dev/memctl/group_2/memory.usage_in_bytes`; echo After task migration to group2 echo group2 memory usage: $GRP2_MEMUSAGE_NEW Bytes if [ $GRP2_MEMUSAGE_NEW -gt $GRP2_MEMUSAGE_OLD ] then echo "TFAIL Memory resource Controller: Task Migration test $TEST_NUM FAILED"; else echo "TPASS Memory Resource Controller: Task Migration test $TEST_NUM PASSED"; fi # Now we can signal the task to finish and do the cleanup for i in $(seq 1 $TOTAL_TASKS) do kill -SIGUSR1 ${PID[$i]}; done ;; "2" ) GRP2_MEMUSAGE_OLD=`cat /dev/memctl/group_2/memory.usage_in_bytes`; # signal the migrated tasks to allocate memory for i in $(seq 1 $TOTAL_TASKS) do kill -SIGUSR2 ${PID[$i]}; done sleep 10; # Is it fine? Need input/alternates GRP2_MEMUSAGE_NEW=`cat /dev/memctl/group_2/memory.usage_in_bytes`; echo After task migration to group2 and doing malloc echo group2 memory usage: $GRP2_MEMUSAGE_NEW Bytes if [ $GRP2_MEMUSAGE_NEW -le $GRP2_MEMUSAGE_OLD ] then echo "TFAIL Memory resource Controller: Task Migration test $TEST_NUM FAILED"; else # Now we can signal the task to finish and do the cleanup for i in $(seq 1 $TOTAL_TASKS) do kill -SIGUSR1 ${PID[$i]}; done echo "TPASS Memory Resource Controller: Task Migration test $TEST_NUM PASSED"; fi ;; esac else echo "Source file not compiled..Please check Makefile...Exiting test" cleanup; exit -1; fi; ;; "*" ) usage; exit -1; ;; esac for i in $(seq 1 $TOTAL_TASKS) do wait ${PID[$i]}; RC=$?; # Return status of the task being waited # In abnormal termination of anyone trap will kill all others # and they will return non zero exit status. So Test broke!! if [ $RC -ne 0 ] then echo "Task $i exited abnormaly with return value: $RC"; tst_resm TINFO "Test could not execute for the expected duration"; cleanup; exit -1; fi done echo "Memory Resource Controller test executed successfully."; cleanup; cd $PWD exit 0; #to let PAN reprt success of test --- NEW FILE: myfunctions.sh --- #!/bin/bash # usage ./functions.sh ################################################################################# # Copyright (c) International Business Machines Corp., 2008 # # # # This program is free software; you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation; either version 2 of the License, or # # (at your option) any later version. # # # # This program is distributed in the hope that it will be useful, # # but WITHOUT ANY WARRANTY; without even the implied warranty of # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See # # the GNU General Public License for more details. # # # # You should have received a copy of the GNU General Public License # # along with this program; if not, write to the Free Software # # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # # ################################################################################# # Name Of File: myfunctions.sh # # # # Description: This file has functions for the setup for testing memory # # controller. setup includes creating controller device, # # mounting it with cgroup filesystem with option memory and # # creating groups in it. # # # # Functions: setup(): creaes /dev/memctl, mounts cgroup fs on it, creates # # groups in that etc. # # setmemlimits(): Sets up memory limits for different groups # # usage(): Shows the usage of this file. # # cleanup(): Does full system cleanup # # # # Author: Sudhir Kumar <sk...@li...> # # # # History: # # # # DATE NAME EMAIL DESC # # # # 15/03/08 Sudhir Kumar <sk...@li...> Created this test # # # ################################################################################# # Write the cleanup function cleanup () { echo "Cleanup called"; rm -f memctl_task_* 2>/dev/null rmdir /dev/memctl/group* 2> /dev/null umount /dev/memctl 2> /dev/null rmdir /dev/memctl 2> /dev/null } # Create /dev/memctl & mount the cgroup file system with memory controller #clean any group created eralier (if any) setup () { if [ -e /dev/memctl ] then echo "WARN:/dev/memctl already exist..overwriting"; cleanup; mkdir /dev/memctl; else mkdir /dev/memctl fi mount -t cgroup -omemory cgroup /dev/memctl 2> /dev/null if [ $? -ne 0 ] then echo "ERROR: Could not mount cgroup filesystem on /dev/memctl..Exiting test"; cleanup; exit -1; fi # Group created earlier may again be visible if not cleaned properly...so clean them if [ -e /dev/memctl/group_1 ] then rmdir /dev/memctl/group* echo "WARN: Earlier groups found and removed..."; fi # Create different groups for i in $(seq 1 $NUM_GROUPS) do group=group_$i; mkdir /dev/memctl/$group;# 2>/dev/null if [ $? -ne 0 ] then echo "ERROR: Can't create $group...Check your permissions..Exiting test"; cleanup; exit -1; fi done } # The usage of the script file usage() { echo "Could not start memory controller test"; echo "usage: run_memctl_test.sh test_num"; echo "Skipping the memory controller test..."; } # Function to set memory limits for different groups setmemlimits() { for i in $(seq 1 $NUM_GROUPS) do limit=MEMLIMIT_GROUP_${i}; eval limit=\$$limit; echo -n $limit >/dev/memctl/group_$i/memory.limit_in_bytes; if [ $? -ne 0 ] then echo "Error in setting the memory limits for group_$i" cleanup; exit -1; fi; done } |