* [PATCH 05/17] pppoatm: drop frames to not-ready vcc
From: David Woodhouse @ 2012-11-30 0:35 UTC (permalink / raw)
To: netdev; +Cc: chas, krzysiek, David Woodhouse
In-Reply-To: <1354235736-26833-1-git-send-email-dwmw2@infradead.org>
From: Krzysztof Mazur <krzysiek@podlesie.net>
Patches "atm: detach protocol before closing vcc"
and "pppoatm: allow assign only on a connected socket" fixed
common cases where the pppoatm_send() crashes while sending
frame to not-ready vcc. However there are still some other cases
where we can send frames to vcc, which is flagged as ATM_VF_CLOSE
(for instance after vcc_release_async()) or it's opened but not
ready yet.
Now pppoatm_send(), like vcc_sendmsg(), checks for vcc flags that
indicate that vcc is not ready. If the vcc is not ready we just
drop frame. Queueing frames is much more complicated because we
don't have callbacks that inform us about vcc flags changes.
Signed-off-by: Krzysztof Mazur <krzysiek@podlesie.net>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
net/atm/pppoatm.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/net/atm/pppoatm.c b/net/atm/pppoatm.c
index c4a57bc..aeb726c 100644
--- a/net/atm/pppoatm.c
+++ b/net/atm/pppoatm.c
@@ -284,6 +284,13 @@ static int pppoatm_send(struct ppp_channel *chan, struct sk_buff *skb)
bh_lock_sock(sk_atm(vcc));
if (sock_owned_by_user(sk_atm(vcc)))
goto nospace;
+ if (test_bit(ATM_VF_RELEASED, &vcc->flags) ||
+ test_bit(ATM_VF_CLOSE, &vcc->flags) ||
+ !test_bit(ATM_VF_READY, &vcc->flags)) {
+ bh_unlock_sock(sk_atm(vcc));
+ kfree_skb(skb);
+ return DROP_PACKET;
+ }
switch (pvcc->encaps) { /* LLC encapsulation needed */
case e_llc:
--
1.8.0
^ permalink raw reply related
* [PATCH 01/17] atm: add owner of push() callback to atmvcc
From: David Woodhouse @ 2012-11-30 0:35 UTC (permalink / raw)
To: netdev; +Cc: chas, krzysiek, David Woodhouse
In-Reply-To: <1354235736-26833-1-git-send-email-dwmw2@infradead.org>
From: Krzysztof Mazur <krzysiek@podlesie.net>
The atm is using atmvcc->push(vcc, NULL) callback to notify protocol
that vcc will be closed and protocol must detach from it. This callback
is usually used by protocol to decrement module usage count by module_put(),
but it leaves small window then module is still used after module_put().
Now the owner of push() callback is kept in atmvcc and
module_put(atmvcc->owner) is called after the protocol is detached from vcc.
Signed-off-by: Krzysztof Mazur <krzysiek@podlesie.net>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Acked-by: Chas Williams <chas@cmf.nrl.navy.mil>
---
include/linux/atmdev.h | 1 +
net/atm/common.c | 2 ++
2 files changed, 3 insertions(+)
diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
index 22ef21c..72db2af 100644
--- a/include/linux/atmdev.h
+++ b/include/linux/atmdev.h
@@ -106,6 +106,7 @@ struct atm_vcc {
void *dev_data; /* per-device data */
void *proto_data; /* per-protocol data */
struct k_atm_aal_stats *stats; /* pointer to AAL stats group */
+ struct module *owner; /* owner of ->push function */
/* SVC part --- may move later ------------------------------------- */
short itf; /* interface number */
struct sockaddr_atmsvc local;
diff --git a/net/atm/common.c b/net/atm/common.c
index 0c0ad93..2421664 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -156,6 +156,7 @@ int vcc_create(struct net *net, struct socket *sock, int protocol, int family)
atomic_set(&sk->sk_rmem_alloc, 0);
vcc->push = NULL;
vcc->pop = NULL;
+ vcc->owner = NULL;
vcc->push_oam = NULL;
vcc->vpi = vcc->vci = 0; /* no VCI/VPI yet */
vcc->atm_options = vcc->aal_options = 0;
@@ -175,6 +176,7 @@ static void vcc_destroy_socket(struct sock *sk)
vcc->dev->ops->close(vcc);
if (vcc->push)
vcc->push(vcc, NULL); /* atmarpd has no push */
+ module_put(vcc->owner);
while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
atm_return(vcc, skb->truesize);
--
1.8.0
^ permalink raw reply related
* [PATCH 02/17] pppoatm: allow assign only on a connected socket
From: David Woodhouse @ 2012-11-30 0:35 UTC (permalink / raw)
To: netdev; +Cc: chas, krzysiek, David Woodhouse
In-Reply-To: <1354235736-26833-1-git-send-email-dwmw2@infradead.org>
From: Krzysztof Mazur <krzysiek@podlesie.net>
The pppoatm does not check if used vcc is in connected state,
causing an Oops in pppoatm_send() when vcc->send() is called
on not fully connected socket.
Now pppoatm can be assigned only on connected sockets; otherwise
-EINVAL error is returned.
Signed-off-by: Krzysztof Mazur <krzysiek@podlesie.net>
Cc: Chas Williams - CONTRACTOR <chas@cmf.nrl.navy.mil>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
net/atm/pppoatm.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/atm/pppoatm.c b/net/atm/pppoatm.c
index 226dca9..f27a07a 100644
--- a/net/atm/pppoatm.c
+++ b/net/atm/pppoatm.c
@@ -406,6 +406,8 @@ static int pppoatm_ioctl(struct socket *sock, unsigned int cmd,
return -ENOIOCTLCMD;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
+ if (sock->state != SS_CONNECTED)
+ return -EINVAL;
return pppoatm_assign_vcc(atmvcc, argp);
}
case PPPIOCGCHAN:
--
1.8.0
^ permalink raw reply related
* [PATCH 07/17] solos-pci: Wait for pending TX to complete when releasing vcc
From: David Woodhouse @ 2012-11-30 0:35 UTC (permalink / raw)
To: netdev; +Cc: chas, krzysiek, David Woodhouse
In-Reply-To: <1354235736-26833-1-git-send-email-dwmw2@infradead.org>
From: David Woodhouse <David.Woodhouse@intel.com>
We should no longer be calling the old pop routine for the vcc, after
vcc_release() has completed. Make sure we wait for any pending TX skbs
to complete, by waiting for our own PKT_PCLOSE control skb to be sent.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
drivers/atm/solos-pci.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index 9851093..387052d 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -92,6 +92,7 @@ struct pkt_hdr {
};
struct solos_skb_cb {
+ struct completion c;
struct atm_vcc *vcc;
uint32_t dma_addr;
};
@@ -881,11 +882,18 @@ static void pclose(struct atm_vcc *vcc)
header->vci = cpu_to_le16(vcc->vci);
header->type = cpu_to_le16(PKT_PCLOSE);
+ init_completion(&SKB_CB(skb)->c);
+
fpga_queue(card, SOLOS_CHAN(vcc->dev), skb, NULL);
clear_bit(ATM_VF_ADDR, &vcc->flags);
clear_bit(ATM_VF_READY, &vcc->flags);
+ if (!wait_for_completion_timeout(&SKB_CB(skb)->c,
+ msecs_to_jiffies(5000)))
+ dev_warn(&card->dev->dev, "Timeout waiting for VCC close on port %d\n",
+ SOLOS_CHAN(vcc->dev));
+
/* Hold up vcc_destroy_socket() (our caller) until solos_bh() in the
tasklet has finished processing any incoming packets (and, more to
the point, using the vcc pointer). */
@@ -1011,9 +1019,12 @@ static uint32_t fpga_tx(struct solos_card *card)
if (vcc) {
atomic_inc(&vcc->stats->tx);
solos_pop(vcc, oldskb);
- } else
+ } else {
+ struct pkt_hdr *header = (void *)oldskb->data;
+ if (le16_to_cpu(header->type) == PKT_PCLOSE)
+ complete(&SKB_CB(oldskb)->c);
dev_kfree_skb_irq(oldskb);
-
+ }
}
}
/* For non-DMA TX, write the 'TX start' bit for all four ports simultaneously */
@@ -1345,6 +1356,8 @@ static struct pci_driver fpga_driver = {
static int __init solos_pci_init(void)
{
+ BUILD_BUG_ON(sizeof(struct solos_skb_cb) > sizeof(((struct sk_buff *)0)->cb));
+
printk(KERN_INFO "Solos PCI Driver Version %s\n", VERSION);
return pci_register_driver(&fpga_driver);
}
--
1.8.0
^ permalink raw reply related
* [PATCH 08/17] br2684: don't send frames on not-ready vcc
From: David Woodhouse @ 2012-11-30 0:35 UTC (permalink / raw)
To: netdev; +Cc: chas, krzysiek, David Woodhouse, David Woodhouse
In-Reply-To: <1354235736-26833-1-git-send-email-dwmw2@infradead.org>
Avoid submitting packets to a vcc which is being closed. Things go badly
wrong when the ->pop method gets later called after everything's been
torn down.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Acked-by: Krzysztof Mazur <krzysiek@podlesie.net>
---
net/atm/br2684.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index 8eb6fbe..c483021 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -249,6 +249,12 @@ static int br2684_xmit_vcc(struct sk_buff *skb, struct net_device *dev,
skb_debug(skb);
ATM_SKB(skb)->vcc = atmvcc = brvcc->atmvcc;
+ if (test_bit(ATM_VF_RELEASED, &atmvcc->flags) ||
+ test_bit(ATM_VF_CLOSE, &atmvcc->flags) ||
+ !test_bit(ATM_VF_READY, &atmvcc->flags)) {
+ dev_kfree_skb(skb);
+ return 0;
+ }
pr_debug("atm_skb(%p)->vcc(%p)->dev(%p)\n", skb, atmvcc, atmvcc->dev);
atomic_add(skb->truesize, &sk_atm(atmvcc)->sk_wmem_alloc);
ATM_SKB(skb)->atm_options = atmvcc->atm_options;
--
1.8.0
^ permalink raw reply related
* [PATCH 14/17] pppoatm: optimise PPP channel wakeups after sock_owned_by_user()
From: David Woodhouse @ 2012-11-30 0:35 UTC (permalink / raw)
To: netdev; +Cc: chas, krzysiek, David Woodhouse
In-Reply-To: <1354235736-26833-1-git-send-email-dwmw2@infradead.org>
From: David Woodhouse <David.Woodhouse@intel.com>
We don't need to schedule the wakeup tasklet on *every* unlock; only if we
actually blocked the channel in the first place.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Acked-by: Krzysztof Mazur <krzysiek@podlesie.net>
---
net/atm/pppoatm.c | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/net/atm/pppoatm.c b/net/atm/pppoatm.c
index 9fcda8c..8c93267 100644
--- a/net/atm/pppoatm.c
+++ b/net/atm/pppoatm.c
@@ -113,7 +113,17 @@ static void pppoatm_release_cb(struct atm_vcc *atmvcc)
{
struct pppoatm_vcc *pvcc = atmvcc_to_pvcc(atmvcc);
- tasklet_schedule(&pvcc->wakeup_tasklet);
+ /*
+ * As in pppoatm_pop(), it's safe to clear the BLOCKED bit here because
+ * the wakeup *can't* race with pppoatm_send(). They both hold the PPP
+ * channel's ->downl lock. And the potential race with *setting* it,
+ * which leads to the double-check dance in pppoatm_may_send(), doesn't
+ * exist here. In the sock_owned_by_user() case in pppoatm_send(), we
+ * set the BLOCKED bit while the socket is still locked. We know that
+ * ->release_cb() can't be called until that's done.
+ */
+ if (test_and_clear_bit(BLOCKED, &pvcc->blocked))
+ tasklet_schedule(&pvcc->wakeup_tasklet);
if (pvcc->old_release_cb)
pvcc->old_release_cb(atmvcc);
}
@@ -292,8 +302,15 @@ static int pppoatm_send(struct ppp_channel *chan, struct sk_buff *skb)
vcc = ATM_SKB(skb)->vcc;
bh_lock_sock(sk_atm(vcc));
- if (sock_owned_by_user(sk_atm(vcc)))
+ if (sock_owned_by_user(sk_atm(vcc))) {
+ /*
+ * Needs to happen (and be flushed, hence test_and_) before we unlock
+ * the socket. It needs to be seen by the time our ->release_cb gets
+ * called.
+ */
+ test_and_set_bit(BLOCKED, &pvcc->blocked);
goto nospace;
+ }
if (test_bit(ATM_VF_RELEASED, &vcc->flags) ||
test_bit(ATM_VF_CLOSE, &vcc->flags) ||
!test_bit(ATM_VF_READY, &vcc->flags)) {
--
1.8.0
^ permalink raw reply related
* [PATCH 04/17] pppoatm: take ATM socket lock in pppoatm_send()
From: David Woodhouse @ 2012-11-30 0:35 UTC (permalink / raw)
To: netdev; +Cc: chas, krzysiek, David Woodhouse
In-Reply-To: <1354235736-26833-1-git-send-email-dwmw2@infradead.org>
From: Krzysztof Mazur <krzysiek@podlesie.net>
The pppoatm_send() does not take any lock that will prevent concurrent
vcc_sendmsg(). This causes two problems:
- there is no locking between checking the send queue size
with atm_may_send() and incrementing sk_wmem_alloc,
and the real queue size can be a little higher than sk_sndbuf
- the vcc->sendmsg() can be called concurrently. I'm not sure
if it's allowed. Some drivers (eni, nicstar, ...) seem
to assume it will never happen.
Now pppoatm_send() takes ATM socket lock, the same that is used
in vcc_sendmsg() and other ATM socket functions. The pppoatm_send()
is called with BH disabled, so bh_lock_sock() is used instead
of lock_sock().
Signed-off-by: Krzysztof Mazur <krzysiek@podlesie.net>
Cc: Chas Williams - CONTRACTOR <chas@cmf.nrl.navy.mil>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
net/atm/pppoatm.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/net/atm/pppoatm.c b/net/atm/pppoatm.c
index b23c672..c4a57bc 100644
--- a/net/atm/pppoatm.c
+++ b/net/atm/pppoatm.c
@@ -272,10 +272,19 @@ static inline int pppoatm_may_send(struct pppoatm_vcc *pvcc, int size)
static int pppoatm_send(struct ppp_channel *chan, struct sk_buff *skb)
{
struct pppoatm_vcc *pvcc = chan_to_pvcc(chan);
+ struct atm_vcc *vcc;
+ int ret;
+
ATM_SKB(skb)->vcc = pvcc->atmvcc;
pr_debug("(skb=0x%p, vcc=0x%p)\n", skb, pvcc->atmvcc);
if (skb->data[0] == '\0' && (pvcc->flags & SC_COMP_PROT))
(void) skb_pull(skb, 1);
+
+ vcc = ATM_SKB(skb)->vcc;
+ bh_lock_sock(sk_atm(vcc));
+ if (sock_owned_by_user(sk_atm(vcc)))
+ goto nospace;
+
switch (pvcc->encaps) { /* LLC encapsulation needed */
case e_llc:
if (skb_headroom(skb) < LLC_LEN) {
@@ -288,8 +297,10 @@ static int pppoatm_send(struct ppp_channel *chan, struct sk_buff *skb)
}
consume_skb(skb);
skb = n;
- if (skb == NULL)
+ if (skb == NULL) {
+ bh_unlock_sock(sk_atm(vcc));
return DROP_PACKET;
+ }
} else if (!pppoatm_may_send(pvcc, skb->truesize))
goto nospace;
memcpy(skb_push(skb, LLC_LEN), pppllc, LLC_LEN);
@@ -299,6 +310,7 @@ static int pppoatm_send(struct ppp_channel *chan, struct sk_buff *skb)
goto nospace;
break;
case e_autodetect:
+ bh_unlock_sock(sk_atm(vcc));
pr_debug("Trying to send without setting encaps!\n");
kfree_skb(skb);
return 1;
@@ -308,9 +320,12 @@ static int pppoatm_send(struct ppp_channel *chan, struct sk_buff *skb)
ATM_SKB(skb)->atm_options = ATM_SKB(skb)->vcc->atm_options;
pr_debug("atm_skb(%p)->vcc(%p)->dev(%p)\n",
skb, ATM_SKB(skb)->vcc, ATM_SKB(skb)->vcc->dev);
- return ATM_SKB(skb)->vcc->send(ATM_SKB(skb)->vcc, skb)
+ ret = ATM_SKB(skb)->vcc->send(ATM_SKB(skb)->vcc, skb)
? DROP_PACKET : 1;
+ bh_unlock_sock(sk_atm(vcc));
+ return ret;
nospace:
+ bh_unlock_sock(sk_atm(vcc));
/*
* We don't have space to send this SKB now, but we might have
* already applied SC_COMP_PROT compression, so may need to undo
--
1.8.0
^ permalink raw reply related
* [PATCH 13/17] br2684: allow assign only on a connected socket
From: David Woodhouse @ 2012-11-30 0:35 UTC (permalink / raw)
To: netdev; +Cc: chas, krzysiek, David Woodhouse
In-Reply-To: <1354235736-26833-1-git-send-email-dwmw2@infradead.org>
From: Krzysztof Mazur <krzysiek@podlesie.net>
The br2684 does not check if used vcc is in connected state,
causing potential Oops in pppoatm_send() when vcc->send() is called
on not fully connected socket.
Now br2684 can be assigned only on connected sockets; otherwise
-EINVAL error is returned.
Signed-off-by: Krzysztof Mazur <krzysiek@podlesie.net>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
net/atm/br2684.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index 373d784..a4ee4ad 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -704,10 +704,13 @@ static int br2684_ioctl(struct socket *sock, unsigned int cmd,
return -ENOIOCTLCMD;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- if (cmd == ATM_SETBACKEND)
+ if (cmd == ATM_SETBACKEND) {
+ if (sock->state != SS_CONNECTED)
+ return -EINVAL;
return br2684_regvcc(atmvcc, argp);
- else
+ } else {
return br2684_create(argp);
+ }
#ifdef CONFIG_ATM_BR2684_IPFILTER
case BR2684_SETFILT:
if (atmvcc->push != br2684_push)
--
1.8.0
^ permalink raw reply related
* [PATCH 10/17] pppoatm: fix missing wakeup in pppoatm_send()
From: David Woodhouse @ 2012-11-30 0:35 UTC (permalink / raw)
To: netdev; +Cc: chas, krzysiek, David Woodhouse
In-Reply-To: <1354235736-26833-1-git-send-email-dwmw2@infradead.org>
From: David Woodhouse <David.Woodhouse@intel.com>
Now that we can return zero from pppoatm_send() for reasons *other* than
the queue being full, that means we can't depend on a subsequent call to
pppoatm_pop() waking the queue, and we might leave it stalled
indefinitely.
Use the ->release_cb() callback to wake the queue after the sock is
unlocked.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Acked-by: Krzysztof Mazur <krzysiek@podlesie.net>
---
net/atm/pppoatm.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/net/atm/pppoatm.c b/net/atm/pppoatm.c
index 3dce84a..9fcda8c 100644
--- a/net/atm/pppoatm.c
+++ b/net/atm/pppoatm.c
@@ -60,6 +60,7 @@ struct pppoatm_vcc {
struct atm_vcc *atmvcc; /* VCC descriptor */
void (*old_push)(struct atm_vcc *, struct sk_buff *);
void (*old_pop)(struct atm_vcc *, struct sk_buff *);
+ void (*old_release_cb)(struct atm_vcc *);
struct module *old_owner;
/* keep old push/pop for detaching */
enum pppoatm_encaps encaps;
@@ -108,6 +109,14 @@ static void pppoatm_wakeup_sender(unsigned long arg)
ppp_output_wakeup((struct ppp_channel *) arg);
}
+static void pppoatm_release_cb(struct atm_vcc *atmvcc)
+{
+ struct pppoatm_vcc *pvcc = atmvcc_to_pvcc(atmvcc);
+
+ tasklet_schedule(&pvcc->wakeup_tasklet);
+ if (pvcc->old_release_cb)
+ pvcc->old_release_cb(atmvcc);
+}
/*
* This gets called every time the ATM card has finished sending our
* skb. The ->old_pop will take care up normal atm flow control,
@@ -152,6 +161,7 @@ static void pppoatm_unassign_vcc(struct atm_vcc *atmvcc)
pvcc = atmvcc_to_pvcc(atmvcc);
atmvcc->push = pvcc->old_push;
atmvcc->pop = pvcc->old_pop;
+ atmvcc->release_cb = pvcc->old_release_cb;
tasklet_kill(&pvcc->wakeup_tasklet);
ppp_unregister_channel(&pvcc->chan);
atmvcc->user_back = NULL;
@@ -388,6 +398,7 @@ static int pppoatm_assign_vcc(struct atm_vcc *atmvcc, void __user *arg)
pvcc->old_push = atmvcc->push;
pvcc->old_pop = atmvcc->pop;
pvcc->old_owner = atmvcc->owner;
+ pvcc->old_release_cb = atmvcc->release_cb;
pvcc->encaps = (enum pppoatm_encaps) be.encaps;
pvcc->chan.private = pvcc;
pvcc->chan.ops = &pppoatm_ops;
@@ -403,6 +414,7 @@ static int pppoatm_assign_vcc(struct atm_vcc *atmvcc, void __user *arg)
atmvcc->user_back = pvcc;
atmvcc->push = pppoatm_push;
atmvcc->pop = pppoatm_pop;
+ atmvcc->release_cb = pppoatm_release_cb;
__module_get(THIS_MODULE);
atmvcc->owner = THIS_MODULE;
--
1.8.0
^ permalink raw reply related
* [PATCH 11/17] br2684: fix module_put() race
From: David Woodhouse @ 2012-11-30 0:35 UTC (permalink / raw)
To: netdev; +Cc: chas, krzysiek, David Woodhouse
In-Reply-To: <1354235736-26833-1-git-send-email-dwmw2@infradead.org>
From: David Woodhouse <David.Woodhouse@intel.com>
The br2684 code used module_put() during unassignment from vcc with
hope that we have BKL. This assumption is no longer true.
Now owner field in atmvcc is used to move this module_put()
to vcc_destroy_socket().
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Acked-by: Krzysztof Mazur <krzysiek@podlesie.net>
---
net/atm/br2684.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index c483021..373d784 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -68,6 +68,7 @@ struct br2684_vcc {
/* keep old push, pop functions for chaining */
void (*old_push)(struct atm_vcc *vcc, struct sk_buff *skb);
void (*old_pop)(struct atm_vcc *vcc, struct sk_buff *skb);
+ struct module *old_owner;
enum br2684_encaps encaps;
struct list_head brvccs;
#ifdef CONFIG_ATM_BR2684_IPFILTER
@@ -385,8 +386,8 @@ static void br2684_close_vcc(struct br2684_vcc *brvcc)
write_unlock_irq(&devs_lock);
brvcc->atmvcc->user_back = NULL; /* what about vcc->recvq ??? */
brvcc->old_push(brvcc->atmvcc, NULL); /* pass on the bad news */
+ module_put(brvcc->old_owner);
kfree(brvcc);
- module_put(THIS_MODULE);
}
/* when AAL5 PDU comes in: */
@@ -560,9 +561,11 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg)
brvcc->encaps = (enum br2684_encaps)be.encaps;
brvcc->old_push = atmvcc->push;
brvcc->old_pop = atmvcc->pop;
+ brvcc->old_owner = atmvcc->owner;
barrier();
atmvcc->push = br2684_push;
atmvcc->pop = br2684_pop;
+ atmvcc->owner = THIS_MODULE;
/* initialize netdev carrier state */
if (atmvcc->dev->signal == ATM_PHY_SIG_LOST)
--
1.8.0
^ permalink raw reply related
* [PATCH 03/17] pppoatm: fix module_put() race
From: David Woodhouse @ 2012-11-30 0:35 UTC (permalink / raw)
To: netdev; +Cc: chas, krzysiek, David Woodhouse
In-Reply-To: <1354235736-26833-1-git-send-email-dwmw2@infradead.org>
From: Krzysztof Mazur <krzysiek@podlesie.net>
The pppoatm used module_put() during unassignment from vcc with
hope that we have BKL. This assumption is no longer true.
Now owner field in atmvcc is used to move this module_put()
to vcc_destroy_socket().
Signed-off-by: Krzysztof Mazur <krzysiek@podlesie.net>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
net/atm/pppoatm.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/net/atm/pppoatm.c b/net/atm/pppoatm.c
index f27a07a..b23c672 100644
--- a/net/atm/pppoatm.c
+++ b/net/atm/pppoatm.c
@@ -60,6 +60,7 @@ struct pppoatm_vcc {
struct atm_vcc *atmvcc; /* VCC descriptor */
void (*old_push)(struct atm_vcc *, struct sk_buff *);
void (*old_pop)(struct atm_vcc *, struct sk_buff *);
+ struct module *old_owner;
/* keep old push/pop for detaching */
enum pppoatm_encaps encaps;
atomic_t inflight;
@@ -155,8 +156,6 @@ static void pppoatm_unassign_vcc(struct atm_vcc *atmvcc)
ppp_unregister_channel(&pvcc->chan);
atmvcc->user_back = NULL;
kfree(pvcc);
- /* Gee, I hope we have the big kernel lock here... */
- module_put(THIS_MODULE);
}
/* Called when an AAL5 PDU comes in */
@@ -165,9 +164,13 @@ static void pppoatm_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
struct pppoatm_vcc *pvcc = atmvcc_to_pvcc(atmvcc);
pr_debug("\n");
if (skb == NULL) { /* VCC was closed */
+ struct module *module;
+
pr_debug("removing ATMPPP VCC %p\n", pvcc);
+ module = pvcc->old_owner;
pppoatm_unassign_vcc(atmvcc);
atmvcc->push(atmvcc, NULL); /* Pass along bad news */
+ module_put(module);
return;
}
atm_return(atmvcc, skb->truesize);
@@ -362,6 +365,7 @@ static int pppoatm_assign_vcc(struct atm_vcc *atmvcc, void __user *arg)
atomic_set(&pvcc->inflight, NONE_INFLIGHT);
pvcc->old_push = atmvcc->push;
pvcc->old_pop = atmvcc->pop;
+ pvcc->old_owner = atmvcc->owner;
pvcc->encaps = (enum pppoatm_encaps) be.encaps;
pvcc->chan.private = pvcc;
pvcc->chan.ops = &pppoatm_ops;
@@ -378,6 +382,7 @@ static int pppoatm_assign_vcc(struct atm_vcc *atmvcc, void __user *arg)
atmvcc->push = pppoatm_push;
atmvcc->pop = pppoatm_pop;
__module_get(THIS_MODULE);
+ atmvcc->owner = THIS_MODULE;
/* re-process everything received between connection setup and
backend setup */
--
1.8.0
^ permalink raw reply related
* [PATCH 17/17] solos-pci: remove list_vccs() debugging function
From: David Woodhouse @ 2012-11-30 0:35 UTC (permalink / raw)
To: netdev; +Cc: chas, krzysiek, David Woodhouse
In-Reply-To: <1354235736-26833-1-git-send-email-dwmw2@infradead.org>
From: David Woodhouse <David.Woodhouse@intel.com>
No idea why we've gone so long dumping a list of VCCs with vci==0 on
every ->open() call...
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
drivers/atm/solos-pci.c | 41 -----------------------------------------
1 file changed, 41 deletions(-)
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index af19202..e59bcfd 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -165,7 +165,6 @@ static void fpga_queue(struct solos_card *card, int port, struct sk_buff *skb,
static uint32_t fpga_tx(struct solos_card *);
static irqreturn_t solos_irq(int irq, void *dev_id);
static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci);
-static int list_vccs(int vci);
static int atm_init(struct solos_card *, struct device *);
static void atm_remove(struct solos_card *);
static int send_command(struct solos_card *card, int dev, const char *buf, size_t size);
@@ -792,44 +791,6 @@ static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci)
return vcc;
}
-static int list_vccs(int vci)
-{
- struct hlist_head *head;
- struct atm_vcc *vcc;
- struct hlist_node *node;
- struct sock *s;
- int num_found = 0;
- int i;
-
- read_lock(&vcc_sklist_lock);
- if (vci != 0){
- head = &vcc_hash[vci & (VCC_HTABLE_SIZE -1)];
- sk_for_each(s, node, head) {
- num_found ++;
- vcc = atm_sk(s);
- printk(KERN_DEBUG "Device: %d Vpi: %d Vci: %d\n",
- vcc->dev->number,
- vcc->vpi,
- vcc->vci);
- }
- } else {
- for(i = 0; i < VCC_HTABLE_SIZE; i++){
- head = &vcc_hash[i];
- sk_for_each(s, node, head) {
- num_found ++;
- vcc = atm_sk(s);
- printk(KERN_DEBUG "Device: %d Vpi: %d Vci: %d\n",
- vcc->dev->number,
- vcc->vpi,
- vcc->vci);
- }
- }
- }
- read_unlock(&vcc_sklist_lock);
- return num_found;
-}
-
-
static int popen(struct atm_vcc *vcc)
{
struct solos_card *card = vcc->dev->dev_data;
@@ -859,8 +820,6 @@ static int popen(struct atm_vcc *vcc)
set_bit(ATM_VF_ADDR, &vcc->flags);
set_bit(ATM_VF_READY, &vcc->flags);
- list_vccs(0);
-
return 0;
}
--
1.8.0
^ permalink raw reply related
* [PATCH 12/17] solos-pci: Fix leak of skb received for unknown vcc
From: David Woodhouse @ 2012-11-30 0:35 UTC (permalink / raw)
To: netdev; +Cc: chas, krzysiek, Nathan Williams, David Woodhouse
In-Reply-To: <1354235736-26833-1-git-send-email-dwmw2@infradead.org>
From: Nathan Williams <nathan@traverse.com.au>
... and ensure that the next skb is set up for RX in the DMA case.
Signed-off-by: Nathan Williams <nathan@traverse.com.au>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
drivers/atm/solos-pci.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index 387052d..6258961 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -711,7 +711,8 @@ void solos_bh(unsigned long card_arg)
dev_warn(&card->dev->dev, "Received packet for unknown VPI.VCI %d.%d on port %d\n",
le16_to_cpu(header->vpi), le16_to_cpu(header->vci),
port);
- continue;
+ dev_kfree_skb_any(skb);
+ break;
}
atm_charge(vcc, skb->truesize);
vcc->push(vcc, skb);
--
1.8.0
^ permalink raw reply related
* [PATCH 09/17] atm: Add release_cb() callback to vcc
From: David Woodhouse @ 2012-11-30 0:35 UTC (permalink / raw)
To: netdev; +Cc: chas, krzysiek, David Woodhouse
In-Reply-To: <1354235736-26833-1-git-send-email-dwmw2@infradead.org>
From: David Woodhouse <David.Woodhouse@intel.com>
The immediate use case for this is that it will allow us to ensure that a
pppoatm queue is woken after it has to drop a packet due to the sock being
locked.
Note that 'release_cb' is called when the socket is *unlocked*. This is
not to be confused with vcc_release() — which probably ought to be called
vcc_close().
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Acked-by: Krzysztof Mazur <krzysiek@podlesie.net>
---
include/linux/atmdev.h | 1 +
net/atm/common.c | 10 ++++++++++
2 files changed, 11 insertions(+)
diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
index 72db2af..c1da539 100644
--- a/include/linux/atmdev.h
+++ b/include/linux/atmdev.h
@@ -99,6 +99,7 @@ struct atm_vcc {
struct atm_dev *dev; /* device back pointer */
struct atm_qos qos; /* QOS */
struct atm_sap sap; /* SAP */
+ void (*release_cb)(struct atm_vcc *vcc); /* release_sock callback */
void (*push)(struct atm_vcc *vcc,struct sk_buff *skb);
void (*pop)(struct atm_vcc *vcc,struct sk_buff *skb); /* optional */
int (*push_oam)(struct atm_vcc *vcc,void *cell);
diff --git a/net/atm/common.c b/net/atm/common.c
index 2421664..806fc0a 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -126,10 +126,19 @@ static void vcc_write_space(struct sock *sk)
rcu_read_unlock();
}
+static void vcc_release_cb(struct sock *sk)
+{
+ struct atm_vcc *vcc = atm_sk(sk);
+
+ if (vcc->release_cb)
+ vcc->release_cb(vcc);
+}
+
static struct proto vcc_proto = {
.name = "VCC",
.owner = THIS_MODULE,
.obj_size = sizeof(struct atm_vcc),
+ .release_cb = vcc_release_cb,
};
int vcc_create(struct net *net, struct socket *sock, int protocol, int family)
@@ -158,6 +167,7 @@ int vcc_create(struct net *net, struct socket *sock, int protocol, int family)
vcc->pop = NULL;
vcc->owner = NULL;
vcc->push_oam = NULL;
+ vcc->release_cb = NULL;
vcc->vpi = vcc->vci = 0; /* no VCI/VPI yet */
vcc->atm_options = vcc->aal_options = 0;
sk->sk_destruct = vcc_sock_destruct;
--
1.8.0
^ permalink raw reply related
* [PATCH 15/17] solos-pci: clean up pclose() function
From: David Woodhouse @ 2012-11-30 0:35 UTC (permalink / raw)
To: netdev; +Cc: chas, krzysiek, David Woodhouse
In-Reply-To: <1354235736-26833-1-git-send-email-dwmw2@infradead.org>
From: David Woodhouse <David.Woodhouse@intel.com>
- Flush pending TX skbs from the queue rather than waiting for them all to
complete (suggested by Krzysztof Mazur <krzysiek@podlesie.net>).
- Clear ATM_VF_ADDR only when the PKT_PCLOSE packet has been submitted.
- Don't clear ATM_VF_READY at all — vcc_destroy_socket() does that for us.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
drivers/atm/solos-pci.c | 26 ++++++++++++++++++--------
1 file changed, 18 insertions(+), 8 deletions(-)
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index 6258961..7c56286 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -868,9 +868,20 @@ static int popen(struct atm_vcc *vcc)
static void pclose(struct atm_vcc *vcc)
{
struct solos_card *card = vcc->dev->dev_data;
- struct sk_buff *skb;
+ unsigned char port = SOLOS_CHAN(vcc->dev);
+ struct sk_buff *skb, *tmpskb;
struct pkt_hdr *header;
+ /* Remove any yet-to-be-transmitted packets from the pending queue */
+ spin_lock(&card->tx_queue_lock);
+ skb_queue_walk_safe(&card->tx_queue[port], skb, tmpskb) {
+ if (SKB_CB(skb)->vcc == vcc) {
+ skb_unlink(skb, &card->tx_queue[port]);
+ solos_pop(vcc, skb);
+ }
+ }
+ spin_unlock(&card->tx_queue_lock);
+
skb = alloc_skb(sizeof(*header), GFP_ATOMIC);
if (!skb) {
dev_warn(&card->dev->dev, "Failed to allocate sk_buff in pclose()\n");
@@ -885,20 +896,19 @@ static void pclose(struct atm_vcc *vcc)
init_completion(&SKB_CB(skb)->c);
- fpga_queue(card, SOLOS_CHAN(vcc->dev), skb, NULL);
-
- clear_bit(ATM_VF_ADDR, &vcc->flags);
- clear_bit(ATM_VF_READY, &vcc->flags);
+ fpga_queue(card, port, skb, NULL);
- if (!wait_for_completion_timeout(&SKB_CB(skb)->c,
- msecs_to_jiffies(5000)))
+ if (!wait_for_completion_timeout(&SKB_CB(skb)->c, 5 * HZ))
dev_warn(&card->dev->dev, "Timeout waiting for VCC close on port %d\n",
- SOLOS_CHAN(vcc->dev));
+ port);
/* Hold up vcc_destroy_socket() (our caller) until solos_bh() in the
tasklet has finished processing any incoming packets (and, more to
the point, using the vcc pointer). */
tasklet_unlock_wait(&card->tlet);
+
+ clear_bit(ATM_VF_ADDR, &vcc->flags);
+
return;
}
--
1.8.0
^ permalink raw reply related
* [PATCH 06/17] pppoatm: do not inline pppoatm_may_send()
From: David Woodhouse @ 2012-11-30 0:35 UTC (permalink / raw)
To: netdev; +Cc: chas, krzysiek, David Woodhouse
In-Reply-To: <1354235736-26833-1-git-send-email-dwmw2@infradead.org>
From: Krzysztof Mazur <krzysiek@podlesie.net>
The pppoatm_may_send() is quite heavy and it's called three times
in pppoatm_send() and inlining costs more than 200 bytes of code
(more than 10% of total pppoatm driver code size).
add/remove: 1/0 grow/shrink: 0/1 up/down: 132/-367 (-235)
function old new delta
pppoatm_may_send - 132 +132
pppoatm_send 900 533 -367
Signed-off-by: Krzysztof Mazur <krzysiek@podlesie.net>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
net/atm/pppoatm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/atm/pppoatm.c b/net/atm/pppoatm.c
index aeb726c..3dce84a 100644
--- a/net/atm/pppoatm.c
+++ b/net/atm/pppoatm.c
@@ -214,7 +214,7 @@ error:
ppp_input_error(&pvcc->chan, 0);
}
-static inline int pppoatm_may_send(struct pppoatm_vcc *pvcc, int size)
+static int pppoatm_may_send(struct pppoatm_vcc *pvcc, int size)
{
/*
* It's not clear that we need to bother with using atm_may_send()
--
1.8.0
^ permalink raw reply related
* [PATCH 16/17] solos-pci: use GFP_KERNEL where possible, not GFP_ATOMIC
From: David Woodhouse @ 2012-11-30 0:35 UTC (permalink / raw)
To: netdev; +Cc: chas, krzysiek, David Woodhouse
In-Reply-To: <1354235736-26833-1-git-send-email-dwmw2@infradead.org>
From: David Woodhouse <David.Woodhouse@intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
drivers/atm/solos-pci.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index 7c56286..af19202 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -842,7 +842,7 @@ static int popen(struct atm_vcc *vcc)
return -EINVAL;
}
- skb = alloc_skb(sizeof(*header), GFP_ATOMIC);
+ skb = alloc_skb(sizeof(*header), GFP_KERNEL);
if (!skb) {
if (net_ratelimit())
dev_warn(&card->dev->dev, "Failed to allocate sk_buff in popen()\n");
@@ -882,7 +882,7 @@ static void pclose(struct atm_vcc *vcc)
}
spin_unlock(&card->tx_queue_lock);
- skb = alloc_skb(sizeof(*header), GFP_ATOMIC);
+ skb = alloc_skb(sizeof(*header), GFP_KERNEL);
if (!skb) {
dev_warn(&card->dev->dev, "Failed to allocate sk_buff in pclose()\n");
return;
@@ -1270,7 +1270,7 @@ static int atm_init(struct solos_card *card, struct device *parent)
card->atmdev[i]->phy_data = (void *)(unsigned long)i;
atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_FOUND);
- skb = alloc_skb(sizeof(*header), GFP_ATOMIC);
+ skb = alloc_skb(sizeof(*header), GFP_KERNEL);
if (!skb) {
dev_warn(&card->dev->dev, "Failed to allocate sk_buff in atm_init()\n");
continue;
--
1.8.0
^ permalink raw reply related
* Re: [PATCH] br2684: don't send frames on not-ready vcc
From: Nathan Williams @ 2012-11-30 1:18 UTC (permalink / raw)
To: David Woodhouse; +Cc: David Miller, chas, krzysiek, netdev, linux-kernel
In-Reply-To: <1354122555.21562.92.camel@shinybook.infradead.org>
On Wed, 2012-11-28 at 17:09 +0000, David Woodhouse wrote:
> On Wed, 2012-11-28 at 12:04 -0500, David Miller wrote:
> > Do you want me to pull that tree into net-next or is there a plan to
> > repost the entire series of work for a final submission?
>
> I think it needs a little more testing/consensus first. I'd like an ack
> from Chas on the atm ->release_cb() thing, at least. And I wouldn't mind
> confirmation from Nathan's customer that they're no longer seeing the
> panics.
>
The customer has confirmed that they haven't seen any panics. I tested
these patches on OpenWrt with Kernel 3.3.8 and couldn't get a panic:
c118dc5 solos-pci: Fix leak of skb received for unknown vcc
e539793 br2684: fix module_put() race
3656320 br2684: don't send frames on not-ready vcc
753f920 solos-pci: Wait for pending TX to complete when releasing vcc
91ab2cf pppoatm: do not inline pppoatm_may_send()
85b48fa pppoatm: drop frames to not-ready vcc
3ac1080 pppoatm: take ATM socket lock in pppoatm_send()
e41faed pppoatm: fix module_put() race
3b1a914 pppoatm: allow assign only on a connected socket
ec809bd atm: add owner of push() callback to atmvcc
ae088d6 atm: br2684: Fix excessive queue bloat
I haven't tested these ones:
230a012 pppoatm: fix missing wakeup in pppoatm_send()
1c0c800 atm: Add release_cb() callback to vcc
^ permalink raw reply
* Re: [PATCH] br2684: don't send frames on not-ready vcc
From: David Woodhouse @ 2012-11-30 1:34 UTC (permalink / raw)
To: Nathan Williams; +Cc: David Miller, chas, krzysiek, netdev, linux-kernel
In-Reply-To: <1354238285.3128.273.camel@dualcore.traverse>
[-- Attachment #1: Type: text/plain, Size: 716 bytes --]
On Fri, 2012-11-30 at 12:18 +1100, Nathan Williams wrote:
> The customer has confirmed that they haven't seen any panics. I tested
> these patches on OpenWrt with Kernel 3.3.8 and couldn't get a panic:
Thanks.
> I haven't tested these ones:
>
> 230a012 pppoatm: fix missing wakeup in pppoatm_send()
> 1c0c800 atm: Add release_cb() callback to vcc
The race that fixes is fairly unlikely, but if you do see transmit
stalls you can make them apply to your 3.3.8 kernel by applying the same
preliminary patch that is now in the OpenWRT Attitude Adjustment branch:
https://dev.openwrt.org/browser/branches/attitude_adjustment/target/linux/generic/patches-3.3/080-prot-release-cb.patch
--
dwmw2
[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 6171 bytes --]
^ permalink raw reply
* regarding netlink usage
From: i trilok @ 2012-11-30 1:36 UTC (permalink / raw)
To: netdev
Hi,
I was trying to port some module code from 2.6.29 to 2.6.34.10 kernel.
I'm using netlink for communication between kernel module and user
application. In the netlink receive call back function I'm retrieving
netlink message header from (struct nlmsghdr*)skb->data and the same
was working in 2.6.29 kernel but when I ported this to 2.6.34.10 I was
seeing (struct nlmsghdr*)skb->head is holding the netlink message
header instead of skb->data, what could be wrong, is this intended
behavior?.
Thanks in advance.
Thanks,
Ina.
^ permalink raw reply
* Re: [PATCH v2 3/3] pppoatm: protect against freeing of vcc
From: Chas Williams (CONTRACTOR) @ 2012-11-30 1:38 UTC (permalink / raw)
To: David Woodhouse
Cc: Krzysztof Mazur, David Laight, davem, netdev, linux-kernel,
nathan
In-Reply-To: <1354227428.21562.230.camel@shinybook.infradead.org>
In message <1354227428.21562.230.camel@shinybook.infradead.org>,David Woodhouse writes:
>At this point, I think we're better off as we are (with Krzysztof's
>patch 1/7 dropped, and leaving vcc->dev->ops->close() being called
>before vcc->push(NULL). We've fairly much solved the issues with that
>arrangement, by checking ATM_VF_READY in the protocols' ->push()
>functions.
it isnt clear to me that fixes the race entirely either.
vcc_destroy_socket() and any of the push()/sends()'s are not serialized.
while you may clear the ATM_VF_READY flag, you might not clear it soon
enough for any particular push() that is already running. so it still
seems like you are racing close() against push() at this point. the
window is greatly reduced, but it still exists.
^ permalink raw reply
* [PATCH] 6lowpan: consider checksum bytes in fragmentation threshold
From: Alan Ott @ 2012-11-30 1:55 UTC (permalink / raw)
To: Alexander Smirnov, Dmitry Eremin-Solenikov, David S. Miller
Cc: linux-zigbee-devel, netdev, linux-kernel, Alan Ott
In-Reply-To: <504EA95C.9010003@signal11.us>
Change the threshold for framentation of a lowpan packet from
using the MTU size to now use the MTU size minus the checksum length,
which is added by the hardware. For IEEE 802.15.4, this effectively
changes it from 127 bytes to 125 bytes.
Signed-off-by: Alan Ott <alan@signal11.us>
---
net/ieee802154/6lowpan.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
index 6d42c17..f651da6 100644
--- a/net/ieee802154/6lowpan.c
+++ b/net/ieee802154/6lowpan.c
@@ -1047,7 +1047,8 @@ static netdev_tx_t lowpan_xmit(struct sk_buff *skb, struct net_device *dev)
goto error;
}
- if (skb->len <= IEEE802154_MTU) {
+ /* Send directly if less than the MTU minus the 2 checksum bytes. */
+ if (skb->len <= IEEE802154_MTU - IEEE802154_MFR_SIZE) {
err = dev_queue_xmit(skb);
goto out;
}
--
1.7.11.2
^ permalink raw reply related
* Re: [PATCH v2 3/3] pppoatm: protect against freeing of vcc
From: David Woodhouse @ 2012-11-30 1:57 UTC (permalink / raw)
To: Chas Williams (CONTRACTOR)
Cc: Krzysztof Mazur, David Laight, davem, netdev, linux-kernel,
nathan
In-Reply-To: <201211300138.qAU1c8sE003388@thirdoffive.cmf.nrl.navy.mil>
[-- Attachment #1: Type: text/plain, Size: 732 bytes --]
On Thu, 2012-11-29 at 20:38 -0500, Chas Williams (CONTRACTOR) wrote:
> it isnt clear to me that fixes the race entirely either.
> vcc_destroy_socket() and any of the push()/sends()'s are not
> serialized.
> while you may clear the ATM_VF_READY flag, you might not clear it soon
> enough for any particular push() that is already running. so it still
> seems like you are racing close() against push() at this point. the
> window is greatly reduced, but it still exists.
I think it's actually fixed for pppoatm by the bh_lock_sock() and the
sock_owned_by_user() check. As soon as vcc_release() calls lock_sock(),
pppoatm stops accepting packets.
It should be simple enough to do the same in br2684.
--
dwmw2
[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 6171 bytes --]
^ permalink raw reply
* Re: [PATCH] 6lowpan: consider checksum bytes in fragmentation threshold
From: Alan Ott @ 2012-11-30 1:58 UTC (permalink / raw)
To: Alan Ott
Cc: Alexander Smirnov, Dmitry Eremin-Solenikov, David S. Miller,
linux-zigbee-devel, netdev, linux-kernel
In-Reply-To: <1354240544-22214-1-git-send-email-alan@signal11.us>
On 11/29/2012 08:55 PM, Alan Ott wrote:
> Change the threshold for framentation of a lowpan packet from
> using the MTU size to now use the MTU size minus the checksum length,
> which is added by the hardware. For IEEE 802.15.4, this effectively
> changes it from 127 bytes to 125 bytes.
>
Sorry, this was put in the wrong thread. One day I'll get one of these
first-try. :(
^ permalink raw reply
* [PATCH 1/2] mac802154: fix memory leaks
From: Alan Ott @ 2012-11-30 4:25 UTC (permalink / raw)
To: Alexander Smirnov, Dmitry Eremin-Solenikov, David S. Miller,
Eric Dumazet
Cc: linux-zigbee-devel, netdev, linux-kernel, Alan Ott
In-Reply-To: <504EA95C.9010003@signal11.us>
kfree_skb() was not getting called in the case of some failures.
This was pointed out by Eric Dumazet.
Signed-off-by: Alan Ott <alan@signal11.us>
---
net/mac802154/tx.c | 5 ++++-
net/mac802154/wpan.c | 4 +++-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c
index 1a4df39..db63914 100644
--- a/net/mac802154/tx.c
+++ b/net/mac802154/tx.c
@@ -85,6 +85,7 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb,
if (!(priv->phy->channels_supported[page] & (1 << chan))) {
WARN_ON(1);
+ kfree_skb(skb);
return NETDEV_TX_OK;
}
@@ -103,8 +104,10 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb,
}
work = kzalloc(sizeof(struct xmit_work), GFP_ATOMIC);
- if (!work)
+ if (!work) {
+ kfree_skb(skb);
return NETDEV_TX_BUSY;
+ }
INIT_WORK(&work->work, mac802154_xmit_worker);
work->skb = skb;
diff --git a/net/mac802154/wpan.c b/net/mac802154/wpan.c
index f30f6d4..1191039 100644
--- a/net/mac802154/wpan.c
+++ b/net/mac802154/wpan.c
@@ -327,8 +327,10 @@ mac802154_wpan_xmit(struct sk_buff *skb, struct net_device *dev)
if (chan == MAC802154_CHAN_NONE ||
page >= WPAN_NUM_PAGES ||
- chan >= WPAN_NUM_CHANNELS)
+ chan >= WPAN_NUM_CHANNELS) {
+ kfree_skb(skb);
return NETDEV_TX_OK;
+ }
skb->skb_iif = dev->ifindex;
dev->stats.tx_packets++;
--
1.7.11.2
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox