mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-11 00:08:50 +00:00
ISDN: fix OOM condition for sending queued I-Frames
The skb_clone() return value was not checked and the skb_realloc_headroom() usage was wrong, the old skb was not freed. It turned out, that the skb_clone is not needed at all, the skb_realloc_headroom() will create a private copy with enough headroom and the original SKB can be used for the ACK queue. We need to requeue the original skb if the call failed, since the upper layer cannot be informed about memory shortage. Thanks to Insu Yun <wuninsu@gmail.com> to remind me on this issue. Signed-off-by: Karsten Keil <keil@b1-systems.de> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
4ef7ea9195
commit
c7a7c95e8e
@ -1247,7 +1247,7 @@ static void
|
||||
l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
|
||||
{
|
||||
struct PStack *st = fi->userdata;
|
||||
struct sk_buff *skb;
|
||||
struct sk_buff *skb, *nskb;
|
||||
struct Layer2 *l2 = &st->l2;
|
||||
u_char header[MAX_HEADER_LEN];
|
||||
int i, hdr_space_needed;
|
||||
@ -1262,14 +1262,10 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
|
||||
return;
|
||||
|
||||
hdr_space_needed = l2headersize(l2, 0);
|
||||
if (hdr_space_needed > skb_headroom(skb)) {
|
||||
struct sk_buff *orig_skb = skb;
|
||||
|
||||
skb = skb_realloc_headroom(skb, hdr_space_needed);
|
||||
if (!skb) {
|
||||
dev_kfree_skb(orig_skb);
|
||||
return;
|
||||
}
|
||||
nskb = skb_realloc_headroom(skb, hdr_space_needed);
|
||||
if (!nskb) {
|
||||
skb_queue_head(&l2->i_queue, skb);
|
||||
return;
|
||||
}
|
||||
spin_lock_irqsave(&l2->lock, flags);
|
||||
if (test_bit(FLG_MOD128, &l2->flag))
|
||||
@ -1282,7 +1278,7 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
|
||||
p1);
|
||||
dev_kfree_skb(l2->windowar[p1]);
|
||||
}
|
||||
l2->windowar[p1] = skb_clone(skb, GFP_ATOMIC);
|
||||
l2->windowar[p1] = skb;
|
||||
|
||||
i = sethdraddr(&st->l2, header, CMD);
|
||||
|
||||
@ -1295,8 +1291,8 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
|
||||
l2->vs = (l2->vs + 1) % 8;
|
||||
}
|
||||
spin_unlock_irqrestore(&l2->lock, flags);
|
||||
memcpy(skb_push(skb, i), header, i);
|
||||
st->l2.l2l1(st, PH_PULL | INDICATION, skb);
|
||||
memcpy(skb_push(nskb, i), header, i);
|
||||
st->l2.l2l1(st, PH_PULL | INDICATION, nskb);
|
||||
test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag);
|
||||
if (!test_and_set_bit(FLG_T200_RUN, &st->l2.flag)) {
|
||||
FsmDelTimer(&st->l2.t203, 13);
|
||||
|
Loading…
x
Reference in New Issue
Block a user