OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [fs/] [dlm/] [ast.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/******************************************************************************
2
*******************************************************************************
3
**
4
**  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
5
**  Copyright (C) 2004-2005 Red Hat, Inc.  All rights reserved.
6
**
7
**  This copyrighted material is made available to anyone wishing to use,
8
**  modify, copy, or redistribute it subject to the terms and conditions
9
**  of the GNU General Public License v.2.
10
**
11
*******************************************************************************
12
******************************************************************************/
13
 
14
#include "dlm_internal.h"
15
#include "lock.h"
16
#include "user.h"
17
#include "ast.h"
18
 
19
#define WAKE_ASTS  0
20
 
21
static struct list_head         ast_queue;
22
static spinlock_t               ast_queue_lock;
23
static struct task_struct *     astd_task;
24
static unsigned long            astd_wakeflags;
25
static struct mutex             astd_running;
26
 
27
 
28
void dlm_del_ast(struct dlm_lkb *lkb)
29
{
30
        spin_lock(&ast_queue_lock);
31
        if (lkb->lkb_ast_type & (AST_COMP | AST_BAST))
32
                list_del(&lkb->lkb_astqueue);
33
        spin_unlock(&ast_queue_lock);
34
}
35
 
36
void dlm_add_ast(struct dlm_lkb *lkb, int type)
37
{
38
        if (lkb->lkb_flags & DLM_IFL_USER) {
39
                dlm_user_add_ast(lkb, type);
40
                return;
41
        }
42
        DLM_ASSERT(lkb->lkb_astaddr != DLM_FAKE_USER_AST, dlm_print_lkb(lkb););
43
 
44
        spin_lock(&ast_queue_lock);
45
        if (!(lkb->lkb_ast_type & (AST_COMP | AST_BAST))) {
46
                kref_get(&lkb->lkb_ref);
47
                list_add_tail(&lkb->lkb_astqueue, &ast_queue);
48
        }
49
        lkb->lkb_ast_type |= type;
50
        spin_unlock(&ast_queue_lock);
51
 
52
        set_bit(WAKE_ASTS, &astd_wakeflags);
53
        wake_up_process(astd_task);
54
}
55
 
56
static void process_asts(void)
57
{
58
        struct dlm_ls *ls = NULL;
59
        struct dlm_rsb *r = NULL;
60
        struct dlm_lkb *lkb;
61
        void (*cast) (long param);
62
        void (*bast) (long param, int mode);
63
        int type = 0, found, bmode;
64
 
65
        for (;;) {
66
                found = 0;
67
                spin_lock(&ast_queue_lock);
68
                list_for_each_entry(lkb, &ast_queue, lkb_astqueue) {
69
                        r = lkb->lkb_resource;
70
                        ls = r->res_ls;
71
 
72
                        if (dlm_locking_stopped(ls))
73
                                continue;
74
 
75
                        list_del(&lkb->lkb_astqueue);
76
                        type = lkb->lkb_ast_type;
77
                        lkb->lkb_ast_type = 0;
78
                        found = 1;
79
                        break;
80
                }
81
                spin_unlock(&ast_queue_lock);
82
 
83
                if (!found)
84
                        break;
85
 
86
                cast = lkb->lkb_astaddr;
87
                bast = lkb->lkb_bastaddr;
88
                bmode = lkb->lkb_bastmode;
89
 
90
                if ((type & AST_COMP) && cast)
91
                        cast(lkb->lkb_astparam);
92
 
93
                /* FIXME: Is it safe to look at lkb_grmode here
94
                   without doing a lock_rsb() ?
95
                   Look at other checks in v1 to avoid basts. */
96
 
97
                if ((type & AST_BAST) && bast)
98
                        if (!dlm_modes_compat(lkb->lkb_grmode, bmode))
99
                                bast(lkb->lkb_astparam, bmode);
100
 
101
                /* this removes the reference added by dlm_add_ast
102
                   and may result in the lkb being freed */
103
                dlm_put_lkb(lkb);
104
 
105
                schedule();
106
        }
107
}
108
 
109
static inline int no_asts(void)
110
{
111
        int ret;
112
 
113
        spin_lock(&ast_queue_lock);
114
        ret = list_empty(&ast_queue);
115
        spin_unlock(&ast_queue_lock);
116
        return ret;
117
}
118
 
119
static int dlm_astd(void *data)
120
{
121
        while (!kthread_should_stop()) {
122
                set_current_state(TASK_INTERRUPTIBLE);
123
                if (!test_bit(WAKE_ASTS, &astd_wakeflags))
124
                        schedule();
125
                set_current_state(TASK_RUNNING);
126
 
127
                mutex_lock(&astd_running);
128
                if (test_and_clear_bit(WAKE_ASTS, &astd_wakeflags))
129
                        process_asts();
130
                mutex_unlock(&astd_running);
131
        }
132
        return 0;
133
}
134
 
135
void dlm_astd_wake(void)
136
{
137
        if (!no_asts()) {
138
                set_bit(WAKE_ASTS, &astd_wakeflags);
139
                wake_up_process(astd_task);
140
        }
141
}
142
 
143
int dlm_astd_start(void)
144
{
145
        struct task_struct *p;
146
        int error = 0;
147
 
148
        INIT_LIST_HEAD(&ast_queue);
149
        spin_lock_init(&ast_queue_lock);
150
        mutex_init(&astd_running);
151
 
152
        p = kthread_run(dlm_astd, NULL, "dlm_astd");
153
        if (IS_ERR(p))
154
                error = PTR_ERR(p);
155
        else
156
                astd_task = p;
157
        return error;
158
}
159
 
160
void dlm_astd_stop(void)
161
{
162
        kthread_stop(astd_task);
163
}
164
 
165
void dlm_astd_suspend(void)
166
{
167
        mutex_lock(&astd_running);
168
}
169
 
170
void dlm_astd_resume(void)
171
{
172
        mutex_unlock(&astd_running);
173
}
174
 

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.