cleanup locking, now ready for 2.6

This commit is contained in:
Karsten Keil 2003-09-06 17:11:42 +00:00
parent 0dc7dd5c8c
commit 90ab30a38d
2 changed files with 71 additions and 54 deletions

View File

@ -494,21 +494,28 @@ legalnr(layer2_t *l2, unsigned int nr)
static void static void
setva(layer2_t *l2, unsigned int nr) setva(layer2_t *l2, unsigned int nr)
{ {
u_long flags;
struct sk_buff *skb;
spin_lock_irqsave(&l2->lock, flags);
while (l2->va != nr) { while (l2->va != nr) {
(l2->va)++; l2->va++;
if(test_bit(FLG_MOD128, &l2->flag)) if(test_bit(FLG_MOD128, &l2->flag))
l2->va %= 128; l2->va %= 128;
else else
l2->va %= 8; l2->va %= 8;
if (l2->windowar[l2->sow]) { if (l2->windowar[l2->sow]) {
skb_trim(l2->windowar[l2->sow], 0); skb_trim(l2->windowar[l2->sow], 0);
if (l2up(l2, DL_DATA | CONFIRM, (int)l2->windowar[l2->sow], skb_queue_tail(&l2->tmp_queue, l2->windowar[l2->sow]);
l2->windowar[l2->sow]))
dev_kfree_skb(l2->windowar[l2->sow]);
l2->windowar[l2->sow] = NULL; l2->windowar[l2->sow] = NULL;
} }
l2->sow = (l2->sow + 1) % l2->window; l2->sow = (l2->sow + 1) % l2->window;
} }
spin_unlock_irqrestore(&l2->lock, flags);
while((skb =skb_dequeue(&l2->tmp_queue))) {
if (l2up(l2, DL_DATA | CONFIRM, (int)skb, skb))
dev_kfree_skb(skb);
}
} }
static void static void
@ -813,16 +820,18 @@ l2_disconnect(struct FsmInst *fi, int event, void *arg)
static void static void
l2_start_multi(struct FsmInst *fi, int event, void *arg) l2_start_multi(struct FsmInst *fi, int event, void *arg)
{ {
layer2_t *l2 = fi->userdata; layer2_t *l2 = fi->userdata;
struct sk_buff *skb = arg; struct sk_buff *skb = arg;
u_long flags;
send_uframe(l2, NULL, UA | get_PollFlag(l2, skb), RSP); spin_lock_irqsave(&l2->lock, flags);
clear_exception(l2);
l2->vs = 0; l2->vs = 0;
l2->va = 0; l2->va = 0;
l2->vr = 0; l2->vr = 0;
l2->sow = 0; l2->sow = 0;
spin_unlock_irqrestore(&l2->lock, flags);
clear_exception(l2);
send_uframe(l2, NULL, UA | get_PollFlag(l2, skb), RSP);
FsmChangeState(fi, ST_L2_7); FsmChangeState(fi, ST_L2_7);
FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 3); FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 3);
skb_trim(skb, 0); skb_trim(skb, 0);
@ -851,9 +860,10 @@ l2_send_DM(struct FsmInst *fi, int event, void *arg)
static void static void
l2_restart_multi(struct FsmInst *fi, int event, void *arg) l2_restart_multi(struct FsmInst *fi, int event, void *arg)
{ {
layer2_t *l2 = fi->userdata; layer2_t *l2 = fi->userdata;
struct sk_buff *skb = arg; struct sk_buff *skb = arg;
int est = 0; int est = 0;
u_long flags;
send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP); send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP);
@ -865,10 +875,12 @@ l2_restart_multi(struct FsmInst *fi, int event, void *arg)
} }
clear_exception(l2); clear_exception(l2);
spin_lock_irqsave(&l2->lock, flags);
l2->vs = 0; l2->vs = 0;
l2->va = 0; l2->va = 0;
l2->vr = 0; l2->vr = 0;
l2->sow = 0; l2->sow = 0;
spin_unlock_irqrestore(&l2->lock, flags);
FsmChangeState(fi, ST_L2_7); FsmChangeState(fi, ST_L2_7);
stop_t200(l2, 3); stop_t200(l2, 3);
FsmRestartTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 3); FsmRestartTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 3);
@ -883,8 +895,8 @@ l2_restart_multi(struct FsmInst *fi, int event, void *arg)
static void static void
l2_stop_multi(struct FsmInst *fi, int event, void *arg) l2_stop_multi(struct FsmInst *fi, int event, void *arg)
{ {
layer2_t *l2 = fi->userdata; layer2_t *l2 = fi->userdata;
struct sk_buff *skb = arg; struct sk_buff *skb = arg;
FsmChangeState(fi, ST_L2_4); FsmChangeState(fi, ST_L2_4);
FsmDelTimer(&l2->t203, 3); FsmDelTimer(&l2->t203, 3);
@ -899,9 +911,10 @@ l2_stop_multi(struct FsmInst *fi, int event, void *arg)
static void static void
l2_connected(struct FsmInst *fi, int event, void *arg) l2_connected(struct FsmInst *fi, int event, void *arg)
{ {
layer2_t *l2 = fi->userdata; layer2_t *l2 = fi->userdata;
struct sk_buff *skb = arg; struct sk_buff *skb = arg;
int pr=-1; int pr=-1;
u_long flags;
if (!get_PollFlag(l2, skb)) { if (!get_PollFlag(l2, skb)) {
l2_mdl_error_ua(fi, event, arg); l2_mdl_error_ua(fi, event, arg);
@ -917,11 +930,12 @@ l2_connected(struct FsmInst *fi, int event, void *arg)
pr = DL_ESTABLISH | INDICATION; pr = DL_ESTABLISH | INDICATION;
} }
stop_t200(l2, 5); stop_t200(l2, 5);
spin_lock_irqsave(&l2->lock, flags);
l2->vr = 0; l2->vr = 0;
l2->vs = 0; l2->vs = 0;
l2->va = 0; l2->va = 0;
l2->sow = 0; l2->sow = 0;
spin_unlock_irqrestore(&l2->lock, flags);
FsmChangeState(fi, ST_L2_7); FsmChangeState(fi, ST_L2_7);
FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 4); FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 4);
if (pr != -1) if (pr != -1)
@ -1045,8 +1059,10 @@ nrerrorrecovery(struct FsmInst *fi)
static void static void
invoke_retransmission(layer2_t *l2, unsigned int nr) invoke_retransmission(layer2_t *l2, unsigned int nr)
{ {
unsigned int p1; u_int p1;
u_long flags;
spin_lock_irqsave(&l2->lock, flags);
if (l2->vs != nr) { if (l2->vs != nr) {
while (l2->vs != nr) { while (l2->vs != nr) {
(l2->vs)--; (l2->vs)--;
@ -1058,13 +1074,13 @@ invoke_retransmission(layer2_t *l2, unsigned int nr)
p1 = (l2->vs - l2->va) % 8; p1 = (l2->vs - l2->va) % 8;
} }
p1 = (p1 + l2->sow) % l2->window; p1 = (p1 + l2->sow) % l2->window;
// if (test_bit(FLG_LAPB, &l2->flag))
// st->l1.bcs->tx_cnt += l2->windowar[p1]->len + l2headersize(l2, 0);
skb_queue_head(&l2->i_queue, l2->windowar[p1]); skb_queue_head(&l2->i_queue, l2->windowar[p1]);
l2->windowar[p1] = NULL; l2->windowar[p1] = NULL;
} }
spin_unlock_irqrestore(&l2->lock, flags);
FsmEvent(&l2->l2m, EV_L2_ACK_PULL, NULL); FsmEvent(&l2->l2m, EV_L2_ACK_PULL, NULL);
} } else
spin_unlock_irqrestore(&l2->lock, flags);
} }
static void static void
@ -1134,8 +1150,6 @@ l2_feed_i_if_reest(struct FsmInst *fi, int event, void *arg)
layer2_t *l2 = fi->userdata; layer2_t *l2 = fi->userdata;
struct sk_buff *skb = arg; struct sk_buff *skb = arg;
// if (test_bit(FLG_LAPB, &l2->flag))
// st->l1.bcs->tx_cnt += skb->len + l2headersize(l2, 0);
if (!test_bit(FLG_L3_INIT, &l2->flag)) if (!test_bit(FLG_L3_INIT, &l2->flag))
skb_queue_tail(&l2->i_queue, skb); skb_queue_tail(&l2->i_queue, skb);
else else
@ -1148,8 +1162,6 @@ l2_feed_i_pull(struct FsmInst *fi, int event, void *arg)
layer2_t *l2 = fi->userdata; layer2_t *l2 = fi->userdata;
struct sk_buff *skb = arg; struct sk_buff *skb = arg;
// if (test_bit(FLG_LAPB, &l2->flag))
// st->l1.bcs->tx_cnt += skb->len + l2headersize(l2, 0);
skb_queue_tail(&l2->i_queue, skb); skb_queue_tail(&l2->i_queue, skb);
FsmEvent(fi, EV_L2_ACK_PULL, NULL); FsmEvent(fi, EV_L2_ACK_PULL, NULL);
} }
@ -1160,8 +1172,6 @@ l2_feed_iqueue(struct FsmInst *fi, int event, void *arg)
layer2_t *l2 = fi->userdata; layer2_t *l2 = fi->userdata;
struct sk_buff *skb = arg; struct sk_buff *skb = arg;
// if (test_bit(FLG_LAPB, &l2->flag))
// st->l1.bcs->tx_cnt += skb->len + l2headersize(l2, 0);
skb_queue_tail(&l2->i_queue, skb); skb_queue_tail(&l2->i_queue, skb);
} }
@ -1172,6 +1182,7 @@ l2_got_iframe(struct FsmInst *fi, int event, void *arg)
struct sk_buff *skb = arg; struct sk_buff *skb = arg;
int PollFlag, i; int PollFlag, i;
u_int ns, nr; u_int ns, nr;
u_long flags;
i = l2addrsize(l2); i = l2addrsize(l2);
if (test_bit(FLG_MOD128, &l2->flag)) { if (test_bit(FLG_MOD128, &l2->flag)) {
@ -1187,29 +1198,34 @@ l2_got_iframe(struct FsmInst *fi, int event, void *arg)
dev_kfree_skb(skb); dev_kfree_skb(skb);
if (PollFlag) if (PollFlag)
enquiry_response(l2); enquiry_response(l2);
} else if (l2->vr == ns) {
(l2->vr)++;
if(test_bit(FLG_MOD128, &l2->flag))
l2->vr %= 128;
else
l2->vr %= 8;
test_and_clear_bit(FLG_REJEXC, &l2->flag);
if (PollFlag)
enquiry_response(l2);
else
test_and_set_bit(FLG_ACK_PEND, &l2->flag);
skb_pull(skb, l2headersize(l2, 0));
if (l2up(l2, DL_DATA | INDICATION, DINFO_SKB, skb))
dev_kfree_skb(skb);
} else { } else {
/* n(s)!=v(r) */ spin_lock_irqsave(&l2->lock, flags);
dev_kfree_skb(skb); if (l2->vr == ns) {
if (test_and_set_bit(FLG_REJEXC, &l2->flag)) { l2->vr++;
if(test_bit(FLG_MOD128, &l2->flag))
l2->vr %= 128;
else
l2->vr %= 8;
test_and_clear_bit(FLG_REJEXC, &l2->flag);
spin_unlock_irqrestore(&l2->lock, flags);
if (PollFlag) if (PollFlag)
enquiry_response(l2); enquiry_response(l2);
else
test_and_set_bit(FLG_ACK_PEND, &l2->flag);
skb_pull(skb, l2headersize(l2, 0));
if (l2up(l2, DL_DATA | INDICATION, DINFO_SKB, skb))
dev_kfree_skb(skb);
} else { } else {
enquiry_cr(l2, REJ, RSP, PollFlag); /* n(s)!=v(r) */
test_and_clear_bit(FLG_ACK_PEND, &l2->flag); spin_unlock_irqrestore(&l2->lock, flags);
dev_kfree_skb(skb);
if (test_and_set_bit(FLG_REJEXC, &l2->flag)) {
if (PollFlag)
enquiry_response(l2);
} else {
enquiry_cr(l2, REJ, RSP, PollFlag);
test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
}
} }
} }
if (legalnr(l2, nr)) { if (legalnr(l2, nr)) {
@ -1364,8 +1380,7 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
if (!skb) if (!skb)
return; return;
save_flags(flags); spin_lock_irqsave(&l2->lock, flags);
cli();
if(test_bit(FLG_MOD128, &l2->flag)) if(test_bit(FLG_MOD128, &l2->flag))
p1 = (l2->vs - l2->va) % 128; p1 = (l2->vs - l2->va) % 128;
else else
@ -1377,10 +1392,7 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
dev_kfree_skb(l2->windowar[p1]); dev_kfree_skb(l2->windowar[p1]);
} }
l2->windowar[p1] = skb; l2->windowar[p1] = skb;
skb = skb_clone(skb, GFP_ATOMIC);
i = sethdraddr(l2, header, CMD); i = sethdraddr(l2, header, CMD);
if (test_bit(FLG_MOD128, &l2->flag)) { if (test_bit(FLG_MOD128, &l2->flag)) {
header[i++] = l2->vs << 1; header[i++] = l2->vs << 1;
header[i++] = l2->vr << 1; header[i++] = l2->vr << 1;
@ -1389,14 +1401,15 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
header[i++] = (l2->vr << 5) | (l2->vs << 1); header[i++] = (l2->vr << 5) | (l2->vs << 1);
l2->vs = (l2->vs + 1) % 8; l2->vs = (l2->vs + 1) % 8;
} }
restore_flags(flags); spin_unlock_irqrestore(&l2->lock, flags);
skb = skb_clone(skb, GFP_ATOMIC);
p1 = skb_headroom(skb); p1 = skb_headroom(skb);
if (p1 >= i) if (p1 >= i)
memcpy(skb_push(skb, i), header, i); memcpy(skb_push(skb, i), header, i);
else { else {
printk(KERN_WARNING printk(KERN_WARNING
"isdnl2 pull_iqueue skb header(%d/%d) too short\n", i, p1); "isdnl2 pull_iqueue skb header(%d/%d) too short\n", i, p1);
oskb = skb; oskb = skb;
skb = alloc_skb(oskb->len + i, GFP_ATOMIC); skb = alloc_skb(oskb->len + i, GFP_ATOMIC);
if (!skb) { if (!skb) {
@ -2066,6 +2079,7 @@ new_l2(mISDNstack_t *st, mISDN_pid_t *pid, layer2_t **newl2) {
return(-ENOMEM); return(-ENOMEM);
} }
memset(nl2, 0, sizeof(layer2_t)); memset(nl2, 0, sizeof(layer2_t));
spin_lock_init(&nl2->lock);
nl2->debug = debug; nl2->debug = debug;
init_mISDNinstance(&nl2->inst, &isdnl2, nl2); init_mISDNinstance(&nl2->inst, &isdnl2, nl2);
nl2->inst.extentions = EXT_INST_CLONE; nl2->inst.extentions = EXT_INST_CLONE;
@ -2149,6 +2163,7 @@ new_l2(mISDNstack_t *st, mISDN_pid_t *pid, layer2_t **newl2) {
skb_queue_head_init(&nl2->i_queue); skb_queue_head_init(&nl2->i_queue);
skb_queue_head_init(&nl2->ui_queue); skb_queue_head_init(&nl2->ui_queue);
skb_queue_head_init(&nl2->down_queue); skb_queue_head_init(&nl2->down_queue);
skb_queue_head_init(&nl2->tmp_queue);
InitWin(nl2); InitWin(nl2);
nl2->l2m.fsm = &l2fsm; nl2->l2m.fsm = &l2fsm;
if (test_bit(FLG_LAPB, &nl2->flag) || if (test_bit(FLG_LAPB, &nl2->flag) ||

View File

@ -53,6 +53,8 @@ typedef struct _layer2 {
struct sk_buff_head i_queue; struct sk_buff_head i_queue;
struct sk_buff_head ui_queue; struct sk_buff_head ui_queue;
struct sk_buff_head down_queue; struct sk_buff_head down_queue;
struct sk_buff_head tmp_queue;
spinlock_t lock;
} layer2_t; } layer2_t;
/* l2 status_info */ /* l2 status_info */