Commit e44db7e2 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] sqrt() fixes

It turns out that the int_sqrt() function in oom_kill.c gets it wrong.

But fb_sqrt() in fbmon.c gets its math right.  Move that function into
lib/int_sqrt.c, and consolidate.

(oom_kill.c fix from Thomas Schlichter <schlicht@uni-mannheim.de>)
parent 9b1ace8b
...@@ -890,30 +890,6 @@ struct __fb_timings { ...@@ -890,30 +890,6 @@ struct __fb_timings {
u32 vtotal; u32 vtotal;
}; };
/*
* a simple function to get the square root of integers
*/
static u32 fb_sqrt(int x)
{
register int op, res, one;
op = x;
res = 0;
one = 1 << 30;
while (one > op) one >>= 2;
while (one != 0) {
if (op >= res + one) {
op = op - (res + one);
res = res + 2 * one;
}
res /= 2;
one /= 4;
}
return((u32) res);
}
/** /**
* fb_get_vblank - get vertical blank time * fb_get_vblank - get vertical blank time
* @hfreq: horizontal freq * @hfreq: horizontal freq
...@@ -1002,7 +978,7 @@ static u32 fb_get_hblank_by_dclk(u32 dclk, u32 xres) ...@@ -1002,7 +978,7 @@ static u32 fb_get_hblank_by_dclk(u32 dclk, u32 xres)
h_period += (M_VAL * xres * 2 * 1000)/(5 * dclk); h_period += (M_VAL * xres * 2 * 1000)/(5 * dclk);
h_period *=10000; h_period *=10000;
h_period = fb_sqrt((int) h_period); h_period = int_sqrt(h_period);
h_period -= (100 - C_VAL) * 100; h_period -= (100 - C_VAL) * 100;
h_period *= 1000; h_period *= 1000;
h_period /= 2 * M_VAL; h_period /= 2 * M_VAL;
......
...@@ -87,6 +87,8 @@ extern int session_of_pgrp(int pgrp); ...@@ -87,6 +87,8 @@ extern int session_of_pgrp(int pgrp);
asmlinkage int printk(const char * fmt, ...) asmlinkage int printk(const char * fmt, ...)
__attribute__ ((format (printf, 1, 2))); __attribute__ ((format (printf, 1, 2)));
unsigned long int_sqrt(unsigned long);
static inline void console_silent(void) static inline void console_silent(void)
{ {
console_loglevel = 0; console_loglevel = 0;
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
lib-y := errno.o ctype.o string.o vsprintf.o cmdline.o \ lib-y := errno.o ctype.o string.o vsprintf.o cmdline.o \
bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \ bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \
kobject.o idr.o div64.o parser.o kobject.o idr.o div64.o parser.o int_sqrt.o
lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
......
#include <linux/kernel.h>
#include <linux/module.h>
/**
* int_sqrt - rough approximation to sqrt
* @x: integer of which to calculate the sqrt
*
* A very rough approximation to the sqrt() function.
*/
unsigned long int_sqrt(unsigned long x)
{
unsigned long op, res, one;
op = x;
res = 0;
one = 1 << 30;
while (one > op)
one >>= 2;
while (one != 0) {
if (op >= res + one) {
op = op - (res + one);
res = res + 2 * one;
}
res /= 2;
one /= 4;
}
return res;
}
EXPORT_SYMBOL(int_sqrt);
...@@ -23,20 +23,6 @@ ...@@ -23,20 +23,6 @@
/* #define DEBUG */ /* #define DEBUG */
/**
* int_sqrt - oom_kill.c internal function, rough approximation to sqrt
* @x: integer of which to calculate the sqrt
*
* A very rough approximation to the sqrt() function.
*/
static unsigned int int_sqrt(unsigned int x)
{
unsigned int out = x;
while (x & ~(unsigned int)1) x >>=2, out >>=1;
if (x) out -= out >> 2;
return (out ? out : 1);
}
/** /**
* oom_badness - calculate a numeric value for how bad this task has been * oom_badness - calculate a numeric value for how bad this task has been
* @p: task struct of which task we should calculate * @p: task struct of which task we should calculate
...@@ -57,7 +43,7 @@ static unsigned int int_sqrt(unsigned int x) ...@@ -57,7 +43,7 @@ static unsigned int int_sqrt(unsigned int x)
static int badness(struct task_struct *p) static int badness(struct task_struct *p)
{ {
int points, cpu_time, run_time; int points, cpu_time, run_time, s;
if (!p->mm) if (!p->mm)
return 0; return 0;
...@@ -77,8 +63,12 @@ static int badness(struct task_struct *p) ...@@ -77,8 +63,12 @@ static int badness(struct task_struct *p)
cpu_time = (p->utime + p->stime) >> (SHIFT_HZ + 3); cpu_time = (p->utime + p->stime) >> (SHIFT_HZ + 3);
run_time = (get_jiffies_64() - p->start_time) >> (SHIFT_HZ + 10); run_time = (get_jiffies_64() - p->start_time) >> (SHIFT_HZ + 10);
points /= int_sqrt(cpu_time); s = int_sqrt(cpu_time);
points /= int_sqrt(int_sqrt(run_time)); if (s)
points /= s;
s = int_sqrt(int_sqrt(run_time));
if (s)
points /= s;
/* /*
* Niced processes are most likely less important, so double * Niced processes are most likely less important, so double
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment