mirror of https://github.com/schoebel/mars
infra: disable irqs during spinlocks
This commit is contained in:
parent
95ff42b7de
commit
386ae8e8d0
|
@ -153,8 +153,9 @@ struct say_channel *find_channel(const void *id)
|
||||||
{
|
{
|
||||||
struct say_channel *res = default_channel;
|
struct say_channel *res = default_channel;
|
||||||
struct say_channel *ch;
|
struct say_channel *ch;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
read_lock(&say_lock);
|
read_lock_irqsave(&say_lock, flags);
|
||||||
for (ch = channel_list; ch; ch = ch->ch_next) {
|
for (ch = channel_list; ch; ch = ch->ch_next) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < ch->ch_id_max; i++) {
|
for (i = 0; i < ch->ch_id_max; i++) {
|
||||||
|
@ -165,7 +166,7 @@ struct say_channel *find_channel(const void *id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
found:
|
found:
|
||||||
read_unlock(&say_lock);
|
read_unlock_irqrestore(&say_lock, flags);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,7 +188,9 @@ void _remove_binding(struct task_struct *whom)
|
||||||
void bind_to_channel(struct say_channel *ch, struct task_struct *whom)
|
void bind_to_channel(struct say_channel *ch, struct task_struct *whom)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
write_lock(&say_lock);
|
unsigned long flags;
|
||||||
|
|
||||||
|
write_lock_irqsave(&say_lock, flags);
|
||||||
_remove_binding(whom);
|
_remove_binding(whom);
|
||||||
for (i = 0; i < ch->ch_id_max; i++) {
|
for (i = 0; i < ch->ch_id_max; i++) {
|
||||||
if (!ch->ch_ids[i]) {
|
if (!ch->ch_ids[i]) {
|
||||||
|
@ -202,11 +205,11 @@ void bind_to_channel(struct say_channel *ch, struct task_struct *whom)
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
write_unlock(&say_lock);
|
write_unlock_irqrestore(&say_lock, flags);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
write_unlock(&say_lock);
|
write_unlock_irqrestore(&say_lock, flags);
|
||||||
|
|
||||||
say_to(default_channel, SAY_ERROR, "ID overflow for thread '%s'\n", whom->comm);
|
say_to(default_channel, SAY_ERROR, "ID overflow for thread '%s'\n", whom->comm);
|
||||||
}
|
}
|
||||||
|
@ -216,8 +219,9 @@ struct say_channel *get_binding(struct task_struct *whom)
|
||||||
{
|
{
|
||||||
struct say_channel *ch;
|
struct say_channel *ch;
|
||||||
int i;
|
int i;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
read_lock(&say_lock);
|
read_lock_irqsave(&say_lock, flags);
|
||||||
for (ch = channel_list; ch; ch = ch->ch_next) {
|
for (ch = channel_list; ch; ch = ch->ch_next) {
|
||||||
for (i = 0; i < ch->ch_id_max; i++) {
|
for (i = 0; i < ch->ch_id_max; i++) {
|
||||||
if (ch->ch_ids[i] == whom) {
|
if (ch->ch_ids[i] == whom) {
|
||||||
|
@ -227,7 +231,7 @@ struct say_channel *get_binding(struct task_struct *whom)
|
||||||
}
|
}
|
||||||
ch = NULL;
|
ch = NULL;
|
||||||
found:
|
found:
|
||||||
read_unlock(&say_lock);
|
read_unlock_irqrestore(&say_lock, flags);
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(get_binding);
|
EXPORT_SYMBOL_GPL(get_binding);
|
||||||
|
@ -236,8 +240,9 @@ void remove_binding_from(struct say_channel *ch, struct task_struct *whom)
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
int i;
|
int i;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
write_lock(&say_lock);
|
write_lock_irqsave(&say_lock, flags);
|
||||||
for (i = 0; i < ch->ch_id_max; i++) {
|
for (i = 0; i < ch->ch_id_max; i++) {
|
||||||
if (ch->ch_ids[i] == whom) {
|
if (ch->ch_ids[i] == whom) {
|
||||||
ch->ch_ids[i] = NULL;
|
ch->ch_ids[i] = NULL;
|
||||||
|
@ -248,15 +253,17 @@ void remove_binding_from(struct say_channel *ch, struct task_struct *whom)
|
||||||
if (!found) {
|
if (!found) {
|
||||||
_remove_binding(whom);
|
_remove_binding(whom);
|
||||||
}
|
}
|
||||||
write_unlock(&say_lock);
|
write_unlock_irqrestore(&say_lock, flags);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(remove_binding_from);
|
EXPORT_SYMBOL_GPL(remove_binding_from);
|
||||||
|
|
||||||
void remove_binding(struct task_struct *whom)
|
void remove_binding(struct task_struct *whom)
|
||||||
{
|
{
|
||||||
write_lock(&say_lock);
|
unsigned long flags;
|
||||||
|
|
||||||
|
write_lock_irqsave(&say_lock, flags);
|
||||||
_remove_binding(whom);
|
_remove_binding(whom);
|
||||||
write_unlock(&say_lock);
|
write_unlock_irqrestore(&say_lock, flags);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(remove_binding);
|
EXPORT_SYMBOL_GPL(remove_binding);
|
||||||
|
|
||||||
|
@ -273,12 +280,13 @@ EXPORT_SYMBOL_GPL(rollover_channel);
|
||||||
void rollover_all(void)
|
void rollover_all(void)
|
||||||
{
|
{
|
||||||
struct say_channel *ch;
|
struct say_channel *ch;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
read_lock(&say_lock);
|
read_lock_irqsave(&say_lock, flags);
|
||||||
for (ch = channel_list; ch; ch = ch->ch_next) {
|
for (ch = channel_list; ch; ch = ch->ch_next) {
|
||||||
ch->ch_rollover = true;
|
ch->ch_rollover = true;
|
||||||
}
|
}
|
||||||
read_unlock(&say_lock);
|
read_unlock_irqrestore(&say_lock, flags);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rollover_all);
|
EXPORT_SYMBOL_GPL(rollover_all);
|
||||||
|
|
||||||
|
@ -301,18 +309,19 @@ void _del_channel(struct say_channel *ch)
|
||||||
struct say_channel *tmp;
|
struct say_channel *tmp;
|
||||||
struct say_channel **_tmp;
|
struct say_channel **_tmp;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
if (!ch)
|
if (!ch)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
write_lock(&say_lock);
|
write_lock_irqsave(&say_lock, flags);
|
||||||
for (_tmp = &channel_list; (tmp = *_tmp) != NULL; _tmp = &tmp->ch_next) {
|
for (_tmp = &channel_list; (tmp = *_tmp) != NULL; _tmp = &tmp->ch_next) {
|
||||||
if (tmp == ch) {
|
if (tmp == ch) {
|
||||||
*_tmp = tmp->ch_next;
|
*_tmp = tmp->ch_next;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
write_unlock(&say_lock);
|
write_unlock_irqrestore(&say_lock, flags);
|
||||||
|
|
||||||
for (i = 0; i < MAX_SAY_CLASS; i++) {
|
for (i = 0; i < MAX_SAY_CLASS; i++) {
|
||||||
for (j = 0; j < 2; j++) {
|
for (j = 0; j < 2; j++) {
|
||||||
|
@ -402,22 +411,23 @@ struct say_channel *make_channel(const char *name, bool must_exist)
|
||||||
{
|
{
|
||||||
struct say_channel *res = NULL;
|
struct say_channel *res = NULL;
|
||||||
struct say_channel *ch;
|
struct say_channel *ch;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
read_lock(&say_lock);
|
read_lock_irqsave(&say_lock, flags);
|
||||||
for (ch = channel_list; ch; ch = ch->ch_next) {
|
for (ch = channel_list; ch; ch = ch->ch_next) {
|
||||||
if (!strcmp(ch->ch_name, name)) {
|
if (!strcmp(ch->ch_name, name)) {
|
||||||
res = ch;
|
res = ch;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
read_unlock(&say_lock);
|
read_unlock_irqrestore(&say_lock, flags);
|
||||||
|
|
||||||
if (unlikely(!res)) {
|
if (unlikely(!res)) {
|
||||||
res = _make_channel(name, must_exist);
|
res = _make_channel(name, must_exist);
|
||||||
if (unlikely(!res))
|
if (unlikely(!res))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
write_lock(&say_lock);
|
write_lock_irqsave(&say_lock, flags);
|
||||||
|
|
||||||
for (ch = channel_list; ch; ch = ch->ch_next) {
|
for (ch = channel_list; ch; ch = ch->ch_next) {
|
||||||
if (ch != res && unlikely(!strcmp(ch->ch_name, name))) {
|
if (ch != res && unlikely(!strcmp(ch->ch_name, name))) {
|
||||||
|
@ -431,7 +441,7 @@ struct say_channel *make_channel(const char *name, bool must_exist)
|
||||||
channel_list = res;
|
channel_list = res;
|
||||||
|
|
||||||
race_found:
|
race_found:
|
||||||
write_unlock(&say_lock);
|
write_unlock_irqrestore(&say_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
@ -804,6 +814,8 @@ void treat_channel(struct say_channel *ch, int class)
|
||||||
static
|
static
|
||||||
int _say_thread(void *data)
|
int _say_thread(void *data)
|
||||||
{
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
while (!kthread_should_stop()) {
|
while (!kthread_should_stop()) {
|
||||||
struct say_channel *ch;
|
struct say_channel *ch;
|
||||||
int i;
|
int i;
|
||||||
|
@ -812,36 +824,36 @@ int _say_thread(void *data)
|
||||||
say_dirty = false;
|
say_dirty = false;
|
||||||
|
|
||||||
restart_rollover:
|
restart_rollover:
|
||||||
read_lock(&say_lock);
|
read_lock_irqsave(&say_lock, flags);
|
||||||
for (ch = channel_list; ch; ch = ch->ch_next) {
|
for (ch = channel_list; ch; ch = ch->ch_next) {
|
||||||
if (ch->ch_rollover && ch->ch_status_written > 0) {
|
if (ch->ch_rollover && ch->ch_status_written > 0) {
|
||||||
read_unlock(&say_lock);
|
read_unlock_irqrestore(&say_lock, flags);
|
||||||
_rollover_channel(ch);
|
_rollover_channel(ch);
|
||||||
goto restart_rollover;
|
goto restart_rollover;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
read_unlock(&say_lock);
|
read_unlock_irqrestore(&say_lock, flags);
|
||||||
|
|
||||||
restart:
|
restart:
|
||||||
read_lock(&say_lock);
|
read_lock_irqsave(&say_lock, flags);
|
||||||
for (ch = channel_list; ch; ch = ch->ch_next) {
|
for (ch = channel_list; ch; ch = ch->ch_next) {
|
||||||
int start = 0;
|
int start = 0;
|
||||||
if (!ch->ch_is_dir)
|
if (!ch->ch_is_dir)
|
||||||
start = SAY_TOTAL;
|
start = SAY_TOTAL;
|
||||||
for (i = start; i < MAX_SAY_CLASS; i++) {
|
for (i = start; i < MAX_SAY_CLASS; i++) {
|
||||||
if (ch->ch_index[i] > 0) {
|
if (ch->ch_index[i] > 0) {
|
||||||
read_unlock(&say_lock);
|
read_unlock_irqrestore(&say_lock, flags);
|
||||||
treat_channel(ch, i);
|
treat_channel(ch, i);
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ch->ch_delete) {
|
if (ch->ch_delete) {
|
||||||
read_unlock(&say_lock);
|
read_unlock_irqrestore(&say_lock, flags);
|
||||||
_del_channel(ch);
|
_del_channel(ch);
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
read_unlock(&say_lock);
|
read_unlock_irqrestore(&say_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue