* [PATCH 1/2][NETLABEL]: Shrink the genl-ops registration code.
From: Pavel Emelyanov @ 2008-02-13 11:09 UTC (permalink / raw)
To: David Miller; +Cc: Paul Moore, Linux Netdev List
Turning them to array and registration in a loop saves
80 lines of code and ~300 bytes from text section.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
net/netlabel/netlabel_cipso_v4.c | 43 +++++++------------
net/netlabel/netlabel_mgmt.c | 79 ++++++++++-----------------------
net/netlabel/netlabel_unlabeled.c | 86 ++++++++++--------------------------
3 files changed, 64 insertions(+), 144 deletions(-)
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
index c7ad64d..283ff4a 100644
--- a/net/netlabel/netlabel_cipso_v4.c
+++ b/net/netlabel/netlabel_cipso_v4.c
@@ -718,36 +718,35 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
* NetLabel Generic NETLINK Command Definitions
*/
-static struct genl_ops netlbl_cipsov4_genl_c_add = {
+static struct genl_ops netlbl_cipsov4_ops[] = {
+ {
.cmd = NLBL_CIPSOV4_C_ADD,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_cipsov4_genl_policy,
.doit = netlbl_cipsov4_add,
.dumpit = NULL,
-};
-
-static struct genl_ops netlbl_cipsov4_genl_c_remove = {
+ },
+ {
.cmd = NLBL_CIPSOV4_C_REMOVE,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_cipsov4_genl_policy,
.doit = netlbl_cipsov4_remove,
.dumpit = NULL,
-};
-
-static struct genl_ops netlbl_cipsov4_genl_c_list = {
+ },
+ {
.cmd = NLBL_CIPSOV4_C_LIST,
.flags = 0,
.policy = netlbl_cipsov4_genl_policy,
.doit = netlbl_cipsov4_list,
.dumpit = NULL,
-};
-
-static struct genl_ops netlbl_cipsov4_genl_c_listall = {
+ },
+ {
.cmd = NLBL_CIPSOV4_C_LISTALL,
.flags = 0,
.policy = netlbl_cipsov4_genl_policy,
.doit = NULL,
.dumpit = netlbl_cipsov4_listall,
+ },
};
/*
@@ -764,28 +763,18 @@ static struct genl_ops netlbl_cipsov4_genl_c_listall = {
*/
int netlbl_cipsov4_genl_init(void)
{
- int ret_val;
+ int ret_val, i;
ret_val = genl_register_family(&netlbl_cipsov4_gnl_family);
if (ret_val != 0)
return ret_val;
- ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family,
- &netlbl_cipsov4_genl_c_add);
- if (ret_val != 0)
- return ret_val;
- ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family,
- &netlbl_cipsov4_genl_c_remove);
- if (ret_val != 0)
- return ret_val;
- ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family,
- &netlbl_cipsov4_genl_c_list);
- if (ret_val != 0)
- return ret_val;
- ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family,
- &netlbl_cipsov4_genl_c_listall);
- if (ret_val != 0)
- return ret_val;
+ for (i = 0; i < ARRAY_SIZE(netlbl_cipsov4_ops); i++) {
+ ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family,
+ &netlbl_cipsov4_ops[i]);
+ if (ret_val != 0)
+ return ret_val;
+ }
return 0;
}
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
index e2258dc..05d9886 100644
--- a/net/netlabel/netlabel_mgmt.c
+++ b/net/netlabel/netlabel_mgmt.c
@@ -517,68 +517,63 @@ version_failure:
* NetLabel Generic NETLINK Command Definitions
*/
-static struct genl_ops netlbl_mgmt_genl_c_add = {
+static struct genl_ops netlbl_mgmt_genl_ops[] = {
+ {
.cmd = NLBL_MGMT_C_ADD,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_mgmt_genl_policy,
.doit = netlbl_mgmt_add,
.dumpit = NULL,
-};
-
-static struct genl_ops netlbl_mgmt_genl_c_remove = {
+ },
+ {
.cmd = NLBL_MGMT_C_REMOVE,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_mgmt_genl_policy,
.doit = netlbl_mgmt_remove,
.dumpit = NULL,
-};
-
-static struct genl_ops netlbl_mgmt_genl_c_listall = {
+ },
+ {
.cmd = NLBL_MGMT_C_LISTALL,
.flags = 0,
.policy = netlbl_mgmt_genl_policy,
.doit = NULL,
.dumpit = netlbl_mgmt_listall,
-};
-
-static struct genl_ops netlbl_mgmt_genl_c_adddef = {
+ },
+ {
.cmd = NLBL_MGMT_C_ADDDEF,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_mgmt_genl_policy,
.doit = netlbl_mgmt_adddef,
.dumpit = NULL,
-};
-
-static struct genl_ops netlbl_mgmt_genl_c_removedef = {
+ },
+ {
.cmd = NLBL_MGMT_C_REMOVEDEF,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_mgmt_genl_policy,
.doit = netlbl_mgmt_removedef,
.dumpit = NULL,
-};
-
-static struct genl_ops netlbl_mgmt_genl_c_listdef = {
+ },
+ {
.cmd = NLBL_MGMT_C_LISTDEF,
.flags = 0,
.policy = netlbl_mgmt_genl_policy,
.doit = netlbl_mgmt_listdef,
.dumpit = NULL,
-};
-
-static struct genl_ops netlbl_mgmt_genl_c_protocols = {
+ },
+ {
.cmd = NLBL_MGMT_C_PROTOCOLS,
.flags = 0,
.policy = netlbl_mgmt_genl_policy,
.doit = NULL,
.dumpit = netlbl_mgmt_protocols,
-};
-
-static struct genl_ops netlbl_mgmt_genl_c_version = {
+ },
+ {
.cmd = NLBL_MGMT_C_VERSION,
.flags = 0,
.policy = netlbl_mgmt_genl_policy,
.doit = netlbl_mgmt_version,
.dumpit = NULL,
+ },
};
/*
@@ -595,44 +590,18 @@ static struct genl_ops netlbl_mgmt_genl_c_version = {
*/
int netlbl_mgmt_genl_init(void)
{
- int ret_val;
+ int ret_val, i;
ret_val = genl_register_family(&netlbl_mgmt_gnl_family);
if (ret_val != 0)
return ret_val;
- ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
- &netlbl_mgmt_genl_c_add);
- if (ret_val != 0)
- return ret_val;
- ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
- &netlbl_mgmt_genl_c_remove);
- if (ret_val != 0)
- return ret_val;
- ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
- &netlbl_mgmt_genl_c_listall);
- if (ret_val != 0)
- return ret_val;
- ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
- &netlbl_mgmt_genl_c_adddef);
- if (ret_val != 0)
- return ret_val;
- ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
- &netlbl_mgmt_genl_c_removedef);
- if (ret_val != 0)
- return ret_val;
- ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
- &netlbl_mgmt_genl_c_listdef);
- if (ret_val != 0)
- return ret_val;
- ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
- &netlbl_mgmt_genl_c_protocols);
- if (ret_val != 0)
- return ret_val;
- ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
- &netlbl_mgmt_genl_c_version);
- if (ret_val != 0)
- return ret_val;
+ for (i = 0; i < ARRAY_SIZE(netlbl_mgmt_genl_ops); i++) {
+ ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
+ &netlbl_mgmt_genl_ops[i]);
+ if (ret_val != 0)
+ return ret_val;
+ }
return 0;
}
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index 3e745b7..f0f1322 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -1553,68 +1553,63 @@ unlabel_staticlistdef_return:
* NetLabel Generic NETLINK Command Definitions
*/
-static struct genl_ops netlbl_unlabel_genl_c_staticadd = {
+static struct genl_ops netlbl_unlabel_genl_ops[] = {
+ {
.cmd = NLBL_UNLABEL_C_STATICADD,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_unlabel_genl_policy,
.doit = netlbl_unlabel_staticadd,
.dumpit = NULL,
-};
-
-static struct genl_ops netlbl_unlabel_genl_c_staticremove = {
+ },
+ {
.cmd = NLBL_UNLABEL_C_STATICREMOVE,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_unlabel_genl_policy,
.doit = netlbl_unlabel_staticremove,
.dumpit = NULL,
-};
-
-static struct genl_ops netlbl_unlabel_genl_c_staticlist = {
+ },
+ {
.cmd = NLBL_UNLABEL_C_STATICLIST,
.flags = 0,
.policy = netlbl_unlabel_genl_policy,
.doit = NULL,
.dumpit = netlbl_unlabel_staticlist,
-};
-
-static struct genl_ops netlbl_unlabel_genl_c_staticadddef = {
+ },
+ {
.cmd = NLBL_UNLABEL_C_STATICADDDEF,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_unlabel_genl_policy,
.doit = netlbl_unlabel_staticadddef,
.dumpit = NULL,
-};
-
-static struct genl_ops netlbl_unlabel_genl_c_staticremovedef = {
+ },
+ {
.cmd = NLBL_UNLABEL_C_STATICREMOVEDEF,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_unlabel_genl_policy,
.doit = netlbl_unlabel_staticremovedef,
.dumpit = NULL,
-};
-
-static struct genl_ops netlbl_unlabel_genl_c_staticlistdef = {
+ },
+ {
.cmd = NLBL_UNLABEL_C_STATICLISTDEF,
.flags = 0,
.policy = netlbl_unlabel_genl_policy,
.doit = NULL,
.dumpit = netlbl_unlabel_staticlistdef,
-};
-
-static struct genl_ops netlbl_unlabel_genl_c_accept = {
+ },
+ {
.cmd = NLBL_UNLABEL_C_ACCEPT,
.flags = GENL_ADMIN_PERM,
.policy = netlbl_unlabel_genl_policy,
.doit = netlbl_unlabel_accept,
.dumpit = NULL,
-};
-
-static struct genl_ops netlbl_unlabel_genl_c_list = {
+ },
+ {
.cmd = NLBL_UNLABEL_C_LIST,
.flags = 0,
.policy = netlbl_unlabel_genl_policy,
.doit = netlbl_unlabel_list,
.dumpit = NULL,
+ },
};
/*
@@ -1631,51 +1626,18 @@ static struct genl_ops netlbl_unlabel_genl_c_list = {
*/
int netlbl_unlabel_genl_init(void)
{
- int ret_val;
+ int ret_val, i;
ret_val = genl_register_family(&netlbl_unlabel_gnl_family);
if (ret_val != 0)
return ret_val;
- ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
- &netlbl_unlabel_genl_c_staticadd);
- if (ret_val != 0)
- return ret_val;
-
- ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
- &netlbl_unlabel_genl_c_staticremove);
- if (ret_val != 0)
- return ret_val;
-
- ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
- &netlbl_unlabel_genl_c_staticlist);
- if (ret_val != 0)
- return ret_val;
-
- ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
- &netlbl_unlabel_genl_c_staticadddef);
- if (ret_val != 0)
- return ret_val;
-
- ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
- &netlbl_unlabel_genl_c_staticremovedef);
- if (ret_val != 0)
- return ret_val;
-
- ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
- &netlbl_unlabel_genl_c_staticlistdef);
- if (ret_val != 0)
- return ret_val;
-
- ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
- &netlbl_unlabel_genl_c_accept);
- if (ret_val != 0)
- return ret_val;
-
- ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
- &netlbl_unlabel_genl_c_list);
- if (ret_val != 0)
- return ret_val;
+ for (i = 0; i < ARRAY_SIZE(netlbl_unlabel_genl_ops); i++) {
+ ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
+ &netlbl_unlabel_genl_ops[i]);
+ if (ret_val != 0)
+ return ret_val;
+ }
return 0;
}
--
1.5.3.4
^ permalink raw reply related
* [PATCH][AX25] mkiss: ax_bump() locking fix
From: Jarek Poplawski @ 2008-02-13 11:17 UTC (permalink / raw)
To: Jeff Garzik, David Miller; +Cc: Jann Traschewski, Ralf Baechle, netdev
In-Reply-To: <20080206074529.GC4496@ff.dom.local>
Hi,
This is unchanged patch previously sent here for testing.
I think it should be applied.
Thanks,
Jarek P.
---------------->
Subject: [PATCH][AX25] mkiss: ax_bump() locking fix
According to one of OOPSes reported by Jann softirq can break
while skb is prepared for netif_rx. The report isn't complete,
so the real reason of the later bug could be different, but
IMHO this locking break in ax_bump is unsafe and unnecessary.
Reported-and-tested-by: Jann Traschewski <jann@gmx.de>
Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
---
drivers/net/hamradio/mkiss.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index cfcd15a..30c9b3b 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -289,7 +289,6 @@ static void ax_bump(struct mkiss *ax)
*ax->rbuff &= ~0x20;
}
}
- spin_unlock_bh(&ax->buflock);
count = ax->rcount;
@@ -297,17 +296,17 @@ static void ax_bump(struct mkiss *ax)
printk(KERN_ERR "mkiss: %s: memory squeeze, dropping packet.\n",
ax->dev->name);
ax->stats.rx_dropped++;
+ spin_unlock_bh(&ax->buflock);
return;
}
- spin_lock_bh(&ax->buflock);
memcpy(skb_put(skb,count), ax->rbuff, count);
- spin_unlock_bh(&ax->buflock);
skb->protocol = ax25_type_trans(skb, ax->dev);
netif_rx(skb);
ax->dev->last_rx = jiffies;
ax->stats.rx_packets++;
ax->stats.rx_bytes += count;
+ spin_unlock_bh(&ax->buflock);
}
static void kiss_unesc(struct mkiss *ax, unsigned char s)
^ permalink raw reply related
* [PATCH 2/2][NETLABEL]: Move some initialization code into __init section.
From: Pavel Emelyanov @ 2008-02-13 11:12 UTC (permalink / raw)
To: David Miller; +Cc: Paul Moore, Linux Netdev List
Everything that is called from netlbl_init() can be marked with
__init. This moves 620 bytes from .text section to .text.init one.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
net/netlabel/netlabel_cipso_v4.c | 2 +-
net/netlabel/netlabel_domainhash.c | 2 +-
net/netlabel/netlabel_mgmt.c | 2 +-
net/netlabel/netlabel_unlabeled.c | 6 +++---
net/netlabel/netlabel_user.c | 2 +-
5 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
index 283ff4a..fdc14a0 100644
--- a/net/netlabel/netlabel_cipso_v4.c
+++ b/net/netlabel/netlabel_cipso_v4.c
@@ -761,7 +761,7 @@ static struct genl_ops netlbl_cipsov4_ops[] = {
* mechanism. Returns zero on success, negative values on failure.
*
*/
-int netlbl_cipsov4_genl_init(void)
+int __init netlbl_cipsov4_genl_init(void)
{
int ret_val, i;
diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c
index fd46231..02c2f7c 100644
--- a/net/netlabel/netlabel_domainhash.c
+++ b/net/netlabel/netlabel_domainhash.c
@@ -171,7 +171,7 @@ static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain)
* values on error.
*
*/
-int netlbl_domhsh_init(u32 size)
+int __init netlbl_domhsh_init(u32 size)
{
u32 iter;
struct netlbl_domhsh_tbl *hsh_tbl;
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
index 05d9886..22c1912 100644
--- a/net/netlabel/netlabel_mgmt.c
+++ b/net/netlabel/netlabel_mgmt.c
@@ -588,7 +588,7 @@ static struct genl_ops netlbl_mgmt_genl_ops[] = {
* mechanism. Returns zero on success, negative values on failure.
*
*/
-int netlbl_mgmt_genl_init(void)
+int __init netlbl_mgmt_genl_init(void)
{
int ret_val, i;
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index f0f1322..4478f2f 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -1624,7 +1624,7 @@ static struct genl_ops netlbl_unlabel_genl_ops[] = {
* mechanism. Returns zero on success, negative values on failure.
*
*/
-int netlbl_unlabel_genl_init(void)
+int __init netlbl_unlabel_genl_init(void)
{
int ret_val, i;
@@ -1661,7 +1661,7 @@ static struct notifier_block netlbl_unlhsh_netdev_notifier = {
* non-zero values on error.
*
*/
-int netlbl_unlabel_init(u32 size)
+int __init netlbl_unlabel_init(u32 size)
{
u32 iter;
struct netlbl_unlhsh_tbl *hsh_tbl;
@@ -1765,7 +1765,7 @@ unlabel_getattr_nolabel:
* and to send unlabeled network traffic by default.
*
*/
-int netlbl_unlabel_defconf(void)
+int __init netlbl_unlabel_defconf(void)
{
int ret_val;
struct netlbl_dom_map *entry;
diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c
index 023fc8f..b17d420 100644
--- a/net/netlabel/netlabel_user.c
+++ b/net/netlabel/netlabel_user.c
@@ -59,7 +59,7 @@
* non-zero on failure.
*
*/
-int netlbl_netlink_init(void)
+int __init netlbl_netlink_init(void)
{
int ret_val;
--
1.5.3.4
^ permalink raw reply related
* Re: BUG: 2.6.25-rc1: iptables postrouting setup causes oops
From: Haavard Skinnemoen @ 2008-02-13 11:29 UTC (permalink / raw)
To: Ben Nizette; +Cc: Andrew Morton, netfilter-devel, linux-kernel, netdev
In-Reply-To: <20080213101024.39347322@dhcp-252-066.norway.atmel.com>
On Wed, 13 Feb 2008 10:10:24 +0100
Haavard Skinnemoen <hskinnemoen@atmel.com> wrote:
> > > ip_tables: (C) 2000-2006 Netfilter Core Team
> > > nf_conntrack version 0.5.0 (1024 buckets, 4096 max)
> > > Unable to handle kernel paging request at virtual address d76a7138
> > > ptbr = 91d3b000 pgd = 0000e5f3 pte = 00014370
>
> Hmm. It actually found something in the pte? Looks like a swap
> entry...but that doesn't make sense at that virtual address. Userspace
> is below 0x80000000.
(...)
> > If so, the bug could be almost anywhere - in slab, or in some random piece
> > of code which scribbles on slab's data structures.
>
> Yes, it looks like memory corruption, especially since the page table
> appears to be corrupted as well. But I'll have a look and see if the
> code that dumps the pte is doing something bogus...
Yes, that code is indeed buggy. The below patch should fix it, although
the page tables probably won't contain anything interesting, and it
could still be a memory corruption issue. And it definitely won't fix
the real issue.
I have a couple of patches that will eliminate the need for this fixup
(and probably improve performance as well), but they are probably 2.6.26
material.
Haavard
diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c
index 6560cb1..ce4e429 100644
--- a/arch/avr32/mm/fault.c
+++ b/arch/avr32/mm/fault.c
@@ -189,6 +189,8 @@ no_context:
page = sysreg_read(PTBR);
printk(KERN_ALERT "ptbr = %08lx", page);
+ if (address >= TASK_SIZE)
+ page = (unsigned long)swapper_pg_dir;
if (page) {
page = ((unsigned long *)page)[address >> 22];
printk(" pgd = %08lx", page);
^ permalink raw reply related
* [PATCH][AX25] ax25_out: check skb for NULL in ax25_kick()
From: Jarek Poplawski @ 2008-02-13 11:56 UTC (permalink / raw)
To: David Miller; +Cc: Jann Traschewski, Bernard Pidoux F6BVP, Ralf Baechle, netdev
In-Reply-To: <20080206074529.GC4496@ff.dom.local>
Hi,
Here is an "official" version of "testing patch #2" from this thread.
The only difference: ax25->vs is changed only after checking skb is
not NULL (plus a comment). IMHO it could be applied.
Thanks,
Jarek P.
---------------->
Subject: [AX25] ax25_out: check skb for NULL in ax25_kick()
According to some OOPS reports ax25_kick tries to clone NULL skbs
sometimes. It looks like a race with ax25_clear_queues(). Probably
there is no need to add more than a simple check for this yet.
Another report suggested there are probably also cases where ax25
->paclen == 0 can happen in ax25_output(); this wasn't confirmed
during testing but let's leave this debugging check for some time.
Reported-and-tested-by: Jann Traschewski <jann@gmx.de>
Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
---
diff -Nurp 2.6.24-mm1-/net/ax25/ax25_out.c 2.6.24-mm1+/net/ax25/ax25_out.c
--- 2.6.24-mm1-/net/ax25/ax25_out.c 2008-01-24 22:58:37.000000000 +0000
+++ 2.6.24-mm1+/net/ax25/ax25_out.c 2008-02-13 10:43:50.000000000 +0000
@@ -117,6 +117,12 @@ void ax25_output(ax25_cb *ax25, int pacl
unsigned char *p;
int frontlen, len, fragno, ka9qfrag, first = 1;
+ if (paclen < 16) {
+ WARN_ON_ONCE(1);
+ kfree_skb(skb);
+ return;
+ }
+
if ((skb->len - 1) > paclen) {
if (*skb->data == AX25_P_TEXT) {
skb_pull(skb, 1); /* skip PID */
@@ -251,8 +257,6 @@ void ax25_kick(ax25_cb *ax25)
if (start == end)
return;
- ax25->vs = start;
-
/*
* Transmit data until either we're out of data to send or
* the window is full. Send a poll on the final I frame if
@@ -261,8 +265,13 @@ void ax25_kick(ax25_cb *ax25)
/*
* Dequeue the frame and copy it.
+ * Check for race with ax25_clear_queues().
*/
skb = skb_dequeue(&ax25->write_queue);
+ if (!skb)
+ return;
+
+ ax25->vs = start;
do {
if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
^ permalink raw reply
* Re: [PATCH 1/2][NETLABEL]: Shrink the genl-ops registration code.
From: Paul Moore @ 2008-02-13 13:33 UTC (permalink / raw)
To: Pavel Emelyanov; +Cc: David Miller, Linux Netdev List
In-Reply-To: <47B2CFF8.50803@openvz.org>
On Wednesday 13 February 2008 6:09:44 am Pavel Emelyanov wrote:
> Turning them to array and registration in a loop saves
> 80 lines of code and ~300 bytes from text section.
>
> Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Definitely an improvement, thank you.
Acked-by: Paul Moore <paul.moore@hp.com>
> ---
> net/netlabel/netlabel_cipso_v4.c | 43 +++++++------------
> net/netlabel/netlabel_mgmt.c | 79 ++++++++++-----------------------
> net/netlabel/netlabel_unlabeled.c | 86
> ++++++++++-------------------------- 3 files changed, 64 insertions(+), 144
> deletions(-)
>
> diff --git a/net/netlabel/netlabel_cipso_v4.c
> b/net/netlabel/netlabel_cipso_v4.c index c7ad64d..283ff4a 100644
> --- a/net/netlabel/netlabel_cipso_v4.c
> +++ b/net/netlabel/netlabel_cipso_v4.c
> @@ -718,36 +718,35 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb,
> struct genl_info *info) * NetLabel Generic NETLINK Command Definitions
> */
>
> -static struct genl_ops netlbl_cipsov4_genl_c_add = {
> +static struct genl_ops netlbl_cipsov4_ops[] = {
> + {
> .cmd = NLBL_CIPSOV4_C_ADD,
> .flags = GENL_ADMIN_PERM,
> .policy = netlbl_cipsov4_genl_policy,
> .doit = netlbl_cipsov4_add,
> .dumpit = NULL,
> -};
> -
> -static struct genl_ops netlbl_cipsov4_genl_c_remove = {
> + },
> + {
> .cmd = NLBL_CIPSOV4_C_REMOVE,
> .flags = GENL_ADMIN_PERM,
> .policy = netlbl_cipsov4_genl_policy,
> .doit = netlbl_cipsov4_remove,
> .dumpit = NULL,
> -};
> -
> -static struct genl_ops netlbl_cipsov4_genl_c_list = {
> + },
> + {
> .cmd = NLBL_CIPSOV4_C_LIST,
> .flags = 0,
> .policy = netlbl_cipsov4_genl_policy,
> .doit = netlbl_cipsov4_list,
> .dumpit = NULL,
> -};
> -
> -static struct genl_ops netlbl_cipsov4_genl_c_listall = {
> + },
> + {
> .cmd = NLBL_CIPSOV4_C_LISTALL,
> .flags = 0,
> .policy = netlbl_cipsov4_genl_policy,
> .doit = NULL,
> .dumpit = netlbl_cipsov4_listall,
> + },
> };
>
> /*
> @@ -764,28 +763,18 @@ static struct genl_ops netlbl_cipsov4_genl_c_listall
> = { */
> int netlbl_cipsov4_genl_init(void)
> {
> - int ret_val;
> + int ret_val, i;
>
> ret_val = genl_register_family(&netlbl_cipsov4_gnl_family);
> if (ret_val != 0)
> return ret_val;
>
> - ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family,
> - &netlbl_cipsov4_genl_c_add);
> - if (ret_val != 0)
> - return ret_val;
> - ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family,
> - &netlbl_cipsov4_genl_c_remove);
> - if (ret_val != 0)
> - return ret_val;
> - ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family,
> - &netlbl_cipsov4_genl_c_list);
> - if (ret_val != 0)
> - return ret_val;
> - ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family,
> - &netlbl_cipsov4_genl_c_listall);
> - if (ret_val != 0)
> - return ret_val;
> + for (i = 0; i < ARRAY_SIZE(netlbl_cipsov4_ops); i++) {
> + ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family,
> + &netlbl_cipsov4_ops[i]);
> + if (ret_val != 0)
> + return ret_val;
> + }
>
> return 0;
> }
> diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
> index e2258dc..05d9886 100644
> --- a/net/netlabel/netlabel_mgmt.c
> +++ b/net/netlabel/netlabel_mgmt.c
> @@ -517,68 +517,63 @@ version_failure:
> * NetLabel Generic NETLINK Command Definitions
> */
>
> -static struct genl_ops netlbl_mgmt_genl_c_add = {
> +static struct genl_ops netlbl_mgmt_genl_ops[] = {
> + {
> .cmd = NLBL_MGMT_C_ADD,
> .flags = GENL_ADMIN_PERM,
> .policy = netlbl_mgmt_genl_policy,
> .doit = netlbl_mgmt_add,
> .dumpit = NULL,
> -};
> -
> -static struct genl_ops netlbl_mgmt_genl_c_remove = {
> + },
> + {
> .cmd = NLBL_MGMT_C_REMOVE,
> .flags = GENL_ADMIN_PERM,
> .policy = netlbl_mgmt_genl_policy,
> .doit = netlbl_mgmt_remove,
> .dumpit = NULL,
> -};
> -
> -static struct genl_ops netlbl_mgmt_genl_c_listall = {
> + },
> + {
> .cmd = NLBL_MGMT_C_LISTALL,
> .flags = 0,
> .policy = netlbl_mgmt_genl_policy,
> .doit = NULL,
> .dumpit = netlbl_mgmt_listall,
> -};
> -
> -static struct genl_ops netlbl_mgmt_genl_c_adddef = {
> + },
> + {
> .cmd = NLBL_MGMT_C_ADDDEF,
> .flags = GENL_ADMIN_PERM,
> .policy = netlbl_mgmt_genl_policy,
> .doit = netlbl_mgmt_adddef,
> .dumpit = NULL,
> -};
> -
> -static struct genl_ops netlbl_mgmt_genl_c_removedef = {
> + },
> + {
> .cmd = NLBL_MGMT_C_REMOVEDEF,
> .flags = GENL_ADMIN_PERM,
> .policy = netlbl_mgmt_genl_policy,
> .doit = netlbl_mgmt_removedef,
> .dumpit = NULL,
> -};
> -
> -static struct genl_ops netlbl_mgmt_genl_c_listdef = {
> + },
> + {
> .cmd = NLBL_MGMT_C_LISTDEF,
> .flags = 0,
> .policy = netlbl_mgmt_genl_policy,
> .doit = netlbl_mgmt_listdef,
> .dumpit = NULL,
> -};
> -
> -static struct genl_ops netlbl_mgmt_genl_c_protocols = {
> + },
> + {
> .cmd = NLBL_MGMT_C_PROTOCOLS,
> .flags = 0,
> .policy = netlbl_mgmt_genl_policy,
> .doit = NULL,
> .dumpit = netlbl_mgmt_protocols,
> -};
> -
> -static struct genl_ops netlbl_mgmt_genl_c_version = {
> + },
> + {
> .cmd = NLBL_MGMT_C_VERSION,
> .flags = 0,
> .policy = netlbl_mgmt_genl_policy,
> .doit = netlbl_mgmt_version,
> .dumpit = NULL,
> + },
> };
>
> /*
> @@ -595,44 +590,18 @@ static struct genl_ops netlbl_mgmt_genl_c_version = {
> */
> int netlbl_mgmt_genl_init(void)
> {
> - int ret_val;
> + int ret_val, i;
>
> ret_val = genl_register_family(&netlbl_mgmt_gnl_family);
> if (ret_val != 0)
> return ret_val;
>
> - ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
> - &netlbl_mgmt_genl_c_add);
> - if (ret_val != 0)
> - return ret_val;
> - ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
> - &netlbl_mgmt_genl_c_remove);
> - if (ret_val != 0)
> - return ret_val;
> - ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
> - &netlbl_mgmt_genl_c_listall);
> - if (ret_val != 0)
> - return ret_val;
> - ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
> - &netlbl_mgmt_genl_c_adddef);
> - if (ret_val != 0)
> - return ret_val;
> - ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
> - &netlbl_mgmt_genl_c_removedef);
> - if (ret_val != 0)
> - return ret_val;
> - ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
> - &netlbl_mgmt_genl_c_listdef);
> - if (ret_val != 0)
> - return ret_val;
> - ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
> - &netlbl_mgmt_genl_c_protocols);
> - if (ret_val != 0)
> - return ret_val;
> - ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
> - &netlbl_mgmt_genl_c_version);
> - if (ret_val != 0)
> - return ret_val;
> + for (i = 0; i < ARRAY_SIZE(netlbl_mgmt_genl_ops); i++) {
> + ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
> + &netlbl_mgmt_genl_ops[i]);
> + if (ret_val != 0)
> + return ret_val;
> + }
>
> return 0;
> }
> diff --git a/net/netlabel/netlabel_unlabeled.c
> b/net/netlabel/netlabel_unlabeled.c index 3e745b7..f0f1322 100644
> --- a/net/netlabel/netlabel_unlabeled.c
> +++ b/net/netlabel/netlabel_unlabeled.c
> @@ -1553,68 +1553,63 @@ unlabel_staticlistdef_return:
> * NetLabel Generic NETLINK Command Definitions
> */
>
> -static struct genl_ops netlbl_unlabel_genl_c_staticadd = {
> +static struct genl_ops netlbl_unlabel_genl_ops[] = {
> + {
> .cmd = NLBL_UNLABEL_C_STATICADD,
> .flags = GENL_ADMIN_PERM,
> .policy = netlbl_unlabel_genl_policy,
> .doit = netlbl_unlabel_staticadd,
> .dumpit = NULL,
> -};
> -
> -static struct genl_ops netlbl_unlabel_genl_c_staticremove = {
> + },
> + {
> .cmd = NLBL_UNLABEL_C_STATICREMOVE,
> .flags = GENL_ADMIN_PERM,
> .policy = netlbl_unlabel_genl_policy,
> .doit = netlbl_unlabel_staticremove,
> .dumpit = NULL,
> -};
> -
> -static struct genl_ops netlbl_unlabel_genl_c_staticlist = {
> + },
> + {
> .cmd = NLBL_UNLABEL_C_STATICLIST,
> .flags = 0,
> .policy = netlbl_unlabel_genl_policy,
> .doit = NULL,
> .dumpit = netlbl_unlabel_staticlist,
> -};
> -
> -static struct genl_ops netlbl_unlabel_genl_c_staticadddef = {
> + },
> + {
> .cmd = NLBL_UNLABEL_C_STATICADDDEF,
> .flags = GENL_ADMIN_PERM,
> .policy = netlbl_unlabel_genl_policy,
> .doit = netlbl_unlabel_staticadddef,
> .dumpit = NULL,
> -};
> -
> -static struct genl_ops netlbl_unlabel_genl_c_staticremovedef = {
> + },
> + {
> .cmd = NLBL_UNLABEL_C_STATICREMOVEDEF,
> .flags = GENL_ADMIN_PERM,
> .policy = netlbl_unlabel_genl_policy,
> .doit = netlbl_unlabel_staticremovedef,
> .dumpit = NULL,
> -};
> -
> -static struct genl_ops netlbl_unlabel_genl_c_staticlistdef = {
> + },
> + {
> .cmd = NLBL_UNLABEL_C_STATICLISTDEF,
> .flags = 0,
> .policy = netlbl_unlabel_genl_policy,
> .doit = NULL,
> .dumpit = netlbl_unlabel_staticlistdef,
> -};
> -
> -static struct genl_ops netlbl_unlabel_genl_c_accept = {
> + },
> + {
> .cmd = NLBL_UNLABEL_C_ACCEPT,
> .flags = GENL_ADMIN_PERM,
> .policy = netlbl_unlabel_genl_policy,
> .doit = netlbl_unlabel_accept,
> .dumpit = NULL,
> -};
> -
> -static struct genl_ops netlbl_unlabel_genl_c_list = {
> + },
> + {
> .cmd = NLBL_UNLABEL_C_LIST,
> .flags = 0,
> .policy = netlbl_unlabel_genl_policy,
> .doit = netlbl_unlabel_list,
> .dumpit = NULL,
> + },
> };
>
> /*
> @@ -1631,51 +1626,18 @@ static struct genl_ops netlbl_unlabel_genl_c_list =
> { */
> int netlbl_unlabel_genl_init(void)
> {
> - int ret_val;
> + int ret_val, i;
>
> ret_val = genl_register_family(&netlbl_unlabel_gnl_family);
> if (ret_val != 0)
> return ret_val;
>
> - ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
> - &netlbl_unlabel_genl_c_staticadd);
> - if (ret_val != 0)
> - return ret_val;
> -
> - ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
> - &netlbl_unlabel_genl_c_staticremove);
> - if (ret_val != 0)
> - return ret_val;
> -
> - ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
> - &netlbl_unlabel_genl_c_staticlist);
> - if (ret_val != 0)
> - return ret_val;
> -
> - ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
> - &netlbl_unlabel_genl_c_staticadddef);
> - if (ret_val != 0)
> - return ret_val;
> -
> - ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
> - &netlbl_unlabel_genl_c_staticremovedef);
> - if (ret_val != 0)
> - return ret_val;
> -
> - ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
> - &netlbl_unlabel_genl_c_staticlistdef);
> - if (ret_val != 0)
> - return ret_val;
> -
> - ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
> - &netlbl_unlabel_genl_c_accept);
> - if (ret_val != 0)
> - return ret_val;
> -
> - ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
> - &netlbl_unlabel_genl_c_list);
> - if (ret_val != 0)
> - return ret_val;
> + for (i = 0; i < ARRAY_SIZE(netlbl_unlabel_genl_ops); i++) {
> + ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
> + &netlbl_unlabel_genl_ops[i]);
> + if (ret_val != 0)
> + return ret_val;
> + }
>
> return 0;
> }
--
paul moore
linux security @ hp
^ permalink raw reply
* Re: [PATCH 2/2][NETLABEL]: Move some initialization code into __init section.
From: Paul Moore @ 2008-02-13 13:37 UTC (permalink / raw)
To: Pavel Emelyanov; +Cc: David Miller, Linux Netdev List
In-Reply-To: <47B2D086.8040008@openvz.org>
On Wednesday 13 February 2008 6:12:06 am Pavel Emelyanov wrote:
> Everything that is called from netlbl_init() can be marked with
> __init. This moves 620 bytes from .text section to .text.init one.
>
> Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
I ran into problems with __init and __exit once because I didn't fully
understand their impact; this caused me to be rather hesitant to make use of
them. However, you seem to know what you are doing and these look like
reasonable changes to me so I'll ack this patch and if we do run into a
problem the fix should be pretty trivial.
I appreciate you taking the time to find these optimizations, thanks again.
Acked-by: Paul Moore <paul.moore@hp.com>
> ---
> net/netlabel/netlabel_cipso_v4.c | 2 +-
> net/netlabel/netlabel_domainhash.c | 2 +-
> net/netlabel/netlabel_mgmt.c | 2 +-
> net/netlabel/netlabel_unlabeled.c | 6 +++---
> net/netlabel/netlabel_user.c | 2 +-
> 5 files changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/net/netlabel/netlabel_cipso_v4.c
> b/net/netlabel/netlabel_cipso_v4.c index 283ff4a..fdc14a0 100644
> --- a/net/netlabel/netlabel_cipso_v4.c
> +++ b/net/netlabel/netlabel_cipso_v4.c
> @@ -761,7 +761,7 @@ static struct genl_ops netlbl_cipsov4_ops[] = {
> * mechanism. Returns zero on success, negative values on failure.
> *
> */
> -int netlbl_cipsov4_genl_init(void)
> +int __init netlbl_cipsov4_genl_init(void)
> {
> int ret_val, i;
>
> diff --git a/net/netlabel/netlabel_domainhash.c
> b/net/netlabel/netlabel_domainhash.c index fd46231..02c2f7c 100644
> --- a/net/netlabel/netlabel_domainhash.c
> +++ b/net/netlabel/netlabel_domainhash.c
> @@ -171,7 +171,7 @@ static struct netlbl_dom_map
> *netlbl_domhsh_search_def(const char *domain) * values on error.
> *
> */
> -int netlbl_domhsh_init(u32 size)
> +int __init netlbl_domhsh_init(u32 size)
> {
> u32 iter;
> struct netlbl_domhsh_tbl *hsh_tbl;
> diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
> index 05d9886..22c1912 100644
> --- a/net/netlabel/netlabel_mgmt.c
> +++ b/net/netlabel/netlabel_mgmt.c
> @@ -588,7 +588,7 @@ static struct genl_ops netlbl_mgmt_genl_ops[] = {
> * mechanism. Returns zero on success, negative values on failure.
> *
> */
> -int netlbl_mgmt_genl_init(void)
> +int __init netlbl_mgmt_genl_init(void)
> {
> int ret_val, i;
>
> diff --git a/net/netlabel/netlabel_unlabeled.c
> b/net/netlabel/netlabel_unlabeled.c index f0f1322..4478f2f 100644
> --- a/net/netlabel/netlabel_unlabeled.c
> +++ b/net/netlabel/netlabel_unlabeled.c
> @@ -1624,7 +1624,7 @@ static struct genl_ops netlbl_unlabel_genl_ops[] = {
> * mechanism. Returns zero on success, negative values on failure.
> *
> */
> -int netlbl_unlabel_genl_init(void)
> +int __init netlbl_unlabel_genl_init(void)
> {
> int ret_val, i;
>
> @@ -1661,7 +1661,7 @@ static struct notifier_block
> netlbl_unlhsh_netdev_notifier = { * non-zero values on error.
> *
> */
> -int netlbl_unlabel_init(u32 size)
> +int __init netlbl_unlabel_init(u32 size)
> {
> u32 iter;
> struct netlbl_unlhsh_tbl *hsh_tbl;
> @@ -1765,7 +1765,7 @@ unlabel_getattr_nolabel:
> * and to send unlabeled network traffic by default.
> *
> */
> -int netlbl_unlabel_defconf(void)
> +int __init netlbl_unlabel_defconf(void)
> {
> int ret_val;
> struct netlbl_dom_map *entry;
> diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c
> index 023fc8f..b17d420 100644
> --- a/net/netlabel/netlabel_user.c
> +++ b/net/netlabel/netlabel_user.c
> @@ -59,7 +59,7 @@
> * non-zero on failure.
> *
> */
> -int netlbl_netlink_init(void)
> +int __init netlbl_netlink_init(void)
> {
> int ret_val;
--
paul moore
linux security @ hp
^ permalink raw reply
* Re: [PATCH] drivers/base: export gpl (un)register_memory_notifier
From: Jan-Bernd Themann @ 2008-02-13 15:17 UTC (permalink / raw)
To: linuxppc-dev
Cc: Thomas Klein, Themann, Jan-Bernd, netdev, Dave Hansen, apw,
linux-kernel, Christoph Raisch, Badari Pulavarty, Greg KH,
Thomas Klein
In-Reply-To: <1202748429.8276.21.camel@nimitz.home.sr71.net>
Hi Dave,
On Monday 11 February 2008 17:47, Dave Hansen wrote:
> Also, just ripping down and completely re-doing the entire mass of cards
> every time a 16MB area of memory is added or removed seems like an
> awfully big sledgehammer to me. I would *HATE* to see anybody else
> using this driver as an example to work off of? Can't you just keep
> track of which areas the driver is actually *USING* and only worry about
> changing mappings if that intersects with an area having hotplug done on
> it?
to form a base for the eHEA memory add / remove concept discussion:
Explanation of the current eHEA memory add / remove concept:
Constraints imposed by HW / FW:
- eHEA has own MMU
- eHEA Memory Regions (MRs) are used by the eHEA MMU to translate virtual
addresses to absolute addresses (like DMA mapped memory on a PCI bus)
- The number of MRs is limited (not enough to have one MR per packet)
- Registration of MRs is comparativley slow as done via slow firmware call
(H_CALL)
- MRs can have a maximum size of the memory available under linux
- MRs cover a contiguous virtual memory block (no holes)
Because of this there is just one big MR that covers entire kernel memory.
We also need a mapping table from kernel addresses to this
contiguous "virtual memory IO space" (here called ehea_bmap).
- When memory is added / removed to LPAR (and linux), the MR has to be updated.
This can only be done by destroying and recreating the MR. There is no H_CALL
to modify MR size. To find holes in the linux kernel memory layout we have to
iterate over the memory sections for recreating a ehea_bmap
(otherwise MR would be bigger then available memory causing the
registration to fail)
- DLPAR userspace tools, kernel, driver, firmware and HMC are involved in that
process on System p
Memory add: version without a external memory notifier call
- new memory used in a transfer_xmit will result in a "ehea_bmap
translation miss", which triggers a rebuild and reregistration
of the ehea_bmap based on the current kernel memory setup.
- advantage: the number of MR rebuilds is reduced significantly compared to
a rebuild for each 16MB chunk of memory added.
Memory add: version with external notifier call:
- We still need a ehea_bmap (whatever structure it has)
Memory remove with notifier:
- We have to rebuild the ehea_bmap instantly to remove the pages that are
no longer available. Without doing that, the firmware (pHYP) cannot remove
that memory from the LPAR. As we don't know if or how many additional
sections are to be removed before the DLPAR user space tool tells the
firmware to remove the memory, we can't wait with the rebuild.
Our current understanding about the current Memory Hotplug System are
(please correct me
if I'm wrong):
- depends on sparse mem
- only whole memory sections are added / removed
- for each section a memory resource is registered
>From the driver side we need:
- some kind of memory notification mechanism.
For memory add we can live without any external memory notification
event. For memory remove we do need an external trigger (see explanation
above).
- a way to iterate over all kernel pages and a way to detect holes in the
kernel memory layout in order to build up our own ehea_bmap.
Memory notification trigger:
- These triggers exist, an exported "register_memory_notifier" /
"unregister_memory_notifier" would work in this scheme
Functions to use while building ehea_bmap + MRs:
- Use either the functions that are used by the memory hotplug system as
well, that means using the section defines + functions (section_nr_to_pfn,
pfn_valid)
- Use currently other not exported functions in kernel/resource.c, like
walk_memory_resource (where we would still need the maximum possible number
of pages NR_MEM_SECTIONS)
- Maybe some kind of new interface?
What would you suggest?
Regards,
Jan-Bernd & Christoph
^ permalink raw reply
* [PATCH] ehea: add kdump support
From: Thomas Klein @ 2008-02-13 15:18 UTC (permalink / raw)
To: Jeff Garzik
Cc: netdev, Christoph Raisch, Jan-Bernd Themann, linux-kernel,
linux-ppc, Marcus Eder, Thomas Klein
This patch adds kdump support to the ehea driver. As the firmware doesn't free
resource handles automatically, the driver has to run an as simple as possible
free resource function in case of a crash shutdown. The function iterates over
two arrays freeing all resource handles which are stored there. The arrays are
kept up-to-date during normal runtime. The crash handler fn is triggered by the
recently introduced PPC crash shutdown reg/unreg functions.
Signed-off-by: Thomas Klein <tklein@de.ibm.com>
---
drivers/net/ehea/ehea.h | 34 +++++-
drivers/net/ehea/ehea_main.c | 281 ++++++++++++++++++++++++++++++++++++++----
2 files changed, 290 insertions(+), 25 deletions(-)
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index 88fb53e..7c4ead3 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -40,7 +40,7 @@
#include <asm/io.h>
#define DRV_NAME "ehea"
-#define DRV_VERSION "EHEA_0083"
+#define DRV_VERSION "EHEA_0087"
/* eHEA capability flags */
#define DLPAR_PORT_ADD_REM 1
@@ -386,6 +386,13 @@ struct ehea_port_res {
#define EHEA_MAX_PORTS 16
+
+#define EHEA_NUM_PORTRES_FW_HANDLES 6 /* QP handle, SendCQ handle,
+ RecvCQ handle, EQ handle,
+ SendMR handle, RecvMR handle */
+#define EHEA_NUM_PORT_FW_HANDLES 1 /* EQ handle */
+#define EHEA_NUM_ADAPTER_FW_HANDLES 2 /* MR handle, NEQ handle */
+
struct ehea_adapter {
u64 handle;
struct of_device *ofdev;
@@ -405,6 +412,31 @@ struct ehea_mc_list {
u64 macaddr;
};
+/* kdump support */
+struct ehea_fw_handle_entry {
+ u64 adh; /* Adapter Handle */
+ u64 fwh; /* Firmware Handle */
+};
+
+struct ehea_fw_handle_array {
+ struct ehea_fw_handle_entry *arr;
+ int num_entries;
+ struct semaphore lock;
+};
+
+struct ehea_bcmc_reg_entry {
+ u64 adh; /* Adapter Handle */
+ u32 port_id; /* Logical Port Id */
+ u8 reg_type; /* Registration Type */
+ u64 macaddr;
+};
+
+struct ehea_bcmc_reg_array {
+ struct ehea_bcmc_reg_entry *arr;
+ int num_entries;
+ struct semaphore lock;
+};
+
#define EHEA_PORT_UP 1
#define EHEA_PORT_DOWN 0
#define EHEA_PHY_LINK_UP 1
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index c051c7e..21af674 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -35,6 +35,7 @@
#include <linux/if_ether.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
+#include <asm/kexec.h>
#include <net/ip.h>
@@ -98,8 +99,10 @@ static int port_name_cnt;
static LIST_HEAD(adapter_list);
u64 ehea_driver_flags;
struct work_struct ehea_rereg_mr_task;
-
struct semaphore dlpar_mem_lock;
+struct ehea_fw_handle_array ehea_fw_handles;
+struct ehea_bcmc_reg_array ehea_bcmc_regs;
+
static int __devinit ehea_probe_adapter(struct of_device *dev,
const struct of_device_id *id);
@@ -132,6 +135,160 @@ void ehea_dump(void *adr, int len, char *msg)
}
}
+static void ehea_update_firmware_handles(void)
+{
+ struct ehea_fw_handle_entry *arr = NULL;
+ struct ehea_adapter *adapter;
+ int num_adapters = 0;
+ int num_ports = 0;
+ int num_portres = 0;
+ int i = 0;
+ int num_fw_handles, k, l;
+
+ /* Determine number of handles */
+ list_for_each_entry(adapter, &adapter_list, list) {
+ num_adapters++;
+
+ for (k = 0; k < EHEA_MAX_PORTS; k++) {
+ struct ehea_port *port = adapter->port[k];
+
+ if (!port || (port->state != EHEA_PORT_UP))
+ continue;
+
+ num_ports++;
+ num_portres += port->num_def_qps + port->num_add_tx_qps;
+ }
+ }
+
+ num_fw_handles = num_adapters * EHEA_NUM_ADAPTER_FW_HANDLES +
+ num_ports * EHEA_NUM_PORT_FW_HANDLES +
+ num_portres * EHEA_NUM_PORTRES_FW_HANDLES;
+
+ if (num_fw_handles) {
+ arr = kzalloc(num_fw_handles * sizeof(*arr), GFP_KERNEL);
+ if (!arr)
+ return; /* Keep the existing array */
+ } else
+ goto out_update;
+
+ list_for_each_entry(adapter, &adapter_list, list) {
+ for (k = 0; k < EHEA_MAX_PORTS; k++) {
+ struct ehea_port *port = adapter->port[k];
+
+ if (!port || (port->state != EHEA_PORT_UP))
+ continue;
+
+ for (l = 0;
+ l < port->num_def_qps + port->num_add_tx_qps;
+ l++) {
+ struct ehea_port_res *pr = &port->port_res[l];
+
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = pr->qp->fw_handle;
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = pr->send_cq->fw_handle;
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = pr->recv_cq->fw_handle;
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = pr->eq->fw_handle;
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = pr->send_mr.handle;
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = pr->recv_mr.handle;
+ }
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = port->qp_eq->fw_handle;
+ }
+
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = adapter->neq->fw_handle;
+
+ if (adapter->mr.handle) {
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = adapter->mr.handle;
+ }
+ }
+
+out_update:
+ kfree(ehea_fw_handles.arr);
+ ehea_fw_handles.arr = arr;
+ ehea_fw_handles.num_entries = i;
+}
+
+static void ehea_update_bcmc_registrations(void)
+{
+ struct ehea_bcmc_reg_entry *arr = NULL;
+ struct ehea_adapter *adapter;
+ struct ehea_mc_list *mc_entry;
+ int num_registrations = 0;
+ int i = 0;
+ int k;
+
+ /* Determine number of registrations */
+ list_for_each_entry(adapter, &adapter_list, list)
+ for (k = 0; k < EHEA_MAX_PORTS; k++) {
+ struct ehea_port *port = adapter->port[k];
+
+ if (!port || (port->state != EHEA_PORT_UP))
+ continue;
+
+ num_registrations += 2; /* Broadcast registrations */
+
+ list_for_each_entry(mc_entry, &port->mc_list->list,list)
+ num_registrations += 2;
+ }
+
+ if (num_registrations) {
+ arr = kzalloc(num_registrations * sizeof(*arr), GFP_KERNEL);
+ if (!arr)
+ return; /* Keep the existing array */
+ } else
+ goto out_update;
+
+ list_for_each_entry(adapter, &adapter_list, list) {
+ for (k = 0; k < EHEA_MAX_PORTS; k++) {
+ struct ehea_port *port = adapter->port[k];
+
+ if (!port || (port->state != EHEA_PORT_UP))
+ continue;
+
+ arr[i].adh = adapter->handle;
+ arr[i].port_id = port->logical_port_id;
+ arr[i].reg_type = EHEA_BCMC_BROADCAST |
+ EHEA_BCMC_UNTAGGED;
+ arr[i++].macaddr = port->mac_addr;
+
+ arr[i].adh = adapter->handle;
+ arr[i].port_id = port->logical_port_id;
+ arr[i].reg_type = EHEA_BCMC_BROADCAST |
+ EHEA_BCMC_VLANID_ALL;
+ arr[i++].macaddr = port->mac_addr;
+
+ list_for_each_entry(mc_entry,
+ &port->mc_list->list, list) {
+ arr[i].adh = adapter->handle;
+ arr[i].port_id = port->logical_port_id;
+ arr[i].reg_type = EHEA_BCMC_SCOPE_ALL |
+ EHEA_BCMC_MULTICAST |
+ EHEA_BCMC_UNTAGGED;
+ arr[i++].macaddr = mc_entry->macaddr;
+
+ arr[i].adh = adapter->handle;
+ arr[i].port_id = port->logical_port_id;
+ arr[i].reg_type = EHEA_BCMC_SCOPE_ALL |
+ EHEA_BCMC_MULTICAST |
+ EHEA_BCMC_VLANID_ALL;
+ arr[i++].macaddr = mc_entry->macaddr;
+ }
+ }
+ }
+
+out_update:
+ kfree(ehea_bcmc_regs.arr);
+ ehea_bcmc_regs.arr = arr;
+ ehea_bcmc_regs.num_entries = i;
+}
+
static struct net_device_stats *ehea_get_stats(struct net_device *dev)
{
struct ehea_port *port = netdev_priv(dev);
@@ -1601,19 +1758,25 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa)
memcpy(dev->dev_addr, mac_addr->sa_data, dev->addr_len);
+ down(&ehea_bcmc_regs.lock);
+
/* Deregister old MAC in pHYP */
ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
if (ret)
- goto out_free;
+ goto out_upregs;
port->mac_addr = cb0->port_mac_addr << 16;
/* Register new MAC in pHYP */
ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
if (ret)
- goto out_free;
+ goto out_upregs;
ret = 0;
+
+out_upregs:
+ ehea_update_bcmc_registrations();
+ up(&ehea_bcmc_regs.lock);
out_free:
kfree(cb0);
out:
@@ -1775,9 +1938,11 @@ static void ehea_set_multicast_list(struct net_device *dev)
}
ehea_promiscuous(dev, 0);
+ down(&ehea_bcmc_regs.lock);
+
if (dev->flags & IFF_ALLMULTI) {
ehea_allmulti(dev, 1);
- return;
+ goto out;
}
ehea_allmulti(dev, 0);
@@ -1803,6 +1968,8 @@ static void ehea_set_multicast_list(struct net_device *dev)
}
out:
+ ehea_update_bcmc_registrations();
+ up(&ehea_bcmc_regs.lock);
return;
}
@@ -2285,6 +2452,8 @@ static int ehea_up(struct net_device *dev)
if (port->state == EHEA_PORT_UP)
return 0;
+ down(&ehea_fw_handles.lock);
+
ret = ehea_port_res_setup(port, port->num_def_qps,
port->num_add_tx_qps);
if (ret) {
@@ -2321,8 +2490,17 @@ static int ehea_up(struct net_device *dev)
}
}
- ret = 0;
+ down(&ehea_bcmc_regs.lock);
+
+ ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
+ if (ret) {
+ ret = -EIO;
+ goto out_free_irqs;
+ }
+
port->state = EHEA_PORT_UP;
+
+ ret = 0;
goto out;
out_free_irqs:
@@ -2334,6 +2512,12 @@ out:
if (ret)
ehea_info("Failed starting %s. ret=%i", dev->name, ret);
+ ehea_update_bcmc_registrations();
+ up(&ehea_bcmc_regs.lock);
+
+ ehea_update_firmware_handles();
+ up(&ehea_fw_handles.lock);
+
return ret;
}
@@ -2382,16 +2566,27 @@ static int ehea_down(struct net_device *dev)
if (port->state == EHEA_PORT_DOWN)
return 0;
+ down(&ehea_bcmc_regs.lock);
ehea_drop_multicast_list(dev);
+ ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
+
ehea_free_interrupts(dev);
+ down(&ehea_fw_handles.lock);
+
port->state = EHEA_PORT_DOWN;
+ ehea_update_bcmc_registrations();
+ up(&ehea_bcmc_regs.lock);
+
ret = ehea_clean_all_portres(port);
if (ret)
ehea_info("Failed freeing resources for %s. ret=%i",
dev->name, ret);
+ ehea_update_firmware_handles();
+ up(&ehea_fw_handles.lock);
+
return ret;
}
@@ -2920,19 +3115,12 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT;
INIT_WORK(&port->reset_task, ehea_reset_port);
-
- ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
- if (ret) {
- ret = -EIO;
- goto out_unreg_port;
- }
-
ehea_set_ethtool_ops(dev);
ret = register_netdev(dev);
if (ret) {
ehea_error("register_netdev failed. ret=%d", ret);
- goto out_dereg_bc;
+ goto out_unreg_port;
}
port->lro_max_aggr = lro_max_aggr;
@@ -2949,9 +3137,6 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
return port;
-out_dereg_bc:
- ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
-
out_unreg_port:
ehea_unregister_port(port);
@@ -2971,7 +3156,6 @@ static void ehea_shutdown_single_port(struct ehea_port *port)
{
unregister_netdev(port->netdev);
ehea_unregister_port(port);
- ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
kfree(port->mc_list);
free_netdev(port->netdev);
port->adapter->active_ports--;
@@ -3014,7 +3198,6 @@ static int ehea_setup_ports(struct ehea_adapter *adapter)
i++;
};
-
return 0;
}
@@ -3159,6 +3342,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev,
ehea_error("Invalid ibmebus device probed");
return -EINVAL;
}
+ down(&ehea_fw_handles.lock);
adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
if (!adapter) {
@@ -3239,7 +3423,10 @@ out_kill_eq:
out_free_ad:
kfree(adapter);
+
out:
+ ehea_update_firmware_handles();
+ up(&ehea_fw_handles.lock);
return ret;
}
@@ -3258,18 +3445,41 @@ static int __devexit ehea_remove(struct of_device *dev)
flush_scheduled_work();
+ down(&ehea_fw_handles.lock);
+
ibmebus_free_irq(adapter->neq->attr.ist1, adapter);
tasklet_kill(&adapter->neq_tasklet);
ehea_destroy_eq(adapter->neq);
ehea_remove_adapter_mr(adapter);
list_del(&adapter->list);
-
kfree(adapter);
+ ehea_update_firmware_handles();
+ up(&ehea_fw_handles.lock);
+
return 0;
}
+void ehea_crash_handler(void)
+{
+ int i;
+
+ if (ehea_fw_handles.arr)
+ for (i = 0; i < ehea_fw_handles.num_entries; i++)
+ ehea_h_free_resource(ehea_fw_handles.arr[i].adh,
+ ehea_fw_handles.arr[i].fwh,
+ FORCE_FREE);
+
+ if (ehea_bcmc_regs.arr)
+ for (i = 0; i < ehea_bcmc_regs.num_entries; i++)
+ ehea_h_reg_dereg_bcmc(ehea_bcmc_regs.arr[i].adh,
+ ehea_bcmc_regs.arr[i].port_id,
+ ehea_bcmc_regs.arr[i].reg_type,
+ ehea_bcmc_regs.arr[i].macaddr,
+ 0, H_DEREG_BCMC);
+}
+
static int ehea_reboot_notifier(struct notifier_block *nb,
unsigned long action, void *unused)
{
@@ -3330,7 +3540,12 @@ int __init ehea_module_init(void)
INIT_WORK(&ehea_rereg_mr_task, ehea_rereg_mrs);
+ memset(&ehea_fw_handles, 0, sizeof(ehea_fw_handles));
+ memset(&ehea_bcmc_regs, 0, sizeof(ehea_bcmc_regs));
+
sema_init(&dlpar_mem_lock, 1);
+ sema_init(&ehea_fw_handles.lock, 1);
+ sema_init(&ehea_bcmc_regs.lock, 1);
ret = check_module_parm();
if (ret)
@@ -3340,12 +3555,18 @@ int __init ehea_module_init(void)
if (ret)
goto out;
- register_reboot_notifier(&ehea_reboot_nb);
+ ret = register_reboot_notifier(&ehea_reboot_nb);
+ if (ret)
+ ehea_info("failed registering reboot notifier");
+
+ ret = crash_shutdown_register(&ehea_crash_handler);
+ if (ret)
+ ehea_info("failed registering crash handler");
ret = ibmebus_register_driver(&ehea_driver);
if (ret) {
ehea_error("failed registering eHEA device driver on ebus");
- goto out;
+ goto out2;
}
ret = driver_create_file(&ehea_driver.driver,
@@ -3353,21 +3574,33 @@ int __init ehea_module_init(void)
if (ret) {
ehea_error("failed to register capabilities attribute, ret=%d",
ret);
- unregister_reboot_notifier(&ehea_reboot_nb);
- ibmebus_unregister_driver(&ehea_driver);
- goto out;
+ goto out3;
}
+ return ret;
+
+out3:
+ ibmebus_unregister_driver(&ehea_driver);
+out2:
+ unregister_reboot_notifier(&ehea_reboot_nb);
+ crash_shutdown_unregister(&ehea_crash_handler);
out:
return ret;
}
static void __exit ehea_module_exit(void)
{
+ int ret;
+
flush_scheduled_work();
driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities);
ibmebus_unregister_driver(&ehea_driver);
unregister_reboot_notifier(&ehea_reboot_nb);
+ ret = crash_shutdown_unregister(&ehea_crash_handler);
+ if (ret)
+ ehea_info("failed unregistering crash handler");
+ kfree(ehea_fw_handles.arr);
+ kfree(ehea_bcmc_regs.arr);
ehea_destroy_busmap();
}
--
1.5.2
^ permalink raw reply related
* Re: [ofa-general] [PATCH 2.6.25] RDMA/cxgb3: Fail loopbackconnections.
From: Roland Dreier @ 2008-02-13 15:46 UTC (permalink / raw)
To: Diego Guella; +Cc: netdev, linux-kernel, general
In-Reply-To: <015c01c86e21$75317210$05c8a8c0@DIEGO>
> how can a static void function return 0?
good question... I've fixed the patch in my tree.
^ permalink raw reply
* Re: [ofa-general] [PATCH 2.6.25] RDMA/cxgb3: Fail loopbackconnections.
From: Steve Wise @ 2008-02-13 15:47 UTC (permalink / raw)
To: Roland Dreier; +Cc: netdev, linux-kernel, general
In-Reply-To: <adaskzwuaeu.fsf@cisco.com>
Roland Dreier wrote:
> > how can a static void function return 0?
>
> good question... I've fixed the patch in my tree.
oops.
^ permalink raw reply
* Re: [ofa-general] [PATCH 2.6.25] RDMA/cxgb3: Fail loopbackconnections.
From: Roland Dreier @ 2008-02-13 15:49 UTC (permalink / raw)
To: Steve Wise; +Cc: netdev, linux-kernel, general
In-Reply-To: <adaskzwuaeu.fsf@cisco.com>
Steve, I had to update the patch adding an include and fixing the
function declaration (as below)... but how much testing have you done
with this??
commit 8704e9a8790cc9e394198663c1c9150c899fb9a2
Author: Steve Wise <swise@opengridcomputing.com>
Date: Tue Feb 12 16:09:29 2008 -0600
RDMA/cxgb3: Fail loopback connections
The cxgb3 HW and driver don't support loopback RDMA connections. So
fail any connection attempt where the destination address is local.
Signed-off-by: Steve Wise <swise@opengridcomputing.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c
index e9a08fa..320f2b6 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c
@@ -35,6 +35,7 @@
#include <linux/skbuff.h>
#include <linux/timer.h>
#include <linux/notifier.h>
+#include <linux/inetdevice.h>
#include <net/neighbour.h>
#include <net/netevent.h>
@@ -1784,6 +1785,17 @@ err:
return err;
}
+static int is_loopback_dst(struct iw_cm_id *cm_id)
+{
+ struct net_device *dev;
+
+ dev = ip_dev_find(&init_net, cm_id->remote_addr.sin_addr.s_addr);
+ if (!dev)
+ return 0;
+ dev_put(dev);
+ return 1;
+}
+
int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
{
int err = 0;
@@ -1791,6 +1803,11 @@ int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
struct iwch_ep *ep;
struct rtable *rt;
+ if (is_loopback_dst(cm_id)) {
+ err = -ENOSYS;
+ goto out;
+ }
+
ep = alloc_ep(sizeof(*ep), GFP_KERNEL);
if (!ep) {
printk(KERN_ERR MOD "%s - cannot alloc ep.\n", __FUNCTION__);
^ permalink raw reply related
* Re: [ofa-general] [PATCH 2.6.25] RDMA/cxgb3: Fail loopbackconnections.
From: Steve Wise @ 2008-02-13 15:51 UTC (permalink / raw)
To: Roland Dreier; +Cc: netdev, linux-kernel, general
In-Reply-To: <adaodakua9v.fsf@cisco.com>
Roland Dreier wrote:
> Steve, I had to update the patch adding an include and fixing the
> function declaration (as below)... but how much testing have you done
> with this??
>
Now I understand. I thought I'd fixed these! I fixed them locally in
the test tree on my victim and then tested, but forgot to update my git
tree.
Sorry for this.
You want me to resubmit?
> commit 8704e9a8790cc9e394198663c1c9150c899fb9a2
> Author: Steve Wise <swise@opengridcomputing.com>
> Date: Tue Feb 12 16:09:29 2008 -0600
>
> RDMA/cxgb3: Fail loopback connections
>
> The cxgb3 HW and driver don't support loopback RDMA connections. So
> fail any connection attempt where the destination address is local.
>
> Signed-off-by: Steve Wise <swise@opengridcomputing.com>
> Signed-off-by: Roland Dreier <rolandd@cisco.com>
>
> diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c
> index e9a08fa..320f2b6 100644
> --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c
> +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c
> @@ -35,6 +35,7 @@
> #include <linux/skbuff.h>
> #include <linux/timer.h>
> #include <linux/notifier.h>
> +#include <linux/inetdevice.h>
>
> #include <net/neighbour.h>
> #include <net/netevent.h>
> @@ -1784,6 +1785,17 @@ err:
> return err;
> }
>
> +static int is_loopback_dst(struct iw_cm_id *cm_id)
> +{
> + struct net_device *dev;
> +
> + dev = ip_dev_find(&init_net, cm_id->remote_addr.sin_addr.s_addr);
> + if (!dev)
> + return 0;
> + dev_put(dev);
> + return 1;
> +}
> +
> int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
> {
> int err = 0;
> @@ -1791,6 +1803,11 @@ int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
> struct iwch_ep *ep;
> struct rtable *rt;
>
> + if (is_loopback_dst(cm_id)) {
> + err = -ENOSYS;
> + goto out;
> + }
> +
> ep = alloc_ep(sizeof(*ep), GFP_KERNEL);
> if (!ep) {
> printk(KERN_ERR MOD "%s - cannot alloc ep.\n", __FUNCTION__);
^ permalink raw reply
* Re: [ofa-general] [PATCH 2.6.25] RDMA/cxgb3: Fail loopbackconnections.
From: Steve Wise @ 2008-02-13 16:03 UTC (permalink / raw)
To: Roland Dreier; +Cc: netdev, linux-kernel, general
In-Reply-To: <47B3120B.3040409@opengridcomputing.com>
Steve Wise wrote:
> Roland Dreier wrote:
>> Steve, I had to update the patch adding an include and fixing the
>> function declaration (as below)... but how much testing have you done
>> with this??
>>
>
> Now I understand. I thought I'd fixed these! I fixed them locally in
> the test tree on my victim and then tested, but forgot to update my git
> tree.
>
> Sorry for this.
>
> You want me to resubmit?
>
BTW: Testing: I cloned my git tree, resolved the two compile issues
(void + include), then built and installed the kernel (2.6.25-rc1 + the
fixed patch). I then ensured that a connection to the local address
caused the ENOSYS error.
I just forgot to pull the updated file back into my stg managed git tree.
:(
^ permalink raw reply
* Re: [PATCH] ixgbe: Correctly obtain protocol information on transmit
From: Andy Gospodarek @ 2008-02-13 16:13 UTC (permalink / raw)
To: Auke Kok; +Cc: e1000-devel, netdev, andy, jeff
In-Reply-To: <20080212232033.13861.17859.stgit@localhost.localdomain>
On Tue, Feb 12, 2008 at 03:20:33PM -0800, Auke Kok wrote:
> In reply to "RE: [Fwd: [PATCH 2.6.25] ixgbe/igb: correctly obtain protocol
> information on transmit]" from Andy Gospodarek:
>
> The driver was incorrectly looking at socket headers for
> protocol information, needed for checksumming offload. Fix
> this by not looking at the socket but frame headers instead.
>
> This disregards extension headers but it's unclear that linux
> generates those anyway.
>
> Tested by Andy Gospodarek.
>
> Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
This works well for me too.
Signed-off-by: Andy Gospodarek <andy@greyhouse.net>
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
^ permalink raw reply
* [PATCh TAKE 2] [IPROUTE2] Add addrlabel sub-command.
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2008-02-13 16:20 UTC (permalink / raw)
To: stephen.hemminger; +Cc: yoshfuji, netdev
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
diff --git a/ip/Makefile b/ip/Makefile
index b427d58..d908817 100644
--- a/ip/Makefile
+++ b/ip/Makefile
@@ -1,4 +1,4 @@
-IPOBJ=ip.o ipaddress.o iproute.o iprule.o \
+IPOBJ=ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o \
rtm_map.o iptunnel.o ip6tunnel.o tunnel.o ipneigh.o ipntable.o iplink.o \
ipmaddr.o ipmonitor.o ipmroute.o ipprefix.o \
ipxfrm.o xfrm_state.o xfrm_policy.o xfrm_monitor.o \
diff --git a/ip/ip.c b/ip/ip.c
index aeb8c68..c4c773f 100644
--- a/ip/ip.c
+++ b/ip/ip.c
@@ -46,8 +46,8 @@ static void usage(void)
fprintf(stderr,
"Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }\n"
" ip [ -force ] [-batch filename\n"
-"where OBJECT := { link | addr | route | rule | neigh | ntable | tunnel |\n"
-" maddr | mroute | monitor | xfrm }\n"
+"where OBJECT := { link | addr | addrlabel | route | rule | neigh | ntable |\n"
+" tunnel | maddr | mroute | monitor | xfrm }\n"
" OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |\n"
" -f[amily] { inet | inet6 | ipx | dnet | link } |\n"
" -o[neline] | -t[imestamp] }\n");
@@ -64,6 +64,7 @@ static const struct cmd {
int (*func)(int argc, char **argv);
} cmds[] = {
{ "address", do_ipaddr },
+ { "addrlabel", do_ipaddrlabel },
{ "maddress", do_multiaddr },
{ "route", do_iproute },
{ "rule", do_iprule },
diff --git a/ip/ip_common.h b/ip/ip_common.h
index 39f2507..1bbd50d 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -4,6 +4,9 @@ extern int print_linkinfo(const struct sockaddr_nl *who,
extern int print_addrinfo(const struct sockaddr_nl *who,
struct nlmsghdr *n,
void *arg);
+extern int print_addrlabelinfo(const struct sockaddr_nl *who,
+ struct nlmsghdr *n,
+ void *arg);
extern int print_neigh(const struct sockaddr_nl *who,
struct nlmsghdr *n, void *arg);
extern int print_ntable(const struct sockaddr_nl *who,
@@ -23,6 +26,7 @@ extern int print_prefix(const struct sockaddr_nl *who,
extern int print_rule(const struct sockaddr_nl *who,
struct nlmsghdr *n, void *arg);
extern int do_ipaddr(int argc, char **argv);
+extern int do_ipaddrlabel(int argc, char **argv);
extern int do_iproute(int argc, char **argv);
extern int do_iprule(int argc, char **argv);
extern int do_ipneigh(int argc, char **argv);
diff --git a/ip/ipaddrlabel.c b/ip/ipaddrlabel.c
new file mode 100644
index 0000000..1c873e9
--- /dev/null
+++ b/ip/ipaddrlabel.c
@@ -0,0 +1,260 @@
+/*
+ * ipaddrlabel.c "ip addrlabel"
+ *
+ * Copyright (C)2007 USAGI/WIDE Project
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+ * Based on iprule.c.
+ *
+ * Authors: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <linux/types.h>
+#include <linux/if_addrlabel.h>
+
+#include "rt_names.h"
+#include "utils.h"
+#include "ip_common.h"
+
+#define IFAL_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrlblmsg))))
+#define IFAL_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifaddrlblmsg))
+
+extern struct rtnl_handle rth;
+
+static void usage(void) __attribute__((noreturn));
+
+static void usage(void)
+{
+ fprintf(stderr, "Usage: ip addrlabel [ list | add | del | flush ] prefix PREFIX [ dev DEV ] [ label LABEL ]\n");
+ exit(-1);
+}
+
+int print_addrlabel(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+{
+ FILE *fp = (FILE*)arg;
+ struct ifaddrlblmsg *ifal = NLMSG_DATA(n);
+ int len = n->nlmsg_len;
+ int host_len = -1;
+ struct rtattr *tb[IFAL_MAX+1];
+ char abuf[256];
+
+ if (n->nlmsg_type != RTM_NEWADDRLABEL && n->nlmsg_type != RTM_DELADDRLABEL)
+ return 0;
+
+ len -= NLMSG_LENGTH(sizeof(*ifal));
+ if (len < 0)
+ return -1;
+
+ parse_rtattr(tb, IFAL_MAX, IFAL_RTA(ifal), len);
+
+ if (ifal->ifal_family == AF_INET)
+ host_len = 32;
+ else if (ifal->ifal_family == AF_INET6)
+ host_len = 128;
+
+ if (n->nlmsg_type == RTM_DELADDRLABEL)
+ fprintf(fp, "Deleted ");
+
+ if (tb[IFAL_ADDRESS]) {
+ fprintf(fp, "prefix %s/%u ",
+ format_host(ifal->ifal_family,
+ RTA_PAYLOAD(tb[IFAL_ADDRESS]),
+ RTA_DATA(tb[IFAL_ADDRESS]),
+ abuf, sizeof(abuf)),
+ ifal->ifal_prefixlen);
+ }
+
+ if (ifal->ifal_index)
+ fprintf(fp, "dev %s ", ll_index_to_name(ifal->ifal_index));
+
+ if (tb[IFAL_LABEL] && RTA_PAYLOAD(tb[IFAL_LABEL]) == sizeof(int32_t)) {
+ int32_t label;
+ memcpy(&label, RTA_DATA(tb[IFAL_LABEL]), sizeof(label));
+ fprintf(fp, "label %d ", label);
+ }
+
+ fprintf(fp, "\n");
+ fflush(fp);
+ return 0;
+}
+
+static int ipaddrlabel_list(int argc, char **argv)
+{
+ int af = preferred_family;
+
+ if (af == AF_UNSPEC)
+ af = AF_INET6;
+
+ if (argc > 0) {
+ fprintf(stderr, "\"ip addrlabel show\" does not take any arguments.\n");
+ return -1;
+ }
+
+ if (rtnl_wilddump_request(&rth, af, RTM_GETADDRLABEL) < 0) {
+ perror("Cannot send dump request");
+ return 1;
+ }
+
+ if (rtnl_dump_filter(&rth, print_addrlabel, stdout, NULL, NULL) < 0) {
+ fprintf(stderr, "Dump terminated\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+
+static int ipaddrlabel_modify(int cmd, int argc, char **argv)
+{
+ struct {
+ struct nlmsghdr n;
+ struct ifaddrlblmsg ifal;
+ char buf[1024];
+ } req;
+
+ inet_prefix prefix;
+ uint32_t label = 0xffffffffUL;
+
+ memset(&req, 0, sizeof(req));
+ memset(&prefix, 0, sizeof(prefix));
+
+ req.n.nlmsg_type = cmd;
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrlblmsg));
+ req.n.nlmsg_flags = NLM_F_REQUEST;
+ req.ifal.ifal_family = preferred_family;
+ req.ifal.ifal_prefixlen = 0;
+ req.ifal.ifal_index = 0;
+
+ if (cmd == RTM_NEWADDRLABEL) {
+ req.n.nlmsg_flags |= NLM_F_CREATE|NLM_F_EXCL;
+ }
+
+ while (argc > 0) {
+ if (strcmp(*argv, "prefix") == 0) {
+ NEXT_ARG();
+ get_prefix(&prefix, *argv, preferred_family);
+ } else if (strcmp(*argv, "dev") == 0) {
+ NEXT_ARG();
+ if ((req.ifal.ifal_index = ll_name_to_index(*argv)) == 0)
+ invarg("dev is invalid\n", *argv);
+ } else if (strcmp(*argv, "label") == 0) {
+ NEXT_ARG();
+ if (get_u32(&label, *argv, 0) || label == 0xffffffffUL)
+ invarg("label is invalid\n", *argv);
+ }
+ argc--;
+ argv++;
+ }
+
+ addattr32(&req.n, sizeof(req), IFAL_LABEL, label);
+ addattr_l(&req.n, sizeof(req), IFAL_ADDRESS, &prefix.data, prefix.bytelen);
+
+ if (req.ifal.ifal_family == AF_UNSPEC)
+ req.ifal.ifal_family = AF_INET6;
+
+ if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
+ return 2;
+
+ return 0;
+}
+
+
+static int flush_addrlabel(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+{
+ struct rtnl_handle rth2;
+ struct rtmsg *r = NLMSG_DATA(n);
+ int len = n->nlmsg_len;
+ struct rtattr * tb[IFAL_MAX+1];
+
+ len -= NLMSG_LENGTH(sizeof(*r));
+ if (len < 0)
+ return -1;
+
+ parse_rtattr(tb, IFAL_MAX, RTM_RTA(r), len);
+
+ if (tb[IFAL_ADDRESS]) {
+ n->nlmsg_type = RTM_DELADDRLABEL;
+ n->nlmsg_flags = NLM_F_REQUEST;
+
+ if (rtnl_open(&rth2, 0) < 0)
+ return -1;
+
+ if (rtnl_talk(&rth2, n, 0, 0, NULL, NULL, NULL) < 0)
+ return -2;
+
+ rtnl_close(&rth2);
+ }
+
+ return 0;
+}
+
+static int ipaddrlabel_flush(int argc, char **argv)
+{
+ int af = preferred_family;
+
+ if (af == AF_UNSPEC)
+ af = AF_INET6;
+
+ if (argc > 0) {
+ fprintf(stderr, "\"ip addrlabel flush\" does not allow extra arguments\n");
+ return -1;
+ }
+
+ if (rtnl_wilddump_request(&rth, af, RTM_GETADDRLABEL) < 0) {
+ perror("Cannot send dump request");
+ return 1;
+ }
+
+ if (rtnl_dump_filter(&rth, flush_addrlabel, NULL, NULL, NULL) < 0) {
+ fprintf(stderr, "Flush terminated\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+int do_ipaddrlabel(int argc, char **argv)
+{
+ if (argc < 1) {
+ return ipaddrlabel_list(0, NULL);
+ } else if (matches(argv[0], "list") == 0 ||
+ matches(argv[0], "show") == 0) {
+ return ipaddrlabel_list(argc-1, argv+1);
+ } else if (matches(argv[0], "add") == 0) {
+ return ipaddrlabel_modify(RTM_NEWADDRLABEL, argc-1, argv+1);
+ } else if (matches(argv[0], "delete") == 0) {
+ return ipaddrlabel_modify(RTM_DELADDRLABEL, argc-1, argv+1);
+ } else if (matches(argv[0], "flush") == 0) {
+ return ipaddrlabel_flush(argc-1, argv+1);
+ } else if (matches(argv[0], "help") == 0)
+ usage();
+
+ fprintf(stderr, "Command \"%s\" is unknown, try \"ip addrlabel help\".\n", *argv);
+ exit(-1);
+}
+
diff --git a/ip/ipmonitor.c b/ip/ipmonitor.c
index f1a1f27..df0fd91 100644
--- a/ip/ipmonitor.c
+++ b/ip/ipmonitor.c
@@ -54,6 +54,10 @@ int accept_msg(const struct sockaddr_nl *who,
print_addrinfo(who, n, arg);
return 0;
}
+ if (n->nlmsg_type == RTM_NEWADDRLABEL || n->nlmsg_type == RTM_DELADDRLABEL) {
+ print_addrlabel(who, n, arg);
+ return 0;
+ }
if (n->nlmsg_type == RTM_NEWNEIGH || n->nlmsg_type == RTM_DELNEIGH) {
print_neigh(who, n, arg);
return 0;
diff --git a/man/man8/ip.8 b/man/man8/ip.8
index 1687045..136448c 100644
--- a/man/man8/ip.8
+++ b/man/man8/ip.8
@@ -13,8 +13,8 @@ ip \- show / manipulate routing, devices, policy routing and tunnels
.ti -8
.IR OBJECT " := { "
-.BR link " | " addr " | " route " | " rule " | " neigh " | " tunnel " | "\
-maddr " | " mroute " | " monitor " }"
+.BR link " | " addr " | " addrlabel " | " route " | " rule " | " neigh " | "\
+ tunnel " | " maddr " | " mroute " | " monitor " }"
.sp
.ti -8
@@ -97,6 +97,17 @@ maddr " | " mroute " | " monitor " }"
tentative " | " deprecated " ]"
.ti -8
+.BR "ip addrlabel" " { " add " | " del " } " prefix
+.BR PREFIX " [ "
+.B dev
+.IR DEV " ] [ "
+.B label
+.IR NUMBER " ]"
+
+.ti -8
+.BR "ip addrlabel" " { " list " | " flush " }"
+
+.ti -8
.BR "ip route" " { "
.BR list " | " flush " } "
.I SELECTOR
@@ -404,6 +415,11 @@ host addresses.
.TP
.B address
- protocol (IP or IPv6) address on a device.
+
+.TP
+.B addrlabel
+- label configuration for protocol address selection.
+
.TP
.B neighbour
- ARP or NDISC cache entry.
@@ -708,6 +724,33 @@ this option is given twice,
also dumps all the deleted addresses in the format described in the
previous subsection.
+.SH ip addrlabel - protocol address label management.
+
+IPv6 address label is used for address selection
+described in RFC 3484. Precedence is managed by userspace,
+and only label is stored in kernel.
+
+.SS ip addrlabel add - add an address label
+the command adds an address label entry to the kernel.
+.TP
+.BI prefix " PREFIX"
+.TP
+.BI dev " DEV"
+the outgoing interface.
+.TP
+.BI label " NUMBER"
+the label for the prefix.
+0xffffffff is reserved.
+.SS ip addrlabel del - delete an address label
+the command deletes an address label entry in the kernel.
+.B Arguments:
+coincide with the arguments of
+.B ip addrlabel add
+but label is not required.
+.SS ip addrlabel list - list address labels
+the command show contents of address labels.
+.SS ip addrlabel flush - flush address labels
+the commoand flushes the contents of address labels and it does not restore default settings.
.SH ip neighbour - neighbour/arp tables management.
.B neighbour
--
YOSHIFUJI Hideaki @ USAGI Project <yoshfuji@linux-ipv6.org>
GPG-FP : 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA
^ permalink raw reply related
* RE: r8169 auto-negotiation problem
From: fgnijuhhu guduggurehug @ 2008-02-13 16:15 UTC (permalink / raw)
To: Francois Romieu; +Cc: netdev
In-Reply-To: <20080212222015.GA21495@electric-eye.fr.zoreil.com>
Thanks for your response.
> Please try a recent kernel. Your r8169 driver is badly outdated.
OK. Now using 2.6.24-1-amd64. The r8169 version still says 2.2LK-NAPI, though.
_________________________________________________________________
Express yourself instantly with MSN Messenger! Download today it's FREE!
http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/
^ permalink raw reply
* Re: BUG: 2.6.25-rc1: iptables postrouting setup causes oops
From: Andrew G. Morgan @ 2008-02-13 16:42 UTC (permalink / raw)
To: Andrew Morton
Cc: Haavard Skinnemoen, Ben Nizette, netfilter-devel, linux-kernel,
netdev
In-Reply-To: <20080213012231.46865608.akpm@linux-foundation.org>
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Haavard,
It means your application is not capable(sic) of using the upper 32-bits
of the 64-bit capability sets supported by this newer kernel.
You might consider rebuilding the offending application linking it
against a newer version of libcap:
http://www.kernel.org/pub/linux/libs/security/linux-privs/libcap2/
However, it is a warning and, for any existing app that doesn't care
about newly added capabilities, the warning is benign.
Cheers
Andrew
Andrew Morton wrote:
| On Wed, 13 Feb 2008 10:10:24 +0100 Haavard Skinnemoen
<hskinnemoen@atmel.com> wrote:
|
|> On Wed, 13 Feb 2008 00:48:29 -0800
|> Andrew Morton <akpm@linux-foundation.org> wrote:
|>
|>> On Tue, 12 Feb 2008 22:46:01 +1100 Ben Nizette <bn@niasdigital.com>
wrote:
|>>
|>>> On an AVR32, root over NFS, config attached, running (from a startup
|>>> script):
|>>>
|>>> iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
|>>>
|>>> Results in (dmesg extract including a bit of context for good measure):
|>>> -------------8<----------------
|>>> VFS: Mounted root (nfs filesystem).
|>>> Freeing init memory: 72K (90000000 - 90012000)
|>>> eth0: no IPv6 routers present
|>>> warning: `dnsmasq' uses 32-bit capabilities (legacy support in use)
|> Hmm. What does that mean? What size do capabilities normally have?
|
| My near-namesake put than in, but I immediately forgot what it means?
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)
iD8DBQFHsx3n+bHCR3gb8jsRAjlNAKDK4RLJsPsMPN96JJnTj3U25Bx91ACdESeN
2P3V2ISny33KY6v107iHsKU=
=1jND
-----END PGP SIGNATURE-----
^ permalink raw reply
* Re: [RFC, PATCH]: Pass link level header from/to PPP interface
From: Urs Thuermann @ 2008-02-13 16:56 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20080212.220603.111665989.davem@davemloft.net>
Hello Dave,
> But if libpcap and tcpdump can already identify PPP packets
> then, besides "consistency", what does this buy us other
> than potential breakage?
My reason for the patch is mostly cleanliness and to make the kernel
match what is described in packet(7).
If you open a PF_PACKET/SOCK_RAW socket and bind it to an interface
you get a fixed type of frame/packet depending on the type of
interface, including the LL header. Also if you bind to all
interfaces you can look at the interface type to know what type of
packet you get. But not for PPP interfaces.
I've written a small packet dump util with a packet parser (somewhat
comparable to tcpdump but much smaller), which looks like this
struct sockaddr_ll addr;
...
s = open(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
...
recvfrom(s, buffer, sizeof(buffer), 0, &addr, &size);
switch (addr.sll_hatype) {
case ARPHRD_ETHER:
case ARPHRD_IEEE80211:
case ARPHRD_LOOPBACK:
parse_ether(buffer);
break;
case ARPHRD_TUNNEL:
parse_ip(buffer);
break;
case ARPHRD_SIT:
parse_ipv6(buffer);
break;
and so on. Only for PPP I need to switch on the addr.sll_protocol
since with PPP I don't get the PPP header:
case ARPHRD_PPP:
switch (ntohs(addr.sll_protocol))
case ETH_P_IP:
parse_ip(buffer);
break;
case ETH_P_IPV6:
parse_ipv6(buffer);
break;
...
}
break;
With my patch you would write
case ARPHRD_PPP:
parse_ppp(buffer);
break;
and the parse function can show the complete PPP frame with protocol
field. Without the patch there is no way to see the 2-byte PPP header
and, in contrast to packet(7), SOCK_DGRAM and SOCK_RAW are the same.
Do you consider this strong enough to justify this change?
urs
^ permalink raw reply
* Re: [PATCH] drivers/base: export gpl (un)register_memory_notifier
From: Dave Hansen @ 2008-02-13 17:05 UTC (permalink / raw)
To: Jan-Bernd Themann
Cc: linuxppc-dev, Thomas Klein, Themann, Jan-Bernd, netdev, apw,
linux-kernel, Thomas Klein, Christoph Raisch, Badari Pulavarty,
Greg KH
In-Reply-To: <200802131617.58646.ossthema@de.ibm.com>
On Wed, 2008-02-13 at 16:17 +0100, Jan-Bernd Themann wrote:
> Constraints imposed by HW / FW:
> - eHEA has own MMU
> - eHEA Memory Regions (MRs) are used by the eHEA MMU to translate virtual
> addresses to absolute addresses (like DMA mapped memory on a PCI bus)
> - The number of MRs is limited (not enough to have one MR per packet)
Are there enough to have one per 16MB section?
> Our current understanding about the current Memory Hotplug System are
> (please correct me if I'm wrong):
>
> - depends on sparse mem
You're wrong ;). In mainline, this is true. There was a version of the
SUSE kernel that did otherwise. But you can not and should not depend
on this never changing. But, someone is perfectly free to go out an
implement something better than sparsemem for memory hotplug. If they
go and do this, your driver may get left behind.
> - only whole memory sections are added / removed
> - for each section a memory resource is registered
True, and true. (There might be exceptions to the whole sections one,
but that's blatant abuse and should be fixed. :)
> From the driver side we need:
> - some kind of memory notification mechanism.
> For memory add we can live without any external memory notification
> event. For memory remove we do need an external trigger (see explanation
> above).
You can export and use (un)register_memory_notifier. You just need to
do it in a reasonable way that compiles for randconfig on your
architecture. Believe me, we don't want to start teaching drivers about
sparsemem.
> - a way to iterate over all kernel pages and a way to detect holes in the
> kernel memory layout in order to build up our own ehea_bmap.
Look at kernel/resource.c
But, I'm really not convinced that you can actually keep this map
yourselves. It's not as simple as you think. What happens if you get
on an LPAR with two sections, one 256MB@0x0 and another
16MB@0x1000000000000000. That's quite possible. I think your vmalloc'd
array will eat all of memory.
That's why we have SPARSEMEM_EXTREME and SPARSEMEM_VMEMMAP implemented
in the core, so that we can deal with these kinds of problems, once and
*NOT* in every single little driver out there.
> Functions to use while building ehea_bmap + MRs:
> - Use either the functions that are used by the memory hotplug system as
> well, that means using the section defines + functions (section_nr_to_pfn,
> pfn_valid)
Basically, you can't use anything related to sections outside of the
core code. You can use things like pfn_valid(), or you can create new
interfaces that are properly abstracted.
> - Use currently other not exported functions in kernel/resource.c, like
> walk_memory_resource (where we would still need the maximum possible number
> of pages NR_MEM_SECTIONS)
It isn't the act of exporting that's the problem. It's making sure that
the exports won't be prone to abuse and that people are using them
properly. You should assume that you can export and use
walk_memory_resource().
Do you know what other operating systems do with this hardware?
In the future, please make an effort to get review from knowledgeable
people about these kinds of things before using them in your driver.
Your company has many, many resources available, and all you need to do
is ask. All that you have to do is look to the tops of the files of the
functions you are calling.
-- Dave
^ permalink raw reply
* Re: [PATCH 1/3][NETLABEL]: Compilation for CONFIG_AUDIT=n case.
From: Paul Moore @ 2008-02-13 17:21 UTC (permalink / raw)
To: David Miller; +Cc: xemul, netdev
In-Reply-To: <20080212.223544.21007139.davem@davemloft.net>
On Wednesday 13 February 2008 1:35:44 am David Miller wrote:
> From: Pavel Emelyanov <xemul@openvz.org>
> Date: Thu, 07 Feb 2008 20:20:30 +0300
>
> > The audit_log_start() will expand into an empty do { } while (0)
> > construction and the audit_ctx becomes unused.
> >
> > The solution: push current->audit_context into audit_log_start()
> > directly, since it is not required in any other place in the
> > calling function.
> >
> > Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
>
> Applied.
Sorry I missed these three patches when they were posted because my
email got screwy and I was dropped from netdev (all of vger.kernel.org
actually). I just dug them up in the archives and they looks fine to
me. Thanks again Pavel.
(better late than never I suppose, applies to all three patches in the
patchset)
Acked-by: Paul Moore <paul.moore@hp.com>
--
paul moore
linux security @ hp
^ permalink raw reply
* RE: [PATCH] [IPROUTE2] Update various classifiers' help output forexpected CLASSID syntax
From: Waskiewicz Jr, Peter P @ 2008-02-13 17:22 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: stephen.hemminger, netdev
In-Reply-To: <20080213085210.GD2542@ff.dom.local>
> > + fprintf(stderr, "\nNOTE: CLASSID is parsed as hexidecimal
> > +input.\n");
>
> s/hexidecimal/hexadecimal/g (?)
Gah! Thanks Jarek, I can correct and resend.
-PJ Waskiewicz
^ permalink raw reply
* Re: BUG: 2.6.25-rc1: iptables postrouting setup causes oops
From: Haavard Skinnemoen @ 2008-02-13 18:19 UTC (permalink / raw)
To: Andrew G. Morgan
Cc: Andrew Morton, Ben Nizette, netfilter-devel, linux-kernel, netdev
In-Reply-To: <47B31DE7.9060400@kernel.org>
On Wed, 13 Feb 2008 08:42:15 -0800
"Andrew G. Morgan" <morgan@kernel.org> wrote:
> However, it is a warning and, for any existing app that doesn't care
> about newly added capabilities, the warning is benign.
Ok, I see. Thanks for explaining.
Haavard
^ permalink raw reply
* [PATCH] [NET 2.6.26]: Add per-connection option to set max TSO frame size
From: PJ Waskiewicz @ 2008-02-13 11:45 UTC (permalink / raw)
To: davem; +Cc: stephen.hemminger, netdev
Update: changed max_gso_frame_size and sk_gso_max_size from signed to
unsigned - thanks Stephen!
This patch adds the ability for device drivers to control the size of the
TSO frames being sent to them, per TCP connection. By setting the
netdevice's max_gso_frame_size value, the socket layer will set the GSO
frame size based on that value. This will propogate into the TCP layer,
and send TSO's of that size to the hardware.
This can be desirable to help tune the bursty nature of TSO on a
per-adapter basis, where one may have 1 GbE and 10 GbE devices coexisting
in a system, one running multiqueue and the other not, etc.
This can also be desirable for devices that cannot support full 64 KB
TSO's, but still want to benefit from some level of segmentation
offloading.
Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
---
include/linux/netdevice.h | 6 ++++++
include/net/sock.h | 2 ++
net/core/dev.c | 1 +
net/core/sock.c | 6 ++++--
net/ipv4/tcp_output.c | 4 ++--
5 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 047d432..853caca 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -616,6 +616,7 @@ struct net_device
/* Partially transmitted GSO packet. */
struct sk_buff *gso_skb;
+ u16 max_gso_frame_size;
/* ingress path synchronizer */
spinlock_t ingress_lock;
@@ -1475,6 +1476,11 @@ static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb)
unlikely(skb->ip_summed != CHECKSUM_PARTIAL));
}
+static inline void netif_set_max_gso_size(struct net_device *dev, u16 size)
+{
+ dev->max_gso_frame_size = size;
+}
+
/* On bonding slaves other than the currently active slave, suppress
* duplicates except for 802.3ad ETH_P_SLOW, alb non-mcast/bcast, and
* ARP on active-backup slaves with arp_validate enabled.
diff --git a/include/net/sock.h b/include/net/sock.h
index 8a7889b..2b07af0 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -151,6 +151,7 @@ struct sock_common {
* @sk_no_check: %SO_NO_CHECK setting, wether or not checkup packets
* @sk_route_caps: route capabilities (e.g. %NETIF_F_TSO)
* @sk_gso_type: GSO type (e.g. %SKB_GSO_TCPV4)
+ * @sk_gso_max_size: Maximum GSO segment size to build
* @sk_lingertime: %SO_LINGER l_linger setting
* @sk_backlog: always used with the per-socket spinlock held
* @sk_callback_lock: used with the callbacks in the end of this struct
@@ -236,6 +237,7 @@ struct sock {
gfp_t sk_allocation;
int sk_route_caps;
int sk_gso_type;
+ __u16 sk_gso_max_size;
int sk_rcvlowat;
unsigned long sk_flags;
unsigned long sk_lingertime;
diff --git a/net/core/dev.c b/net/core/dev.c
index 9549417..f635b29 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4022,6 +4022,7 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
}
dev->egress_subqueue_count = queue_count;
+ dev->max_gso_frame_size = 65536;
dev->get_stats = internal_stats;
netpoll_netdev_init(dev);
diff --git a/net/core/sock.c b/net/core/sock.c
index 433715f..a8b0ae5 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1076,10 +1076,12 @@ void sk_setup_caps(struct sock *sk, struct dst_entry *dst)
if (sk->sk_route_caps & NETIF_F_GSO)
sk->sk_route_caps |= NETIF_F_GSO_SOFTWARE;
if (sk_can_gso(sk)) {
- if (dst->header_len)
+ if (dst->header_len) {
sk->sk_route_caps &= ~NETIF_F_GSO_MASK;
- else
+ } else {
sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;
+ sk->sk_gso_max_size = dst->dev->max_gso_frame_size;
+ }
}
}
EXPORT_SYMBOL_GPL(sk_setup_caps);
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index ed750f9..8cd128d 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -998,7 +998,7 @@ unsigned int tcp_current_mss(struct sock *sk, int large_allowed)
xmit_size_goal = mss_now;
if (doing_tso) {
- xmit_size_goal = (65535 -
+ xmit_size_goal = ((sk->sk_gso_max_size - 1) -
inet_csk(sk)->icsk_af_ops->net_header_len -
inet_csk(sk)->icsk_ext_hdr_len -
tp->tcp_header_len);
@@ -1274,7 +1274,7 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb)
limit = min(send_win, cong_win);
/* If a full-sized TSO skb can be sent, do it. */
- if (limit >= 65536)
+ if (limit >= sk->sk_gso_max_size)
goto send_now;
if (sysctl_tcp_tso_win_divisor) {
^ permalink raw reply related
* [PATCH] [IPROUTE2] Update various classifiers' help output for expected CLASSID syntax
From: PJ Waskiewicz @ 2008-02-13 11:49 UTC (permalink / raw)
To: stephen.hemminger; +Cc: jarka02, netdev
update: Fix the spelling of "hexidecimal"
This updates the help output to specify that CLASSID should be hexidecimal.
This makes sure that a user entering "flowid 1:10" gets his flow put into
band 15 (0x10) and knows why.
Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
---
doc/actions/actions-general | 3 +++
tc/f_basic.c | 1 +
tc/f_fw.c | 1 +
tc/f_route.c | 1 +
tc/f_rsvp.c | 1 +
tc/f_u32.c | 1 +
6 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/doc/actions/actions-general b/doc/actions/actions-general
index 6561eda..70f7cd6 100644
--- a/doc/actions/actions-general
+++ b/doc/actions/actions-general
@@ -88,6 +88,9 @@ tc filter add dev lo parent ffff: protocol ip prio 8 u32 \
match ip dst 127.0.0.8/32 flowid 1:12 \
action ipt -j mark --set-mark 2
+NOTE: flowid 1:12 is parsed flowid 0x1:0x12. Make sure if you want flowid
+decimal 12, then use flowid 1:c.
+
3) A feature i call pipe
The motivation is derived from Unix pipe mechanism but applied to packets.
Essentially take a matching packet and pass it through
diff --git a/tc/f_basic.c b/tc/f_basic.c
index 19a7edf..aab946b 100644
--- a/tc/f_basic.c
+++ b/tc/f_basic.c
@@ -32,6 +32,7 @@ static void explain(void)
fprintf(stderr, "\n");
fprintf(stderr, "Where: SELECTOR := SAMPLE SAMPLE ...\n");
fprintf(stderr, " FILTERID := X:Y:Z\n");
+ fprintf(stderr, "\nNOTE: CLASSID is parsed as hexadecimal input.\n");
}
static int basic_parse_opt(struct filter_util *qu, char *handle,
diff --git a/tc/f_fw.c b/tc/f_fw.c
index 6d1490b..b511735 100644
--- a/tc/f_fw.c
+++ b/tc/f_fw.c
@@ -28,6 +28,7 @@ static void explain(void)
fprintf(stderr, "Usage: ... fw [ classid CLASSID ] [ police POLICE_SPEC ]\n");
fprintf(stderr, " POLICE_SPEC := ... look at TBF\n");
fprintf(stderr, " CLASSID := X:Y\n");
+ fprintf(stderr, "\nNOTE: CLASSID is parsed as hexadecimal input.\n");
}
#define usage() return(-1)
diff --git a/tc/f_route.c b/tc/f_route.c
index a41b9d5..67dd49c 100644
--- a/tc/f_route.c
+++ b/tc/f_route.c
@@ -31,6 +31,7 @@ static void explain(void)
fprintf(stderr, " [ flowid CLASSID ] [ police POLICE_SPEC ]\n");
fprintf(stderr, " POLICE_SPEC := ... look at TBF\n");
fprintf(stderr, " CLASSID := X:Y\n");
+ fprintf(stderr, "\nNOTE: CLASSID is parsed as hexadecimal input.\n");
}
#define usage() return(-1)
diff --git a/tc/f_rsvp.c b/tc/f_rsvp.c
index 13fcf97..7e1e6d9 100644
--- a/tc/f_rsvp.c
+++ b/tc/f_rsvp.c
@@ -34,6 +34,7 @@ static void explain(void)
fprintf(stderr, " u{8|16|32} NUMBER mask MASK at OFFSET}\n");
fprintf(stderr, " POLICE_SPEC := ... look at TBF\n");
fprintf(stderr, " FILTERID := X:Y\n");
+ fprintf(stderr, "\nNOTE: CLASSID is parsed as hexadecimal input.\n");
}
#define usage() return(-1)
diff --git a/tc/f_u32.c b/tc/f_u32.c
index 91f2838..d75e76c 100644
--- a/tc/f_u32.c
+++ b/tc/f_u32.c
@@ -36,6 +36,7 @@ static void explain(void)
fprintf(stderr, "Where: SELECTOR := SAMPLE SAMPLE ...\n");
fprintf(stderr, " SAMPLE := { ip | ip6 | udp | tcp | icmp | u{32|16|8} | mark } SAMPLE_ARGS [divisor DIVISOR]\n");
fprintf(stderr, " FILTERID := X:Y:Z\n");
+ fprintf(stderr, "\nNOTE: CLASSID is parsed at hexadecimal input.\n");
}
#define usage() return(-1)
^ 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