From aba4e552a2f2c1492441acbccedd8e0a4c53f916 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 18 Feb 2000 22:06:10 +0000 Subject: Merge with Linux 2.3.43. --- arch/sparc/mm/asyncd.c | 290 ------------------------------------------------- 1 file changed, 290 deletions(-) delete mode 100644 arch/sparc/mm/asyncd.c (limited to 'arch/sparc/mm/asyncd.c') diff --git a/arch/sparc/mm/asyncd.c b/arch/sparc/mm/asyncd.c deleted file mode 100644 index 0034cb60b..000000000 --- a/arch/sparc/mm/asyncd.c +++ /dev/null @@ -1,290 +0,0 @@ -/* $Id: asyncd.c,v 1.20 2000/01/21 11:38:47 jj Exp $ - * The asyncd kernel daemon. This handles paging on behalf of - * processes that receive page faults due to remote (async) memory - * accesses. - * - * Idea and skeleton code courtesy of David Miller (bless his cotton socks) - * - * Implemented by tridge - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include /* for cli()/sti() */ -#include /* for memcpy_to/fromfs */ -#include -#include -#include - -#define DEBUG 0 - -#define WRITE_LIMIT 100 -#define LOOP_LIMIT 200 - -static struct { - int faults, read, write, success, failure, errors; -} stats; - -/* - * The wait queue for waking up the async daemon: - */ -static DECLARE_WAIT_QUEUE_HEAD(asyncd_wait); - -struct async_job { - volatile struct async_job *next; - int taskid; - struct mm_struct *mm; - unsigned long address; - int write; - void (*callback)(int,unsigned long,int,int); -}; - -static volatile struct async_job *async_queue = NULL; -static volatile struct async_job *async_queue_end = NULL; - -static void add_to_async_queue(int taskid, - struct mm_struct *mm, - unsigned long address, - int write, - void (*callback)(int,unsigned long,int,int)) -{ - struct async_job *a = kmalloc(sizeof(*a),GFP_ATOMIC); - - if (!a) { - printk("ERROR: out of memory in asyncd\n"); - a->callback(taskid,address,write,1); - return; - } - - if (write) - stats.write++; - else - stats.read++; - - a->next = NULL; - a->taskid = taskid; - a->mm = mm; - a->address = address; - a->write = write; - a->callback = callback; - - if (!async_queue) { - async_queue = a; - } else { - async_queue_end->next = a; - } - async_queue_end = a; -} - - -void async_fault(unsigned long address, int write, int taskid, - void (*callback)(int,unsigned long,int,int)) -{ - struct task_struct *tsk = task[taskid]; - struct mm_struct *mm = tsk->mm; - - stats.faults++; - -#if 0 - printk("paging in %x for task=%d\n",address,taskid); -#endif - - add_to_async_queue(taskid, mm, address, write, callback); - wake_up(&asyncd_wait); - mark_bh(TQUEUE_BH); -} - -static int fault_in_page(int taskid, - struct vm_area_struct *vma, - unsigned address,int write) -{ - static unsigned last_address; - static int last_task, loop_counter; - struct task_struct *tsk = task[taskid]; - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - siginfo_t info; - - if (!tsk || !tsk->mm) - return 1; - - if (!vma || (write && !(vma->vm_flags & VM_WRITE))) - goto bad_area; - if (vma->vm_start > address) - goto bad_area; - - if (address == last_address && taskid == last_task) { - loop_counter++; - } else { - loop_counter = 0; - last_address = address; - last_task = taskid; - } - - if (loop_counter == WRITE_LIMIT && !write) { - printk("MSC bug? setting write request\n"); - stats.errors++; - write = 1; - } - - if (loop_counter == LOOP_LIMIT) { - printk("MSC bug? failing request\n"); - stats.errors++; - return 1; - } - - pgd = pgd_offset(vma->vm_mm, address); - pmd = pmd_alloc(pgd,address); - if(!pmd) - goto no_memory; - pte = pte_alloc(pmd, address); - if(!pte) - goto no_memory; - if(!pte_present(*pte)) { - handle_mm_fault(tsk, vma, address, write); - goto finish_up; - } - set_pte(pte, pte_mkyoung(*pte)); - flush_tlb_page(vma, address); - if(!write) - goto finish_up; - if(pte_write(*pte)) { - set_pte(pte, pte_mkdirty(*pte)); - flush_tlb_page(vma, address); - goto finish_up; - } - handle_mm_fault(tsk, vma, address, write); - - /* Fall through for do_wp_page */ -finish_up: - stats.success++; - return 0; - -no_memory: - stats.failure++; - oom(tsk); - return 1; - -bad_area: - stats.failure++; - info.si_signo = SIGSEGV; - info.si_errno = 0; - info.si_code = SEGV_MAPERR; - info.si_addr = (void *)address; - info.si_trapno = 0; - send_sig_info(SIGSEGV, &info, tsk); - return 1; -} - - -/* Note the semaphore operations must be done here, and _not_ - * in async_fault(). - */ -static void run_async_queue(void) -{ - int ret; - unsigned flags; - - while (async_queue) { - volatile struct async_job *a; - struct mm_struct *mm; - struct vm_area_struct *vma; - - save_flags(flags); cli(); - a = async_queue; - async_queue = async_queue->next; - restore_flags(flags); - - mm = a->mm; - - down(&mm->mmap_sem); - vma = find_vma(mm, a->address); - ret = fault_in_page(a->taskid,vma,a->address,a->write); -#if DEBUG - printk("fault_in_page(task=%d addr=%x write=%d) = %d\n", - a->taskid,a->address,a->write,ret); -#endif - a->callback(a->taskid,a->address,a->write,ret); - up(&mm->mmap_sem); - kfree_s((void *)a,sizeof(*a)); - } -} - - -#if CONFIG_AP1000 -static void asyncd_info(void) -{ - printk("CID(%d) faults: total=%d read=%d write=%d success=%d fail=%d err=%d\n", - mpp_cid(),stats.faults, stats.read, stats.write, stats.success, - stats.failure, stats.errors); -} -#endif - - -/* - * The background async daemon. - * Started as a kernel thread from the init process. - */ -int asyncd(void *unused) -{ - current->session = 1; - current->pgrp = 1; - sprintf(current->comm, "asyncd"); - sigfillset(¤t->blocked); /* block all signals */ - recalc_sigpending(current); - - /* Give asyncd a realtime priority. */ - current->policy = SCHED_FIFO; - current->priority = 32; /* Fixme --- we need to standardise our - namings for POSIX.4 realtime scheduling - priorities. */ - - printk("Started asyncd\n"); - -#if CONFIG_AP1000 - bif_add_debug_key('a',asyncd_info,"stats on asyncd"); -#endif - - while (1) { - unsigned flags; - - save_flags(flags); cli(); - - while (!async_queue) { - spin_lock(¤t->sigmask_lock); - flush_signals(current); - spin_unlock(¤t->sigmask_lock); - interruptible_sleep_on(&asyncd_wait); - __sti(); cli(); - } - - restore_flags(flags); - - run_async_queue(); - } -} - -#if CONFIG_AP1000 - -static int __init init_ap1000(void) -{ - kernel_thread(asyncd, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); - return 0; -} - -module_init(init_ap1000) - -#endif -- cgit v1.2.3