lkml.org 
[lkml]   [2000]   [Oct]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patches in this message
/
Date
From
Subject[PATCH] 2.2.18pre13: Small patches from Andrea
I suppose I should let Andrea submit these, but he has such a huge
patch collection (thank you!) that I thought it might be useful to
pick out some of the smaller ones that would be less controversial
for inclusion in the main kernel.

* nanosleep-4
Provide nanosleep usec resolution so that a signal flood doesn't hang
glibc folks that correctly trust the rem field to resume the nanosleep
after a syscall interruption. (without the patch nanosleep resolution
is instead 10msec on IA32 and around 1msec on alpha)
* tsc-calibration-non-compile-time-1
TSC calibration must be dynamic and not a compile time thing because
gettimeofday is dynamic and it depends on the TSCs to be in sync.
* IO-wait-2
Avoid spurious unplug of the I/O queue.
* buf-run_task_queue
Avoid spurious unplug of the I/O queue. (again!)
* account-failed-buffer-tries-1
Account also for failed buffer tries during shrink_mmap.
* overcommit-1
Make sure to not understimate the available memory (the cache and
buffers may be under the min percent).

--
Chip Salzenberg - a.k.a. - <chip@valinux.com>
"I wanted to play hopscotch with the impenetrable mystery of existence,
but he stepped in a wormhole and had to go in early." // MST3K
Tag: KERNEL-2-2-18-PRE11-PATCH-6
Patch: nanosleep-4
From: Andrea Arcangeli <andrea@suse.de>

Provide nanosleep usec resolution so that a signal flood doesn't hang
glibc folks that correctly trust the rem field to resume the nanosleep
after a syscall interruption. (without the patch nanosleep resolution
is instead 10msec on IA32 and around 1msec on alpha)


Index: linux/arch/alpha/kernel/time.c
diff -u linux/arch/alpha/kernel/time.c:1.2 linux/arch/alpha/kernel/time.c:1.2.6.1
--- linux/arch/alpha/kernel/time.c:1.2 Wed Sep 13 08:32:22 2000
+++ linux/arch/alpha/kernel/time.c Wed Sep 27 23:55:48 2000
@@ -339,8 +339,22 @@
irq_handler = timer_interrupt;
if (request_irq(TIMER_IRQ, irq_handler, 0, "timer", NULL))
panic("Could not allocate timer IRQ!");
+ do_get_fast_time = do_gettimeofday;
}

+static inline void
+timeval_normalize(struct timeval * tv)
+{
+ time_t __sec;
+
+ __sec = tv->tv_usec / 1000000;
+ if (__sec)
+ {
+ tv->tv_usec %= 1000000;
+ tv->tv_sec += __sec;
+ }
+}
+
/*
* Use the cycle counter to estimate an displacement from the last time
* tick. Unfortunately the Alpha designers made only the low 32-bits of
@@ -389,13 +403,11 @@
#endif

usec += delta_usec;
- if (usec >= 1000000) {
- sec += 1;
- usec -= 1000000;
- }

tv->tv_sec = sec;
tv->tv_usec = usec;
+
+ timeval_normalize(tv);
}

void
Index: linux/arch/i386/kernel/time.c
diff -u linux/arch/i386/kernel/time.c:1.2 linux/arch/i386/kernel/time.c:1.2.6.1
--- linux/arch/i386/kernel/time.c:1.2 Wed Sep 13 08:32:22 2000
+++ linux/arch/i386/kernel/time.c Wed Sep 27 23:55:48 2000
@@ -239,6 +239,20 @@

#endif

+/* FIXME: should be inline but gcc is buggy and breaks */
+static void
+timeval_normalize(struct timeval * tv)
+{
+ time_t __sec;
+
+ __sec = tv->tv_usec / 1000000;
+ if (__sec)
+ {
+ tv->tv_usec %= 1000000;
+ tv->tv_sec += __sec;
+ }
+}
+
/*
* This version of gettimeofday has microsecond resolution
* and better than microsecond precision on fast x86 machines with TSC.
@@ -259,13 +273,10 @@
usec += xtime.tv_usec;
read_unlock_irqrestore(&xtime_lock, flags);

- while (usec >= 1000000) {
- usec -= 1000000;
- sec++;
- }
-
tv->tv_sec = sec;
tv->tv_usec = usec;
+
+ timeval_normalize(tv);
}

void do_settimeofday(struct timeval *tv)
Index: linux/arch/ppc/kernel/time.c
diff -u linux/arch/ppc/kernel/time.c:1.2 linux/arch/ppc/kernel/time.c:1.2.14.1
--- linux/arch/ppc/kernel/time.c:1.2 Thu Jul 6 22:41:19 2000
+++ linux/arch/ppc/kernel/time.c Wed Sep 27 23:55:48 2000
@@ -147,6 +147,19 @@
hardirq_exit(cpu);
}

+static inline void
+timeval_normalize(struct timeval * tv)
+{
+ time_t __sec;
+
+ __sec = tv->tv_usec / 1000000;
+ if (__sec)
+ {
+ tv->tv_usec %= 1000000;
+ tv->tv_sec += __sec;
+ }
+}
+
/*
* This version of gettimeofday has microsecond resolution.
*/
@@ -161,10 +174,7 @@
#ifndef __SMP__
tv->tv_usec += (decrementer_count - get_dec())
* count_period_num / count_period_den;
- if (tv->tv_usec >= 1000000) {
- tv->tv_usec -= 1000000;
- tv->tv_sec++;
- }
+ timeval_normalize(tv);
#endif
restore_flags(flags);
}
Index: linux/include/linux/time.h
diff -u linux/include/linux/time.h:1.1 linux/include/linux/time.h:1.1.14.1
--- linux/include/linux/time.h:1.1 Thu Jul 6 22:04:59 2000
+++ linux/include/linux/time.h Wed Sep 27 23:55:48 2000
@@ -46,10 +46,53 @@
value->tv_sec = jiffies / HZ;
}

+static __inline__ int
+timespec_before(struct timespec a, struct timespec b)
+{
+ if (a.tv_sec == b.tv_sec)
+ return a.tv_nsec < b.tv_nsec;
+ return a.tv_sec < b.tv_sec;
+}
+
+/* computes `a - b' and write the result in `result', assumes `a >= b' */
+static inline void
+timespec_less(struct timespec a, struct timespec b, struct timespec * result)
+{
+ if (a.tv_nsec < b.tv_nsec)
+ {
+ a.tv_sec--;
+ a.tv_nsec += 1000000000;
+ }
+
+ result->tv_sec = a.tv_sec - b.tv_sec;
+ result->tv_nsec = a.tv_nsec - b.tv_nsec;
+}
+
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
+
+/* computes `a - b' and write the result in `result', assumes `a >= b' */
+static inline void
+timeval_less(struct timeval a, struct timeval b, struct timeval * result)
+{
+ if (a.tv_usec < b.tv_usec)
+ {
+ a.tv_sec--;
+ a.tv_usec += 1000000;
+ }
+
+ result->tv_sec = a.tv_sec - b.tv_sec;
+ result->tv_usec = a.tv_usec - b.tv_usec;
+}
+
+static __inline__ void
+timeval_to_timespec(struct timeval tv, struct timespec * ts)
+{
+ ts->tv_sec = tv.tv_sec;
+ ts->tv_nsec = (long) tv.tv_usec * 1000;
+}

struct timezone {
int tz_minuteswest; /* minutes west of Greenwich */
Index: linux/kernel/sched.c
diff -u linux/kernel/sched.c:1.2.10.2 linux/kernel/sched.c:1.2.10.3
--- linux/kernel/sched.c:1.2.10.2 Wed Sep 27 23:55:16 2000
+++ linux/kernel/sched.c Wed Sep 27 23:55:48 2000
@@ -1946,6 +1946,7 @@
{
struct timespec t;
unsigned long expire;
+ struct timeval before, after;

if(copy_from_user(&t, rqtp, sizeof(struct timespec)))
return -EFAULT;
@@ -1970,11 +1971,20 @@
expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec);

current->state = TASK_INTERRUPTIBLE;
+ get_fast_time(&before);
expire = schedule_timeout(expire);
+ get_fast_time(&after);

if (expire) {
if (rmtp) {
- jiffies_to_timespec(expire, &t);
+ struct timespec elapsed;
+
+ timeval_less(after, before, &after);
+ timeval_to_timespec(after, &elapsed);
+ if (timespec_before(elapsed, t))
+ timespec_less(t, elapsed, &t);
+ else
+ t.tv_nsec = t.tv_sec = 0;
if (copy_to_user(rmtp, &t, sizeof(struct timespec)))
return -EFAULT;
}Tag: KERNEL-2-2-18-PRE11-PATCH-17
Patch: tsc-calibration-non-compile-time-1
From: Andrea Arcangeli <andrea@suse.de>

TSC calibration must be dynamic and not a compile time thing because
gettimeofday is dynamic and it depends on the TSCs to be in sync.


Index: linux/arch/i386/kernel/smp.c
diff -u linux/arch/i386/kernel/smp.c:1.3.6.1 linux/arch/i386/kernel/smp.c:1.3.6.2
--- linux/arch/i386/kernel/smp.c:1.3.6.1 Wed Sep 27 23:54:02 2000
+++ linux/arch/i386/kernel/smp.c Thu Sep 28 00:03:31 2000
@@ -795,7 +795,6 @@
return memory_start;
}

-#ifdef CONFIG_X86_TSC
/*
* TSC synchronization.
*
@@ -995,8 +994,6 @@
}
#undef NR_LOOPS

-#endif
-
extern void calibrate_delay(void);

void __init smp_callin(void)
@@ -1083,12 +1080,11 @@
*/
set_bit(cpuid, (unsigned long *)&cpu_callin_map[0]);

-#ifdef CONFIG_X86_TSC
/*
* Synchronize the TSC with the BP
*/
- synchronize_tsc_ap ();
-#endif
+ if (boot_cpu_data.x86_capability & X86_FEATURE_TSC)
+ synchronize_tsc_ap ();
}

int cpucount = 0;
@@ -1624,13 +1620,11 @@

smp_done:

-#ifdef CONFIG_X86_TSC
/*
* Synchronize the TSC with the AP
*/
- if (cpucount)
+ if (boot_cpu_data.x86_capability & X86_FEATURE_TSC && cpucount)
synchronize_tsc_bp();
-#endif
}

/*Tag: KERNEL-2-2-18-PRE11-PATCH-8
Patch: IO-wait-2
From: Andrea Arcangeli <andrea@suse.de>

Avoid spurious unplug of the I/O queue.


Index: linux/fs/buffer.c
diff -u linux/fs/buffer.c:1.2 linux/fs/buffer.c:1.2.14.1
--- linux/fs/buffer.c:1.2 Thu Jul 6 22:41:37 2000
+++ linux/fs/buffer.c Wed Sep 27 23:57:09 2000
@@ -143,13 +143,14 @@
bh->b_count++;
wait.task = tsk;
add_wait_queue(&bh->b_wait, &wait);
-repeat:
- tsk->state = TASK_UNINTERRUPTIBLE;
- run_task_queue(&tq_disk);
- if (buffer_locked(bh)) {
+ do {
+ run_task_queue(&tq_disk);
+ tsk->state = TASK_UNINTERRUPTIBLE;
+ mb();
+ if (!buffer_locked(bh))
+ break;
schedule();
- goto repeat;
- }
+ } while (buffer_locked(bh));
tsk->state = TASK_RUNNING;
remove_wait_queue(&bh->b_wait, &wait);
bh->b_count--;
Index: linux/mm/filemap.c
diff -u linux/mm/filemap.c:1.4 linux/mm/filemap.c:1.4.4.1
--- linux/mm/filemap.c:1.4 Thu Sep 21 19:43:11 2000
+++ linux/mm/filemap.c Wed Sep 27 23:57:09 2000
@@ -357,13 +357,14 @@

wait.task = tsk;
add_wait_queue(&page->wait, &wait);
-repeat:
- tsk->state = TASK_UNINTERRUPTIBLE;
- sync_page(page);
- if (PageLocked(page)) {
+ do {
+ sync_page(page);
+ tsk->state = TASK_UNINTERRUPTIBLE;
+ mb();
+ if (!PageLocked(page))
+ break;
schedule();
- goto repeat;
- }
+ } while (PageLocked(page));
tsk->state = TASK_RUNNING;
remove_wait_queue(&page->wait, &wait);
}Tag: KERNEL-2-2-18-PRE11-PATCH-14
Patch: buf-run_task_queue
From: Andrea Arcangeli <andrea@suse.de>

Avoid spurious unplug of the I/O queue.


Index: linux/fs/buffer.c
diff -u linux/fs/buffer.c:1.2.14.1 linux/fs/buffer.c:1.2.14.2
--- linux/fs/buffer.c:1.2.14.1 Wed Sep 27 23:57:09 2000
+++ linux/fs/buffer.c Thu Sep 28 00:01:06 2000
@@ -1758,7 +1758,6 @@
if (ncount) printk("sync_old_buffers: %d dirty buffers not on dirty list\n", ncount);
printk("Wrote %d/%d buffers\n", nwritten, ndirty);
#endif
- run_task_queue(&tq_disk);
return 0;
}
Tag: KERNEL-2-2-18-PRE11-PATCH-9
Patch: account-failed-buffer-tries-1
From: Andrea Arcangeli <andrea@suse.de>

Account also the failed buffer tries during shrink_mmap.


Index: linux/mm/filemap.c
diff -u linux/mm/filemap.c:1.4.4.1 linux/mm/filemap.c:1.4.4.2
--- linux/mm/filemap.c:1.4.4.1 Wed Sep 27 23:57:09 2000
+++ linux/mm/filemap.c Wed Sep 27 23:57:48 2000
@@ -188,6 +188,8 @@
if ((gfp_mask & __GFP_DMA) && !PageDMA(page))
continue;

+ count--;
+
/*
* Is it a page swap page? If so, we want to
* drop it if it is no longer used, even if it
@@ -233,7 +235,7 @@
return 1;
}

- } while (--count > 0);
+ } while (count > 0);
return 0;
}
Tag: KERNEL-2-2-18-PRE11-PATCH-11
Patch: overcommit-1
From: Andrea Arcangeli <andrea@suse.de>

Make sure to not understimate the available memory (the cache and
buffers may be under the min percent).


Index: linux/mm/mmap.c
diff -u linux/mm/mmap.c:1.2 linux/mm/mmap.c:1.2.4.1
--- linux/mm/mmap.c:1.2 Thu Sep 21 19:43:11 2000
+++ linux/mm/mmap.c Wed Sep 27 23:59:06 2000
@@ -66,7 +66,6 @@
free += page_cache_size;
free += nr_free_pages;
free += nr_swap_pages;
- free -= (page_cache.min_percent + buffer_mem.min_percent + 2)*num_physpages/100;
return free > pages;
}
\
 
 \ /
  Last update: 2005-03-22 12:39    [W:0.047 / U:4.452 seconds]
©2003-2018 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site