Coverage Report

Created: 2017-10-25 09:10

/root/src/xen/xen/common/softirq.c
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 * common/softirq.c
3
 * 
4
 * Softirqs in Xen are only executed in an outermost activation (e.g., never 
5
 * within an interrupt activation). This simplifies some things and generally 
6
 * seems a good thing.
7
 * 
8
 * Copyright (c) 2003, K A Fraser
9
 * Copyright (c) 1992, Linus Torvalds
10
 */
11
12
#include <xen/init.h>
13
#include <xen/mm.h>
14
#include <xen/preempt.h>
15
#include <xen/sched.h>
16
#include <xen/rcupdate.h>
17
#include <xen/softirq.h>
18
19
#ifndef __ARCH_IRQ_STAT
20
irq_cpustat_t irq_stat[NR_CPUS];
21
#endif
22
23
static softirq_handler softirq_handlers[NR_SOFTIRQS];
24
25
static DEFINE_PER_CPU(cpumask_t, batch_mask);
26
static DEFINE_PER_CPU(unsigned int, batching);
27
28
static void __do_softirq(unsigned long ignore_mask)
29
8.57M
{
30
8.57M
    unsigned int i, cpu;
31
8.57M
    unsigned long pending;
32
8.57M
33
8.57M
    for ( ; ; )
34
11.9M
    {
35
11.9M
        /*
36
11.9M
         * Initialise @cpu on every iteration: SCHEDULE_SOFTIRQ may move
37
11.9M
         * us to another processor.
38
11.9M
         */
39
11.9M
        cpu = smp_processor_id();
40
11.9M
41
11.9M
        if ( rcu_pending(cpu) )
42
0
            rcu_check_callbacks(cpu);
43
11.9M
44
11.9M
        if ( ((pending = (softirq_pending(cpu) & ~ignore_mask)) == 0)
45
9.17M
             || cpu_is_offline(cpu) )
46
3.83M
            break;
47
11.9M
48
8.15M
        i = find_first_set_bit(pending);
49
8.15M
        clear_bit(i, &softirq_pending(cpu));
50
8.15M
        (*softirq_handlers[i])();
51
8.15M
    }
52
8.57M
}
53
54
void process_pending_softirqs(void)
55
1.92M
{
56
1.92M
    ASSERT(!in_irq() && local_irq_is_enabled());
57
1.92M
    /* Do not enter scheduler as it can preempt the calling context. */
58
1.92M
    __do_softirq(1ul<<SCHEDULE_SOFTIRQ);
59
1.92M
}
60
61
void do_softirq(void)
62
6.61M
{
63
6.61M
    ASSERT_NOT_IN_ATOMIC();
64
6.61M
    __do_softirq(0);
65
6.61M
}
66
67
void open_softirq(int nr, softirq_handler handler)
68
11
{
69
11
    ASSERT(nr < NR_SOFTIRQS);
70
11
    softirq_handlers[nr] = handler;
71
11
}
72
73
void cpumask_raise_softirq(const cpumask_t *mask, unsigned int nr)
74
66.8k
{
75
66.8k
    unsigned int cpu, this_cpu = smp_processor_id();
76
66.8k
    cpumask_t send_mask, *raise_mask;
77
66.8k
78
66.8k
    if ( !per_cpu(batching, this_cpu) || in_irq() )
79
66.8k
    {
80
66.8k
        cpumask_clear(&send_mask);
81
66.8k
        raise_mask = &send_mask;
82
66.8k
    }
83
66.8k
    else
84
18.4E
        raise_mask = &per_cpu(batch_mask, this_cpu);
85
66.8k
86
66.8k
    for_each_cpu(cpu, mask)
87
66.8k
        if ( !test_and_set_bit(nr, &softirq_pending(cpu)) &&
88
66.8k
             cpu != this_cpu &&
89
64.2k
             !arch_skip_send_event_check(cpu) )
90
1.12k
            __cpumask_set_cpu(cpu, raise_mask);
91
66.8k
92
66.8k
    if ( raise_mask == &send_mask )
93
66.8k
        smp_send_event_check_mask(raise_mask);
94
66.8k
}
95
96
void cpu_raise_softirq(unsigned int cpu, unsigned int nr)
97
3.77M
{
98
3.77M
    unsigned int this_cpu = smp_processor_id();
99
3.77M
100
3.77M
    if ( test_and_set_bit(nr, &softirq_pending(cpu))
101
4.16M
         || (cpu == this_cpu)
102
34.4k
         || arch_skip_send_event_check(cpu) )
103
4.10M
        return;
104
3.77M
105
18.4E
    if ( !per_cpu(batching, this_cpu) || in_irq() )
106
34.4k
        smp_send_event_check_cpu(cpu);
107
18.4E
    else
108
18.4E
        __cpumask_set_cpu(cpu, &per_cpu(batch_mask, this_cpu));
109
18.4E
}
110
111
void cpu_raise_softirq_batch_begin(void)
112
0
{
113
0
    ++this_cpu(batching);
114
0
}
115
116
void cpu_raise_softirq_batch_finish(void)
117
0
{
118
0
    unsigned int cpu, this_cpu = smp_processor_id();
119
0
    cpumask_t *mask = &per_cpu(batch_mask, this_cpu);
120
0
121
0
    ASSERT(per_cpu(batching, this_cpu));
122
0
    for_each_cpu ( cpu, mask )
123
0
        if ( !softirq_pending(cpu) )
124
0
            __cpumask_clear_cpu(cpu, mask);
125
0
    smp_send_event_check_mask(mask);
126
0
    cpumask_clear(mask);
127
0
    --per_cpu(batching, this_cpu);
128
0
}
129
130
void raise_softirq(unsigned int nr)
131
4.73M
{
132
4.73M
    set_bit(nr, &softirq_pending(smp_processor_id()));
133
4.73M
}
134
135
void __init softirq_init(void)
136
1
{
137
1
}
138
139
/*
140
 * Local variables:
141
 * mode: C
142
 * c-file-style: "BSD"
143
 * c-basic-offset: 4
144
 * tab-width: 4
145
 * indent-tabs-mode: nil
146
 * End:
147
 */