[VLAN]: Avoid a 4-order allocation.
This patch splits the vlan_group struct into a multi-allocated struct. On x86_64, the size of the original struct is a little more than 32KB, causing a 4-order allocation, which is prune to problems caused by buddy-system external fragmentation conditions. I couldn't just use vmalloc() because vfree() cannot be called in the softirq context of the RCU callback. Signed-off-by: Dan Aloni <da-x@monatomic.org> Acked-by: Jeff Garzik <jeff@garzik.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
b5284e5aa9
commit
5c15bdec5c
@@ -3654,7 +3654,7 @@ qeth_verify_vlan_dev(struct net_device *dev, struct qeth_card *card)
|
||||
return rc;
|
||||
|
||||
for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++){
|
||||
if (vg->vlan_devices[i] == dev){
|
||||
if (vlan_group_get_device(vg, i) == dev){
|
||||
rc = QETH_VLAN_CARD;
|
||||
break;
|
||||
}
|
||||
@@ -5261,7 +5261,7 @@ qeth_free_vlan_addresses4(struct qeth_card *card, unsigned short vid)
|
||||
QETH_DBF_TEXT(trace, 4, "frvaddr4");
|
||||
|
||||
rcu_read_lock();
|
||||
in_dev = __in_dev_get_rcu(card->vlangrp->vlan_devices[vid]);
|
||||
in_dev = __in_dev_get_rcu(vlan_group_get_device(card->vlangrp, vid));
|
||||
if (!in_dev)
|
||||
goto out;
|
||||
for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
|
||||
@@ -5288,7 +5288,7 @@ qeth_free_vlan_addresses6(struct qeth_card *card, unsigned short vid)
|
||||
|
||||
QETH_DBF_TEXT(trace, 4, "frvaddr6");
|
||||
|
||||
in6_dev = in6_dev_get(card->vlangrp->vlan_devices[vid]);
|
||||
in6_dev = in6_dev_get(vlan_group_get_device(card->vlangrp, vid));
|
||||
if (!in6_dev)
|
||||
return;
|
||||
for (ifa = in6_dev->addr_list; ifa; ifa = ifa->lst_next){
|
||||
@@ -5360,7 +5360,7 @@ qeth_layer2_process_vlans(struct qeth_card *card, int clear)
|
||||
if (!card->vlangrp)
|
||||
return;
|
||||
for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
|
||||
if (card->vlangrp->vlan_devices[i] == NULL)
|
||||
if (vlan_group_get_device(card->vlangrp, i) == NULL)
|
||||
continue;
|
||||
if (clear)
|
||||
qeth_layer2_send_setdelvlan(card, i, IPA_CMD_DELVLAN);
|
||||
@@ -5398,8 +5398,7 @@ qeth_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
|
||||
spin_lock_irqsave(&card->vlanlock, flags);
|
||||
/* unregister IP addresses of vlan device */
|
||||
qeth_free_vlan_addresses(card, vid);
|
||||
if (card->vlangrp)
|
||||
card->vlangrp->vlan_devices[vid] = NULL;
|
||||
vlan_group_set_device(card->vlangrp, vid, NULL);
|
||||
spin_unlock_irqrestore(&card->vlanlock, flags);
|
||||
if (card->options.layer2)
|
||||
qeth_layer2_send_setdelvlan(card, vid, IPA_CMD_DELVLAN);
|
||||
@@ -5662,10 +5661,11 @@ qeth_add_vlan_mc(struct qeth_card *card)
|
||||
|
||||
vg = card->vlangrp;
|
||||
for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
|
||||
if (vg->vlan_devices[i] == NULL ||
|
||||
!(vg->vlan_devices[i]->flags & IFF_UP))
|
||||
struct net_device *netdev = vlan_group_get_device(vg, i);
|
||||
if (netdev == NULL ||
|
||||
!(netdev->flags & IFF_UP))
|
||||
continue;
|
||||
in_dev = in_dev_get(vg->vlan_devices[i]);
|
||||
in_dev = in_dev_get(netdev);
|
||||
if (!in_dev)
|
||||
continue;
|
||||
read_lock(&in_dev->mc_list_lock);
|
||||
@@ -5749,10 +5749,11 @@ qeth_add_vlan_mc6(struct qeth_card *card)
|
||||
|
||||
vg = card->vlangrp;
|
||||
for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
|
||||
if (vg->vlan_devices[i] == NULL ||
|
||||
!(vg->vlan_devices[i]->flags & IFF_UP))
|
||||
struct net_device *netdev = vlan_group_get_device(vg, i);
|
||||
if (netdev == NULL ||
|
||||
!(netdev->flags & IFF_UP))
|
||||
continue;
|
||||
in_dev = in6_dev_get(vg->vlan_devices[i]);
|
||||
in_dev = in6_dev_get(netdev);
|
||||
if (!in_dev)
|
||||
continue;
|
||||
read_lock(&in_dev->lock);
|
||||
|
Reference in New Issue
Block a user