si_swapinfo patch

Uwe Ohse (uwe@tirka.gun.de)
Tue, 8 Apr 1997 00:47:36 +0200 (MET DST)


Hello,

the following patch makes si_swapinfo much more efficient.
On my (unloaded, at the moment) 2*P133 machine with about 300M swap
space si_swapinfo was the most time consuming function in the kernel.

The diff is make against 2.1.32 but should patch cleanly into 2.0.29 as
well.

While i'm looking at it: is it guaranted that no swap page is ever
duplicated 128 times or more?

Regards, Uwe
------------------------------------------------------------------------
--- include/linux/swap.h.old Tue Mar 25 01:43:05 1997
+++ include/linux/swap.h Mon Apr 7 21:59:21 1997
@@ -29,6 +29,8 @@
unsigned int cluster_nr;
int prio; /* swap priority */
int pages;
+ int total; /* statistics */
+ int free; /* statistics */
unsigned long max;
int next; /* next entry on swap list */
};
--- mm/swapfile.c.old Mon Apr 7 21:38:04 1997
+++ mm/swapfile.c Mon Apr 7 22:14:37 1997
@@ -69,6 +69,7 @@
si->lowest_bit = offset;
got_page:
si->swap_map[offset] = 1;
+ si->free--;
nr_swap_pages--;
if (offset == si->highest_bit)
si->highest_bit--;
@@ -152,8 +153,10 @@
if (!p->swap_map[offset])
printk("swap_free: swap-space map bad (entry %08lx)\n",entry);
else
- if (!--p->swap_map[offset])
+ if (!--p->swap_map[offset]) {
+ p->free++;
nr_swap_pages++;
+ }
if (p->prio > swap_info[swap_list.next].prio) {
swap_list.next = swap_list.head;
}
@@ -412,7 +415,7 @@
int get_swaparea_info(char *buf)
{
struct swap_info_struct *ptr = swap_info;
- int i, j, len = 0, usedswap;
+ int i, len = 0;

len += sprintf(buf, "Filename\t\t\tType\t\tSize\tUsed\tPriority\n");
for (i = 0 ; i < nr_swapfiles ; i++, ptr++)
@@ -425,17 +428,8 @@
len += sprintf(buf + len, "file\t\t");
else
len += sprintf(buf + len, "partition\t");
- usedswap = 0;
- for (j = 0; j < ptr->max; ++j)
- switch (ptr->swap_map[j]) {
- case 128:
- case 0:
- continue;
- default:
- usedswap++;
- }
len += sprintf(buf + len, "%d\t%d\t%d\n", ptr->pages << (PAGE_SHIFT - 10),
- usedswap << (PAGE_SHIFT - 10), ptr->prio);
+ (ptr->total-ptr->free) << (PAGE_SHIFT - 10), ptr->prio);
}
return len;
}
@@ -478,6 +472,7 @@
p->highest_bit = 0;
p->cluster_nr = 0;
p->max = 1;
+ p->free = 0;
p->next = -1;
if (swap_flags & SWAP_FLAG_PREFER) {
p->prio =
@@ -555,11 +550,14 @@
goto bad_swap;
}
for (i = 1 ; i < p->max ; i++) {
- if (test_bit(i,p->swap_lockmap))
+ if (test_bit(i,p->swap_lockmap)) {
p->swap_map[i] = 0;
- else
+ p->free++;
+ } else {
p->swap_map[i] = 0x80;
+ }
}
+ p->total=p->free;
p->swap_map[0] = 0x80;
memset(p->swap_lockmap,0,PAGE_SIZE);
p->flags = SWP_WRITEOK;
@@ -609,21 +607,14 @@

void si_swapinfo(struct sysinfo *val)
{
- unsigned int i, j;
+ unsigned int i;

val->freeswap = val->totalswap = 0;
for (i = 0; i < nr_swapfiles; i++) {
if ((swap_info[i].flags & SWP_WRITEOK) != SWP_WRITEOK)
continue;
- for (j = 0; j < swap_info[i].max; ++j)
- switch (swap_info[i].swap_map[j]) {
- case 128:
- continue;
- case 0:
- ++val->freeswap;
- default:
- ++val->totalswap;
- }
+ val->freeswap+=swap_info[i].free;
+ val->totalswap+=swap_info[i].total;
}
val->freeswap <<= PAGE_SHIFT;
val->totalswap <<= PAGE_SHIFT;