All of lore.kernel.org
 help / color / mirror / Atom feed
From: Martin Wilck <Martin.Wilck@fujitsu-siemens.com>
To: linux-ia64@vger.kernel.org
Subject: [Linux-ia64] IO-TLB monitoring patch & tool v0.2
Date: Mon, 25 Jun 2001 19:30:55 +0000	[thread overview]
Message-ID: <marc-linux-ia64-105590693005758@msgid-missing> (raw)

Hello,

Here is a corrected version of the kernel patch & tool for
monitoring IO-TLB usage. It works correctly now, and is even fun to watch!

It can display summary information or show a IO-TLB "map" in two different
modes.

Even if the aic7xxx problems may be history soon, this tool may
still be useful with other controllers/drivers.

Cheers
Martin

-- 
Martin Wilck     <Martin.Wilck@fujitsu-siemens.com>
FSC EP PS DS1, Paderborn      Tel. +49 5251 8 15113

#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.2.1).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 2001-06-25 21:18 CEST by <martin@tl02.pdb.fsc.net>.
# Source directory was `/home/martin'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode       name
# ------ ---------- ------------------------------------------
#    358 -rw-rw-r-- iotlb-mon-0.2/Makefile
#   1347 -rw-rw-r-- iotlb-mon-0.2/README
#  12720 -rw-rw-r-- iotlb-mon-0.2/iotlb-mon.c
#  10022 -rw-rw-r-- iotlb-mon-0.2/swiotlb_proc.patch
#
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dirúILED
locale_dirúILED
first_param="$1"
for dir in $PATH
do
  if test "$gettext_dir" = FAILED && test -f $dir/gettext \
     && ($dir/gettext --version >/dev/null 2>&1)
  then
    set `$dir/gettext --version 2>&1`
    if test "$3" = GNU
    then
      gettext_dir=$dir
    fi
  fi
  if test "$locale_dir" = FAILED && test -f $dir/shar \
     && ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
  then
    locale_dir=`$dir/shar --print-text-domain-dir`
  fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
  echoìho
else
  TEXTDOMAINDIR=$locale_dir
  export TEXTDOMAINDIR
  TEXTDOMAIN=sharutils
  export TEXTDOMAIN
  echo="$gettext_dir/gettext -s"
fi
if touch -am -t 200112312359.59 $$.touch >/dev/null 2>&1 && test ! -f 200112312359.59 -a -f $$.touch; then
  shar_touch='touch -am -t $1$2$3$4$5$6.$7 "$8"'
elif touch -am 123123592001.59 $$.touch >/dev/null 2>&1 && test ! -f 123123592001.59 -a ! -f 123123592001.5 -a -f $$.touch; then
  shar_touch='touch -am $3$4$5$6$1$2.$7 "$8"'
elif touch -am 1231235901 $$.touch >/dev/null 2>&1 && test ! -f 1231235901 -a -f $$.touch; then
  shar_touch='touch -am $3$4$5$6$2 "$8"'
else
  shar_touch=:
  echo
  $echo 'WARNING: not restoring timestamps.  Consider getting and'
  $echo "installing GNU \`touch', distributed in GNU File Utilities..."
  echo
fi
rm -f 200112312359.59 123123592001.59 123123592001.5 1231235901 $$.touch
#
if mkdir _sh04019; then
  $echo 'x -' 'creating lock directory'
else
  $echo 'failed to create lock directory'
  exit 1
fi
# ======= iotlb-mon-0.2/Makefile =======
if test ! -d 'iotlb-mon-0.2'; then
  $echo 'x -' 'creating directory' 'iotlb-mon-0.2'
  mkdir 'iotlb-mon-0.2'
fi
if test -f 'iotlb-mon-0.2/Makefile' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'iotlb-mon-0.2/Makefile' '(file already exists)'
else
  $echo 'x -' extracting 'iotlb-mon-0.2/Makefile' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'iotlb-mon-0.2/Makefile' &&
CFLAGS = -O2 -Wall
LDFLAGS = -s
PREFIX = /usr/local
X
OBJ = iotlb-mon.o
LIBS = -lncurses
EXE = iotlb-mon
X
sbindir = $(PREFIX)/sbin
X
default:	$(EXE)
X
$(EXE):	$(OBJ)
X	$(CC) $(CFLAGS) $(LDFLAGS) -o $(EXE) $(OBJ) $(LIBS)
X
install:	$(EXE)
X	install -d $(sbindir)
X	install -m 755 $(EXE) $(sbindir)
X
clean:
X	rm -f $(EXE) $(OBJ) core
X
distclean:	clean
X	rm -f *~ '#'*
SHAR_EOF
  (set 20 01 06 13 23 08 50 'iotlb-mon-0.2/Makefile'; eval "$shar_touch") &&
  chmod 0664 'iotlb-mon-0.2/Makefile' ||
  $echo 'restore of' 'iotlb-mon-0.2/Makefile' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'iotlb-mon-0.2/Makefile:' 'MD5 check failed'
54357a32a53e5ade6918ff7b409a31a0  iotlb-mon-0.2/Makefile
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'iotlb-mon-0.2/Makefile'`"
    test 358 -eq "$shar_count" ||
    $echo 'iotlb-mon-0.2/Makefile:' 'original size' '358,' 'current size' "$shar_count!"
  fi
fi
# ======= iotlb-mon-0.2/README =======
if test -f 'iotlb-mon-0.2/README' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'iotlb-mon-0.2/README' '(file already exists)'
else
  $echo 'x -' extracting 'iotlb-mon-0.2/README' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'iotlb-mon-0.2/README' &&
X
X  iotlb-mon.c - utility to monitor software IO-TLB usage on
X                IA-64 Linux systems.
X
X  (c) 2001 Martin Wilck <Martin.Wilck@Fujitsu-Siemens.com>
X
X  Copying and modification granted under the terms of the
X  GNU General Public License (GPL).
X
X  *************************************************************
X  This program comes with NO WARRANTY, for details see the GPL.
X  *************************************************************
X
X  Version 0.2, 25.06.2001
X
X  Installing the kernel patch
X  =============X
X  Patch the 2.4.5 kernel + IA64 patch (30.05.2001)
X  with the patch file (swiotlb_proc.patch) from this directory.
X  Activate building the module in the "General setup" section
X  (/proc/swiotlb support). Build & install kernel and modules as usual.
X  The module built is called "swiotlb_proc.o".
X
X  Compiling iotlb-mon
X  =========X
X  Requires the ncurses library and header files.
X
X  make; make PREFIX=[my_install_root] install
X
X  Default for PREFIX is /usr/local.
X  The program installs to $(PREFIX)/sbin.
X
X  Using iotlb-mon
X  =======X
X  usage: ioltb-mon
X  Hit '?' in running program to display keyboard controls.
X
X  BUGS:
X  -----
X
X  Probably many.
X  Sometimes read () yields unreasonable sizes.
X
X  Please report bugs and suggest improvements to
X  <Martin.Wilck@Fujitsu-Siemens.com>.
X
SHAR_EOF
  (set 20 01 06 25 21 17 59 'iotlb-mon-0.2/README'; eval "$shar_touch") &&
  chmod 0664 'iotlb-mon-0.2/README' ||
  $echo 'restore of' 'iotlb-mon-0.2/README' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'iotlb-mon-0.2/README:' 'MD5 check failed'
c37d1441828e166ac808b1ae2410ccea  iotlb-mon-0.2/README
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'iotlb-mon-0.2/README'`"
    test 1347 -eq "$shar_count" ||
    $echo 'iotlb-mon-0.2/README:' 'original size' '1347,' 'current size' "$shar_count!"
  fi
fi
# ======= iotlb-mon-0.2/iotlb-mon.c =======
if test -f 'iotlb-mon-0.2/iotlb-mon.c' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'iotlb-mon-0.2/iotlb-mon.c' '(file already exists)'
else
  $echo 'x -' extracting 'iotlb-mon-0.2/iotlb-mon.c' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'iotlb-mon-0.2/iotlb-mon.c' &&
/*
X
X  iotlb-mon.c - utility to monitor software IO-TLB usage on
X                IA-64 Linux systems.
X  (c) 2001 Martin Wilck <Martin.Wilck@Fujitsu-Siemens.com>
X
*/
X
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <curses.h>
#include <sys/time.h>
X
#define N_INFO_FIELDS 8
#define PWIN_BORDER 1
#define INFO_X PWIN_BORDER
#define INFO_Y (PWIN_BORDER)
#define PWIN_HEIGHT (N_INFO_FIELDS+INFO_Y+PWIN_BORDER)
#define INFO_SPC 2
#define INFO_FLEN 18
#define INFO_UFMT "%18u"
#define INFO_PFMT "%18p"
#define PWIN_X 2
#define PWIN_Y 2
#define MIN_INTERVAL 1
#define MAX_INTERVAL 10
#define IWIN_HEIGHT (LINES - 1)
#define INDEX_STEP 1024
X
typedef enum {
X	QUIT = 0,
X	PARAMS,
X	LIST,
X	GROUP,
X	HELP
} run_t;
X
struct iotlb_info_struct {
X	unsigned long n_slots;
X	unsigned int index;
X	unsigned int used_buffers;
X	unsigned int used_slots;
X	unsigned int max_used_buffers;
X	unsigned int max_used_slots;
X	void *start;
X	void *end;
};
X
static const char *params_name = "/proc/swiotlb/params";
static const char *list_name = "/proc/swiotlb/list";
static const char *info_desc [N_INFO_FIELDS] = {
X	"Allocated",
X	"Index",
X	"Used buffers",
X	"Max used buffers",
X	"Used slots",
X	"Max used slots",
X	"Start address",
X	"End address"
};
X
static char *help_msg = "Hit 'h' or '?' for help";
static char *help_exit_msg = "Hit 'i', 'd', or 'c' to leave help";
static char *follow_off_msg = "Follow mode OFF";
static char *follow_on_msg = "Follow mode ON";
static char *current_msg = NULL;
X
static unsigned int first_index = 0;
static bool follow_index = FALSE;
static int iotlb_fd, list_fd;
static int interval = 5;
static WINDOW *mainwin, *pwin, *cwin, *iwin;
volatile sig_atomic_t alarm_received = 0;
X
void
cleanup ()
{
X	endwin ();
X	close (iotlb_fd);
X	close (list_fd);
}
X
static int
info_len (int force)
{
X	static int maxl = 0;
X	int i;
X
X	if (maxl && !force)
X		return maxl;
X
X	maxl = 0;
X	for (i = 0; i < N_INFO_FIELDS; i++) {
X		int l = strlen (info_desc[i]);
X		if (l > maxl)
X			maxl = l;
X	};
X	maxl++;
X	return maxl;
}
X
void
refresh_cwin (void)
{
X	werase (cwin);
X	mvwprintw (cwin, 0, 0, current_msg);
X	mvwprintw (cwin, 0, COLS - 30, "Timer interval (1/10 s): %3d", interval);
X	wrefresh (cwin);
}
X
static void
create_windows (void)
{
X	int width = info_len(0) + INFO_SPC + INFO_FLEN + 2*PWIN_BORDER;
X
X	pwin = newwin (PWIN_HEIGHT,
X		       width,
X		       PWIN_Y,
X		       (COLS - width) >> 1);
X	cwin = newwin (1, 0, LINES - 1, 0);
X	iwin = newwin (IWIN_HEIGHT, 0, 0, 0);
X
X	if (!pwin || !cwin || !iwin) {
X		cleanup ();
X		fprintf (stderr, "Error creating windows");
X		exit (1);
X	};
X	box (pwin, 0, 0);
X	refresh_cwin ();
}
X
static int
print_info_desc (int force)
{
X
X	int maxl = info_len (force),  i;
X	mvwprintw (pwin, 0, INFO_X,
X		   "Software IO-TLB status");
X	for (i = 0; i < N_INFO_FIELDS; i++) {
X		mvwprintw (pwin, INFO_Y + i, INFO_X,
X			  "%s", info_desc[i]);
X		mvwaddch (pwin, INFO_Y + i, INFO_X + maxl, ':');
X	};
X
X	return maxl;
}
X
static int
read_info (struct iotlb_info_struct *inf)
{	int nread;
X	int st;
X
X	st = lseek (iotlb_fd, 0, SEEK_SET);
X
X	nread = read (iotlb_fd, inf, sizeof (struct iotlb_info_struct));
X	if (nread != sizeof (struct iotlb_info_struct)) {
X		cleanup ();
X		fprintf (stderr, "error in read () on %s\n",
X			 params_name);
X		exit (1);
X	};
X
X	return nread;
}
X
static void
print_info (void)
{
X	struct iotlb_info_struct info;
X	int nread, col;
X
X	nread = read_info (&info);
X	col = print_info_desc (0) + INFO_X + INFO_SPC;
X
X	mvwprintw (pwin, INFO_Y + 0, col, INFO_UFMT, info.n_slots);
X	mvwprintw (pwin, INFO_Y + 1, col, INFO_UFMT, info.index);
X	mvwprintw (pwin, INFO_Y + 2, col, INFO_UFMT, info.used_buffers);
X	mvwprintw (pwin, INFO_Y + 3, col, INFO_UFMT, info.max_used_buffers);
X	mvwprintw (pwin, INFO_Y + 4, col, INFO_UFMT, info.used_slots);
X	mvwprintw (pwin, INFO_Y + 5, col, INFO_UFMT, info.max_used_slots);
X	mvwprintw (pwin, INFO_Y + 6, col, INFO_PFMT, info.start);
X	mvwprintw (pwin, INFO_Y + 7, col, INFO_PFMT, info.end);
X	wrefresh (pwin);
}
X
static int
read_list (unsigned int **lst, struct iotlb_info_struct *info)
{
X	static int size = 0;
X	static unsigned int *list = NULL;
X	int nread, st, n, i;
X	char *pos;
X
X	nread = read_info (info);
X	if (!list) {
X		size = info->n_slots;
X		if (size > 0) {
X			list = malloc (size * sizeof (unsigned int));
X		};
X		if (!list) {
X			cleanup ();
X			fprintf (stderr,
X				 "Error in malloc ()\n");
X			exit (1);
X		};
X		for (i = 0; i < size; i++)
X			list[i] = 1;
X	};
X
X	st = lseek (list_fd, 0, SEEK_SET);
X
X	pos = (char*) list;
X	n = size * sizeof (unsigned int);
X	do {
X		nread = read (list_fd, pos, n);
X  		pos += nread;
X		n -= nread;
X	} while (0); /* (nread > 0); */
X
X	if (nread < 0) {
X		cleanup ();
X		fprintf (stderr, "error in read () on %s: %d\n",
X			 list_name, nread);
X		exit (1);
X	};
X
X	*lst = list;
X	return size - n;
}
X
static chtype
make_ch (unsigned int v)
{
X	chtype c;
X	if (v < 10u)
X		c = '0' + v;
X	else if (v < 36u)
X		c = 'a' + v - 10;
X	else if (v < 62u)
X		c = 'A' + v - 36;
X	else
X		c = '-';
X	return c;
}
X
static chtype
make_group_ch (unsigned int *slot, const unsigned int *highest)
{
X	chtype free = 0;
X
X	for (; slot < highest; slot++)
X		if (*slot)
X			free++;
X	if (free = 16)
X		free = '*';
X	else if (free <= 9)
X		free += '0';
X	else
X		free += 'A' - 10;
X        return free;
}
X
static void
print_list_group (void)
{
X	unsigned int *list, *index, *curr, *next, *last;
X	int sz, mx;
X	struct iotlb_info_struct info;
X
X	sz = read_list (&list, &info);
X	index = list + info.index;
X
X	mx = (COLS * IWIN_HEIGHT) << 4;
X
X	if (mx >= sz)
X		first_index = 0;
X
X	if (first_index >= sz) {
X		first_index = (sz - 1) & ~(INDEX_STEP - 1);
X	};
X
X	if (follow_index &&
X	    (list + first_index > index || index - (list + first_index) > mx)) {
X		first_index = (index - list) & ~(INDEX_STEP - 1);
X	};
X
X	last = list + first_index + mx;
X	if (last > list + sz)
X		last = list + sz;
X
X	werase (iwin);
X	mvwprintw (iwin, 0, 0, "Condensed map of slot %8u - %8u. "
X		   "Current slot index: %u, total used slots: %u",
X		   first_index, last - list, info.index, info.used_slots);
X
X	wmove (iwin, 1, 0);
X	for (curr = list + first_index; curr < last; curr = next) {
X		next = curr + 16;
X		if (next > last)
X			next = last;
X		if (curr <= index && index < next) {
X			wattron (iwin, A_REVERSE);
X			waddch (iwin, make_group_ch (curr, next));
X			wattroff (iwin, A_REVERSE);
X		} else
X			waddch (iwin, make_group_ch (curr, next));
X	};
X	wrefresh (iwin);
}
X
static void
print_list (void)
{
X	unsigned int *list, index;
X	int sz, mx, i, last;
X	struct iotlb_info_struct info;
X
X	sz = read_list (&list, &info);
X	index = info.index;
X	mx = COLS * IWIN_HEIGHT;
X
X	if (mx >= sz)
X		first_index = 0;
X
X	if (first_index >= sz) {
X		first_index = (sz - 1) & ~(INDEX_STEP - 1);
X	};
X
X	if (follow_index &&
X	    (first_index > index || index - first_index > mx)) {
X		first_index = index & ~(INDEX_STEP - 1);
X	};
X
X	last = first_index + mx;
X	if (last > sz)
X		last = sz;
X
X	werase (iwin);
X	mvwprintw (iwin, 0, 0, "Map of slot %8u - %8u. "
X		   "Current slot index: %u, total used slots: %u",
X		   first_index, last, index, info.used_slots);
X
X	wmove (iwin, 1, 0);
X	for (i = first_index; i < last; ++i) {
X		if (i = index) {
X			wattron (iwin, A_REVERSE);
X			waddch (iwin, make_ch (list[i]));
X			wattroff (iwin, A_REVERSE);
X		} else if (i % 2048 = 0) {
X			wattron (iwin, A_REVERSE);
X			waddch (iwin, make_ch (list[i]));
X			wattroff (iwin, A_REVERSE);
X		} else
X			waddch (iwin, make_ch (list[i]));
X	};
X	wrefresh (iwin);
}
X
void
alrm_handler (int sig)
{
X	alarm_received = 1;
}
X
int
start_timer (long int decisec)
{
X	static const struct itimerval itv0 = {
X		{ 0, 0}, { 0, 0}
X	};
X	struct itimerval itv;
X	int st;
X	long int sec = decisec / 10;
X	long int usec = 100000 * (decisec % 10);
X	struct sigaction act;
X
X	act.sa_handler = alrm_handler;
X	sigemptyset (&act.sa_mask);
X	sigaction (SIGALRM, &act, NULL);
X
X	itv.it_interval.tv_sec = sec;
X	itv.it_interval.tv_usec = usec;
X	itv.it_value.tv_sec = sec;
X	itv.it_value.tv_usec = usec;
X
X	setitimer (ITIMER_REAL, &itv0, NULL);
X	st = setitimer (ITIMER_REAL, &itv, NULL);
X
X	return st;
}
X
#define HELP_TAB 8
X
static void
help (void)
{
X	int line = 0;
X	werase (iwin);
X
X	wattron (iwin, A_UNDERLINE);
X	mvwprintw (iwin, line, 0, "iotlb-mon - Monitor the state of the IO-TLB buffers");
X	wattroff (iwin, A_UNDERLINE);
X
X	line ++;
X	mvwprintw (iwin, line, 0, "(c) 2001 Martin Wilck <Martin.Wilck@Fujitsu-Siemens.com>");
X
X	line += 2;
X	wattron (iwin, A_UNDERLINE);
X	mvwprintw (iwin, line, 0, "Keyboard controls:");
X	wattroff (iwin, A_UNDERLINE);
X
X	mvwprintw (iwin, ++line, 0, "h or ?");
X	mvwprintw (iwin, line, HELP_TAB, "Show this help");
X	mvwprintw (iwin, ++line, 0, "q or x");
X	mvwprintw (iwin, line, HELP_TAB, "Exit utility");
X
X	mvwprintw (iwin, ++line, 0, "+,-");
X	mvwprintw (iwin, line, HELP_TAB, "Increase / decrease update interval by 1/10 sec");
X
X	mvwprintw (iwin, ++line, 0, "i");
X	wattron (iwin, A_UNDERLINE);
X	mvwprintw (iwin, line, HELP_TAB, "Info mode: show IO-TLB usage summary");
X	wattroff (iwin, A_UNDERLINE);
X
X	mvwprintw (iwin, ++line, 0, "c");
X	wattron (iwin, A_UNDERLINE);
X	mvwprintw (iwin, line, HELP_TAB, "Condensed mode: show condensed slot usage map");
X	wattroff (iwin, A_UNDERLINE);
X	mvwprintw (iwin, ++line, HELP_TAB, "Each character represents 16 IO-TLB slots");
X	mvwprintw (iwin, ++line, HELP_TAB, "Hex digit 0-F: Number of free slots in group");
X	mvwprintw (iwin, ++line, HELP_TAB, "*            : all slots in group are free");
X
X	mvwprintw (iwin, ++line, 0, "d");
X	wattron (iwin, A_UNDERLINE);
X	mvwprintw (iwin, line, HELP_TAB, "Detailed mode: show detailed slot usage map");
X	wattroff (iwin, A_UNDERLINE);
X	mvwprintw (iwin, ++line, HELP_TAB, "Each character represents a single IO-TLB slot");
X	mvwprintw (iwin, ++line, HELP_TAB, "0            : slot occupied");
X	mvwprintw (iwin, ++line, HELP_TAB, "1-9, a-z, A-Z: number of free slots (including current)");
X	mvwprintw (iwin, ++line, HELP_TAB, "               after current position");
X	mvwprintw (iwin, ++line, HELP_TAB, "-            : >= 61 slots starting from current are free");
X
X	mvwprintw (iwin, ++line, 0, "f");
X	mvwprintw (iwin, line, HELP_TAB, "Toggle Follow mode: Page follows slot index "
X		   "(detailed / condensed mode)");
X	mvwprintw (iwin, ++line, 0, "p,n");
X	mvwprintw (iwin, line, HELP_TAB, "Previous / next page (detailed and condensed mode)");
X	mvwprintw (iwin, ++line, 0, "<,>");
X	mvwprintw (iwin, line, HELP_TAB, "First / last page (detailed and condensed mode)");
X
X	wrefresh (iwin);
X
X	current_msg = help_exit_msg;
X	refresh_cwin ();
}
X
run_t
handle_input (run_t run)
{
X	chtype ch;
X	ch = wgetch(cwin);
X	if (ch != ERR) {
X		switch (ch) {
X		case '+':
X			if (interval < MAX_INTERVAL) {
X				interval++;
X				start_timer (interval);
X			};
X			break;
X		case '-':
X			if (interval > MIN_INTERVAL) {
X				interval--;
X				start_timer (interval);
X			};
X			break;
X		case 'h':
X		case '?':
X			run = HELP;
X			werase (pwin);
X			wrefresh (pwin);
X			help ();
X			break;
X		case 'i':
X			run = PARAMS;
X			werase (iwin);
X			wrefresh (iwin);
X			box (pwin, 0, 0);
X			current_msg = help_msg;
X			break;
X		case 'd':
X		case 'l':
X			run = LIST;
X			werase (pwin);
X			wrefresh (pwin);
X			current_msg = help_msg;
X			break;
X		case 'c':
X		case 'g':
X			run = GROUP;
X			werase (pwin);
X			wrefresh (pwin);
X			current_msg = help_msg;
X			break;
X		case 'q':
X		case 'x':
X			run = QUIT;
X			break;
X		case 'f':
X			follow_index = ~follow_index & 1;
X			if (follow_index)
X				current_msg = follow_on_msg;
X			else
X				current_msg = follow_off_msg;
X			break;
X		case '<':
X			first_index = 0;
X			break;
X		case '>':
X			first_index = 1 << 24;
X			break;
X		case 'n':
X			first_index += INDEX_STEP;
X			break;
X		case 'p':
X			first_index -= INDEX_STEP;
X			break;
X 		default:
X			break;
X		};
X		refresh_cwin ();
X	};
X
X	return run;
}
X
int
main (int argc, char **argv)
{
X	sigset_t alrm_mask;
X	run_t run = PARAMS;
X
X	iotlb_fd = open (params_name, O_RDONLY, 0);
X	list_fd = open (list_name, O_RDONLY, 0);
X	if (iotlb_fd < 0 || list_fd < 0) {
X		perror ("open");
X		fprintf (stderr, "ERROR: Could not open /proc/swiotlb.\n"
X			 "     Is the swiotlb_proc module loaded ?\n");
X		exit (1);
X	};
X
X	current_msg = help_msg;
X	mainwin = initscr ();
X	cbreak ();
X	noecho ();
X
X	create_windows ();
X
X	sigemptyset (&alrm_mask);
X	sigaddset (&alrm_mask, SIGALRM);
X
X	start_timer (interval);
X
X	while (run != QUIT) {
X		run = handle_input (run);
X		sigprocmask (SIG_BLOCK, &alrm_mask, NULL);
X		if (alarm_received) {
X			alarm_received = 0;
X			switch (run) {
X			case PARAMS:
X				print_info ();
X				break;
X			case LIST:
X				print_list ();
X				break;
X			case GROUP:
X				print_list_group ();
X				break;
X			default:
X				break;
X			};
X		};
X		sigprocmask (SIG_UNBLOCK, &alrm_mask, NULL);
X	};
X
X	cleanup ();
X	return 0;
}
SHAR_EOF
  (set 20 01 06 25 21 13 10 'iotlb-mon-0.2/iotlb-mon.c'; eval "$shar_touch") &&
  chmod 0664 'iotlb-mon-0.2/iotlb-mon.c' ||
  $echo 'restore of' 'iotlb-mon-0.2/iotlb-mon.c' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'iotlb-mon-0.2/iotlb-mon.c:' 'MD5 check failed'
8efeb5b0783014a807e2095824095158  iotlb-mon-0.2/iotlb-mon.c
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'iotlb-mon-0.2/iotlb-mon.c'`"
    test 12720 -eq "$shar_count" ||
    $echo 'iotlb-mon-0.2/iotlb-mon.c:' 'original size' '12720,' 'current size' "$shar_count!"
  fi
fi
# ======= iotlb-mon-0.2/swiotlb_proc.patch =======
if test -f 'iotlb-mon-0.2/swiotlb_proc.patch' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'iotlb-mon-0.2/swiotlb_proc.patch' '(file already exists)'
else
  $echo 'x -' extracting 'iotlb-mon-0.2/swiotlb_proc.patch' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'iotlb-mon-0.2/swiotlb_proc.patch' &&
diff -ruN linux-2.4.5/Documentation/Configure.help linux-2.4.5mw/Documentation/Configure.help
--- linux-2.4.5/Documentation/Configure.help	Mon Jun 25 14:45:01 2001
+++ linux-2.4.5mw/Documentation/Configure.help	Mon Jun 25 21:02:47 2001
@@ -17776,6 +17776,21 @@
X   To use this option, you have to check that the "/proc file system
X   support" (CONFIG_PROC_FS) is enabled, too.
X
+/proc/swiotlb support
+CONFIG_PROCFS_SWIOTLB
+  If you say Y here, you will find information on the software
+  IO-TLB usage in your machine in /proc/swiotlb.
+
+  IO-TLBs (Translation Lookaside Buffers) are needed if PCI devices
+  unable to do 64-bit addressing are used in machines with large RAM.
+  This is mainly useful for debugging purposes on machines with
+  >= 4GB RAM.
+
+  To use this option, you have to check that the "/proc file system
+  support" (CONFIG_PROC_FS) is enabled, too.
+
+  If unsure, say N.
+
X #
X # A couple of things I keep forgetting:
X #   capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet,
diff -ruN linux-2.4.5/arch/ia64/config.in linux-2.4.5mw/arch/ia64/config.in
--- linux-2.4.5/arch/ia64/config.in	Mon Jun 25 14:45:01 2001
+++ linux-2.4.5mw/arch/ia64/config.in	Mon Jun 25 21:02:47 2001
@@ -111,6 +111,7 @@
X bool 'Performance monitor support' CONFIG_PERFMON
X tristate '/proc/pal support' CONFIG_IA64_PALINFO
X tristate '/proc/efi/vars support' CONFIG_EFI_VARS
+tristate '/proc/swiotlb support' CONFIG_PROCFS_SWIOTLB
X
X bool 'Networking support' CONFIG_NET
X bool 'System V IPC' CONFIG_SYSVIPC
diff -ruN linux-2.4.5/arch/ia64/kernel/Makefile linux-2.4.5mw/arch/ia64/kernel/Makefile
--- linux-2.4.5/arch/ia64/kernel/Makefile	Mon Jun 25 14:45:01 2001
+++ linux-2.4.5mw/arch/ia64/kernel/Makefile	Mon Jun 25 21:02:47 2001
@@ -20,6 +20,7 @@
X obj-$(CONFIG_IA64_DIG) += iosapic.o
X obj-$(CONFIG_IA64_PALINFO) += palinfo.o
X obj-$(CONFIG_EFI_VARS) += efivars.o
+obj-$(CONFIG_PROCFS_SWIOTLB) += swiotlb_proc.o
X obj-$(CONFIG_PCI) += pci.o
X obj-$(CONFIG_SMP) += smp.o smpboot.o
X obj-$(CONFIG_IA64_MCA) += mca.o mca_asm.o
diff -ruN linux-2.4.5/arch/ia64/kernel/swiotlb_proc.c linux-2.4.5mw/arch/ia64/kernel/swiotlb_proc.c
--- linux-2.4.5/arch/ia64/kernel/swiotlb_proc.c	Thu Jan  1 01:00:00 1970
+++ linux-2.4.5mw/arch/ia64/kernel/swiotlb_proc.c	Mon Jun 25 18:44:47 2001
@@ -0,0 +1,176 @@
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/malloc.h>
+#include <linux/proc_fs.h>
+
+MODULE_AUTHOR("Martin Wilck <Martin.Wilck@Fujitsu-Siemens.com>");
+MODULE_DESCRIPTION("/proc interface for software IO/TLB status");
+
+struct iotlb_info_struct {
+	unsigned long n_slots;
+	unsigned int index;
+	unsigned int used_buffers;
+	unsigned int used_slots;
+	unsigned int max_used_buffers;
+	unsigned int max_used_slots;
+	void *start;
+	void *end;
+};
+
+/* Variables exported from arch/ia64/lib/swiotlb.c */
+extern char *io_tlb_start, *io_tlb_end;
+extern unsigned long io_tlb_nslabs;
+extern unsigned int *io_tlb_list;
+extern unsigned int io_tlb_index;
+extern unsigned int io_tlb_used_buffers;
+extern unsigned int io_tlb_used_slots;
+extern unsigned int io_tlb_max_used_buffers;
+extern unsigned int io_tlb_max_used_slots;
+
+static struct proc_dir_entry *swiotlb_proc_dir;
+static struct proc_dir_entry *proc_iotlb_list;
+static struct proc_dir_entry *proc_iotlb_params;
+static struct proc_dir_entry *proc_iotlb_parameters;
+
+static char *swiotlb_outbuf = NULL;
+
+static int
+read_iotlb_list(char *page, char **start, off_t offset, int count, int *eof, void *data)
+{
+	int nbytes = io_tlb_nslabs * sizeof (int);
+	int kbytes = count + offset;
+	char *buf;
+	int cnt;
+
+	MOD_INC_USE_COUNT;
+	if (nbytes > PAGE_SIZE) {
+		if (!swiotlb_outbuf) {
+			swiotlb_outbuf = kmalloc (io_tlb_nslabs * sizeof (int), GFP_KERNEL);
+			if (!swiotlb_outbuf) {
+				cnt = -ENOMEM;
+				goto exit;
+			};
+		};
+		*start = buf = swiotlb_outbuf + offset;
+	} else {
+		buf = page + offset;
+	};
+
+	/* copy only if offset = 0 for max consistency */
+	if (!offset)
+		memcpy (buf, (char*) io_tlb_list, nbytes);
+
+	if (kbytes < nbytes)
+		cnt = count;
+	else {
+		cnt = nbytes - offset;
+		if (cnt < 0)
+			cnt = 0;
+		*eof = 1;
+	};
+
+ exit:
+	MOD_DEC_USE_COUNT;
+	return cnt;
+
+}
+
+static int
+read_iotlb_params(char *page, char **start, off_t offset, int count, int *eof, void *data)
+{
+	struct iotlb_info_struct *iotlb_params +		(struct iotlb_info_struct*) page;
+	const int nbytes = sizeof (struct iotlb_info_struct);
+	int res;
+
+	MOD_INC_USE_COUNT;
+
+	iotlb_params->n_slots = io_tlb_nslabs;
+	iotlb_params->index = io_tlb_index;
+	iotlb_params->used_buffers = io_tlb_used_buffers;
+	iotlb_params->used_slots = io_tlb_used_slots;
+	iotlb_params->max_used_buffers = io_tlb_max_used_buffers;
+	iotlb_params->max_used_slots = io_tlb_max_used_slots;
+	iotlb_params->start = io_tlb_start;
+	iotlb_params->end = io_tlb_end;
+
+	if (offset + count >= nbytes) {
+		*eof = 1;
+		res = (nbytes - offset < 0 ? 0 : nbytes - offset);
+	} else {
+		res = count;
+	};
+
+	MOD_DEC_USE_COUNT;
+	return res;
+}
+
+static int
+read_iotlb_parameters(char *page, char **start, off_t offset, int count, int *eof, void *data)
+{
+	int len, res;
+	MOD_INC_USE_COUNT;
+	len = sprintf (page,
+		       "Slots allocated  : %8ld\n"
+		       "Current Index    : %8d\n"
+		       "Buffers used     : %8d\n"
+		       "Slots used       : %8d\n"
+		       "Max Buffers used : %8d\n"
+		       "Max Slots used   : %8d\n"
+		       "Start address    : 0x%p\n"
+		       "End address      : 0x%p\n",
+		       io_tlb_nslabs,
+		       io_tlb_index,
+		       io_tlb_used_buffers,
+		       io_tlb_used_slots,
+		       io_tlb_max_used_buffers,
+		       io_tlb_max_used_slots,
+		       (void*) io_tlb_start,
+		       (void*) io_tlb_end);
+	if (offset + count >= len) {
+		*eof = 1;
+		len -= offset;
+		res = (len < 0 ? 0 : len);
+	} else
+		res = count;
+	MOD_DEC_USE_COUNT;
+	return res;
+}
+
+static int __init
+swiotlb_init_proc (void)
+{
+	printk (KERN_INFO "Loading /proc/swiotlb support\n");
+
+	swiotlb_proc_dir = proc_mkdir ("swiotlb", NULL);
+	proc_iotlb_list +		create_proc_entry ("list", 0444, swiotlb_proc_dir);
+	proc_iotlb_params +		create_proc_entry ("params", 0444, swiotlb_proc_dir);
+	proc_iotlb_parameters +		create_proc_entry ("parameters", 0444, swiotlb_proc_dir);
+
+	proc_iotlb_list->read_proc = read_iotlb_list;
+	proc_iotlb_params->read_proc = read_iotlb_params;
+	proc_iotlb_parameters->read_proc = read_iotlb_parameters;
+
+	return 0;
+}
+
+
+static void __exit
+swiotlb_exit_proc (void)
+{
+	printk (KERN_INFO "Unloading /proc/swiotlb support\n");
+	if (swiotlb_outbuf)
+		kfree (swiotlb_outbuf);
+	remove_proc_entry ("list", swiotlb_proc_dir);
+	remove_proc_entry ("params", swiotlb_proc_dir);
+	remove_proc_entry ("parameters", swiotlb_proc_dir);
+	remove_proc_entry ("swiotlb", 0);
+}
+
+module_init(swiotlb_init_proc);
+module_exit(swiotlb_exit_proc);
diff -ruN linux-2.4.5/arch/ia64/lib/swiotlb.c linux-2.4.5mw/arch/ia64/lib/swiotlb.c
--- linux-2.4.5/arch/ia64/lib/swiotlb.c	Mon Jun 25 14:45:01 2001
+++ linux-2.4.5mw/arch/ia64/lib/swiotlb.c	Mon Jun 25 21:02:47 2001
@@ -24,6 +24,13 @@
X #include <linux/init.h>
X #include <linux/bootmem.h>
X
+#if defined CONFIG_PROCFS_SWIOTLB || defined CONFIG_PROCFS_SWIOTLB_MODULE
+#   define EXPORT_IOTLB_SYMS 1
+#   define IOTLB_STATIC
+#else
+#   define IOTLB_STATIC static
+#endif
+
X #define ALIGN(val, align) ((unsigned long)	\
X 	(((unsigned long) (val) + ((align) - 1)) & ~((align) - 1)))
X
@@ -36,19 +43,19 @@
X  * Used to do a quick range check in swiotlb_unmap_single and swiotlb_sync_single, to see
X  * if the memory was in fact allocated by this API.
X  */
-static char *io_tlb_start, *io_tlb_end;
+IOTLB_STATIC char *io_tlb_start, *io_tlb_end;
X
X /*
X  * The number of IO TLB blocks (in groups of 64) betweeen io_tlb_start and io_tlb_end.
X  * This is command line adjustable via setup_io_tlb_npages.
X  */
-static unsigned long io_tlb_nslabs = 1024;
+IOTLB_STATIC unsigned long io_tlb_nslabs = 1024;
X
X /*
X  * This is a free list describing the number of free entries available from each index
X  */
-static unsigned int *io_tlb_list;
-static unsigned int io_tlb_index;
+IOTLB_STATIC unsigned int *io_tlb_list;
+IOTLB_STATIC unsigned int io_tlb_index;
X
X /*
X  * We need to save away the original address corresponding to a mapped entry for the sync
@@ -56,6 +63,16 @@
X  */
X static unsigned char **io_tlb_orig_addr;
X
+#ifdef EXPORT_IOTLB_SYMS
+/*
+ * Usage data for /proc entries
+ */
+unsigned int io_tlb_used_buffers = 0;
+unsigned int io_tlb_used_slots = 0;
+unsigned int io_tlb_max_used_buffers = 0;
+unsigned int io_tlb_max_used_slots = 0;
+#endif
+
X /*
X  * Protect the above data structures in the map and unmap calls
X  */
@@ -173,6 +190,15 @@
X   found:
X 	spin_unlock_irqrestore(&io_tlb_lock, flags);
X
+#ifdef EXPORT_IOTLB_SYMS
+	io_tlb_used_slots += nslots;
+	io_tlb_used_buffers++;
+	if (io_tlb_used_slots > io_tlb_max_used_slots)
+		io_tlb_max_used_slots = io_tlb_used_slots;
+	if (io_tlb_used_buffers > io_tlb_max_used_buffers)
+		io_tlb_max_used_buffers = io_tlb_used_buffers;
+#endif
+
X 	/*
X 	 * Save away the mapping from the original address to the DMA address.  This is
X 	 * needed when we sync the memory.  Then we sync the buffer if needed.
@@ -228,6 +254,10 @@
X 			io_tlb_list[i] = ++count;
X 	}
X 	spin_unlock_irqrestore(&io_tlb_lock, flags);
+#ifdef EXPORT_IOTLB_SYMS
+	io_tlb_used_buffers--;
+	io_tlb_used_slots -= nslots;
+#endif
X }
X
X static void
@@ -462,3 +492,15 @@
X EXPORT_SYMBOL(swiotlb_dma_address);
X EXPORT_SYMBOL(swiotlb_alloc_consistent);
X EXPORT_SYMBOL(swiotlb_free_consistent);
+
+#ifdef EXPORT_IOTLB_SYMS
+EXPORT_SYMBOL(io_tlb_start);
+EXPORT_SYMBOL(io_tlb_end);
+EXPORT_SYMBOL(io_tlb_nslabs);
+EXPORT_SYMBOL(io_tlb_index);
+EXPORT_SYMBOL(io_tlb_list);
+EXPORT_SYMBOL(io_tlb_used_buffers);
+EXPORT_SYMBOL(io_tlb_used_slots);
+EXPORT_SYMBOL(io_tlb_max_used_buffers);
+EXPORT_SYMBOL(io_tlb_max_used_slots);
+#endif  /* EXPORT_IOTLB_SYMS */
SHAR_EOF
  (set 20 01 06 25 21 05 57 'iotlb-mon-0.2/swiotlb_proc.patch'; eval "$shar_touch") &&
  chmod 0664 'iotlb-mon-0.2/swiotlb_proc.patch' ||
  $echo 'restore of' 'iotlb-mon-0.2/swiotlb_proc.patch' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'iotlb-mon-0.2/swiotlb_proc.patch:' 'MD5 check failed'
509bf43c7d000ddf3845d2c791277122  iotlb-mon-0.2/swiotlb_proc.patch
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'iotlb-mon-0.2/swiotlb_proc.patch'`"
    test 10022 -eq "$shar_count" ||
    $echo 'iotlb-mon-0.2/swiotlb_proc.patch:' 'original size' '10022,' 'current size' "$shar_count!"
  fi
fi
rm -fr _sh04019
exit 0




                 reply	other threads:[~2001-06-25 19:30 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=marc-linux-ia64-105590693005758@msgid-missing \
    --to=martin.wilck@fujitsu-siemens.com \
    --cc=linux-ia64@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.