* Re: ip_rt_bug questions.
From: Dave Jones @ 2011-04-18 21:59 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20110418.145023.13728986.davem@davemloft.net>
On Mon, Apr 18, 2011 at 02:50:23PM -0700, David Miller wrote:
> >> ip_rt_bug: 0.0.0.0 -> 255.255.255.255, ?
> >>
> > It's a very serious issue, it means we used an input route for
> > packet output.
> >
> > Kernel version and what you were doing to trigger this?
current HEAD from Linus' tree.
It fell out twice so far this afternoon from my system call fuzzer.
> BTW, if you could modify this thing to spit out a stack
> trace (probably by using WARN_ON() or similar) that will
> probably show us where the bug is coming from.
Ok, I'll add that, and see if I can reproduce it again.
Dave
^ permalink raw reply
* Re: unregister_netdevice: waiting for lo to become free. Usage count = 8
From: Julian Anastasov @ 2011-04-18 22:23 UTC (permalink / raw)
To: Hans Schillstrom; +Cc: Simon Horman, netdev, lvs-devel, Eric W. Biederman
In-Reply-To: <201104182348.05228.hans@schillstrom.com>
Hello,
On Mon, 18 Apr 2011, Hans Schillstrom wrote:
> On Monday, April 18, 2011 23:12:27 Julian Anastasov wrote:
> >
> > Hello,
> >
> > On Mon, 18 Apr 2011, Hans Schillstrom wrote:
> >
> > > Actually I forgot to tell there is a need for a
> > > ip_vs_service_cleanup() due to above.
> > > Do you see any drawbacks with it ?
> >
> > May be ip_vs_service_cleanup() should call only
> > ip_vs_flush(), under __ip_vs_mutex.
>
> Hmm,
> I'm not sure if the IP_VS_WAIT_WHILE() in ip_vs_flush is a good idea in this case...
> That was why I wrote ip_vs_service_cleanup()
IP_VS_WAIT_WHILE should be called because some
schedulers do not use locks for ->schedule, eg. WLC.
They rely on svc->usecnt reference to hold the virtual
service. Nothing changes now with netns. It is currently the
only way to modify or delete virtual service or scheduler.
Of course, __ip_vs_svc_lock is now global but we do not
have a choice.
> > _cleanup_net. Now there are many register_pernet_subsys()
> > calls and I'm not sure we preserve the needed order for
> > cleanup. Are the ->exit methods called in reverse order?
>
> Yes
You mean, only in the planned patch, yes?
> > I don't see it in ops_exit_list() and we can not rely
> > on such registration order. I think, ip_vs_init() should
> > call global functions as now but __ip_vs_init() and
> > __ip_vs_cleanup() should call the _net methods in right
> > order.
>
> Exactly,
> I have already done that in my next patch, and some other small changes :-)
> For the ip_vs.ko there is only one register/unregister now, the schedulers still have their own.
> Hopefully the patch is ready to morrow
OK, very good.
Regards
--
Julian Anastasov <ja@ssi.bg>
^ permalink raw reply
* [PATCH net-next 0/5] be2net: allow register dump only for PFs
From: Ajit Khaparde @ 2011-04-18 22:29 UTC (permalink / raw)
To: davem; +Cc: netdev
Series of 5 patches against net-next-2.6
Please apply.
Thanks
-Ajit
[1/5] allow register dump only for PFs
[2/5] Add code to display nic speeds other than 1Gbps/10Gbps
[3/5] fix be_mcc_compl_process to identify eth_get_stat command
[4/5] pass domain id to be_cmd_link_status_query
[5/5] add code to display default value of tx rate for VFs
^ permalink raw reply
* [PATCH net-next 1/5] be2net: allow register dump only for PFs
From: Ajit Khaparde @ 2011-04-18 22:29 UTC (permalink / raw)
To: davem; +Cc: netdev
Signed-off-by: Ajit Khaparde <ajit.khaparde@emulex.com>
---
drivers/net/benet/be_ethtool.c | 10 +++++++---
1 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c
index 28716a6..22523b9 100644
--- a/drivers/net/benet/be_ethtool.c
+++ b/drivers/net/benet/be_ethtool.c
@@ -161,7 +161,9 @@ be_get_reg_len(struct net_device *netdev)
struct be_adapter *adapter = netdev_priv(netdev);
u32 log_size = 0;
- be_cmd_get_reg_len(adapter, &log_size);
+ if (be_physfn(adapter))
+ be_cmd_get_reg_len(adapter, &log_size);
+
return log_size;
}
@@ -170,8 +172,10 @@ be_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *buf)
{
struct be_adapter *adapter = netdev_priv(netdev);
- memset(buf, 0, regs->len);
- be_cmd_get_regs(adapter, regs->len, buf);
+ if (be_physfn(adapter)) {
+ memset(buf, 0, regs->len);
+ be_cmd_get_regs(adapter, regs->len, buf);
+ }
}
static int
--
1.7.1
^ permalink raw reply related
* [PATCH net-next 2/5] be2net: Add code to display nic speeds other than 1Gbps/10Gbps
From: Ajit Khaparde @ 2011-04-18 22:30 UTC (permalink / raw)
To: davem; +Cc: netdev
Signed-off-by: Ajit Khaparde <ajit.khaparde@emulex.com>
---
drivers/net/benet/be_ethtool.c | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c
index 22523b9..33c2bec 100644
--- a/drivers/net/benet/be_ethtool.c
+++ b/drivers/net/benet/be_ethtool.c
@@ -384,12 +384,21 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
ecmd->speed = link_speed*10;
} else {
switch (mac_speed) {
+ case PHY_LINK_SPEED_10MBPS:
+ ecmd->speed = SPEED_10;
+ break;
+ case PHY_LINK_SPEED_100MBPS:
+ ecmd->speed = SPEED_100;
+ break;
case PHY_LINK_SPEED_1GBPS:
ecmd->speed = SPEED_1000;
break;
case PHY_LINK_SPEED_10GBPS:
ecmd->speed = SPEED_10000;
break;
+ case PHY_LINK_SPEED_ZERO:
+ ecmd->speed = 0;
+ break;
}
}
--
1.7.1
^ permalink raw reply related
* [PATCH net-next 3/5] be2net: fix be_mcc_compl_process to identify eth_get_stat command
From: Ajit Khaparde @ 2011-04-18 22:30 UTC (permalink / raw)
To: davem; +Cc: netdev
eth_get_statistics and vlan_config command have same opcode.
Use opcode subsystem id to differentiate one from other.
Signed-off-by: Ajit Khaparde <ajit.khaparde@emulex.com>
---
drivers/net/benet/be_cmds.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 11b774a..a94e980 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -78,7 +78,8 @@ static int be_mcc_compl_process(struct be_adapter *adapter,
}
if (compl_status == MCC_STATUS_SUCCESS) {
- if (compl->tag0 == OPCODE_ETH_GET_STATISTICS) {
+ if ((compl->tag0 == OPCODE_ETH_GET_STATISTICS) &&
+ (compl->tag1 == CMD_SUBSYSTEM_ETH)) {
struct be_cmd_resp_get_stats *resp =
adapter->stats_cmd.va;
be_dws_le_to_cpu(&resp->hw_stats,
@@ -1096,6 +1097,7 @@ int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd)
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
OPCODE_ETH_GET_STATISTICS, sizeof(*req));
+ wrb->tag1 = CMD_SUBSYSTEM_ETH;
sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
sge->len = cpu_to_le32(nonemb_cmd->size);
--
1.7.1
^ permalink raw reply related
* [PATCH net-next 4/5] be2net: pass domain id to be_cmd_link_status_query
From: Ajit Khaparde @ 2011-04-18 22:30 UTC (permalink / raw)
To: davem; +Cc: netdev
Signed-off-by: Ajit Khaparde <ajit.khaparde@emulex.com>
---
drivers/net/benet/be.h | 1 -
drivers/net/benet/be_cmds.c | 4 +++-
drivers/net/benet/be_cmds.h | 2 +-
drivers/net/benet/be_ethtool.c | 4 ++--
drivers/net/benet/be_main.c | 34 ++++++++++------------------------
5 files changed, 16 insertions(+), 29 deletions(-)
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index a0b4743..4ba9c68 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -293,7 +293,6 @@ struct be_adapter {
u8 eq_next_idx;
struct be_drv_stats drv_stats;
- struct vlan_group *vlan_grp;
u16 vlans_added;
u16 max_vlans; /* Number of vlans supported */
u8 vlan_tag[VLAN_N_VID];
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index a94e980..7a580a9 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -1112,7 +1112,7 @@ err:
/* Uses synchronous mcc */
int be_cmd_link_status_query(struct be_adapter *adapter,
- bool *link_up, u8 *mac_speed, u16 *link_speed)
+ bool *link_up, u8 *mac_speed, u16 *link_speed, u32 dom)
{
struct be_mcc_wrb *wrb;
struct be_cmd_req_link_status *req;
@@ -1135,6 +1135,8 @@ int be_cmd_link_status_query(struct be_adapter *adapter,
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_NTWK_LINK_STATUS_QUERY, sizeof(*req));
+ req->hdr.domain = dom;
+
status = be_mcc_notify_wait(adapter);
if (!status) {
struct be_cmd_resp_link_status *resp = embedded_payload(wrb);
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index 3fb6e0a..af4bbff 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -1112,7 +1112,7 @@ extern int be_cmd_rxq_create(struct be_adapter *adapter,
extern int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
int type);
extern int be_cmd_link_status_query(struct be_adapter *adapter,
- bool *link_up, u8 *mac_speed, u16 *link_speed);
+ bool *link_up, u8 *mac_speed, u16 *link_speed, u32 dom);
extern int be_cmd_reset(struct be_adapter *adapter);
extern int be_cmd_get_stats(struct be_adapter *adapter,
struct be_dma_mem *nonemb_cmd);
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c
index 33c2bec..6565f3e 100644
--- a/drivers/net/benet/be_ethtool.c
+++ b/drivers/net/benet/be_ethtool.c
@@ -376,7 +376,7 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
if ((adapter->link_speed < 0) || (!(netdev->flags & IFF_UP))) {
status = be_cmd_link_status_query(adapter, &link_up,
- &mac_speed, &link_speed);
+ &mac_speed, &link_speed, 0);
be_link_status_update(adapter, link_up);
/* link_speed is in units of 10 Mbps */
@@ -661,7 +661,7 @@ be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data)
}
if (be_cmd_link_status_query(adapter, &link_up, &mac_speed,
- &qos_link_speed) != 0) {
+ &qos_link_speed, 0) != 0) {
test->flags |= ETH_TEST_FL_FAILED;
data[4] = -1;
} else if (!mac_speed) {
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 1bb763c..94a9c4a 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -464,7 +464,7 @@ static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr,
AMAP_SET_BITS(struct amap_eth_hdr_wrb, udpcs, hdr, 1);
}
- if (adapter->vlan_grp && vlan_tx_tag_present(skb)) {
+ if (vlan_tx_tag_present(skb)) {
AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan, hdr, 1);
vlan_tag = vlan_tx_tag_get(skb);
vlan_prio = (vlan_tag & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
@@ -658,13 +658,6 @@ static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num)
return status;
}
-static void be_vlan_register(struct net_device *netdev, struct vlan_group *grp)
-{
- struct be_adapter *adapter = netdev_priv(netdev);
-
- adapter->vlan_grp = grp;
-}
-
static void be_vlan_add_vid(struct net_device *netdev, u16 vid)
{
struct be_adapter *adapter = netdev_priv(netdev);
@@ -683,7 +676,6 @@ static void be_vlan_rem_vid(struct net_device *netdev, u16 vid)
struct be_adapter *adapter = netdev_priv(netdev);
adapter->vlans_added--;
- vlan_group_set_device(adapter->vlan_grp, vid, NULL);
if (!be_physfn(adapter))
return;
@@ -1012,15 +1004,10 @@ static void be_rx_compl_process(struct be_adapter *adapter,
skb->rxhash = rxcp->rss_hash;
- if (unlikely(rxcp->vlanf)) {
- if (!adapter->vlan_grp || adapter->vlans_added == 0) {
- kfree_skb(skb);
- return;
- }
- vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, rxcp->vid);
- } else {
- netif_receive_skb(skb);
- }
+ if (unlikely(rxcp->vlanf))
+ __vlan_hwaccel_put_tag(skb, rxcp->vid);
+
+ netif_receive_skb(skb);
}
/* Process the RX completion indicated by rxcp when GRO is enabled */
@@ -1074,10 +1061,10 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
if (adapter->netdev->features & NETIF_F_RXHASH)
skb->rxhash = rxcp->rss_hash;
- if (likely(!rxcp->vlanf))
- napi_gro_frags(&eq_obj->napi);
- else
- vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, rxcp->vid);
+ if (unlikely(rxcp->vlanf))
+ __vlan_hwaccel_put_tag(skb, rxcp->vid);
+
+ napi_gro_frags(&eq_obj->napi);
}
static void be_parse_rx_compl_v1(struct be_adapter *adapter,
@@ -2171,7 +2158,7 @@ static int be_open(struct net_device *netdev)
be_async_mcc_enable(adapter);
status = be_cmd_link_status_query(adapter, &link_up, &mac_speed,
- &link_speed);
+ &link_speed, 0);
if (status)
goto err;
be_link_status_update(adapter, link_up);
@@ -2613,7 +2600,6 @@ static struct net_device_ops be_netdev_ops = {
.ndo_set_mac_address = be_mac_addr_set,
.ndo_change_mtu = be_change_mtu,
.ndo_validate_addr = eth_validate_addr,
- .ndo_vlan_rx_register = be_vlan_register,
.ndo_vlan_rx_add_vid = be_vlan_add_vid,
.ndo_vlan_rx_kill_vid = be_vlan_rem_vid,
.ndo_set_vf_mac = be_set_vf_mac,
--
1.7.1
^ permalink raw reply related
* [PATCH net-next 5/5] be2net: add code to display default value of tx rate for VFs
From: Ajit Khaparde @ 2011-04-18 22:30 UTC (permalink / raw)
To: davem; +Cc: netdev
This change will allow the default value of tx rate to be displayed
when ip link show is called on a PF interface.
Signed-off-by: Ajit Khaparde <ajit.khaparde@emulex.com>
---
drivers/net/benet/be_main.c | 13 +++++++++++++
1 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 94a9c4a..30fbb3b 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -3068,9 +3068,22 @@ static int __devinit be_probe(struct pci_dev *pdev,
netif_carrier_off(netdev);
if (be_physfn(adapter) && adapter->sriov_enabled) {
+ u8 mac_speed;
+ bool link_up;
+ u16 vf, lnk_speed;
+
status = be_vf_eth_addr_config(adapter);
if (status)
goto unreg_netdev;
+
+ for (vf = 0; vf < num_vfs; vf++) {
+ status = be_cmd_link_status_query(adapter, &link_up,
+ &mac_speed, &lnk_speed, vf + 1);
+ if (!status)
+ adapter->vf_cfg[vf].vf_tx_rate = lnk_speed * 10;
+ else
+ goto unreg_netdev;
+ }
}
dev_info(&pdev->dev, "%s port %d\n", nic_name(pdev), adapter->port_num);
--
1.7.1
^ permalink raw reply related
* Re: [Bugme-new] [Bug 33502] New: Caught 64-bit read from uninitialized memory in __alloc_skb
From: Andrew Morton @ 2011-04-18 22:38 UTC (permalink / raw)
To: netdev
Cc: bugzilla-daemon, bugme-daemon, casteyde.christian, Vegard Nossum,
Pekka Enberg
In-Reply-To: <bug-33502-10286@https.bugzilla.kernel.org/>
(switched to email. Please respond via emailed reply-to-all, not via the
bugzilla web interface).
On Sun, 17 Apr 2011 19:29:39 GMT
bugzilla-daemon@bugzilla.kernel.org wrote:
> https://bugzilla.kernel.org/show_bug.cgi?id=33502
>
> Summary: Caught 64-bit read from uninitialized memory in
> __alloc_skb
> Product: Networking
> Version: 2.5
> Kernel Version: 2.6.39-rc3
> Platform: All
> OS/Version: Linux
> Tree: Mainline
> Status: NEW
> Severity: normal
> Priority: P1
> Component: IPV4
> AssignedTo: shemminger@linux-foundation.org
> ReportedBy: casteyde.christian@free.fr
> Regression: Yes
>
>
> Acer Aspire 1511LMi
> Athlon 64 3GHz in 64bits mode
> Slackware 64 13.1
>
> Since 2.6.39-rc3 with kmemcheck enabled, I get the following warning:
> ...
> pcmcia_socket pcmcia_socket0: cs: memory probe 0x0c0000-0x0fffff: excluding
> 0xc0000-0xfffff
> pcmcia_socket pcmcia_socket0: cs: memory probe 0x60000000-0x60ffffff: excluding
> 0x60000000-0x
> 60ffffff
> pcmcia_socket pcmcia_socket0: cs: memory probe 0xa0000000-0xa0ffffff: excluding
> 0xa0000000-0x
> a0ffffff
> udev: renamed network interface wlan0 to eth1
> WARNING: kmemcheck: Caught 64-bit read from uninitialized memory
> (ffff88001b0bb800)
> 00b00b1b0088ffff0000000000000000cafe1dea20009b0000299a3100000000
> u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u
> ^
>
> Pid: 1511, comm: udevd Not tainted 2.6.39-rc3 #1 Acer,Inc. Aspire 1510 /Aspire
> 1510
> RIP: 0010:[<ffffffff810c2f0c>] [<ffffffff810c2f0c>]
> __kmalloc_track_caller+0xbc/0x1d0
> RSP: 0018:ffff88001d3a7a18 EFLAGS: 00010246
> RAX: 0000000000000000 RBX: 0000000000000010 RCX: 000000000000284f
> RDX: 000000000000284e RSI: ffff88001fe5b160 RDI: ffffffff8177e39a
> RBP: ffff88001d3a7a48 R08: 0000000000000000 R09: ffff88001b931100
> R10: 0000000000000000 R11: 0000000000000003 R12: ffff88001b0bb800
> R13: ffff88001f803840 R14: 00000000000004d0 R15: ffffffff814769c6
> FS: 00007f6ee81f1700(0000) GS:ffffffff81a1b000(0000) knlGS:0000000000000000
> CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
> CR2: ffff88001d0b3938 CR3: 000000001d38b000 CR4: 00000000000006f0
> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> DR3: 0000000000000000 DR6: 00000000ffff4ff0 DR7: 0000000000000400
> [<ffffffff8147ccf2>] __alloc_skb+0x72/0x190
> [<ffffffff814769c6>] sock_alloc_send_pskb+0x236/0x3a0
> [<ffffffff81476b40>] sock_alloc_send_skb+0x10/0x20
> [<ffffffff81523c18>] unix_dgram_sendmsg+0x298/0x770
> [<ffffffff814715f3>] sock_sendmsg+0xe3/0x110
> [<ffffffff81472603>] sys_sendmsg+0x243/0x3c0
> [<ffffffff815e7238>] system_call_fastpath+0x16/0x1b
> [<ffffffffffffffff>] 0xffffffffffffffff
hum. I wonder if kmemcheck is disliking prefetchw()?
^ permalink raw reply
* (unknown)
From: Wen Lee @ 2011-04-18 22:55 UTC (permalink / raw)
I am requesting for your partnership in re-profiling funds I will give the details, but
in summary, the funds are coming via Bank Of Taipei Taiwan.Contact me for further details (lwen88@9.cn)
Wen Lee.
^ permalink raw reply
* [PATCH] net: qlge: convert to hw_features
From: Michał Mirosław @ 2011-04-18 23:31 UTC (permalink / raw)
To: netdev; +Cc: Ron Mercer, linux-driver
Another simple conversion.
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
drivers/net/qlge/qlge_ethtool.c | 34 ----------------------------------
drivers/net/qlge/qlge_main.c | 21 ++++++++-------------
2 files changed, 8 insertions(+), 47 deletions(-)
diff --git a/drivers/net/qlge/qlge_ethtool.c b/drivers/net/qlge/qlge_ethtool.c
index 687754d..78dc40c 100644
--- a/drivers/net/qlge/qlge_ethtool.c
+++ b/drivers/net/qlge/qlge_ethtool.c
@@ -655,32 +655,6 @@ static int ql_set_pauseparam(struct net_device *netdev,
return status;
}
-static u32 ql_get_rx_csum(struct net_device *netdev)
-{
- struct ql_adapter *qdev = netdev_priv(netdev);
- return qdev->rx_csum;
-}
-
-static int ql_set_rx_csum(struct net_device *netdev, uint32_t data)
-{
- struct ql_adapter *qdev = netdev_priv(netdev);
- qdev->rx_csum = data;
- return 0;
-}
-
-static int ql_set_tso(struct net_device *ndev, uint32_t data)
-{
-
- if (data) {
- ndev->features |= NETIF_F_TSO;
- ndev->features |= NETIF_F_TSO6;
- } else {
- ndev->features &= ~NETIF_F_TSO;
- ndev->features &= ~NETIF_F_TSO6;
- }
- return 0;
-}
-
static u32 ql_get_msglevel(struct net_device *ndev)
{
struct ql_adapter *qdev = netdev_priv(ndev);
@@ -707,14 +681,6 @@ const struct ethtool_ops qlge_ethtool_ops = {
.self_test = ql_self_test,
.get_pauseparam = ql_get_pauseparam,
.set_pauseparam = ql_set_pauseparam,
- .get_rx_csum = ql_get_rx_csum,
- .set_rx_csum = ql_set_rx_csum,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
- .get_tso = ethtool_op_get_tso,
- .set_tso = ql_set_tso,
.get_coalesce = ql_get_coalesce,
.set_coalesce = ql_set_coalesce,
.get_sset_count = ql_get_sset_count,
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index f61e717..6c9d124 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -1571,7 +1571,7 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev,
skb->protocol = eth_type_trans(skb, ndev);
skb_checksum_none_assert(skb);
- if (qdev->rx_csum &&
+ if ((ndev->features & NETIF_F_RXCSUM) &&
!(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) {
/* TCP frame. */
if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) {
@@ -1684,7 +1684,7 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev,
/* If rx checksum is on, and there are no
* csum or frame errors.
*/
- if (qdev->rx_csum &&
+ if ((ndev->features & NETIF_F_RXCSUM) &&
!(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) {
/* TCP frame. */
if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) {
@@ -2004,7 +2004,7 @@ static void ql_process_mac_split_rx_intr(struct ql_adapter *qdev,
/* If rx checksum is on, and there are no
* csum or frame errors.
*/
- if (qdev->rx_csum &&
+ if ((ndev->features & NETIF_F_RXCSUM) &&
!(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) {
/* TCP frame. */
if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) {
@@ -4621,7 +4621,6 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
/*
* Set up the operating parameters.
*/
- qdev->rx_csum = 1;
qdev->workqueue = create_singlethread_workqueue(ndev->name);
INIT_DELAYED_WORK(&qdev->asic_reset_work, ql_asic_reset_work);
INIT_DELAYED_WORK(&qdev->mpi_reset_work, ql_mpi_reset_work);
@@ -4695,15 +4694,11 @@ static int __devinit qlge_probe(struct pci_dev *pdev,
qdev = netdev_priv(ndev);
SET_NETDEV_DEV(ndev, &pdev->dev);
- ndev->features = (0
- | NETIF_F_IP_CSUM
- | NETIF_F_SG
- | NETIF_F_TSO
- | NETIF_F_TSO6
- | NETIF_F_TSO_ECN
- | NETIF_F_HW_VLAN_TX
- | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER);
- ndev->features |= NETIF_F_GRO;
+ ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
+ NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN |
+ NETIF_F_HW_VLAN_TX | NETIF_F_RXCSUM;
+ ndev->features = ndev->hw_features |
+ NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
if (test_bit(QL_DMA64, &qdev->flags))
ndev->features |= NETIF_F_HIGHDMA;
--
1.7.2.5
^ permalink raw reply related
* [PATCH] net: s2io: convert to hw_features
From: Michał Mirosław @ 2011-04-18 23:31 UTC (permalink / raw)
To: netdev; +Cc: Jon Mason
This removes advertising HW_CSUM as driver does not support it.
Note: driver advertises TSO6 but not IPV6_CSUM - bug maybe?
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
drivers/net/s2io.c | 100 ++++++++++-----------------------------------------
1 files changed, 20 insertions(+), 80 deletions(-)
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 2302d97..58b78f4 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -6618,25 +6618,6 @@ static int s2io_ethtool_get_regs_len(struct net_device *dev)
}
-static u32 s2io_ethtool_get_rx_csum(struct net_device *dev)
-{
- struct s2io_nic *sp = netdev_priv(dev);
-
- return sp->rx_csum;
-}
-
-static int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data)
-{
- struct s2io_nic *sp = netdev_priv(dev);
-
- if (data)
- sp->rx_csum = 1;
- else
- sp->rx_csum = 0;
-
- return 0;
-}
-
static int s2io_get_eeprom_len(struct net_device *dev)
{
return XENA_EEPROM_SPACE;
@@ -6688,61 +6669,27 @@ static void s2io_ethtool_get_strings(struct net_device *dev,
}
}
-static int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
-{
- if (data)
- dev->features |= NETIF_F_IP_CSUM;
- else
- dev->features &= ~NETIF_F_IP_CSUM;
-
- return 0;
-}
-
-static u32 s2io_ethtool_op_get_tso(struct net_device *dev)
-{
- return (dev->features & NETIF_F_TSO) != 0;
-}
-
-static int s2io_ethtool_op_set_tso(struct net_device *dev, u32 data)
-{
- if (data)
- dev->features |= (NETIF_F_TSO | NETIF_F_TSO6);
- else
- dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
-
- return 0;
-}
-
-static int s2io_ethtool_set_flags(struct net_device *dev, u32 data)
+static int s2io_set_features(struct net_device *dev, u32 features)
{
struct s2io_nic *sp = netdev_priv(dev);
- int rc = 0;
- int changed = 0;
-
- if (ethtool_invalid_flags(dev, data, ETH_FLAG_LRO))
- return -EINVAL;
-
- if (data & ETH_FLAG_LRO) {
- if (!(dev->features & NETIF_F_LRO)) {
- dev->features |= NETIF_F_LRO;
- changed = 1;
- }
- } else if (dev->features & NETIF_F_LRO) {
- dev->features &= ~NETIF_F_LRO;
- changed = 1;
- }
+ u32 changed = (features ^ dev->features) & NETIF_F_LRO;
if (changed && netif_running(dev)) {
+ int rc;
+
s2io_stop_all_tx_queue(sp);
s2io_card_down(sp);
+ dev->features = features;
rc = s2io_card_up(sp);
if (rc)
s2io_reset(sp);
else
s2io_start_all_tx_queue(sp);
+
+ return rc ? rc : 1;
}
- return rc;
+ return 0;
}
static const struct ethtool_ops netdev_ethtool_ops = {
@@ -6758,15 +6705,6 @@ static const struct ethtool_ops netdev_ethtool_ops = {
.get_ringparam = s2io_ethtool_gringparam,
.get_pauseparam = s2io_ethtool_getpause_data,
.set_pauseparam = s2io_ethtool_setpause_data,
- .get_rx_csum = s2io_ethtool_get_rx_csum,
- .set_rx_csum = s2io_ethtool_set_rx_csum,
- .set_tx_csum = s2io_ethtool_op_set_tx_csum,
- .set_flags = s2io_ethtool_set_flags,
- .get_flags = ethtool_op_get_flags,
- .set_sg = ethtool_op_set_sg,
- .get_tso = s2io_ethtool_op_get_tso,
- .set_tso = s2io_ethtool_op_set_tso,
- .set_ufo = ethtool_op_set_ufo,
.self_test = s2io_ethtool_test,
.get_strings = s2io_ethtool_get_strings,
.set_phys_id = s2io_ethtool_set_led,
@@ -7538,7 +7476,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
if ((rxdp->Control_1 & TCP_OR_UDP_FRAME) &&
((!ring_data->lro) ||
(ring_data->lro && (!(rxdp->Control_1 & RXD_FRAME_IP_FRAG)))) &&
- (sp->rx_csum)) {
+ (dev->features & NETIF_F_RXCSUM)) {
l3_csum = RXD_GET_L3_CKSUM(rxdp->Control_1);
l4_csum = RXD_GET_L4_CKSUM(rxdp->Control_1);
if ((l3_csum == L3_CKSUM_OK) && (l4_csum == L4_CKSUM_OK)) {
@@ -7799,6 +7737,7 @@ static const struct net_device_ops s2io_netdev_ops = {
.ndo_do_ioctl = s2io_ioctl,
.ndo_set_mac_address = s2io_set_mac_addr,
.ndo_change_mtu = s2io_change_mtu,
+ .ndo_set_features = s2io_set_features,
.ndo_vlan_rx_register = s2io_vlan_rx_register,
.ndo_vlan_rx_kill_vid = s2io_vlan_rx_kill_vid,
.ndo_tx_timeout = s2io_tx_watchdog,
@@ -8040,17 +7979,18 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
/* Driver entry points */
dev->netdev_ops = &s2io_netdev_ops;
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
- dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
- dev->features |= NETIF_F_LRO;
- dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+ dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
+ NETIF_F_TSO | NETIF_F_TSO6 |
+ NETIF_F_RXCSUM | NETIF_F_LRO;
+ dev->features |= dev->hw_features |
+ NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+ if (sp->device_type & XFRAME_II_DEVICE) {
+ dev->hw_features |= NETIF_F_UFO;
+ if (ufo)
+ dev->features |= NETIF_F_UFO;
+ }
if (sp->high_dma_flag == true)
dev->features |= NETIF_F_HIGHDMA;
- dev->features |= NETIF_F_TSO;
- dev->features |= NETIF_F_TSO6;
- if ((sp->device_type & XFRAME_II_DEVICE) && (ufo)) {
- dev->features |= NETIF_F_UFO;
- dev->features |= NETIF_F_HW_CSUM;
- }
dev->watchdog_timeo = WATCH_DOG_TIMEOUT;
INIT_WORK(&sp->rst_timer_task, s2io_restart_nic);
INIT_WORK(&sp->set_link_task, s2io_set_link);
--
1.7.2.5
^ permalink raw reply related
* [PATCH v2] net: chelsio: convert to hw_features
From: Michał Mirosław @ 2011-04-18 23:31 UTC (permalink / raw)
To: netdev; +Cc: David S. Miller
In-Reply-To: <20110417101546.EE73713A67@rere.qmqm.pl>
Also remove flags that were not used or are now redundant to hw_features bits.
No device had UDP_CSUM_CAPABLE set.
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
v2: fix usage of uninitialized variable in sge_rx()
drivers/net/chelsio/common.h | 5 ----
drivers/net/chelsio/cxgb2.c | 48 ++++++-----------------------------------
drivers/net/chelsio/sge.c | 13 ++++++-----
drivers/net/chelsio/tp.c | 5 ----
drivers/net/chelsio/tp.h | 1 -
5 files changed, 14 insertions(+), 58 deletions(-)
diff --git a/drivers/net/chelsio/common.h b/drivers/net/chelsio/common.h
index 092f31a..c26d863 100644
--- a/drivers/net/chelsio/common.h
+++ b/drivers/net/chelsio/common.h
@@ -264,11 +264,6 @@ struct adapter {
enum { /* adapter flags */
FULL_INIT_DONE = 1 << 0,
- TSO_CAPABLE = 1 << 2,
- TCP_CSUM_CAPABLE = 1 << 3,
- UDP_CSUM_CAPABLE = 1 << 4,
- VLAN_ACCEL_CAPABLE = 1 << 5,
- RX_CSUM_ENABLED = 1 << 6,
};
struct mdio_ops;
diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c
index 0f71304..5f82c9c 100644
--- a/drivers/net/chelsio/cxgb2.c
+++ b/drivers/net/chelsio/cxgb2.c
@@ -192,10 +192,8 @@ static void link_start(struct port_info *p)
static void enable_hw_csum(struct adapter *adapter)
{
- if (adapter->flags & TSO_CAPABLE)
+ if (adapter->port[0].dev->hw_features & NETIF_F_TSO)
t1_tp_set_ip_checksum_offload(adapter->tp, 1); /* for TSO only */
- if (adapter->flags & UDP_CSUM_CAPABLE)
- t1_tp_set_udp_checksum_offload(adapter->tp, 1);
t1_tp_set_tcp_checksum_offload(adapter->tp, 1);
}
@@ -705,33 +703,6 @@ static int set_pauseparam(struct net_device *dev,
return 0;
}
-static u32 get_rx_csum(struct net_device *dev)
-{
- struct adapter *adapter = dev->ml_priv;
-
- return (adapter->flags & RX_CSUM_ENABLED) != 0;
-}
-
-static int set_rx_csum(struct net_device *dev, u32 data)
-{
- struct adapter *adapter = dev->ml_priv;
-
- if (data)
- adapter->flags |= RX_CSUM_ENABLED;
- else
- adapter->flags &= ~RX_CSUM_ENABLED;
- return 0;
-}
-
-static int set_tso(struct net_device *dev, u32 value)
-{
- struct adapter *adapter = dev->ml_priv;
-
- if (!(adapter->flags & TSO_CAPABLE))
- return value ? -EOPNOTSUPP : 0;
- return ethtool_op_set_tso(dev, value);
-}
-
static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
{
struct adapter *adapter = dev->ml_priv;
@@ -831,17 +802,12 @@ static const struct ethtool_ops t1_ethtool_ops = {
.get_eeprom = get_eeprom,
.get_pauseparam = get_pauseparam,
.set_pauseparam = set_pauseparam,
- .get_rx_csum = get_rx_csum,
- .set_rx_csum = set_rx_csum,
- .set_tx_csum = ethtool_op_set_tx_csum,
- .set_sg = ethtool_op_set_sg,
.get_link = ethtool_op_get_link,
.get_strings = get_strings,
.get_sset_count = get_sset_count,
.get_ethtool_stats = get_stats,
.get_regs_len = get_regs_len,
.get_regs = get_regs,
- .set_tso = set_tso,
};
static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
@@ -1105,28 +1071,28 @@ static int __devinit init_one(struct pci_dev *pdev,
netdev->mem_start = mmio_start;
netdev->mem_end = mmio_start + mmio_len - 1;
netdev->ml_priv = adapter;
- netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
- netdev->features |= NETIF_F_LLTX;
+ netdev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM |
+ NETIF_F_RXCSUM;
+ netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM |
+ NETIF_F_RXCSUM | NETIF_F_LLTX;
- adapter->flags |= RX_CSUM_ENABLED | TCP_CSUM_CAPABLE;
if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
if (vlan_tso_capable(adapter)) {
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
- adapter->flags |= VLAN_ACCEL_CAPABLE;
netdev->features |=
NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
#endif
/* T204: disable TSO */
if (!(is_T2(adapter)) || bi->port_number != 4) {
- adapter->flags |= TSO_CAPABLE;
+ netdev->hw_features |= NETIF_F_TSO;
netdev->features |= NETIF_F_TSO;
}
}
netdev->netdev_ops = &cxgb_netdev_ops;
- netdev->hard_header_len += (adapter->flags & TSO_CAPABLE) ?
+ netdev->hard_header_len += (netdev->hw_features & NETIF_F_TSO) ?
sizeof(struct cpl_tx_pkt_lso) : sizeof(struct cpl_tx_pkt);
netif_napi_add(netdev, &adapter->napi, t1_poll, 64);
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c
index 8754d44..b948ea7 100644
--- a/drivers/net/chelsio/sge.c
+++ b/drivers/net/chelsio/sge.c
@@ -929,7 +929,7 @@ void t1_sge_intr_enable(struct sge *sge)
u32 en = SGE_INT_ENABLE;
u32 val = readl(sge->adapter->regs + A_PL_ENABLE);
- if (sge->adapter->flags & TSO_CAPABLE)
+ if (sge->adapter->port[0].dev->hw_features & NETIF_F_TSO)
en &= ~F_PACKET_TOO_BIG;
writel(en, sge->adapter->regs + A_SG_INT_ENABLE);
writel(val | SGE_PL_INTR_MASK, sge->adapter->regs + A_PL_ENABLE);
@@ -952,7 +952,7 @@ int t1_sge_intr_error_handler(struct sge *sge)
struct adapter *adapter = sge->adapter;
u32 cause = readl(adapter->regs + A_SG_INT_CAUSE);
- if (adapter->flags & TSO_CAPABLE)
+ if (adapter->port[0].dev->hw_features & NETIF_F_TSO)
cause &= ~F_PACKET_TOO_BIG;
if (cause & F_RESPQ_EXHAUSTED)
sge->stats.respQ_empty++;
@@ -1369,6 +1369,7 @@ static void sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len)
const struct cpl_rx_pkt *p;
struct adapter *adapter = sge->adapter;
struct sge_port_stats *st;
+ struct net_device *dev;
skb = get_packet(adapter->pdev, fl, len - sge->rx_pkt_pad);
if (unlikely(!skb)) {
@@ -1384,9 +1385,10 @@ static void sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len)
__skb_pull(skb, sizeof(*p));
st = this_cpu_ptr(sge->port_stats[p->iff]);
+ dev = adapter->port[p->iff].dev;
- skb->protocol = eth_type_trans(skb, adapter->port[p->iff].dev);
- if ((adapter->flags & RX_CSUM_ENABLED) && p->csum == 0xffff &&
+ skb->protocol = eth_type_trans(skb, dev);
+ if ((dev->features & NETIF_F_RXCSUM) && p->csum == 0xffff &&
skb->protocol == htons(ETH_P_IP) &&
(skb->data[9] == IPPROTO_TCP || skb->data[9] == IPPROTO_UDP)) {
++st->rx_cso_good;
@@ -1838,8 +1840,7 @@ netdev_tx_t t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;
}
- if (!(adapter->flags & UDP_CSUM_CAPABLE) &&
- skb->ip_summed == CHECKSUM_PARTIAL &&
+ if (skb->ip_summed == CHECKSUM_PARTIAL &&
ip_hdr(skb)->protocol == IPPROTO_UDP) {
if (unlikely(skb_checksum_help(skb))) {
pr_debug("%s: unable to do udp checksum\n", dev->name);
diff --git a/drivers/net/chelsio/tp.c b/drivers/net/chelsio/tp.c
index 6222d58..8bed4a5 100644
--- a/drivers/net/chelsio/tp.c
+++ b/drivers/net/chelsio/tp.c
@@ -152,11 +152,6 @@ void t1_tp_set_ip_checksum_offload(struct petp *tp, int enable)
set_csum_offload(tp, F_IP_CSUM, enable);
}
-void t1_tp_set_udp_checksum_offload(struct petp *tp, int enable)
-{
- set_csum_offload(tp, F_UDP_CSUM, enable);
-}
-
void t1_tp_set_tcp_checksum_offload(struct petp *tp, int enable)
{
set_csum_offload(tp, F_TCP_CSUM, enable);
diff --git a/drivers/net/chelsio/tp.h b/drivers/net/chelsio/tp.h
index 32fc71e..dfd8ce2 100644
--- a/drivers/net/chelsio/tp.h
+++ b/drivers/net/chelsio/tp.h
@@ -65,7 +65,6 @@ void t1_tp_intr_clear(struct petp *tp);
int t1_tp_intr_handler(struct petp *tp);
void t1_tp_get_mib_statistics(adapter_t *adap, struct tp_mib_statistics *tps);
-void t1_tp_set_udp_checksum_offload(struct petp *tp, int enable);
void t1_tp_set_tcp_checksum_offload(struct petp *tp, int enable);
void t1_tp_set_ip_checksum_offload(struct petp *tp, int enable);
int t1_tp_set_coalescing_size(struct petp *tp, unsigned int size);
--
1.7.2.5
^ permalink raw reply related
* [PATCH] net: vxge: convert to hw_features
From: Michał Mirosław @ 2011-04-18 23:31 UTC (permalink / raw)
To: netdev; +Cc: Jon Mason
Side effect: ->gro_enable is removed as napi_gro_receive() does the
fallback itself.
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
drivers/net/vxge/vxge-ethtool.c | 72 ----------------------------
drivers/net/vxge/vxge-main.c | 100 +++++++++++++++++++++-----------------
drivers/net/vxge/vxge-main.h | 14 ++----
3 files changed, 59 insertions(+), 127 deletions(-)
diff --git a/drivers/net/vxge/vxge-ethtool.c b/drivers/net/vxge/vxge-ethtool.c
index 43c4583..5aef6c8 100644
--- a/drivers/net/vxge/vxge-ethtool.c
+++ b/drivers/net/vxge/vxge-ethtool.c
@@ -1071,35 +1071,6 @@ static int vxge_ethtool_get_regs_len(struct net_device *dev)
return sizeof(struct vxge_hw_vpath_reg) * vdev->no_of_vpath;
}
-static u32 vxge_get_rx_csum(struct net_device *dev)
-{
- struct vxgedev *vdev = netdev_priv(dev);
-
- return vdev->rx_csum;
-}
-
-static int vxge_set_rx_csum(struct net_device *dev, u32 data)
-{
- struct vxgedev *vdev = netdev_priv(dev);
-
- if (data)
- vdev->rx_csum = 1;
- else
- vdev->rx_csum = 0;
-
- return 0;
-}
-
-static int vxge_ethtool_op_set_tso(struct net_device *dev, u32 data)
-{
- if (data)
- dev->features |= (NETIF_F_TSO | NETIF_F_TSO6);
- else
- dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
-
- return 0;
-}
-
static int vxge_ethtool_get_sset_count(struct net_device *dev, int sset)
{
struct vxgedev *vdev = netdev_priv(dev);
@@ -1119,40 +1090,6 @@ static int vxge_ethtool_get_sset_count(struct net_device *dev, int sset)
}
}
-static int vxge_set_flags(struct net_device *dev, u32 data)
-{
- struct vxgedev *vdev = netdev_priv(dev);
- enum vxge_hw_status status;
-
- if (ethtool_invalid_flags(dev, data, ETH_FLAG_RXHASH))
- return -EINVAL;
-
- if (!!(data & ETH_FLAG_RXHASH) == vdev->devh->config.rth_en)
- return 0;
-
- if (netif_running(dev) || (vdev->config.rth_steering == NO_STEERING))
- return -EINVAL;
-
- vdev->devh->config.rth_en = !!(data & ETH_FLAG_RXHASH);
-
- /* Enabling RTH requires some of the logic in vxge_device_register and a
- * vpath reset. Due to these restrictions, only allow modification
- * while the interface is down.
- */
- status = vxge_reset_all_vpaths(vdev);
- if (status != VXGE_HW_OK) {
- vdev->devh->config.rth_en = !vdev->devh->config.rth_en;
- return -EFAULT;
- }
-
- if (vdev->devh->config.rth_en)
- dev->features |= NETIF_F_RXHASH;
- else
- dev->features &= ~NETIF_F_RXHASH;
-
- return 0;
-}
-
static int vxge_fw_flash(struct net_device *dev, struct ethtool_flash *parms)
{
struct vxgedev *vdev = netdev_priv(dev);
@@ -1181,19 +1118,10 @@ static const struct ethtool_ops vxge_ethtool_ops = {
.get_link = ethtool_op_get_link,
.get_pauseparam = vxge_ethtool_getpause_data,
.set_pauseparam = vxge_ethtool_setpause_data,
- .get_rx_csum = vxge_get_rx_csum,
- .set_rx_csum = vxge_set_rx_csum,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_ipv6_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
- .get_tso = ethtool_op_get_tso,
- .set_tso = vxge_ethtool_op_set_tso,
.get_strings = vxge_ethtool_get_strings,
.set_phys_id = vxge_ethtool_idnic,
.get_sset_count = vxge_ethtool_get_sset_count,
.get_ethtool_stats = vxge_get_ethtool_stats,
- .set_flags = vxge_set_flags,
.flash_device = vxge_fw_flash,
};
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
index d192dad..fc837cf 100644
--- a/drivers/net/vxge/vxge-main.c
+++ b/drivers/net/vxge/vxge-main.c
@@ -304,22 +304,14 @@ vxge_rx_complete(struct vxge_ring *ring, struct sk_buff *skb, u16 vlan,
"%s: %s:%d skb protocol = %d",
ring->ndev->name, __func__, __LINE__, skb->protocol);
- if (ring->gro_enable) {
- if (ring->vlgrp && ext_info->vlan &&
- (ring->vlan_tag_strip ==
- VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE))
- vlan_gro_receive(ring->napi_p, ring->vlgrp,
- ext_info->vlan, skb);
- else
- napi_gro_receive(ring->napi_p, skb);
- } else {
- if (ring->vlgrp && vlan &&
- (ring->vlan_tag_strip ==
- VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE))
- vlan_hwaccel_receive_skb(skb, ring->vlgrp, vlan);
- else
- netif_receive_skb(skb);
- }
+ if (ring->vlgrp && ext_info->vlan &&
+ (ring->vlan_tag_strip ==
+ VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE))
+ vlan_gro_receive(ring->napi_p, ring->vlgrp,
+ ext_info->vlan, skb);
+ else
+ napi_gro_receive(ring->napi_p, skb);
+
vxge_debug_entryexit(VXGE_TRACE,
"%s: %s:%d Exiting...", ring->ndev->name, __func__, __LINE__);
}
@@ -490,7 +482,7 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr,
if ((ext_info.proto & VXGE_HW_FRAME_PROTO_TCP_OR_UDP) &&
!(ext_info.proto & VXGE_HW_FRAME_PROTO_IP_FRAG) &&
- ring->rx_csum && /* Offload Rx side CSUM */
+ (dev->features & NETIF_F_RXCSUM) && /* Offload Rx side CSUM */
ext_info.l3_cksum == VXGE_HW_L3_CKSUM_OK &&
ext_info.l4_cksum == VXGE_HW_L4_CKSUM_OK)
skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -2094,11 +2086,9 @@ static int vxge_open_vpaths(struct vxgedev *vdev)
vdev->config.fifo_indicate_max_pkts;
vpath->fifo.tx_vector_no = 0;
vpath->ring.rx_vector_no = 0;
- vpath->ring.rx_csum = vdev->rx_csum;
vpath->ring.rx_hwts = vdev->rx_hwts;
vpath->is_open = 1;
vdev->vp_handles[i] = vpath->handle;
- vpath->ring.gro_enable = vdev->config.gro_enable;
vpath->ring.vlan_tag_strip = vdev->vlan_tag_strip;
vdev->stats.vpaths_open++;
} else {
@@ -2670,6 +2660,40 @@ static void vxge_poll_vp_lockup(unsigned long data)
mod_timer(&vdev->vp_lockup_timer, jiffies + HZ / 1000);
}
+static u32 vxge_fix_features(struct net_device *dev, u32 features)
+{
+ u32 changed = dev->features ^ features;
+
+ /* Enabling RTH requires some of the logic in vxge_device_register and a
+ * vpath reset. Due to these restrictions, only allow modification
+ * while the interface is down.
+ */
+ if ((changed & NETIF_F_RXHASH) && netif_running(dev))
+ features ^= NETIF_F_RXHASH;
+
+ return features;
+}
+
+static int vxge_set_features(struct net_device *dev, u32 features)
+{
+ struct vxgedev *vdev = netdev_priv(dev);
+ u32 changed = dev->features ^ features;
+
+ if (!(changed & NETIF_F_RXHASH))
+ return 0;
+
+ /* !netif_running() ensured by vxge_fix_features() */
+
+ vdev->devh->config.rth_en = !!(features & NETIF_F_RXHASH);
+ if (vxge_reset_all_vpaths(vdev) != VXGE_HW_OK) {
+ dev->features = features ^ NETIF_F_RXHASH;
+ vdev->devh->config.rth_en = !!(dev->features & NETIF_F_RXHASH);
+ return -EIO;
+ }
+
+ return 0;
+}
+
/**
* vxge_open
* @dev: pointer to the device structure.
@@ -3369,6 +3393,8 @@ static const struct net_device_ops vxge_netdev_ops = {
.ndo_do_ioctl = vxge_ioctl,
.ndo_set_mac_address = vxge_set_mac_addr,
.ndo_change_mtu = vxge_change_mtu,
+ .ndo_fix_features = vxge_fix_features,
+ .ndo_set_features = vxge_set_features,
.ndo_vlan_rx_register = vxge_vlan_rx_register,
.ndo_vlan_rx_kill_vid = vxge_vlan_rx_kill_vid,
.ndo_vlan_rx_add_vid = vxge_vlan_rx_add_vid,
@@ -3415,14 +3441,21 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev,
vdev->devh = hldev;
vdev->pdev = hldev->pdev;
memcpy(&vdev->config, config, sizeof(struct vxge_config));
- vdev->rx_csum = 1; /* Enable Rx CSUM by default. */
vdev->rx_hwts = 0;
vdev->titan1 = (vdev->pdev->revision == VXGE_HW_TITAN1_PCI_REVISION);
SET_NETDEV_DEV(ndev, &vdev->pdev->dev);
- ndev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
- NETIF_F_HW_VLAN_FILTER;
+ ndev->hw_features = NETIF_F_RXCSUM | NETIF_F_SG |
+ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+ NETIF_F_TSO | NETIF_F_TSO6 |
+ NETIF_F_HW_VLAN_TX;
+ if (vdev->config.rth_steering != NO_STEERING)
+ ndev->hw_features |= NETIF_F_RXHASH;
+
+ ndev->features |= ndev->hw_features |
+ NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
+
/* Driver entry points */
ndev->irq = vdev->pdev->irq;
ndev->base_addr = (unsigned long) hldev->bar0;
@@ -3434,11 +3467,6 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev,
vxge_initialize_ethtool_ops(ndev);
- if (vdev->config.rth_steering != NO_STEERING) {
- ndev->features |= NETIF_F_RXHASH;
- hldev->config.rth_en = VXGE_HW_RTH_ENABLE;
- }
-
/* Allocate memory for vpath */
vdev->vpaths = kzalloc((sizeof(struct vxge_vpath)) *
no_of_vpath, GFP_KERNEL);
@@ -3450,9 +3478,6 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev,
goto _out1;
}
- ndev->features |= NETIF_F_SG;
-
- ndev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
vxge_debug_init(vxge_hw_device_trace_level_get(hldev),
"%s : checksuming enabled", __func__);
@@ -3462,11 +3487,6 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev,
"%s : using High DMA", __func__);
}
- ndev->features |= NETIF_F_TSO | NETIF_F_TSO6;
-
- if (vdev->config.gro_enable)
- ndev->features |= NETIF_F_GRO;
-
ret = register_netdev(ndev);
if (ret) {
vxge_debug_init(vxge_hw_device_trace_level_get(hldev),
@@ -3996,15 +4016,6 @@ static void __devinit vxge_print_parm(struct vxgedev *vdev, u64 vpath_mask)
vdev->config.tx_steering_type = 0;
}
- if (vdev->config.gro_enable) {
- vxge_debug_init(VXGE_ERR,
- "%s: Generic receive offload enabled",
- vdev->ndev->name);
- } else
- vxge_debug_init(VXGE_TRACE,
- "%s: Generic receive offload disabled",
- vdev->ndev->name);
-
if (vdev->config.addr_learn_en)
vxge_debug_init(VXGE_TRACE,
"%s: MAC Address learning enabled", vdev->ndev->name);
@@ -4589,7 +4600,6 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
/* set private device info */
pci_set_drvdata(pdev, hldev);
- ll_config->gro_enable = VXGE_GRO_ALWAYS_AGGREGATE;
ll_config->fifo_indicate_max_pkts = VXGE_FIFO_INDICATE_MAX_PKTS;
ll_config->addr_learn_en = addr_learn_en;
ll_config->rth_algorithm = RTH_ALG_JENKINS;
diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h
index 40474f0..ed120ab 100644
--- a/drivers/net/vxge/vxge-main.h
+++ b/drivers/net/vxge/vxge-main.h
@@ -168,9 +168,6 @@ struct vxge_config {
#define NEW_NAPI_WEIGHT 64
int napi_weight;
-#define VXGE_GRO_DONOT_AGGREGATE 0
-#define VXGE_GRO_ALWAYS_AGGREGATE 1
- int gro_enable;
int intr_type;
#define INTA 0
#define MSI 1
@@ -290,13 +287,11 @@ struct vxge_ring {
unsigned long interrupt_count;
unsigned long jiffies;
- /* copy of the flag indicating whether rx_csum is to be used */
- u32 rx_csum:1,
- rx_hwts:1;
+ /* copy of the flag indicating whether rx_hwts is to be used */
+ u32 rx_hwts:1;
int pkts_processed;
int budget;
- int gro_enable;
struct napi_struct napi;
struct napi_struct *napi_p;
@@ -369,9 +364,8 @@ struct vxgedev {
*/
u16 all_multi_flg;
- /* A flag indicating whether rx_csum is to be used or not. */
- u32 rx_csum:1,
- rx_hwts:1,
+ /* A flag indicating whether rx_hwts is to be used or not. */
+ u32 rx_hwts:1,
titan1:1;
struct vxge_msix_entry *vxge_entries;
--
1.7.2.5
^ permalink raw reply related
* [PATCH] net: fix section mismatches
From: Michał Mirosław @ 2011-04-18 23:31 UTC (permalink / raw)
To: netdev
Cc: Steffen Klassert, Jaroslav Kysela, Samuel Ortiz, Grant Grundler,
David Miller
Fix build warnings like the following:
WARNING: drivers/net/built-in.o(.data+0x12434): Section mismatch in reference from the variable madgemc_driver to the variable .init.data:madgemc_adapter_ids
And add some consts to EISA device ID tables along the way.
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
This is what I now use to keep all those section mismatch warnings from
clobbering my build log that kept me from noticing more important warnings.
Please accept or ignore as you see fit.
Thanks,
Michał Mirosław
---
drivers/net/3c509.c | 14 ++++++------
drivers/net/3c59x.c | 4 +-
drivers/net/depca.c | 35 ++++++++++++++++---------------
drivers/net/hp100.c | 12 +++++-----
drivers/net/ibmlana.c | 4 +-
drivers/net/irda/smsc-ircc2.c | 44 +++++++++++++++++++-------------------
drivers/net/ne3210.c | 15 ++++++++-----
drivers/net/smc-mca.c | 6 ++--
drivers/net/tokenring/madgemc.c | 2 +-
drivers/net/tulip/de4x5.c | 4 +-
10 files changed, 72 insertions(+), 68 deletions(-)
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
index 91abb96..cb39ded 100644
--- a/drivers/net/3c509.c
+++ b/drivers/net/3c509.c
@@ -185,7 +185,7 @@ static int max_interrupt_work = 10;
static int nopnp;
#endif
-static int __devinit el3_common_init(struct net_device *dev);
+static int el3_common_init(struct net_device *dev);
static void el3_common_remove(struct net_device *dev);
static ushort id_read_eeprom(int index);
static ushort read_eeprom(int ioaddr, int index);
@@ -395,7 +395,7 @@ static struct isa_driver el3_isa_driver = {
static int isa_registered;
#ifdef CONFIG_PNP
-static struct pnp_device_id el3_pnp_ids[] = {
+static const struct pnp_device_id el3_pnp_ids[] __devinitconst = {
{ .id = "TCM5090" }, /* 3Com Etherlink III (TP) */
{ .id = "TCM5091" }, /* 3Com Etherlink III */
{ .id = "TCM5094" }, /* 3Com Etherlink III (combo) */
@@ -478,7 +478,7 @@ static int pnp_registered;
#endif /* CONFIG_PNP */
#ifdef CONFIG_EISA
-static struct eisa_device_id el3_eisa_ids[] = {
+static const struct eisa_device_id el3_eisa_ids[] __devinitconst = {
{ "TCM5090" },
{ "TCM5091" },
{ "TCM5092" },
@@ -508,7 +508,7 @@ static int eisa_registered;
#ifdef CONFIG_MCA
static int el3_mca_probe(struct device *dev);
-static short el3_mca_adapter_ids[] __initdata = {
+static const short el3_mca_adapter_ids[] __devinitconst = {
0x627c,
0x627d,
0x62db,
@@ -517,7 +517,7 @@ static short el3_mca_adapter_ids[] __initdata = {
0x0000
};
-static char *el3_mca_adapter_names[] __initdata = {
+static const char *const el3_mca_adapter_names[] __devinitconst = {
"3Com 3c529 EtherLink III (10base2)",
"3Com 3c529 EtherLink III (10baseT)",
"3Com 3c529 EtherLink III (test mode)",
@@ -601,7 +601,7 @@ static void el3_common_remove (struct net_device *dev)
}
#ifdef CONFIG_MCA
-static int __init el3_mca_probe(struct device *device)
+static int __devinit el3_mca_probe(struct device *device)
{
/* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch,
* heavily modified by Chris Beauregard
@@ -671,7 +671,7 @@ static int __init el3_mca_probe(struct device *device)
#endif /* CONFIG_MCA */
#ifdef CONFIG_EISA
-static int __init el3_eisa_probe (struct device *device)
+static int __devinit el3_eisa_probe (struct device *device)
{
short i;
int ioaddr, irq, if_port;
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 8cc2256..99f43d2 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -901,14 +901,14 @@ static const struct dev_pm_ops vortex_pm_ops = {
#endif /* !CONFIG_PM */
#ifdef CONFIG_EISA
-static struct eisa_device_id vortex_eisa_ids[] = {
+static const struct eisa_device_id vortex_eisa_ids[] __devinitconst = {
{ "TCM5920", CH_3C592 },
{ "TCM5970", CH_3C597 },
{ "" }
};
MODULE_DEVICE_TABLE(eisa, vortex_eisa_ids);
-static int __init vortex_eisa_probe(struct device *device)
+static int __devinit vortex_eisa_probe(struct device *device)
{
void __iomem *ioaddr;
struct eisa_device *edev;
diff --git a/drivers/net/depca.c b/drivers/net/depca.c
index 8b0084d..1765405 100644
--- a/drivers/net/depca.c
+++ b/drivers/net/depca.c
@@ -331,18 +331,18 @@ static struct {
"DE422",\
""}
-static char* __initdata depca_signature[] = DEPCA_SIGNATURE;
+static const char* const depca_signature[] __devinitconst = DEPCA_SIGNATURE;
enum depca_type {
DEPCA, de100, de101, de200, de201, de202, de210, de212, de422, unknown
};
-static char depca_string[] = "depca";
+static const char depca_string[] = "depca";
static int depca_device_remove (struct device *device);
#ifdef CONFIG_EISA
-static struct eisa_device_id depca_eisa_ids[] = {
+static const struct eisa_device_id depca_eisa_ids[] __devinitconst = {
{ "DEC4220", de422 },
{ "" }
};
@@ -367,19 +367,19 @@ static struct eisa_driver depca_eisa_driver = {
#define DE210_ID 0x628d
#define DE212_ID 0x6def
-static short depca_mca_adapter_ids[] = {
+static const short depca_mca_adapter_ids[] __devinitconst = {
DE210_ID,
DE212_ID,
0x0000
};
-static char *depca_mca_adapter_name[] = {
+static const char *depca_mca_adapter_name[] = {
"DEC EtherWORKS MC Adapter (DE210)",
"DEC EtherWORKS MC Adapter (DE212)",
NULL
};
-static enum depca_type depca_mca_adapter_type[] = {
+static const enum depca_type depca_mca_adapter_type[] = {
de210,
de212,
0
@@ -541,10 +541,9 @@ static void SetMulticastFilter(struct net_device *dev);
static int load_packet(struct net_device *dev, struct sk_buff *skb);
static void depca_dbg_open(struct net_device *dev);
-static u_char de1xx_irq[] __initdata = { 2, 3, 4, 5, 7, 9, 0 };
-static u_char de2xx_irq[] __initdata = { 5, 9, 10, 11, 15, 0 };
-static u_char de422_irq[] __initdata = { 5, 9, 10, 11, 0 };
-static u_char *depca_irq;
+static const u_char de1xx_irq[] __devinitconst = { 2, 3, 4, 5, 7, 9, 0 };
+static const u_char de2xx_irq[] __devinitconst = { 5, 9, 10, 11, 15, 0 };
+static const u_char de422_irq[] __devinitconst = { 5, 9, 10, 11, 0 };
static int irq;
static int io;
@@ -580,7 +579,7 @@ static const struct net_device_ops depca_netdev_ops = {
.ndo_validate_addr = eth_validate_addr,
};
-static int __init depca_hw_init (struct net_device *dev, struct device *device)
+static int __devinit depca_hw_init (struct net_device *dev, struct device *device)
{
struct depca_private *lp;
int i, j, offset, netRAM, mem_len, status = 0;
@@ -748,6 +747,7 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device)
if (dev->irq < 2) {
unsigned char irqnum;
unsigned long irq_mask, delay;
+ const u_char *depca_irq;
irq_mask = probe_irq_on();
@@ -770,6 +770,7 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device)
break;
default:
+ depca_irq = NULL;
break; /* Not reached */
}
@@ -1302,7 +1303,7 @@ static void SetMulticastFilter(struct net_device *dev)
}
}
-static int __init depca_common_init (u_long ioaddr, struct net_device **devp)
+static int __devinit depca_common_init (u_long ioaddr, struct net_device **devp)
{
int status = 0;
@@ -1333,7 +1334,7 @@ static int __init depca_common_init (u_long ioaddr, struct net_device **devp)
/*
** Microchannel bus I/O device probe
*/
-static int __init depca_mca_probe(struct device *device)
+static int __devinit depca_mca_probe(struct device *device)
{
unsigned char pos[2];
unsigned char where;
@@ -1457,7 +1458,7 @@ static int __init depca_mca_probe(struct device *device)
** ISA bus I/O device probe
*/
-static void __init depca_platform_probe (void)
+static void __devinit depca_platform_probe (void)
{
int i;
struct platform_device *pldev;
@@ -1497,7 +1498,7 @@ static void __init depca_platform_probe (void)
}
}
-static enum depca_type __init depca_shmem_probe (ulong *mem_start)
+static enum depca_type __devinit depca_shmem_probe (ulong *mem_start)
{
u_long mem_base[] = DEPCA_RAM_BASE_ADDRESSES;
enum depca_type adapter = unknown;
@@ -1558,7 +1559,7 @@ static int __devinit depca_isa_probe (struct platform_device *device)
*/
#ifdef CONFIG_EISA
-static int __init depca_eisa_probe (struct device *device)
+static int __devinit depca_eisa_probe (struct device *device)
{
enum depca_type adapter = unknown;
struct eisa_device *edev;
@@ -1629,7 +1630,7 @@ static int __devexit depca_device_remove (struct device *device)
** and Boot (readb) ROM. This will also give us a clue to the network RAM
** base address.
*/
-static int __init DepcaSignature(char *name, u_long base_addr)
+static int __devinit DepcaSignature(char *name, u_long base_addr)
{
u_int i, j, k;
void __iomem *ptr;
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
index 8e10d2f..c52a1df 100644
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -188,14 +188,14 @@ struct hp100_private {
* variables
*/
#ifdef CONFIG_ISA
-static const char *hp100_isa_tbl[] = {
+static const char *const hp100_isa_tbl[] __devinitconst = {
"HWPF150", /* HP J2573 rev A */
"HWP1950", /* HP J2573 */
};
#endif
#ifdef CONFIG_EISA
-static struct eisa_device_id hp100_eisa_tbl[] = {
+static const struct eisa_device_id hp100_eisa_tbl[] __devinitconst = {
{ "HWPF180" }, /* HP J2577 rev A */
{ "HWP1920" }, /* HP 27248B */
{ "HWP1940" }, /* HP J2577 */
@@ -336,7 +336,7 @@ static __devinit const char *hp100_read_id(int ioaddr)
}
#ifdef CONFIG_ISA
-static __init int hp100_isa_probe1(struct net_device *dev, int ioaddr)
+static __devinit int hp100_isa_probe1(struct net_device *dev, int ioaddr)
{
const char *sig;
int i;
@@ -372,7 +372,7 @@ static __init int hp100_isa_probe1(struct net_device *dev, int ioaddr)
* EISA and PCI are handled by device infrastructure.
*/
-static int __init hp100_isa_probe(struct net_device *dev, int addr)
+static int __devinit hp100_isa_probe(struct net_device *dev, int addr)
{
int err = -ENODEV;
@@ -396,7 +396,7 @@ static int __init hp100_isa_probe(struct net_device *dev, int addr)
#endif /* CONFIG_ISA */
#if !defined(MODULE) && defined(CONFIG_ISA)
-struct net_device * __init hp100_probe(int unit)
+struct net_device * __devinit hp100_probe(int unit)
{
struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private));
int err;
@@ -2843,7 +2843,7 @@ static void cleanup_dev(struct net_device *d)
}
#ifdef CONFIG_EISA
-static int __init hp100_eisa_probe (struct device *gendev)
+static int __devinit hp100_eisa_probe (struct device *gendev)
{
struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private));
struct eisa_device *edev = to_eisa_device(gendev);
diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c
index a7d6cad..136d754 100644
--- a/drivers/net/ibmlana.c
+++ b/drivers/net/ibmlana.c
@@ -895,12 +895,12 @@ static int ibmlana_irq;
static int ibmlana_io;
static int startslot; /* counts through slots when probing multiple devices */
-static short ibmlana_adapter_ids[] __initdata = {
+static const short ibmlana_adapter_ids[] __devinitconst = {
IBM_LANA_ID,
0x0000
};
-static char *ibmlana_adapter_names[] __devinitdata = {
+static const char *const ibmlana_adapter_names[] __devinitconst = {
"IBM LAN Adapter/A",
NULL
};
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
index 8800e1f..69b5707 100644
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -222,19 +222,19 @@ static void smsc_ircc_set_transceiver_for_speed(struct smsc_ircc_cb *self, u32 s
static void smsc_ircc_sir_wait_hw_transmitter_finish(struct smsc_ircc_cb *self);
/* Probing */
-static int __init smsc_ircc_look_for_chips(void);
-static const struct smsc_chip * __init smsc_ircc_probe(unsigned short cfg_base, u8 reg, const struct smsc_chip *chip, char *type);
-static int __init smsc_superio_flat(const struct smsc_chip *chips, unsigned short cfg_base, char *type);
-static int __init smsc_superio_paged(const struct smsc_chip *chips, unsigned short cfg_base, char *type);
-static int __init smsc_superio_fdc(unsigned short cfg_base);
-static int __init smsc_superio_lpc(unsigned short cfg_base);
+static int smsc_ircc_look_for_chips(void);
+static const struct smsc_chip * smsc_ircc_probe(unsigned short cfg_base, u8 reg, const struct smsc_chip *chip, char *type);
+static int smsc_superio_flat(const struct smsc_chip *chips, unsigned short cfg_base, char *type);
+static int smsc_superio_paged(const struct smsc_chip *chips, unsigned short cfg_base, char *type);
+static int smsc_superio_fdc(unsigned short cfg_base);
+static int smsc_superio_lpc(unsigned short cfg_base);
#ifdef CONFIG_PCI
-static int __init preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuration *conf);
-static int __init preconfigure_through_82801(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf);
-static void __init preconfigure_ali_port(struct pci_dev *dev,
+static int preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuration *conf);
+static int preconfigure_through_82801(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf);
+static void preconfigure_ali_port(struct pci_dev *dev,
unsigned short port);
-static int __init preconfigure_through_ali(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf);
-static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg,
+static int preconfigure_through_ali(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf);
+static int smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg,
unsigned short ircc_fir,
unsigned short ircc_sir,
unsigned char ircc_dma,
@@ -366,7 +366,7 @@ static inline void register_bank(int iobase, int bank)
}
/* PNP hotplug support */
-static const struct pnp_device_id smsc_ircc_pnp_table[] = {
+static const struct pnp_device_id smsc_ircc_pnp_table[] __devinitconst = {
{ .id = "SMCf010", .driver_data = 0 },
/* and presumably others */
{ }
@@ -515,7 +515,7 @@ static const struct net_device_ops smsc_ircc_netdev_ops = {
* Try to open driver instance
*
*/
-static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u8 dma, u8 irq)
+static int __devinit smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u8 dma, u8 irq)
{
struct smsc_ircc_cb *self;
struct net_device *dev;
@@ -2273,7 +2273,7 @@ static int __init smsc_superio_paged(const struct smsc_chip *chips, unsigned sho
}
-static int __init smsc_access(unsigned short cfg_base, unsigned char reg)
+static int __devinit smsc_access(unsigned short cfg_base, unsigned char reg)
{
IRDA_DEBUG(1, "%s\n", __func__);
@@ -2281,7 +2281,7 @@ static int __init smsc_access(unsigned short cfg_base, unsigned char reg)
return inb(cfg_base) != reg ? -1 : 0;
}
-static const struct smsc_chip * __init smsc_ircc_probe(unsigned short cfg_base, u8 reg, const struct smsc_chip *chip, char *type)
+static const struct smsc_chip * __devinit smsc_ircc_probe(unsigned short cfg_base, u8 reg, const struct smsc_chip *chip, char *type)
{
u8 devid, xdevid, rev;
@@ -2406,7 +2406,7 @@ static int __init smsc_superio_lpc(unsigned short cfg_base)
#ifdef CONFIG_PCI
#define PCIID_VENDOR_INTEL 0x8086
#define PCIID_VENDOR_ALI 0x10b9
-static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __initdata = {
+static const struct smsc_ircc_subsystem_configuration subsystem_configurations[] __devinitconst = {
/*
* Subsystems needing entries:
* 0x10b9:0x1533 0x103c:0x0850 HP nx9010 family
@@ -2532,7 +2532,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini
* (FIR port, SIR port, FIR DMA, FIR IRQ)
* through the chip configuration port.
*/
-static int __init preconfigure_smsc_chip(struct
+static int __devinit preconfigure_smsc_chip(struct
smsc_ircc_subsystem_configuration
*conf)
{
@@ -2633,7 +2633,7 @@ static int __init preconfigure_smsc_chip(struct
* or Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge.
* They all work the same way!
*/
-static int __init preconfigure_through_82801(struct pci_dev *dev,
+static int __devinit preconfigure_through_82801(struct pci_dev *dev,
struct
smsc_ircc_subsystem_configuration
*conf)
@@ -2786,7 +2786,7 @@ static int __init preconfigure_through_82801(struct pci_dev *dev,
* This is based on reverse-engineering since ALi does not
* provide any data sheet for the 1533 chip.
*/
-static void __init preconfigure_ali_port(struct pci_dev *dev,
+static void __devinit preconfigure_ali_port(struct pci_dev *dev,
unsigned short port)
{
unsigned char reg;
@@ -2824,7 +2824,7 @@ static void __init preconfigure_ali_port(struct pci_dev *dev,
IRDA_MESSAGE("Activated ALi 1533 ISA bridge port 0x%04x.\n", port);
}
-static int __init preconfigure_through_ali(struct pci_dev *dev,
+static int __devinit preconfigure_through_ali(struct pci_dev *dev,
struct
smsc_ircc_subsystem_configuration
*conf)
@@ -2837,7 +2837,7 @@ static int __init preconfigure_through_ali(struct pci_dev *dev,
return preconfigure_smsc_chip(conf);
}
-static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg,
+static int __devinit smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg,
unsigned short ircc_fir,
unsigned short ircc_sir,
unsigned char ircc_dma,
@@ -2849,7 +2849,7 @@ static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg,
int ret = 0;
for_each_pci_dev(dev) {
- struct smsc_ircc_subsystem_configuration *conf;
+ const struct smsc_ircc_subsystem_configuration *conf;
/*
* Cache the subsystem vendor/device:
diff --git a/drivers/net/ne3210.c b/drivers/net/ne3210.c
index 243ed2a..e8984b0 100644
--- a/drivers/net/ne3210.c
+++ b/drivers/net/ne3210.c
@@ -80,17 +80,20 @@ static void ne3210_block_output(struct net_device *dev, int count, const unsigne
#define NE3210_DEBUG 0x0
-static unsigned char irq_map[] __initdata = {15, 12, 11, 10, 9, 7, 5, 3};
-static unsigned int shmem_map[] __initdata = {0xff0, 0xfe0, 0xfff0, 0xd8, 0xffe0, 0xffc0, 0xd0, 0x0};
-static const char *ifmap[] __initdata = {"UTP", "?", "BNC", "AUI"};
-static int ifmap_val[] __initdata = {
+static const unsigned char irq_map[] __devinitconst =
+ { 15, 12, 11, 10, 9, 7, 5, 3 };
+static const unsigned int shmem_map[] __devinitconst =
+ { 0xff0, 0xfe0, 0xfff0, 0xd8, 0xffe0, 0xffc0, 0xd0, 0x0 };
+static const char *const ifmap[] __devinitconst =
+ { "UTP", "?", "BNC", "AUI" };
+static const int ifmap_val[] __devinitconst = {
IF_PORT_10BASET,
IF_PORT_UNKNOWN,
IF_PORT_10BASE2,
IF_PORT_AUI,
};
-static int __init ne3210_eisa_probe (struct device *device)
+static int __devinit ne3210_eisa_probe (struct device *device)
{
unsigned long ioaddr, phys_mem;
int i, retval, port_index;
@@ -313,7 +316,7 @@ static void ne3210_block_output(struct net_device *dev, int count,
memcpy_toio(shmem, buf, count);
}
-static struct eisa_device_id ne3210_ids[] = {
+static const struct eisa_device_id ne3210_ids[] __devinitconst = {
{ "EGL0101" },
{ "NVL1801" },
{ "" },
diff --git a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c
index d07c39c..0f29f26 100644
--- a/drivers/net/smc-mca.c
+++ b/drivers/net/smc-mca.c
@@ -156,7 +156,7 @@ static const struct {
{ 14, 15 }
};
-static short smc_mca_adapter_ids[] __initdata = {
+static const short smc_mca_adapter_ids[] __devinitconst = {
0x61c8,
0x61c9,
0x6fc0,
@@ -168,7 +168,7 @@ static short smc_mca_adapter_ids[] __initdata = {
0x0000
};
-static char *smc_mca_adapter_names[] __initdata = {
+static const char *const smc_mca_adapter_names[] __devinitconst = {
"SMC Ethercard PLUS Elite/A BNC/AUI (WD8013EP/A)",
"SMC Ethercard PLUS Elite/A UTP/AUI (WD8013WP/A)",
"WD Ethercard PLUS/A (WD8003E/A or WD8003ET/A)",
@@ -199,7 +199,7 @@ static const struct net_device_ops ultramca_netdev_ops = {
#endif
};
-static int __init ultramca_probe(struct device *gen_dev)
+static int __devinit ultramca_probe(struct device *gen_dev)
{
unsigned short ioaddr;
struct net_device *dev;
diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c
index 2bedc0a..1313aa1 100644
--- a/drivers/net/tokenring/madgemc.c
+++ b/drivers/net/tokenring/madgemc.c
@@ -727,7 +727,7 @@ static int __devexit madgemc_remove(struct device *device)
return 0;
}
-static short madgemc_adapter_ids[] __initdata = {
+static const short madgemc_adapter_ids[] __devinitconst = {
0x002d,
0x0000
};
diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
index efaa1d6..45144d5 100644
--- a/drivers/net/tulip/de4x5.c
+++ b/drivers/net/tulip/de4x5.c
@@ -1995,7 +1995,7 @@ SetMulticastFilter(struct net_device *dev)
static u_char de4x5_irq[] = EISA_ALLOWED_IRQ_LIST;
-static int __init de4x5_eisa_probe (struct device *gendev)
+static int __devinit de4x5_eisa_probe (struct device *gendev)
{
struct eisa_device *edev;
u_long iobase;
@@ -2097,7 +2097,7 @@ static int __devexit de4x5_eisa_remove (struct device *device)
return 0;
}
-static struct eisa_device_id de4x5_eisa_ids[] = {
+static const struct eisa_device_id de4x5_eisa_ids[] __devinitconst = {
{ "DEC4250", 0 }, /* 0 is the board name index... */
{ "" }
};
--
1.7.2.5
^ permalink raw reply related
* [PATCH] net: vmxnet3: convert to hw_features
From: Michał Mirosław @ 2011-04-18 23:31 UTC (permalink / raw)
To: netdev; +Cc: Shreyas Bhatewara, VMware, Inc.
This also removes private feature flags that were always set to true.
You may want to move vmxnet3_set_features() to vmxnet3_drv.c as a following
cleanup.
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
drivers/net/vmxnet3/vmxnet3_drv.c | 40 +++++++-------------
drivers/net/vmxnet3/vmxnet3_ethtool.c | 67 +++++---------------------------
drivers/net/vmxnet3/vmxnet3_int.h | 7 +--
3 files changed, 28 insertions(+), 86 deletions(-)
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index 0d47c3a..7a494f7 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -1082,7 +1082,7 @@ vmxnet3_rx_csum(struct vmxnet3_adapter *adapter,
struct sk_buff *skb,
union Vmxnet3_GenericDesc *gdesc)
{
- if (!gdesc->rcd.cnc && adapter->rxcsum) {
+ if (!gdesc->rcd.cnc && adapter->netdev->features & NETIF_F_RXCSUM) {
/* typical case: TCP/UDP over IP and both csums are correct */
if ((le32_to_cpu(gdesc->dword[3]) & VMXNET3_RCD_CSUM_OK) ==
VMXNET3_RCD_CSUM_OK) {
@@ -2081,10 +2081,10 @@ vmxnet3_setup_driver_shared(struct vmxnet3_adapter *adapter)
devRead->misc.ddLen = cpu_to_le32(sizeof(struct vmxnet3_adapter));
/* set up feature flags */
- if (adapter->rxcsum)
+ if (adapter->netdev->features & NETIF_F_RXCSUM)
devRead->misc.uptFeatures |= UPT1_F_RXCSUM;
- if (adapter->lro) {
+ if (adapter->netdev->features & NETIF_F_LRO) {
devRead->misc.uptFeatures |= UPT1_F_LRO;
devRead->misc.maxNumRxSG = cpu_to_le16(1 + MAX_SKB_FRAGS);
}
@@ -2593,9 +2593,6 @@ vmxnet3_change_mtu(struct net_device *netdev, int new_mtu)
if (new_mtu < VMXNET3_MIN_MTU || new_mtu > VMXNET3_MAX_MTU)
return -EINVAL;
- if (new_mtu > 1500 && !adapter->jumbo_frame)
- return -EINVAL;
-
netdev->mtu = new_mtu;
/*
@@ -2641,28 +2638,18 @@ vmxnet3_declare_features(struct vmxnet3_adapter *adapter, bool dma64)
{
struct net_device *netdev = adapter->netdev;
- netdev->features = NETIF_F_SG |
- NETIF_F_HW_CSUM |
- NETIF_F_HW_VLAN_TX |
- NETIF_F_HW_VLAN_RX |
- NETIF_F_HW_VLAN_FILTER |
- NETIF_F_TSO |
- NETIF_F_TSO6 |
- NETIF_F_LRO;
-
- printk(KERN_INFO "features: sg csum vlan jf tso tsoIPv6 lro");
-
- adapter->rxcsum = true;
- adapter->jumbo_frame = true;
- adapter->lro = true;
-
- if (dma64) {
+ netdev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM |
+ NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_TX |
+ NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_LRO;
+ if (dma64)
netdev->features |= NETIF_F_HIGHDMA;
- printk(" highDMA");
- }
+ netdev->vlan_features = netdev->hw_features & ~NETIF_F_HW_VLAN_TX;
+ netdev->features = netdev->hw_features |
+ NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
- netdev->vlan_features = netdev->features;
- printk("\n");
+ netdev_info(adapter->netdev,
+ "features: sg csum vlan jf tso tsoIPv6 lro%s\n",
+ dma64 ? " highDMA" : "");
}
@@ -2874,6 +2861,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
.ndo_start_xmit = vmxnet3_xmit_frame,
.ndo_set_mac_address = vmxnet3_set_mac_addr,
.ndo_change_mtu = vmxnet3_change_mtu,
+ .ndo_set_features = vmxnet3_set_features,
.ndo_get_stats = vmxnet3_get_stats,
.ndo_tx_timeout = vmxnet3_tx_timeout,
.ndo_set_multicast_list = vmxnet3_set_mc,
diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c
index 51f2ef1..70c1ab9 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethtool.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c
@@ -33,40 +33,6 @@ struct vmxnet3_stat_desc {
};
-static u32
-vmxnet3_get_rx_csum(struct net_device *netdev)
-{
- struct vmxnet3_adapter *adapter = netdev_priv(netdev);
- return adapter->rxcsum;
-}
-
-
-static int
-vmxnet3_set_rx_csum(struct net_device *netdev, u32 val)
-{
- struct vmxnet3_adapter *adapter = netdev_priv(netdev);
- unsigned long flags;
-
- if (adapter->rxcsum != val) {
- adapter->rxcsum = val;
- if (netif_running(netdev)) {
- if (val)
- adapter->shared->devRead.misc.uptFeatures |=
- UPT1_F_RXCSUM;
- else
- adapter->shared->devRead.misc.uptFeatures &=
- ~UPT1_F_RXCSUM;
-
- spin_lock_irqsave(&adapter->cmd_lock, flags);
- VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
- VMXNET3_CMD_UPDATE_FEATURE);
- spin_unlock_irqrestore(&adapter->cmd_lock, flags);
- }
- }
- return 0;
-}
-
-
/* per tq stats maintained by the device */
static const struct vmxnet3_stat_desc
vmxnet3_tq_dev_stats[] = {
@@ -296,28 +262,27 @@ vmxnet3_get_strings(struct net_device *netdev, u32 stringset, u8 *buf)
}
}
-static int
-vmxnet3_set_flags(struct net_device *netdev, u32 data)
+int vmxnet3_set_features(struct net_device *netdev, u32 features)
{
struct vmxnet3_adapter *adapter = netdev_priv(netdev);
- u8 lro_requested = (data & ETH_FLAG_LRO) == 0 ? 0 : 1;
- u8 lro_present = (netdev->features & NETIF_F_LRO) == 0 ? 0 : 1;
unsigned long flags;
+ u32 changed = features ^ netdev->features;
- if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO))
- return -EINVAL;
+ if (changed & (NETIF_F_RXCSUM|NETIF_F_LRO)) {
+ if (features & NETIF_F_RXCSUM)
+ adapter->shared->devRead.misc.uptFeatures |=
+ UPT1_F_RXCSUM;
+ else
+ adapter->shared->devRead.misc.uptFeatures &=
+ ~UPT1_F_RXCSUM;
- if (lro_requested ^ lro_present) {
- /* toggle the LRO feature*/
- netdev->features ^= NETIF_F_LRO;
-
- /* update harware LRO capability accordingly */
- if (lro_requested)
+ if (features & NETIF_F_LRO)
adapter->shared->devRead.misc.uptFeatures |=
UPT1_F_LRO;
else
adapter->shared->devRead.misc.uptFeatures &=
~UPT1_F_LRO;
+
spin_lock_irqsave(&adapter->cmd_lock, flags);
VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
VMXNET3_CMD_UPDATE_FEATURE);
@@ -654,17 +619,7 @@ static struct ethtool_ops vmxnet3_ethtool_ops = {
.get_wol = vmxnet3_get_wol,
.set_wol = vmxnet3_set_wol,
.get_link = ethtool_op_get_link,
- .get_rx_csum = vmxnet3_get_rx_csum,
- .set_rx_csum = vmxnet3_set_rx_csum,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_hw_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
- .get_tso = ethtool_op_get_tso,
- .set_tso = ethtool_op_set_tso,
.get_strings = vmxnet3_get_strings,
- .get_flags = ethtool_op_get_flags,
- .set_flags = vmxnet3_set_flags,
.get_sset_count = vmxnet3_get_sset_count,
.get_ethtool_stats = vmxnet3_get_ethtool_stats,
.get_ringparam = vmxnet3_get_ringparam,
diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h
index fb5d245..8ba7b5f 100644
--- a/drivers/net/vmxnet3/vmxnet3_int.h
+++ b/drivers/net/vmxnet3/vmxnet3_int.h
@@ -329,10 +329,6 @@ struct vmxnet3_adapter {
u8 __iomem *hw_addr0; /* for BAR 0 */
u8 __iomem *hw_addr1; /* for BAR 1 */
- /* feature control */
- bool rxcsum;
- bool lro;
- bool jumbo_frame;
#ifdef VMXNET3_RSS
struct UPT1_RSSConf *rss_conf;
bool rss;
@@ -404,6 +400,9 @@ void
vmxnet3_rq_destroy_all(struct vmxnet3_adapter *adapter);
int
+vmxnet3_set_features(struct net_device *netdev, u32 features);
+
+int
vmxnet3_create_queues(struct vmxnet3_adapter *adapter,
u32 tx_ring_size, u32 rx_ring_size, u32 rx_ring2_size);
--
1.7.2.5
^ permalink raw reply related
* Re: net: Automatic IRQ siloing for network devices
From: Neil Horman @ 2011-04-19 0:52 UTC (permalink / raw)
To: Ben Hutchings
Cc: Stephen Hemminger, netdev, davem, Thomas Gleixner,
Alexander Duyck, Jeff Kirsher
In-Reply-To: <1303163494.2857.98.camel@bwh-desktop>
On Mon, Apr 18, 2011 at 10:51:34PM +0100, Ben Hutchings wrote:
> On Sun, 2011-04-17 at 21:08 -0400, Neil Horman wrote:
> > On Sun, Apr 17, 2011 at 07:38:59PM +0100, Ben Hutchings wrote:
> > > On Sun, 2011-04-17 at 13:20 -0400, Neil Horman wrote:
> > > > On Sat, Apr 16, 2011 at 09:17:04AM -0700, Stephen Hemminger wrote:
> > > [...]
> > > > > My gut feeling is that:
> > > > > * kernel should default to a simple static sane irq policy without user
> > > > > space. This is especially true for multi-queue devices where the default
> > > > > puts all IRQ's on one cpu.
> > > > >
> > > > Thats not how it currently works, AFAICS. The default kernel policy is
> > > > currently that cpu affinity for any newly requested irq is all cpus. Any
> > > > restriction beyond that is the purview and doing of userspace (irqbalance or
> > > > manual affinity setting).
> > >
> > > Right. Though it may be reasonable for the kernel to use the hint as
> > > the initial affinity for a newly allocated IRQ (not sure quite how we
> > > determine that).
> > >
> > So I understand what your saying here, but I'm having a hard time reconciling
> > the two notions. Currently as it stands, affinity_hint gets set by a single
> > function call in the kernel (irq_set_affinity_hint), and is called by drivers
> > wishing to guide irqbalances behavior (currently only ixgbe does this). The
> > behavior a driver is capable of guiding however are either overly simple (ixgbe
> > just tells irqbalance to place each irq on a separate cpu, which irqbalance
> > would do anyway)
>
> It's a bit more subtle than that.
>
> ixgbe is trying to set up hardware flow steering. Some versions of the
> hardware can steer packets to RX queues based on the TX queue that was
> last used for the same flow. The TX queue selection based on CPU in
> ixgbe_select_queue() should be the inverse of the IRQ affinity mapping
> of RX queues, and the affinity hints are supposed to ensure that this is
> true.
>
Ah, ok, that makes a bit more sense then. Thank you for that.
> I think it should be possible to replace those hints with use of
> irq_cpu_rmap for TX queue selection.
>
> > or overly complex (forcing policy into the kernel, which I
> > tried to do with this patch series, but based on the responses I've gotten here,
> > that seems non-desireable).
>
> The trouble is that irqbalance has been so bad for multiqueue net
> devices in the past that many vendors (including Solarflare) recommended
> that it be disabled. I think irqbalance does sensible things now but
> many systems will be running without it for some time to come.
>
> I was thinking that if the drivers could set sane hints to start with
> then it would improve matters for those systems without irqbalance. But
> maybe it would be better still for some part of the networking core or
> IRQ core to set up a default spreading of multiqueue IRQs.
>
But doesn't this force policy for irqbalancing into the kernel, as Thomas and
Eric alluded to? It seems to me that, if we can export just a bit more
information regarding irqs and their associations to devices (which has been a
major achilles heel of irqblance in the past), then I think we can create a sane
default balancing policy with some simple udev rules. I've been messing with
this a bit today.
> [...]
> > > > Actually, as I read back to myself, that acutally sounds kind of good to me. It
> > > > keeps all the policy for this in user space, and minimizes what we have to add
> > > > to the kernel to make it happen (some process information in /proc and another
> > > > udev event). I'd like to get some feedback before I start implementing this,
> > > > but I think this could be done. What do you think?
> > >
> > > I don't think it's a good idea to override the scheduler dynamically
> > > like this.
> > >
> > Why not? Not disagreeing here, but I'm curious as to why you think this is bad.
> > We already have several interfaces for doing this in user space (cgroups and
> > taskset come to mind). Nominally they are used directly by sysadmins, and used
> > sparingly for specific configurations.
>
> Yes, that is why I think this is different.
>
Ok, fair enough.
> > All I'm suggesting is that we create a
> > daemon to identify processes that would benefit from running closer to the nics
> > they are getting data from, and restricting them to cpus that fit that benefit.
> > If a sysadmin doesn't want that behavior, they can stop the daemon, or change
> > its configuration to avoid including processes they don't want to move/restrict.
>
> I think this could improve latency under low CPU load and throughput
> under high CPU load for small numbers of relatively long-lived flows.
> But for large numbers of flows or high turnover of flows the affinity
> will just be noise.
>
> You're welcome to do your own experiments, obviously!
>
I will, but I'll start with the low hanging fruit. I'm going to try exporting
the msi table for a device. With that I can use the netdev_registration uevent
to properly identify network based irqs without the need for 1/2 assed regex
searches and volume counts and do one shot rebalancing of them.
Thanks for your time & thoughts!
Neil
> Ben.
>
> --
> Ben Hutchings, Senior Software Engineer, Solarflare
> Not speaking for my employer; that's the marketing department's job.
> They asked us to note that Solarflare product names are trademarked.
>
>
^ permalink raw reply
* Re: [PATCH net-next-2.6 3/3] bonding,ipv4,ipv6,vlan: Handle NETDEV_BONDING_FAILOVER like NETDEV_NOTIFY_PEERS
From: Brian Haley @ 2011-04-19 1:32 UTC (permalink / raw)
To: Ben Hutchings
Cc: Jay Vosburgh, David Miller, Andy Gospodarek, Patrick McHardy,
netdev
In-Reply-To: <1303153792.2857.32.camel@bwh-desktop>
On 04/18/2011 03:09 PM, Ben Hutchings wrote:
> How about restoring the parameters like this:
>
> ---
> From: Ben Hutchings <bhutchings@solarflare.com>
> Date: Mon, 18 Apr 2011 19:36:48 +0100
> Subject: [PATCH net-next-2.6] ipv4,ipv6,bonding: Restore control over number of peer notifications
>
> For backward compatibility, we should retain the module parameters and
> sysfs attributes to control the number of peer notifications
> (gratuitous ARPs and unsolicited NAs) sent after bonding failover.
> Also, it is possible for failover to take place even though the new
> active slave does not have link up, and in that case the peer
> notification should be deferred until it does.
>
> Change ipv4 and ipv6 so they do not automatically send peer
> notifications on bonding failover. Change the bonding driver to send
> separate NETDEV_NOTIFY_PEERS notifications when the link is up, as
> many times as requested. Since it does not directly control which
> protocols send notifications, make num_grat_arp and num_unsol_na
> aliases for a single parameter.
Hi Ben,
I think this looks good, I'll try and get this tested here when I have
a chance, but for now I can:
Acked-by: Brian Haley <brian.haley@hp.com>
Should we just go ahead and make a new parameter for peer notification?
Compiled but untested patch below.
Thanks,
-Brian
--
Make a new bonding parameter, called num_peer_notif, to control how
many peer notifications are sent on fail-over. Mark the old values,
num_grat_arp and num_unsol_na, as deprecated in the documentation.
Signed-off-by: Brian Haley <brian.haley@hp.com>
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
index 511b4e5..8b16beb 100644
--- a/Documentation/networking/bonding.txt
+++ b/Documentation/networking/bonding.txt
@@ -585,8 +585,15 @@ mode
chosen.
num_grat_arp
+
+ Deprecated. Use num_peer_notif instead.
+
num_unsol_na
+ Deprecated. Use num_peer_notif instead.
+
+num_peer_notif
+
Specify the number of peer notifications (gratuitous ARPs and
unsolicited IPv6 Neighbor Advertisements) to be issued after a
failover event. As soon as the link is up on the new slave
@@ -595,7 +602,7 @@ num_unsol_na
each link monitor interval (arp_interval or miimon, whichever
is active) if the number is greater than 1.
- These notifications are now generated by the ipv4 and ipv6 code
+ These notifications are now generated by the IPv4 and IPv6 code
and the numbers of repetitions cannot be set independently.
The valid range is 0 - 255; the default value is 1. These options
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 956a6f7..631ca9e 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -116,6 +116,8 @@ module_param_named(num_grat_arp, num_peer_notif, int, 0644);
MODULE_PARM_DESC(num_grat_arp, "Number of peer notifications to send on failover event");
module_param_named(num_unsol_na, num_peer_notif, int, 0644);
MODULE_PARM_DESC(num_unsol_na, "Number of peer notifications to send on failover event");
+module_param_named(num_peer_notif, num_peer_notif, int, 0644);
+MODULE_PARM_DESC(num_unsol_na, "Number of peer notifications to send on failover event");
module_param(miimon, int, 0);
MODULE_PARM_DESC(miimon, "Link check interval in milliseconds");
module_param(updelay, int, 0);
@@ -4699,7 +4701,7 @@ static int bond_check_params(struct bond_params *params)
}
if (num_peer_notif < 0 || num_peer_notif > 255) {
- pr_warning("Warning: num_grat_arp/num_unsol_na (%d) not in range 0-255 so it was reset to 1\n",
+ pr_warning("Warning: num_peer_notif (%d) not in range 0-255 so it was reset to 1\n",
num_peer_notif);
num_peer_notif = 1;
}
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 58fb3e9..b03e7be 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -896,6 +896,8 @@ static DEVICE_ATTR(num_grat_arp, S_IRUGO | S_IWUSR,
bonding_show_num_peer_notif, bonding_store_num_peer_notif);
static DEVICE_ATTR(num_unsol_na, S_IRUGO | S_IWUSR,
bonding_show_num_peer_notif, bonding_store_num_peer_notif);
+static DEVICE_ATTR(num_peer_notif, S_IRUGO | S_IWUSR,
+ bonding_show_num_peer_notif, bonding_store_num_peer_notif);
/*
* Show and set the MII monitor interval. There are two tricky bits
@@ -1598,6 +1600,7 @@ static struct attribute *per_bond_attrs[] = {
&dev_attr_xmit_hash_policy.attr,
&dev_attr_num_grat_arp.attr,
&dev_attr_num_unsol_na.attr,
+ &dev_attr_num_peer_notif.attr,
&dev_attr_miimon.attr,
&dev_attr_primary.attr,
&dev_attr_primary_reselect.attr,
^ permalink raw reply related
* Re: Network performance with small packets
From: Rusty Russell @ 2011-04-19 0:33 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: habanero, Shirley Ma, Krishna Kumar2, David Miller, kvm, netdev,
steved, Tom Lendacky, borntraeger
In-Reply-To: <20110414160359.GA11218@redhat.com>
On Thu, 14 Apr 2011 19:03:59 +0300, "Michael S. Tsirkin" <mst@redhat.com> wrote:
> On Thu, Apr 14, 2011 at 08:58:41PM +0930, Rusty Russell wrote:
> > They have to offer the feature, so if the have some way of allocating
> > non-page-aligned amounts of memory, they'll have to add those extra 2
> > bytes.
> >
> > So I think it's OK...
> > Rusty.
>
> To clarify, my concern is that we always seem to try to map
> these extra 2 bytes, which thinkably might fail?
No, if you look at the layout it's clear that there's always most of a
page left for this extra room, both in the middle and at the end.
Cheers,
Rusty.
^ permalink raw reply
* [PATCH 2.6.36 1/1] IPv6: Create temp address based on advertised network prefix
From: Glenn Wurster @ 2011-04-19 1:24 UTC (permalink / raw)
To: David S. Miller, Alexey Kuznetsov, Pekka Savola (ipv6),
James Morris, Hideaki YOSHIFUJI <yosh
Cc: linux-kernel, dbarrera
As discussed ;Login: Volume 36, number 1, create a temporary address
by hashing a random value along with the advertised network
prefix. This results on the temporary address changing whenever
the network prefix changes (i.e., the host changes networks), or
whenever the random value (which can be set by a user-space
application with sufficient privilege) changes.
Signed-off-by: Glenn Wurster <gwurster@scs.carleton.ca>
---
Documentation/networking/ip-sysctl.txt | 20 ++++-
include/linux/ipv6.h | 4 +
include/net/if_inet6.h | 3 +
net/ipv6/Kconfig | 22 +++++
net/ipv6/addrconf.c | 159
+++++++++++++++++++++++++-------
5 files changed, 175 insertions(+), 33 deletions(-)
diff --git a/Documentation/networking/ip-sysctl.txt
b/Documentation/networking/ip-sysctl.txt
index f350c69..b366c28 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -1128,11 +1128,18 @@ router_solicitations - INTEGER
use_tempaddr - INTEGER
Preference for Privacy Extensions (RFC3041).
+ Bits 0 and 1:
<= 0 : disable Privacy Extensions
== 1 : enable Privacy Extensions, but prefer public
addresses over temporary addresses.
- > 1 : enable Privacy Extensions and prefer temporary
+ >= 2 : enable Privacy Extensions and prefer temporary
addresses over public addresses.
+ Bit 2:
+ == 0 : Use RFC3041 random algorithm for generating
+ temporary addresses.
+ == 1 : Use the output of a hash based on the network prefix
+ and random number from temp_random.
+
Default: 0 (for most devices)
-1 (for point-to-point devices and loopback devices)
@@ -1144,6 +1151,17 @@ temp_prefered_lft - INTEGER
Preferred lifetime (in seconds) for temporary addresses.
Default: 86400 (1 day)
+temp_random - INTEGER[4]
+ Random number used as input to the hash function when
+ generating temporary addresses also based on the network
+ prefix.
+ == 0 : Generate a new random value when a temporary address
+ is created. This random value replaces the 0 in
+ temp_random
+ > 0 : A random number used as input to the hash
+
+ Default: 0
+
max_desync_factor - INTEGER
Maximum value for DESYNC_FACTOR, which is a random value
that ensures that clients don't synchronize with each
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index e62683b..b9bd404 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -172,6 +172,9 @@ struct ipv6_devconf {
__s32 disable_ipv6;
__s32 accept_dad;
__s32 force_tllao;
+#ifdef CONFIG_IPV6_PRIVACY_HASH
+ __u32 temp_random[4];
+#endif
void *sysctl;
};
@@ -213,6 +216,7 @@ enum {
DEVCONF_DISABLE_IPV6,
DEVCONF_ACCEPT_DAD,
DEVCONF_FORCE_TLLAO,
+ DEVCONF_TEMP_RANDOM,
DEVCONF_MAX
};
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index f95ff8d..99428bf 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -183,6 +183,9 @@ struct inet6_dev {
#ifdef CONFIG_IPV6_PRIVACY
u8 rndid[8];
+#ifdef CONFIG_IPV6_PRIVACY_HASH
+ __u32 rndid_inc;
+#endif
struct timer_list regen_timer;
struct list_head tempaddr_list;
#endif
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index 36d7437..c0bc79a 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -39,6 +39,28 @@ config IPV6_PRIVACY
See <file:Documentation/networking/ip-sysctl.txt> for details.
+if IPV6_PRIVACY
+
+config IPV6_PRIVACY_HASH
+ bool "IPv6: Privacy Extension Hash Support"
+ select CRYPTO
+ select CRYPTO_SHA256
+ ---help---
+ Generate the pseudo-random global-scope unicast address(es) based on
+ the output of hashing together the broadcast prefix with a random
+ value. The algorithm is discussed in Volume 36, Number 1 of the USENIX
+ ;Login: publication.
+
+ To use hash-based temorary addresses, do
+
+ echo 6 >/proc/sys/net/ipv6/conf/all/use_tempaddr
+
+ To modify the input to the hash, do
+
+ echo <random> >/proc/sys/net/ipv6/conf/all/temp_random
+
+endif # if IPV6_PRIVACY
+
config IPV6_ROUTER_PREF
bool "IPv6: Router Preference (RFC 4191) support"
---help---
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 89bcb62..4a2eaca 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -118,6 +118,7 @@ static inline void addrconf_sysctl_unregister(struct
inet6_dev *idev)
#endif
#ifdef CONFIG_IPV6_PRIVACY
+static int __ipv6_is_invalid_rndid(const __u8 * rndid);
static int __ipv6_regen_rndid(struct inet6_dev *idev);
static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr
*tmpaddr);
static void ipv6_regen_rndid(unsigned long data);
@@ -177,6 +178,9 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = {
.temp_prefered_lft = TEMP_PREFERRED_LIFETIME,
.regen_max_retry = REGEN_MAX_RETRY,
.max_desync_factor = MAX_DESYNC_FACTOR,
+#ifdef CONFIG_IPV6_PRIVACY_HASH
+ .temp_random = { 0, 0, 0, 0 },
+#endif
#endif
.max_addresses = IPV6_MAX_ADDRESSES,
.accept_ra_defrtr = 1,
@@ -211,6 +215,9 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly
= {
.temp_prefered_lft = TEMP_PREFERRED_LIFETIME,
.regen_max_retry = REGEN_MAX_RETRY,
.max_desync_factor = MAX_DESYNC_FACTOR,
+#ifdef CONFIG_IPV6_PRIVACY_HASH
+ .temp_random = { 0, 0, 0, 0 },
+#endif
#endif
.max_addresses = IPV6_MAX_ADDRESSES,
.accept_ra_defrtr = 1,
@@ -849,6 +856,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp,
struct inet6_ifaddr *i
memcpy(&addr.s6_addr[8], &ift->addr.s6_addr[8], 8);
spin_unlock_bh(&ift->lock);
tmpaddr = &addr;
+ ift = NULL;
} else {
tmpaddr = NULL;
}
@@ -875,17 +883,71 @@ retry:
}
in6_ifa_hold(ifp);
memcpy(addr.s6_addr, ifp->addr.s6_addr, 8);
- if (__ipv6_try_regen_rndid(idev, tmpaddr) < 0) {
- spin_unlock_bh(&ifp->lock);
- write_unlock(&idev->lock);
- printk(KERN_WARNING
- "ipv6_create_tempaddr(): regeneration of randomized
interface id failed.\n");
- in6_ifa_put(ifp);
- in6_dev_put(idev);
- ret = -1;
- goto out;
+#ifdef CONFIG_IPV6_PRIVACY_HASH
+ while (idev->cnf.use_tempaddr > 4) {
+ char hash[32];
+ __u32 temp_random[4];
+ int i;
+
+ struct hash_desc desc = { .tfm = NULL, .flags = 0 };
+ struct scatterlist sg;
+
+ BUG_ON (sizeof(temp_random) != sizeof(idev->cnf.temp_random));
+
+ for (i = 0; unlikely(idev->cnf.temp_random[i] == 0) && i < 4; i++);
+ if (unlikely(i == 4))
+ get_random_bytes(idev->cnf.temp_random, sizeof(idev-
>cnf.temp_random));
+
+ desc.tfm = crypto_alloc_hash ("sha256", 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(desc.tfm)) {
+ idev->cnf.use_tempaddr &= 0x03;
+ printk (KERN_WARNING
+ "ipv6_create_tempaddr(): Hash unavailable,
reverting use_tempaddr to %d.\n",
+ idev->cnf.use_tempaddr);
+ break;
+ }
+
+ BUG_ON (crypto_hash_digestsize(desc.tfm) > sizeof(hash));
+ BUG_ON (sizeof(idev->rndid) < 8);
+
+ crypto_hash_init (&desc);
+
+ sg_init_one (&sg, (u8 *)addr.s6_addr, 8);
+ crypto_hash_update (&desc, &sg, 8);
+
+ memcpy (temp_random, idev->cnf.temp_random, sizeof(temp_random));
+ temp_random[3] += idev->rndid_inc;
+ sg_init_one (&sg, (u8 *)temp_random, sizeof(temp_random));
+ crypto_hash_update (&desc, &sg, sizeof(temp_random));
+
+ crypto_hash_final (&desc, hash);
+ crypto_free_hash (desc.tfm);
+
+ memcpy (&addr.s6_addr[8], hash, 8);
+ if (__ipv6_is_invalid_rndid(&addr.s6_addr[8])) {
+ idev->rndid_inc++;
+ continue;
+ }
+
+ ift = ipv6_get_ifaddr (dev_net(idev->dev), &addr, idev->dev, 0);
+ break;
+ }
+#else
+ idev->cnf.use_tempaddr &= 0x03;
+#endif
+ if (idev->cnf.use_tempaddr < 4) {
+ if (__ipv6_try_regen_rndid(idev, tmpaddr) < 0) {
+ spin_unlock_bh(&ifp->lock);
+ write_unlock(&idev->lock);
+ printk(KERN_WARNING
+ "ipv6_create_tempaddr(): regeneration of randomized
interface id failed.\n");
+ in6_ifa_put(ifp);
+ in6_dev_put(idev);
+ ret = -1;
+ goto out;
+ }
+ memcpy(&addr.s6_addr[8], idev->rndid, 8);
}
- memcpy(&addr.s6_addr[8], idev->rndid, 8);
age = (jiffies - ifp->tstamp) / HZ;
tmp_valid_lft = min_t(__u32,
ifp->valid_lft,
@@ -922,11 +984,11 @@ retry:
if (ifp->flags & IFA_F_OPTIMISTIC)
addr_flags |= IFA_F_OPTIMISTIC;
- ift = !max_addresses ||
- ipv6_count_addresses(idev) < max_addresses ?
- ipv6_add_addr(idev, &addr, tmp_plen,
- ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK,
- addr_flags) : NULL;
+ if (!ift && (!max_addresses || ipv6_count_addresses(idev) <
max_addresses)) {
+ ift = ipv6_add_addr(idev, &addr, tmp_plen,
+ ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK,
+ addr_flags);
+ }
if (!ift || IS_ERR(ift)) {
in6_ifa_put(ifp);
in6_dev_put(idev);
@@ -943,9 +1005,11 @@ retry:
ift->prefered_lft = tmp_prefered_lft;
ift->cstamp = tmp_cstamp;
ift->tstamp = tmp_tstamp;
+ ift->regen_count = 0;
spin_unlock_bh(&ift->lock);
- addrconf_dad_start(ift, 0);
+ if (ift->flags & IFA_F_TENTATIVE)
+ addrconf_dad_start(ift, 0);
in6_ifa_put(ift);
in6_dev_put(idev);
out:
@@ -1090,7 +1154,7 @@ static int ipv6_get_saddr_eval(struct net *net,
*/
int preftmp = dst->prefs & (IPV6_PREFER_SRC_PUBLIC|
IPV6_PREFER_SRC_TMP) ?
!!(dst->prefs & IPV6_PREFER_SRC_TMP) :
- score->ifa->idev->cnf.use_tempaddr >= 2;
+ !!(score->ifa->idev->cnf.use_tempaddr & 2);
ret = (!(score->ifa->flags & IFA_F_TEMPORARY)) ^ preftmp;
break;
}
@@ -1398,6 +1462,9 @@ static void addrconf_dad_stop(struct inet6_ifaddr *ifp,
int dad_failed)
if (ifpub) {
in6_ifa_hold(ifpub);
spin_unlock_bh(&ifp->lock);
+#ifdef CONFIG_IPV6_PRIVACY_HASH
+ ifp->idev->rndid_inc++;
+#endif
ipv6_create_tempaddr(ifpub, ifp);
in6_ifa_put(ifpub);
} else {
@@ -1605,13 +1672,8 @@ static int ipv6_inherit_eui64(u8 *eui, struct inet6_dev
*idev)
}
#ifdef CONFIG_IPV6_PRIVACY
-/* (re)generation of randomized interface identifier (RFC 3041 3.2, 3.5) */
-static int __ipv6_regen_rndid(struct inet6_dev *idev)
+static int __ipv6_is_invalid_rndid(const __u8 * rndid)
{
-regen:
- get_random_bytes(idev->rndid, sizeof(idev->rndid));
- idev->rndid[0] &= ~0x02;
-
/*
* <draft-ietf-ipngwg-temp-addresses-v2-00.txt>:
* check if generated address is not inappropriate
@@ -1623,15 +1685,35 @@ regen:
* - value 0
* - XXX: already assigned to an address on the device
*/
- if (idev->rndid[0] == 0xfd &&
- (idev->rndid[1]&idev->rndid[2]&idev->rndid[3]&idev->rndid[4]&idev-
>rndid[5]&idev->rndid[6]) == 0xff &&
- (idev->rndid[7]&0x80))
- goto regen;
- if ((idev->rndid[0]|idev->rndid[1]) == 0) {
- if (idev->rndid[2] == 0x5e && idev->rndid[3] == 0xfe)
- goto regen;
- if ((idev->rndid[2]|idev->rndid[3]|idev->rndid[4]|idev->rndid[5]|
idev->rndid[6]|idev->rndid[7]) == 0x00)
- goto regen;
+
+ if (rndid[0] == 0xfd &&
+ (rndid[1]&rndid[2]&rndid[3]&rndid[4]&rndid[5]&rndid[6]) == 0xff &&
+ (rndid[7]&0x80))
+ return -1;
+ if ((rndid[0]|rndid[1]) == 0) {
+ if (rndid[2] == 0x5e && rndid[3] == 0xfe)
+ return -1;
+ if ((rndid[2]|rndid[3]|rndid[4]|rndid[5]|rndid[6]|rndid[7]) ==
0x00)
+ return -1;
+ }
+ return 0;
+}
+
+/* (re)generation of randomized interface identifier (RFC 3041 3.2, 3.5) */
+static int __ipv6_regen_rndid(struct inet6_dev *idev)
+{
+#ifdef CONFIG_IPV6_PRIVACY_HASH
+ if (idev->cnf.use_tempaddr > 4) {
+ get_random_bytes(idev->cnf.temp_random, sizeof(idev-
>cnf.temp_random));
+ }
+#else
+ idev->cnf.use_tempaddr &= 0x03;
+#endif
+ if (idev->cnf.use_tempaddr < 4) {
+ do {
+ get_random_bytes(idev->rndid, sizeof(idev->rndid));
+ idev->rndid[0] &= ~0x02;
+ } while (__ipv6_is_invalid_rndid(idev->rndid));
}
return 0;
@@ -1903,6 +1985,10 @@ ok:
int max_addresses = in6_dev->cnf.max_addresses;
u32 addr_flags = 0;
+#ifdef CONFIG_IPV6_PRIVACY_HASH
+ in6_dev->rndid_inc = 0;
+#endif
+
#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
if (in6_dev->cnf.optimistic_dad &&
!net->ipv6.devconf_all->forwarding)
@@ -4454,6 +4540,15 @@ static struct addrconf_sysctl_table
.mode = 0644,
.proc_handler = proc_dointvec
},
+#ifdef CONFIG_IPV6_PRIVACY_HASH
+ {
+ .procname = "temp_random",
+ .data = &ipv6_devconf.temp_random,
+ .maxlen = sizeof(ipv6_devconf.temp_random),
+ .mode = 0640,
+ .proc_handler = proc_dointvec,
+ },
+#endif
{
/* sentinel */
}
--
1.7.2.3
^ permalink raw reply related
* Re: [Bugme-new] [Bug 33502] New: Caught 64-bit read from uninitialized memory in __alloc_skb
From: Eric Dumazet @ 2011-04-19 2:51 UTC (permalink / raw)
To: Andrew Morton
Cc: netdev, bugzilla-daemon, bugme-daemon, casteyde.christian,
Vegard Nossum, Pekka Enberg, Christoph Lameter
In-Reply-To: <20110418153852.153d3ed3.akpm@linux-foundation.org>
Le lundi 18 avril 2011 à 15:38 -0700, Andrew Morton a écrit :
> (switched to email. Please respond via emailed reply-to-all, not via the
> bugzilla web interface).
>
> On Sun, 17 Apr 2011 19:29:39 GMT
> bugzilla-daemon@bugzilla.kernel.org wrote:
>
> > https://bugzilla.kernel.org/show_bug.cgi?id=33502
> >
> > Summary: Caught 64-bit read from uninitialized memory in
> > __alloc_skb
> > Product: Networking
> > Version: 2.5
> > Kernel Version: 2.6.39-rc3
> > Platform: All
> > OS/Version: Linux
> > Tree: Mainline
> > Status: NEW
> > Severity: normal
> > Priority: P1
> > Component: IPV4
> > AssignedTo: shemminger@linux-foundation.org
> > ReportedBy: casteyde.christian@free.fr
> > Regression: Yes
> >
> >
> > Acer Aspire 1511LMi
> > Athlon 64 3GHz in 64bits mode
> > Slackware 64 13.1
> >
> > Since 2.6.39-rc3 with kmemcheck enabled, I get the following warning:
> > ...
> > pcmcia_socket pcmcia_socket0: cs: memory probe 0x0c0000-0x0fffff: excluding
> > 0xc0000-0xfffff
> > pcmcia_socket pcmcia_socket0: cs: memory probe 0x60000000-0x60ffffff: excluding
> > 0x60000000-0x
> > 60ffffff
> > pcmcia_socket pcmcia_socket0: cs: memory probe 0xa0000000-0xa0ffffff: excluding
> > 0xa0000000-0x
> > a0ffffff
> > udev: renamed network interface wlan0 to eth1
> > WARNING: kmemcheck: Caught 64-bit read from uninitialized memory
> > (ffff88001b0bb800)
> > 00b00b1b0088ffff0000000000000000cafe1dea20009b0000299a3100000000
> > u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u u
> > ^
> >
> > Pid: 1511, comm: udevd Not tainted 2.6.39-rc3 #1 Acer,Inc. Aspire 1510 /Aspire
> > 1510
> > RIP: 0010:[<ffffffff810c2f0c>] [<ffffffff810c2f0c>]
> > __kmalloc_track_caller+0xbc/0x1d0
> > RSP: 0018:ffff88001d3a7a18 EFLAGS: 00010246
> > RAX: 0000000000000000 RBX: 0000000000000010 RCX: 000000000000284f
> > RDX: 000000000000284e RSI: ffff88001fe5b160 RDI: ffffffff8177e39a
> > RBP: ffff88001d3a7a48 R08: 0000000000000000 R09: ffff88001b931100
> > R10: 0000000000000000 R11: 0000000000000003 R12: ffff88001b0bb800
> > R13: ffff88001f803840 R14: 00000000000004d0 R15: ffffffff814769c6
> > FS: 00007f6ee81f1700(0000) GS:ffffffff81a1b000(0000) knlGS:0000000000000000
> > CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
> > CR2: ffff88001d0b3938 CR3: 000000001d38b000 CR4: 00000000000006f0
> > DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> > DR3: 0000000000000000 DR6: 00000000ffff4ff0 DR7: 0000000000000400
> > [<ffffffff8147ccf2>] __alloc_skb+0x72/0x190
> > [<ffffffff814769c6>] sock_alloc_send_pskb+0x236/0x3a0
> > [<ffffffff81476b40>] sock_alloc_send_skb+0x10/0x20
> > [<ffffffff81523c18>] unix_dgram_sendmsg+0x298/0x770
> > [<ffffffff814715f3>] sock_sendmsg+0xe3/0x110
> > [<ffffffff81472603>] sys_sendmsg+0x243/0x3c0
> > [<ffffffff815e7238>] system_call_fastpath+0x16/0x1b
> > [<ffffffffffffffff>] 0xffffffffffffffff
>
> hum. I wonder if kmemcheck is disliking prefetchw()?
Nope, prefetchw() is OK versus kmemcheck.
This is in __kmalloc_track_caller(), not in networking stuff.
CC Christoph Lameter
I guess this_cpu_cmpxchg16b() is the offender.
A disassembly of __kmalloc_track_caller() would help, but I feel its the
read of s->cpu_slab->freelist
It seems to be at address
0xffff88001b0bb800 and contains 0xffff88001b0bb000 but kmemcheck thinks
its not initialized.
Its located in percpu zone, maybe kmemcheck has a problem with it ?
alloc_kmem_cache_cpus() does a call to __alloc_percpu(), so this must
have been zeroed at the very beginning of kmem_cache life.
Hmm, looking at mm/slub.c, I wonder what prevents "object" from pointing
to a now freed and unreachable zone of memory. (Say we are interrupted,
object given to interrupt handler and this one wants to change page bits
to trap access)
^ permalink raw reply
* Re: [Bugme-new] [Bug 33502] New: Caught 64-bit read from uninitialized memory in __alloc_skb
From: Eric Dumazet @ 2011-04-19 3:09 UTC (permalink / raw)
To: Andrew Morton
Cc: netdev, bugzilla-daemon, bugme-daemon, casteyde.christian,
Vegard Nossum, Pekka Enberg, Christoph Lameter
In-Reply-To: <1303181466.4152.39.camel@edumazet-laptop>
Le mardi 19 avril 2011 à 04:51 +0200, Eric Dumazet a écrit :
> Hmm, looking at mm/slub.c, I wonder what prevents "object" from pointing
> to a now freed and unreachable zone of memory. (Say we are interrupted,
> object given to interrupt handler and this one wants to change page bits
> to trap access)
Yes, I suspect this whole business is not kmemcheck compatable, or
DEBUG_PAGEALLOC
get_freepointer(s, object) can access to freed memory and kmemcheck
triggers the fault, while this_cpu_cmpxchg_double() would presumably
detect a change of tid and would not perform the freelist/tid change.
^ permalink raw reply
* linux-next: manual merge of the net tree with the net-current tree
From: Stephen Rothwell @ 2011-04-19 3:16 UTC (permalink / raw)
To: David Miller, netdev
Cc: linux-next, linux-kernel, Yaniv Rosner, stephen hemminger
Hi all,
Today's linux-next merge of the net tree got a conflict in
drivers/net/bnx2x/bnx2x_ethtool.c between commit 70dda99c41fc ("bnx2x:
Fix port identification problem") from the net-current tree and commit
32d3613475d8 ("bnx2x: convert to set_phys_id") from the net tree.
I fixed it up (maybe - see below) and can carry the fix as necessary.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
diff --cc drivers/net/bnx2x/bnx2x_ethtool.c
index 89cb977,e711a22..0000000
--- a/drivers/net/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/bnx2x/bnx2x_ethtool.c
@@@ -2097,35 -2013,38 +2013,36 @@@ static void bnx2x_get_ethtool_stats(str
}
}
- static int bnx2x_phys_id(struct net_device *dev, u32 data)
+ static int bnx2x_set_phys_id(struct net_device *dev,
+ enum ethtool_phys_id_state state)
{
struct bnx2x *bp = netdev_priv(dev);
- int i;
if (!netif_running(dev))
- return 0;
+ return -EAGAIN;
if (!bp->port.pmf)
- return 0;
+ return -EOPNOTSUPP;
- if (data == 0)
- data = 2;
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ return 1; /* cycle on/off once per second */
- for (i = 0; i < (data * 2); i++) {
- if ((i % 2) == 0)
- bnx2x_set_led(&bp->link_params, &bp->link_vars,
- LED_MODE_ON, SPEED_1000);
- else
- bnx2x_set_led(&bp->link_params, &bp->link_vars,
- LED_MODE_FRONT_PANEL_OFF, 0);
+ case ETHTOOL_ID_ON:
+ bnx2x_set_led(&bp->link_params, &bp->link_vars,
- LED_MODE_OPER, SPEED_1000);
++ LED_MODE_ON, SPEED_1000);
+ break;
- msleep_interruptible(500);
- if (signal_pending(current))
- break;
- }
+ case ETHTOOL_ID_OFF:
+ bnx2x_set_led(&bp->link_params, &bp->link_vars,
- LED_MODE_OFF, 0);
++ LED_MODE_FRONT_PANEL_OFF, 0);
+
+ break;
- bnx2x_set_led(&bp->link_params, &bp->link_vars,
- LED_MODE_OPER, bp->link_vars.line_speed);
+ case ETHTOOL_ID_INACTIVE:
- if (bp->link_vars.link_up)
- bnx2x_set_led(&bp->link_params, &bp->link_vars,
- LED_MODE_OPER,
- bp->link_vars.line_speed);
++ bnx2x_set_led(&bp->link_params, &bp->link_vars,
++ LED_MODE_OPER, bp->link_vars.line_speed);
+ }
return 0;
}
^ permalink raw reply
* Re: [Bugme-new] [Bug 33502] New: Caught 64-bit read from uninitialized memory in __alloc_skb
From: Eric Dumazet @ 2011-04-19 3:20 UTC (permalink / raw)
To: Andrew Morton
Cc: netdev, bugzilla-daemon, bugme-daemon, casteyde.christian,
Vegard Nossum, Pekka Enberg, Christoph Lameter
In-Reply-To: <1303182557.4152.48.camel@edumazet-laptop>
Le mardi 19 avril 2011 à 05:09 +0200, Eric Dumazet a écrit :
> Le mardi 19 avril 2011 à 04:51 +0200, Eric Dumazet a écrit :
>
> > Hmm, looking at mm/slub.c, I wonder what prevents "object" from pointing
> > to a now freed and unreachable zone of memory. (Say we are interrupted,
> > object given to interrupt handler and this one wants to change page bits
> > to trap access)
>
>
> Yes, I suspect this whole business is not kmemcheck compatable, or
> DEBUG_PAGEALLOC
>
> get_freepointer(s, object) can access to freed memory and kmemcheck
> triggers the fault, while this_cpu_cmpxchg_double() would presumably
> detect a change of tid and would not perform the freelist/tid change.
>
>
>
Christian, please try following patch, thanks
diff --git a/mm/slub.c b/mm/slub.c
index 94d2a33..84febe9 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1540,7 +1540,12 @@ static void unfreeze_slab(struct kmem_cache *s, struct page *page, int tail)
}
}
-#ifdef CONFIG_CMPXCHG_LOCAL
+#if defined(CONFIG_CMPXCHG_LOCAL) && \
+ !defined(CONFIG_KMEMCHECK) && !defined(DEBUG_PAGEALLOC)
+#define SLUB_USE_CMPXCHG_DOUBLE
+#endif
+
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
#ifdef CONFIG_PREEMPT
/*
* Calculate the next globally unique transaction for disambiguiation
@@ -1604,7 +1609,7 @@ static inline void note_cmpxchg_failure(const char *n,
void init_kmem_cache_cpus(struct kmem_cache *s)
{
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
int cpu;
for_each_possible_cpu(cpu)
@@ -1643,7 +1648,7 @@ static void deactivate_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
page->inuse--;
}
c->page = NULL;
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
c->tid = next_tid(c->tid);
#endif
unfreeze_slab(s, page, tail);
@@ -1780,7 +1785,7 @@ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
{
void **object;
struct page *new;
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
unsigned long flags;
local_irq_save(flags);
@@ -1819,7 +1824,7 @@ load_freelist:
c->node = page_to_nid(c->page);
unlock_out:
slab_unlock(c->page);
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
c->tid = next_tid(c->tid);
local_irq_restore(flags);
#endif
@@ -1858,7 +1863,7 @@ new_slab:
}
if (!(gfpflags & __GFP_NOWARN) && printk_ratelimit())
slab_out_of_memory(s, gfpflags, node);
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
local_irq_restore(flags);
#endif
return NULL;
@@ -1887,7 +1892,7 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
{
void **object;
struct kmem_cache_cpu *c;
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
unsigned long tid;
#else
unsigned long flags;
@@ -1896,7 +1901,7 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
if (slab_pre_alloc_hook(s, gfpflags))
return NULL;
-#ifndef CONFIG_CMPXCHG_LOCAL
+#ifndef SLUB_USE_CMPXCHG_DOUBLE
local_irq_save(flags);
#else
redo:
@@ -1910,7 +1915,7 @@ redo:
*/
c = __this_cpu_ptr(s->cpu_slab);
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
/*
* The transaction ids are globally unique per cpu and per operation on
* a per cpu queue. Thus they can be guarantee that the cmpxchg_double
@@ -1927,7 +1932,7 @@ redo:
object = __slab_alloc(s, gfpflags, node, addr, c);
else {
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
/*
* The cmpxchg will only match if there was no additional
* operation and if we are on the right processor.
@@ -1954,7 +1959,7 @@ redo:
stat(s, ALLOC_FASTPATH);
}
-#ifndef CONFIG_CMPXCHG_LOCAL
+#ifndef SLUB_USE_CMPXCHG_DOUBLE
local_irq_restore(flags);
#endif
@@ -2034,7 +2039,7 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
{
void *prior;
void **object = (void *)x;
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
unsigned long flags;
local_irq_save(flags);
@@ -2070,7 +2075,7 @@ checks_ok:
out_unlock:
slab_unlock(page);
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
local_irq_restore(flags);
#endif
return;
@@ -2084,7 +2089,7 @@ slab_empty:
stat(s, FREE_REMOVE_PARTIAL);
}
slab_unlock(page);
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
local_irq_restore(flags);
#endif
stat(s, FREE_SLAB);
@@ -2113,7 +2118,7 @@ static __always_inline void slab_free(struct kmem_cache *s,
{
void **object = (void *)x;
struct kmem_cache_cpu *c;
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
unsigned long tid;
#else
unsigned long flags;
@@ -2121,7 +2126,7 @@ static __always_inline void slab_free(struct kmem_cache *s,
slab_free_hook(s, x);
-#ifndef CONFIG_CMPXCHG_LOCAL
+#ifndef SLUB_USE_CMPXCHG_DOUBLE
local_irq_save(flags);
#else
@@ -2136,7 +2141,7 @@ redo:
*/
c = __this_cpu_ptr(s->cpu_slab);
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
tid = c->tid;
barrier();
#endif
@@ -2144,7 +2149,7 @@ redo:
if (likely(page == c->page && c->node != NUMA_NO_NODE)) {
set_freepointer(s, object, c->freelist);
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
if (unlikely(!this_cpu_cmpxchg_double(
s->cpu_slab->freelist, s->cpu_slab->tid,
c->freelist, tid,
@@ -2160,7 +2165,7 @@ redo:
} else
__slab_free(s, page, x, addr);
-#ifndef CONFIG_CMPXCHG_LOCAL
+#ifndef SLUB_USE_CMPXCHG_DOUBLE
local_irq_restore(flags);
#endif
}
@@ -2354,7 +2359,7 @@ static inline int alloc_kmem_cache_cpus(struct kmem_cache *s)
BUILD_BUG_ON(PERCPU_DYNAMIC_EARLY_SIZE <
SLUB_PAGE_SHIFT * sizeof(struct kmem_cache_cpu));
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
/*
* Must align to double word boundary for the double cmpxchg instructions
* to work.
^ permalink raw reply related
* Re: [PATCH v2] net: r8169: convert to hw_features
From: David Dillow @ 2011-04-19 3:24 UTC (permalink / raw)
To: Francois Romieu; +Cc: netdev, Realtek, davem
In-Reply-To: <20110418180857.GB18469@electric-eye.fr.zoreil.com>
On Mon, 2011-04-18 at 20:08 +0200, Francois Romieu wrote:
> [...]
> > I've attached my ancient patch, if it helps.
>
> Thanks, it works way better now (see below). It is ok for me to use
> you s-o-b on it ?
You may have it if you want it -- and I appreciate the offer -- but I
don't think you need it. You had it mostly working prior to my sending
you anything.
You did the work; you deserve the credit.
Thanks,
Dave
^ permalink raw reply
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