Coverage Report

Created: 2017-10-25 09:10

/root/src/xen/xen/common/notifier.c
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 * common/notifier.c
3
 *
4
 * Routines to manage notifier chains for passing status changes to any
5
 * interested routines.
6
 *
7
 * Original code from Linux kernel 2.6.27 (Alan Cox <Alan.Cox@linux.org>)
8
 */
9
10
#include <xen/init.h>
11
#include <xen/notifier.h>
12
13
/**
14
 * notifier_chain_register - Add notifier to a raw notifier chain
15
 * @nh: Pointer to head of the raw notifier chain
16
 * @n: New entry in notifier chain
17
 *
18
 * Adds a notifier to a raw notifier chain.
19
 * All locking must be provided by the caller.
20
 */
21
void __init notifier_chain_register(
22
    struct notifier_head *nh, struct notifier_block *n)
23
18
{
24
18
    struct list_head *chain = &nh->head.chain;
25
18
    struct notifier_block *nb;
26
18
27
159
    while ( chain->next != &nh->head.chain )
28
143
    {
29
143
        nb = list_entry(chain->next, struct notifier_block, chain);
30
143
        if ( n->priority > nb->priority )
31
2
            break;
32
141
        chain = chain->next;
33
141
    }
34
18
35
18
    list_add(&n->chain, chain);
36
18
}
37
38
/**
39
 * notifier_chain_unregister - Remove notifier from a raw notifier chain
40
 * @nh: Pointer to head of the raw notifier chain
41
 * @n: Entry to remove from notifier chain
42
 *
43
 * Removes a notifier from a raw notifier chain.
44
 * All locking must be provided by the caller.
45
 */
46
void __init notifier_chain_unregister(
47
    struct notifier_head *nh, struct notifier_block *n)
48
0
{
49
0
    list_del(&n->chain);
50
0
}
51
52
/**
53
 * notifier_call_chain - Informs the registered notifiers about an event.
54
 * @nh: Pointer to head of the raw notifier chain
55
 * @val:  Value passed unmodified to notifier function
56
 * @v:  Pointer passed unmodified to notifier function
57
 * @pcursor: If non-NULL, position in chain to start from. Also updated on
58
 *           return to indicate how far notifications got before stopping.
59
 *
60
 * Calls each function in a notifier chain in turn.  The functions run in an
61
 * undefined context. All locking must be provided by the caller.
62
 *
63
 * If the return value of the notifier can be and'ed with %NOTIFY_STOP_MASK
64
 * then notifier_call_chain() will return immediately, with teh return value of
65
 * the notifier function which halted execution. Otherwise the return value is
66
 * the return value of the last notifier function called.
67
 */
68
int notifier_call_chain(
69
    struct notifier_head *nh, unsigned long val, void *v,
70
    struct notifier_block **pcursor)
71
33
{
72
33
    int ret = NOTIFY_DONE;
73
33
    struct list_head *cursor;
74
33
    struct notifier_block *nb;
75
33
    bool_t reverse = !!(val & NOTIFY_REVERSE);
76
33
77
33
    cursor = &(pcursor && *pcursor ? *pcursor : &nh->head)->chain;
78
33
79
495
    do {
80
495
        cursor = reverse ? cursor->prev : cursor->next;
81
495
        nb = list_entry(cursor, struct notifier_block, chain);
82
495
        if ( cursor == &nh->head.chain )
83
33
            break;
84
462
        ret = nb->notifier_call(nb, val, v);
85
462
    } while ( !(ret & NOTIFY_STOP_MASK) );
86
33
87
33
    if ( pcursor )
88
11
        *pcursor = nb;
89
33
90
33
    return ret;
91
33
}