ia64/xen-unstable
changeset 3091:e0351a3744a5
bitkeeper revision 1.1159.187.4 (41a471c8NjyQJy-vepqpb8H7LdzHzA)
Allow preemption of long-running hypercalls for softirq processing.
Allow preemption of long-running hypercalls for softirq processing.
author | kaf24@scramble.cl.cam.ac.uk |
---|---|
date | Wed Nov 24 11:34:32 2004 +0000 (2004-11-24) |
parents | 50eaaedc0d3c |
children | 6b22a56f55d3 2fae9947de6f 6595a3a973e3 |
files | xen/arch/x86/domain.c xen/arch/x86/memory.c xen/arch/x86/traps.c xen/arch/x86/x86_32/entry.S xen/common/dom_mem_ops.c xen/common/grant_table.c xen/include/xen/irq_cpustat.h xen/include/xen/sched.h |
line diff
1.1 --- a/xen/arch/x86/domain.c Tue Nov 23 22:46:54 2004 +0000 1.2 +++ b/xen/arch/x86/domain.c Wed Nov 24 11:34:32 2004 +0000 1.3 @@ -426,6 +426,22 @@ long do_iopl(domid_t domain, unsigned in 1.4 return 0; 1.5 } 1.6 1.7 +void hypercall_create_continuation(unsigned int op, unsigned int nr_args, ...) 1.8 +{ 1.9 + execution_context_t *ec = get_execution_context(); 1.10 + unsigned long *preg = &ec->ebx; 1.11 + unsigned int i; 1.12 + va_list args; 1.13 + 1.14 + ec->eax = op; 1.15 + ec->eip -= 2; /* re-execute 'int 0x82' */ 1.16 + 1.17 + va_start(args, nr_args); 1.18 + for ( i = 0; i < nr_args; i++ ) 1.19 + *preg++ = va_arg(args, unsigned long); 1.20 + va_end(args); 1.21 +} 1.22 + 1.23 #endif 1.24 1.25
2.1 --- a/xen/arch/x86/memory.c Tue Nov 23 22:46:54 2004 +0000 2.2 +++ b/xen/arch/x86/memory.c Wed Nov 24 11:34:32 2004 +0000 2.3 @@ -1300,6 +1300,9 @@ int do_mmu_update(mmu_update_t *ureqs, i 2.4 2.5 for ( i = 0; i < count; i++ ) 2.6 { 2.7 + hypercall_may_preempt( 2.8 + __HYPERVISOR_mmu_update, 3, ureqs, count-i, success_count); 2.9 + 2.10 if ( unlikely(__copy_from_user(&req, ureqs, sizeof(req)) != 0) ) 2.11 { 2.12 MEM_LOG("Bad __copy_from_user"); 2.13 @@ -1455,7 +1458,7 @@ int do_mmu_update(mmu_update_t *ureqs, i 2.14 } 2.15 2.16 if ( unlikely(success_count != NULL) ) 2.17 - put_user(count, success_count); 2.18 + put_user(i, success_count); 2.19 2.20 return rc; 2.21 }
3.1 --- a/xen/arch/x86/traps.c Tue Nov 23 22:46:54 2004 +0000 3.2 +++ b/xen/arch/x86/traps.c Wed Nov 24 11:34:32 2004 +0000 3.3 @@ -804,6 +804,8 @@ long do_set_trap_table(trap_info_t *trap 3.4 3.5 for ( ; ; ) 3.6 { 3.7 + hypercall_may_preempt(__HYPERVISOR_set_trap_table, 1, traps); 3.8 + 3.9 if ( copy_from_user(&cur, traps, sizeof(cur)) ) return -EFAULT; 3.10 3.11 if ( cur.address == 0 ) break;
4.1 --- a/xen/arch/x86/x86_32/entry.S Tue Nov 23 22:46:54 2004 +0000 4.2 +++ b/xen/arch/x86/x86_32/entry.S Wed Nov 24 11:34:32 2004 +0000 4.3 @@ -95,6 +95,11 @@ do_multicall: 4.4 jnc bad_multicall_address 4.5 multicall_loop: 4.6 pushl %ecx 4.7 + movl 4(%esp),%ecx # %ecx = struct domain 4.8 + movl DOMAIN_processor(%ecx),%eax 4.9 + shl $6,%eax # sizeof(irq_cpustat) == 64 4.10 + testl $~0,SYMBOL_NAME(irq_stat)(%eax,1) 4.11 + jnz multicall_preempt 4.12 multicall_fault1: 4.13 pushl 20(%ebx) # args[4] 4.14 multicall_fault2: 4.15 @@ -120,6 +125,17 @@ multicall_fault7: 4.16 xorl %eax,%eax 4.17 jmp ret_from_hypercall 4.18 4.19 +multicall_preempt: 4.20 + # NB. remaining nr_calls is already at top of stack 4.21 + pushl %ebx # call_list 4.22 + pushl $2 # nr_args == 2 4.23 + pushl $__HYPERVISOR_multicall # op == __HYPERVISOR_multicall 4.24 + call hypercall_create_continuation 4.25 + addl $16,%esp 4.26 + popl %ebx 4.27 + movl $__HYPERVISOR_multicall,%eax 4.28 + jmp ret_from_hypercall 4.29 + 4.30 bad_multicall_address: 4.31 popl %ebx 4.32 movl $-EFAULT,%eax
5.1 --- a/xen/common/dom_mem_ops.c Tue Nov 23 22:46:54 2004 +0000 5.2 +++ b/xen/common/dom_mem_ops.c Wed Nov 24 11:34:32 2004 +0000 5.3 @@ -35,6 +35,12 @@ static long alloc_dom_mem(struct domain 5.4 5.5 for ( i = 0; i < nr_extents; i++ ) 5.6 { 5.7 + hypercall_may_preempt( 5.8 + __HYPERVISOR_dom_mem_op, 5, 5.9 + MEMOP_increase_reservation, 5.10 + &extent_list[i], nr_extents-i, extent_order, 5.11 + (d == current) ? DOMID_SELF : d->id); 5.12 + 5.13 if ( unlikely((page = alloc_domheap_pages(d, extent_order)) == NULL) ) 5.14 { 5.15 DPRINTK("Could not allocate a frame\n"); 5.16 @@ -63,6 +69,12 @@ static long free_dom_mem(struct domain * 5.17 5.18 for ( i = 0; i < nr_extents; i++ ) 5.19 { 5.20 + hypercall_may_preempt( 5.21 + __HYPERVISOR_dom_mem_op, 5, 5.22 + MEMOP_decrease_reservation, 5.23 + &extent_list[i], nr_extents-i, extent_order, 5.24 + (d == current) ? DOMID_SELF : d->id); 5.25 + 5.26 if ( unlikely(__get_user(mpfn, &extent_list[i]) != 0) ) 5.27 return i; 5.28
6.1 --- a/xen/common/grant_table.c Tue Nov 23 22:46:54 2004 +0000 6.2 +++ b/xen/common/grant_table.c Wed Nov 24 11:34:32 2004 +0000 6.3 @@ -437,6 +437,9 @@ do_grant_table_op( 6.4 { 6.5 long rc; 6.6 6.7 + /* XXX stubbed out XXX */ 6.8 + return -ENOSYS; 6.9 + 6.10 if ( count > 512 ) 6.11 return -EINVAL; 6.12
7.1 --- a/xen/include/xen/irq_cpustat.h Tue Nov 23 22:46:54 2004 +0000 7.2 +++ b/xen/include/xen/irq_cpustat.h Wed Nov 24 11:34:32 2004 +0000 7.3 @@ -10,6 +10,7 @@ 7.4 */ 7.5 7.6 #include <xen/config.h> 7.7 +#include <asm/hardirq.h> 7.8 7.9 /* 7.10 * Simple wrappers reducing source bloat. Define all irq_stat fields 7.11 @@ -17,7 +18,7 @@ 7.12 * definitions instead of differing sets for each arch. 7.13 */ 7.14 7.15 -extern irq_cpustat_t irq_stat[]; /* defined in asm/hardirq.h */ 7.16 +extern irq_cpustat_t irq_stat[]; 7.17 7.18 #ifdef CONFIG_SMP 7.19 #define __IRQ_STAT(cpu, member) (irq_stat[cpu].member)
8.1 --- a/xen/include/xen/sched.h Tue Nov 23 22:46:54 2004 +0000 8.2 +++ b/xen/include/xen/sched.h Wed Nov 24 11:34:32 2004 +0000 8.3 @@ -21,6 +21,7 @@ 8.4 #include <asm/current.h> 8.5 #include <xen/spinlock.h> 8.6 #include <xen/grant_table.h> 8.7 +#include <xen/irq_cpustat.h> 8.8 8.9 extern unsigned long volatile jiffies; 8.10 extern rwlock_t domlist_lock; 8.11 @@ -217,6 +218,14 @@ void continue_cpu_idle_loop(void); 8.12 8.13 void continue_nonidle_task(void); 8.14 8.15 +void hypercall_create_continuation(unsigned int op, unsigned int nr_args, ...); 8.16 +#define hypercall_may_preempt(_op, _nr_args, _args...) \ 8.17 + do { \ 8.18 + if ( unlikely(softirq_pending(smp_processor_id())) ) { \ 8.19 + hypercall_create_continuation(_op , _nr_args , ##_args); \ 8.20 + return _op; \ 8.21 + } } while ( 0 ) 8.22 + 8.23 /* This domain_hash and domain_list are protected by the domlist_lock. */ 8.24 #define DOMAIN_HASH_SIZE 256 8.25 #define DOMAIN_HASH(_id) ((int)(_id)&(DOMAIN_HASH_SIZE-1))