summaryrefslogtreecommitdiffstats
path: root/sys/dev/e1000
diff options
context:
space:
mode:
authoryongari <yongari@FreeBSD.org>2010-08-28 00:34:22 +0000
committeryongari <yongari@FreeBSD.org>2010-08-28 00:34:22 +0000
commit8203781f0e877f100602ff4676f0e5da09890261 (patch)
treeafd3011d44393f04dc0215f819448c55b43cd532 /sys/dev/e1000
parentc4045967a29d41b5ba3c97b74ba4a05831e19c48 (diff)
downloadFreeBSD-src-8203781f0e877f100602ff4676f0e5da09890261.zip
FreeBSD-src-8203781f0e877f100602ff4676f0e5da09890261.tar.gz
Do not allocate multicast array memory in multicast filter
configuration function. For failed memory allocations, em(4)/lem(4) called panic(9) which is not acceptable on production box. igb(4)/ixgb(4)/ix(4) allocated the required memory in stack which consumed 768 bytes of stack memory which looks too big. To address these issues, allocate multicast array memory in device attach time and make multicast configuration success under any conditions. This change also removes the excessive use of memory in stack. Reviewed by: jfv
Diffstat (limited to 'sys/dev/e1000')
-rw-r--r--sys/dev/e1000/if_em.c22
-rw-r--r--sys/dev/e1000/if_em.h2
-rw-r--r--sys/dev/e1000/if_igb.c17
-rw-r--r--sys/dev/e1000/if_igb.h2
-rw-r--r--sys/dev/e1000/if_lem.c22
-rw-r--r--sys/dev/e1000/if_lem.h2
6 files changed, 50 insertions, 17 deletions
diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
index 56859ea..e5dfa36 100644
--- a/sys/dev/e1000/if_em.c
+++ b/sys/dev/e1000/if_em.c
@@ -576,6 +576,15 @@ em_attach(device_t dev)
goto err_pci;
}
+ /* Allocate multicast array memory. */
+ adapter->mta = malloc(sizeof(u8) * ETH_ADDR_LEN *
+ MAX_NUM_MULTICAST_ADDRESSES, M_DEVBUF, M_NOWAIT);
+ if (adapter->mta == NULL) {
+ device_printf(dev, "Can not allocate multicast setup array\n");
+ error = ENOMEM;
+ goto err_late;
+ }
+
/*
** Start from a known state, this is
** important in reading the nvm and
@@ -674,6 +683,7 @@ err_late:
if_free(adapter->ifp);
err_pci:
em_free_pci_resources(adapter);
+ free(adapter->mta, M_DEVBUF);
EM_CORE_LOCK_DESTROY(adapter);
return (error);
@@ -739,6 +749,7 @@ em_detach(device_t dev)
em_free_receive_structures(adapter);
em_release_hw_control(adapter);
+ free(adapter->mta, M_DEVBUF);
return (0);
}
@@ -1998,6 +2009,9 @@ em_set_multi(struct adapter *adapter)
IOCTL_DEBUGOUT("em_set_multi: begin");
+ mta = adapter->mta;
+ bzero(mta, sizeof(u8) * ETH_ADDR_LEN * MAX_NUM_MULTICAST_ADDRESSES);
+
if (adapter->hw.mac.type == e1000_82542 &&
adapter->hw.revision_id == E1000_REVISION_2) {
reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
@@ -2008,13 +2022,6 @@ em_set_multi(struct adapter *adapter)
msec_delay(5);
}
- /* Allocate temporary memory to setup array */
- mta = malloc(sizeof(u8) *
- (ETH_ADDR_LEN * MAX_NUM_MULTICAST_ADDRESSES),
- M_DEVBUF, M_NOWAIT | M_ZERO);
- if (mta == NULL)
- panic("em_set_multi memory failure\n");
-
#if __FreeBSD_version < 800000
IF_ADDR_LOCK(ifp);
#else
@@ -2052,7 +2059,6 @@ em_set_multi(struct adapter *adapter)
if (adapter->hw.bus.pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
e1000_pci_set_mwi(&adapter->hw);
}
- free(mta, M_DEVBUF);
}
diff --git a/sys/dev/e1000/if_em.h b/sys/dev/e1000/if_em.h
index 225a8d0..d164edb 100644
--- a/sys/dev/e1000/if_em.h
+++ b/sys/dev/e1000/if_em.h
@@ -391,6 +391,8 @@ struct adapter {
bool has_manage;
bool has_amt;
+ /* Multicast array memory */
+ u8 *mta;
/* Info about the board itself */
uint8_t link_active;
uint16_t link_speed;
diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c
index d8371af..3e14f24 100644
--- a/sys/dev/e1000/if_igb.c
+++ b/sys/dev/e1000/if_igb.c
@@ -515,6 +515,15 @@ igb_attach(device_t dev)
goto err_late;
}
+ /* Allocate multicast array memory. */
+ adapter->mta = malloc(sizeof(u8) * ETH_ADDR_LEN *
+ MAX_NUM_MULTICAST_ADDRESSES, M_DEVBUF, M_NOWAIT);
+ if (adapter->mta == NULL) {
+ device_printf(dev, "Can not allocate multicast setup array\n");
+ error = ENOMEM;
+ goto err_late;
+ }
+
/*
** Start from a known state, this is
** important in reading the nvm and
@@ -618,6 +627,7 @@ err_late:
if_free(adapter->ifp);
err_pci:
igb_free_pci_resources(adapter);
+ free(adapter->mta, M_DEVBUF);
IGB_CORE_LOCK_DESTROY(adapter);
return (error);
@@ -688,6 +698,7 @@ igb_detach(device_t dev)
igb_free_transmit_structures(adapter);
igb_free_receive_structures(adapter);
+ free(adapter->mta, M_DEVBUF);
IGB_CORE_LOCK_DESTROY(adapter);
@@ -1861,12 +1872,16 @@ igb_set_multi(struct adapter *adapter)
struct ifnet *ifp = adapter->ifp;
struct ifmultiaddr *ifma;
u32 reg_rctl = 0;
- u8 mta[MAX_NUM_MULTICAST_ADDRESSES * ETH_ADDR_LEN];
+ u8 *mta;
int mcnt = 0;
IOCTL_DEBUGOUT("igb_set_multi: begin");
+ mta = adapter->mta;
+ bzero(mta, sizeof(uint8_t) * ETH_ADDR_LEN *
+ MAX_NUM_MULTICAST_ADDRESSES);
+
#if __FreeBSD_version < 800000
IF_ADDR_LOCK(ifp);
#else
diff --git a/sys/dev/e1000/if_igb.h b/sys/dev/e1000/if_igb.h
index 4388e07..28f5d32 100644
--- a/sys/dev/e1000/if_igb.h
+++ b/sys/dev/e1000/if_igb.h
@@ -422,6 +422,8 @@ struct adapter {
u32 rx_mbuf_sz;
u32 rx_mask;
+ /* Multicast array memory */
+ u8 *mta;
/* Misc stats maintained by the driver */
unsigned long dropped_pkts;
unsigned long mbuf_defrag_failed;
diff --git a/sys/dev/e1000/if_lem.c b/sys/dev/e1000/if_lem.c
index f5c9e293..71a82e5 100644
--- a/sys/dev/e1000/if_lem.c
+++ b/sys/dev/e1000/if_lem.c
@@ -550,6 +550,15 @@ lem_attach(device_t dev)
adapter->rx_desc_base =
(struct e1000_rx_desc *)adapter->rxdma.dma_vaddr;
+ /* Allocate multicast array memory. */
+ adapter->mta = malloc(sizeof(u8) * ETH_ADDR_LEN *
+ MAX_NUM_MULTICAST_ADDRESSES, M_DEVBUF, M_NOWAIT);
+ if (adapter->mta == NULL) {
+ device_printf(dev, "Can not allocate multicast setup array\n");
+ error = ENOMEM;
+ goto err_hw_init;
+ }
+
/*
** Start from a known state, this is
** important in reading the nvm and
@@ -676,6 +685,7 @@ err_pci:
if (adapter->ifp != NULL)
if_free(adapter->ifp);
lem_free_pci_resources(adapter);
+ free(adapter->mta, M_DEVBUF);
EM_TX_LOCK_DESTROY(adapter);
EM_RX_LOCK_DESTROY(adapter);
EM_CORE_LOCK_DESTROY(adapter);
@@ -762,6 +772,7 @@ lem_detach(device_t dev)
}
lem_release_hw_control(adapter);
+ free(adapter->mta, M_DEVBUF);
EM_TX_LOCK_DESTROY(adapter);
EM_RX_LOCK_DESTROY(adapter);
EM_CORE_LOCK_DESTROY(adapter);
@@ -1942,6 +1953,9 @@ lem_set_multi(struct adapter *adapter)
IOCTL_DEBUGOUT("lem_set_multi: begin");
+ mta = adapter->mta;
+ bzero(mta, sizeof(u8) * ETH_ADDR_LEN * MAX_NUM_MULTICAST_ADDRESSES);
+
if (adapter->hw.mac.type == e1000_82542 &&
adapter->hw.revision_id == E1000_REVISION_2) {
reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
@@ -1952,13 +1966,6 @@ lem_set_multi(struct adapter *adapter)
msec_delay(5);
}
- /* Allocate temporary memory to setup array */
- mta = malloc(sizeof(u8) *
- (ETH_ADDR_LEN * MAX_NUM_MULTICAST_ADDRESSES),
- M_DEVBUF, M_NOWAIT | M_ZERO);
- if (mta == NULL)
- panic("lem_set_multi memory failure\n");
-
#if __FreeBSD_version < 800000
IF_ADDR_LOCK(ifp);
#else
@@ -1996,7 +2003,6 @@ lem_set_multi(struct adapter *adapter)
if (adapter->hw.bus.pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
e1000_pci_set_mwi(&adapter->hw);
}
- free(mta, M_DEVBUF);
}
diff --git a/sys/dev/e1000/if_lem.h b/sys/dev/e1000/if_lem.h
index 13c2cbc..0ada7df 100644
--- a/sys/dev/e1000/if_lem.h
+++ b/sys/dev/e1000/if_lem.h
@@ -339,6 +339,8 @@ struct adapter {
bool has_manage;
bool has_amt;
+ /* Multicast array memory */
+ u8 *mta;
/* Info about the board itself */
uint8_t link_active;
uint16_t link_speed;
OpenPOWER on IntegriCloud