Commit 0b9ded43 authored by Linus Torvalds's avatar Linus Torvalds

v2.4.8.3 -> v2.4.8.4

  - Tim Hockin: NatSemi ethernet update
  - Kurt Garloff: make PS/2 mouse reconnect adjustable like 2.2.x
  - Daniel Phillips: unlazy use-once
  - David Miller: undo poll() limit braindamage
  - me: make return value from do_try_to_free_pages() meaningful
parent a45eec07
VERSION = 2 VERSION = 2
PATCHLEVEL = 4 PATCHLEVEL = 4
SUBLEVEL = 9 SUBLEVEL = 9
EXTRAVERSION =-pre3 EXTRAVERSION =-pre4
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
......
...@@ -63,6 +63,7 @@ static void kbd_write_output_w(int data); ...@@ -63,6 +63,7 @@ static void kbd_write_output_w(int data);
#ifdef CONFIG_PSMOUSE #ifdef CONFIG_PSMOUSE
static void aux_write_ack(int val); static void aux_write_ack(int val);
static void __aux_write_ack(int val); static void __aux_write_ack(int val);
static int aux_reconnect = 0;
#endif #endif
static spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED; static spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED;
...@@ -81,7 +82,8 @@ static volatile unsigned char resend; ...@@ -81,7 +82,8 @@ static volatile unsigned char resend;
static int __init psaux_init(void); static int __init psaux_init(void);
#define AUX_RECONNECT 170 /* scancode when ps2 device is plugged (back) in */ #define AUX_RECONNECT1 0xaa /* scancode1 when ps2 device is plugged (back) in */
#define AUX_RECONNECT2 0x00 /* scancode2 when ps2 device is plugged (back) in */
static struct aux_queue *queue; /* Mouse data buffer. */ static struct aux_queue *queue; /* Mouse data buffer. */
static int aux_count; static int aux_count;
...@@ -396,6 +398,7 @@ char pckbd_unexpected_up(unsigned char keycode) ...@@ -396,6 +398,7 @@ char pckbd_unexpected_up(unsigned char keycode)
static inline void handle_mouse_event(unsigned char scancode) static inline void handle_mouse_event(unsigned char scancode)
{ {
#ifdef CONFIG_PSMOUSE #ifdef CONFIG_PSMOUSE
static unsigned char prev_code;
if (mouse_reply_expected) { if (mouse_reply_expected) {
if (scancode == AUX_ACK) { if (scancode == AUX_ACK) {
mouse_reply_expected--; mouse_reply_expected--;
...@@ -403,12 +406,15 @@ static inline void handle_mouse_event(unsigned char scancode) ...@@ -403,12 +406,15 @@ static inline void handle_mouse_event(unsigned char scancode)
} }
mouse_reply_expected = 0; mouse_reply_expected = 0;
} }
else if(scancode == AUX_RECONNECT){ else if(scancode == AUX_RECONNECT2 && prev_code == AUX_RECONNECT1
&& aux_reconnect) {
printk (KERN_INFO "PS/2 mouse reconnect detected\n");
queue->head = queue->tail = 0; /* Flush input queue */ queue->head = queue->tail = 0; /* Flush input queue */
__aux_write_ack(AUX_ENABLE_DEV); /* ping the mouse :) */ __aux_write_ack(AUX_ENABLE_DEV); /* ping the mouse :) */
return; return;
} }
prev_code = scancode;
add_mouse_randomness(scancode); add_mouse_randomness(scancode);
if (aux_count) { if (aux_count) {
int head = queue->head; int head = queue->head;
...@@ -835,6 +841,14 @@ void __init pckbd_init_hw(void) ...@@ -835,6 +841,14 @@ void __init pckbd_init_hw(void)
#if defined CONFIG_PSMOUSE #if defined CONFIG_PSMOUSE
static int __init aux_reconnect_setup (char *str)
{
aux_reconnect = 1;
return 1;
}
__setup("psaux-reconnect", aux_reconnect_setup);
/* /*
* Check if this is a dual port controller. * Check if this is a dual port controller.
*/ */
......
This diff is collapsed.
...@@ -419,9 +419,6 @@ asmlinkage long sys_poll(struct pollfd * ufds, unsigned int nfds, long timeout) ...@@ -419,9 +419,6 @@ asmlinkage long sys_poll(struct pollfd * ufds, unsigned int nfds, long timeout)
if (nfds > NR_OPEN) if (nfds > NR_OPEN)
return -EINVAL; return -EINVAL;
if (nfds > current->files->max_fds)
nfds = current->files->max_fds;
if (timeout) { if (timeout) {
/* Careful about overflow in the intermediate values */ /* Careful about overflow in the intermediate values */
if ((unsigned long) timeout < MAX_SCHEDULE_TIMEOUT / HZ) if ((unsigned long) timeout < MAX_SCHEDULE_TIMEOUT / HZ)
......
...@@ -38,11 +38,22 @@ struct ethtool_drvinfo { ...@@ -38,11 +38,22 @@ struct ethtool_drvinfo {
u32 regdump_len; /* Amount of data from ETHTOOL_GREGS */ u32 regdump_len; /* Amount of data from ETHTOOL_GREGS */
}; };
#define SOPASS_MAX 6
/* wake-on-lan settings */
struct ethtool_wolinfo {
u32 cmd;
u32 supported;
u32 wolopts;
u8 sopass[SOPASS_MAX]; /* SecureOn(tm) password */
};
/* CMDs currently supported */ /* CMDs currently supported */
#define ETHTOOL_GSET 0x00000001 /* Get settings. */ #define ETHTOOL_GSET 0x00000001 /* Get settings. */
#define ETHTOOL_SSET 0x00000002 /* Set settings, privileged. */ #define ETHTOOL_SSET 0x00000002 /* Set settings, privileged. */
#define ETHTOOL_GDRVINFO 0x00000003 /* Get driver info. */ #define ETHTOOL_GDRVINFO 0x00000003 /* Get driver info. */
#define ETHTOOL_GREGS 0x00000004 /* Get NIC registers, privileged. */ #define ETHTOOL_GREGS 0x00000004 /* Get NIC registers, privileged. */
#define ETHTOOL_GWOL 0x00000005 /* Get wake-on-lan options. */
#define ETHTOOL_SWOL 0x00000006 /* Set wake-on-lan options. */
/* compatibility with older code */ /* compatibility with older code */
#define SPARC_ETH_GSET ETHTOOL_GSET #define SPARC_ETH_GSET ETHTOOL_GSET
...@@ -109,4 +120,13 @@ struct ethtool_drvinfo { ...@@ -109,4 +120,13 @@ struct ethtool_drvinfo {
#define AUTONEG_DISABLE 0x00 #define AUTONEG_DISABLE 0x00
#define AUTONEG_ENABLE 0x01 #define AUTONEG_ENABLE 0x01
/* Wake-On-Lan options. */
#define WAKE_PHY (1 << 0)
#define WAKE_UCAST (1 << 1)
#define WAKE_MCAST (1 << 2)
#define WAKE_BCAST (1 << 3)
#define WAKE_ARP (1 << 4)
#define WAKE_MAGIC (1 << 5)
#define WAKE_MAGICSECURE (1 << 6) /* only meaningful if WAKE_MAGIC */
#endif /* _LINUX_ETHTOOL_H */ #endif /* _LINUX_ETHTOOL_H */
...@@ -979,10 +979,14 @@ static void generic_file_readahead(int reada_ok, ...@@ -979,10 +979,14 @@ static void generic_file_readahead(int reada_ok,
static inline void check_used_once (struct page *page) static inline void check_used_once (struct page *page)
{ {
if (!page->age) { if (!PageActive(page)) {
if (page->age)
activate_page(page);
else {
page->age = PAGE_AGE_START; page->age = PAGE_AGE_START;
ClearPageReferenced(page); ClearPageReferenced(page);
} }
}
} }
/* /*
......
...@@ -806,59 +806,32 @@ int inactive_shortage(void) ...@@ -806,59 +806,32 @@ int inactive_shortage(void)
} }
/* /*
* Refill_inactive is the function used to scan and age the pages on * Loop until we are no longer under an inactive or free
* the active list and in the working set of processes, moving the * shortage. Return 1 on success, 0 if we failed to get
* little-used pages to the inactive list. * there even after "maxtry" loops.
*
* When called by kswapd, we try to deactivate as many pages as needed
* to recover from the inactive page shortage. This makes it possible
* for kswapd to keep up with memory demand so user processes can get
* low latency on memory allocations.
*
* However, when the system starts to get overloaded we can get called
* by user processes. For user processes we want to both reduce the
* latency and make sure that multiple user processes together don't
* deactivate too many pages. To achieve this we simply do less work
* when called from a user process.
*/ */
#define INACTIVE_SHORTAGE 1
static int refill_inactive(unsigned int gfp_mask) #define FREE_SHORTAGE 2
#define GENERAL_SHORTAGE 4
static int do_try_to_free_pages(unsigned int gfp_mask, int user)
{ {
int progress = 0, maxtry; /* Always walk at least the active queue when called */
int shortage = INACTIVE_SHORTAGE;
int maxtry;
maxtry = 1 << DEF_PRIORITY; maxtry = 1 << DEF_PRIORITY;
do { do {
if (current->need_resched) {
__set_current_state(TASK_RUNNING);
schedule();
if (!inactive_shortage())
return 1;
}
/* Walk the VM space for a bit.. */
swap_out(DEF_PRIORITY, gfp_mask);
/* ..and refill the inactive list */
progress += refill_inactive_scan(DEF_PRIORITY);
if (--maxtry <= 0)
break;
} while (inactive_shortage());
return progress;
}
static int do_try_to_free_pages(unsigned int gfp_mask, int user)
{
int ret = 0;
/* /*
* If needed, we move pages from the active list * If needed, we move pages from the active list
* to the inactive list. * to the inactive list.
*/ */
if (inactive_shortage()) if (shortage & INACTIVE_SHORTAGE) {
ret += refill_inactive(gfp_mask); /* Walk the VM space for a bit.. */
swap_out(DEF_PRIORITY, gfp_mask);
/* ..and refill the inactive list */
refill_inactive_scan(DEF_PRIORITY);
}
/* /*
* If we're low on free pages, move pages from the * If we're low on free pages, move pages from the
...@@ -868,17 +841,35 @@ static int do_try_to_free_pages(unsigned int gfp_mask, int user) ...@@ -868,17 +841,35 @@ static int do_try_to_free_pages(unsigned int gfp_mask, int user)
* before we get around to moving them to the other * before we get around to moving them to the other
* list, so this is a relatively cheap operation. * list, so this is a relatively cheap operation.
*/ */
ret += page_launder(gfp_mask, user); if (shortage & FREE_SHORTAGE)
page_launder(gfp_mask, user);
ret += shrink_dcache_memory(DEF_PRIORITY, gfp_mask);
ret += shrink_icache_memory(DEF_PRIORITY, gfp_mask);
/* /*
* Reclaim unused slab cache if memory is low. * Reclaim unused slab cache if we were short on memory.
*/ */
if (shortage & GENERAL_SHORTAGE) {
shrink_dcache_memory(DEF_PRIORITY, gfp_mask);
shrink_icache_memory(DEF_PRIORITY, gfp_mask);
kmem_cache_reap(gfp_mask); kmem_cache_reap(gfp_mask);
}
return ret; if (current->need_resched) {
__set_current_state(TASK_RUNNING);
schedule();
}
shortage = 0;
if (inactive_shortage())
shortage |= INACTIVE_SHORTAGE | GENERAL_SHORTAGE;
if (free_shortage())
shortage |= FREE_SHORTAGE | GENERAL_SHORTAGE;
if (--maxtry <= 0)
break;
} while (shortage);
return !shortage;
} }
DECLARE_WAIT_QUEUE_HEAD(kswapd_wait); DECLARE_WAIT_QUEUE_HEAD(kswapd_wait);
...@@ -925,47 +916,22 @@ int kswapd(void *unused) ...@@ -925,47 +916,22 @@ int kswapd(void *unused)
for (;;) { for (;;) {
static long recalc = 0; static long recalc = 0;
/* If needed, try to free some memory. */
if (inactive_shortage() || free_shortage())
do_try_to_free_pages(GFP_KSWAPD, 0);
/* Once a second ... */ /* Once a second ... */
if (time_after(jiffies, recalc + HZ)) { if (time_after(jiffies, recalc + HZ)) {
recalc = jiffies; recalc = jiffies;
/* Recalculate VM statistics. */ /* Recalculate VM statistics. */
recalculate_vm_stats(); recalculate_vm_stats();
}
/* Do background page aging. */ if (!do_try_to_free_pages(GFP_KSWAPD, 1)) {
refill_inactive_scan(DEF_PRIORITY); if (out_of_memory())
oom_kill();
continue;
} }
/*
* We go to sleep if either the free page shortage
* or the inactive page shortage is gone. We do this
* because:
* 1) we need no more free pages or
* 2) the inactive pages need to be flushed to disk,
* it wouldn't help to eat CPU time now ...
*
* We go to sleep for one second, but if it's needed
* we'll be woken up earlier...
*/
if (!free_shortage() || !inactive_shortage()) {
run_task_queue(&tq_disk); run_task_queue(&tq_disk);
interruptible_sleep_on_timeout(&kswapd_wait, HZ); interruptible_sleep_on_timeout(&kswapd_wait, HZ);
/*
* If we couldn't free enough memory, we see if it was
* due to the system just not having enough memory.
* If that is the case, the only solution is to kill
* a process (the alternative is enternal deadlock).
*
* If there still is enough memory around, we just loop
* and try free some more memory...
*/
} else if (out_of_memory()) {
oom_kill();
}
} }
} }
......
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