svn commit: r213218 - in stable/8/sys/dev: e1000 ixgb ixgbe

Pyun YongHyeon yongari at FreeBSD.org
Mon Sep 27 17:54:13 UTC 2010


Author: yongari
Date: Mon Sep 27 17:54:04 2010
New Revision: 213218
URL: http://svn.freebsd.org/changeset/base/213218

Log:
  MFC r211913:
    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

Modified:
  stable/8/sys/dev/e1000/if_em.c
  stable/8/sys/dev/e1000/if_em.h
  stable/8/sys/dev/e1000/if_igb.c
  stable/8/sys/dev/e1000/if_igb.h
  stable/8/sys/dev/e1000/if_lem.c
  stable/8/sys/dev/e1000/if_lem.h
  stable/8/sys/dev/ixgb/if_ixgb.c
  stable/8/sys/dev/ixgb/if_ixgb.h
  stable/8/sys/dev/ixgbe/ixgbe.c
  stable/8/sys/dev/ixgbe/ixgbe.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/dev/e1000/if_em.c
==============================================================================
--- stable/8/sys/dev/e1000/if_em.c	Mon Sep 27 17:50:56 2010	(r213217)
+++ stable/8/sys/dev/e1000/if_em.c	Mon Sep 27 17:54:04 2010	(r213218)
@@ -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);
 }
 
 

Modified: stable/8/sys/dev/e1000/if_em.h
==============================================================================
--- stable/8/sys/dev/e1000/if_em.h	Mon Sep 27 17:50:56 2010	(r213217)
+++ stable/8/sys/dev/e1000/if_em.h	Mon Sep 27 17:54:04 2010	(r213218)
@@ -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;

Modified: stable/8/sys/dev/e1000/if_igb.c
==============================================================================
--- stable/8/sys/dev/e1000/if_igb.c	Mon Sep 27 17:50:56 2010	(r213217)
+++ stable/8/sys/dev/e1000/if_igb.c	Mon Sep 27 17:54:04 2010	(r213218)
@@ -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

Modified: stable/8/sys/dev/e1000/if_igb.h
==============================================================================
--- stable/8/sys/dev/e1000/if_igb.h	Mon Sep 27 17:50:56 2010	(r213217)
+++ stable/8/sys/dev/e1000/if_igb.h	Mon Sep 27 17:54:04 2010	(r213218)
@@ -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;

Modified: stable/8/sys/dev/e1000/if_lem.c
==============================================================================
--- stable/8/sys/dev/e1000/if_lem.c	Mon Sep 27 17:50:56 2010	(r213217)
+++ stable/8/sys/dev/e1000/if_lem.c	Mon Sep 27 17:54:04 2010	(r213218)
@@ -538,6 +538,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
@@ -666,6 +675,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);
@@ -752,6 +762,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);
@@ -1932,6 +1943,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);
@@ -1942,13 +1956,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
@@ -1986,7 +1993,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);
 }
 
 

Modified: stable/8/sys/dev/e1000/if_lem.h
==============================================================================
--- stable/8/sys/dev/e1000/if_lem.h	Mon Sep 27 17:50:56 2010	(r213217)
+++ stable/8/sys/dev/e1000/if_lem.h	Mon Sep 27 17:54:04 2010	(r213218)
@@ -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;

Modified: stable/8/sys/dev/ixgb/if_ixgb.c
==============================================================================
--- stable/8/sys/dev/ixgb/if_ixgb.c	Mon Sep 27 17:50:56 2010	(r213217)
+++ stable/8/sys/dev/ixgb/if_ixgb.c	Mon Sep 27 17:54:04 2010	(r213218)
@@ -328,6 +328,15 @@ ixgb_attach(device_t dev)
 	}
 	adapter->rx_desc_base = (struct ixgb_rx_desc *) adapter->rxdma.dma_vaddr;
 
+	/* Allocate multicast array memory. */
+	adapter->mta = malloc(sizeof(u_int8_t) * IXGB_ETH_LENGTH_OF_ADDRESS *
+	    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;
+	}
+
 	/* Initialize the hardware */
 	if (ixgb_hardware_init(adapter)) {
 		printf("ixgb%d: Unable to initialize the hardware\n",
@@ -356,6 +365,7 @@ err_pci:
 		if_free(adapter->ifp);
 	ixgb_free_pci_resources(adapter);
 	sysctl_ctx_free(&adapter->sysctl_ctx);
+	free(adapter->mta, M_DEVBUF);
 	return (error);
 
 }
@@ -416,6 +426,7 @@ ixgb_detach(device_t dev)
 		adapter->next->prev = adapter->prev;
 	if (adapter->prev != NULL)
 		adapter->prev->next = adapter->next;
+	free(adapter->mta, M_DEVBUF);
 
 	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
 	ifp->if_timer = 0;
@@ -1086,13 +1097,17 @@ static void
 ixgb_set_multi(struct adapter * adapter)
 {
 	u_int32_t       reg_rctl = 0;
-	u_int8_t        mta[MAX_NUM_MULTICAST_ADDRESSES * IXGB_ETH_LENGTH_OF_ADDRESS];
+	u_int8_t        *mta;
 	struct ifmultiaddr *ifma;
 	int             mcnt = 0;
 	struct ifnet   *ifp = adapter->ifp;
 
 	IOCTL_DEBUGOUT("ixgb_set_multi: begin");
 
+	mta = adapter->mta;
+	bzero(mta, sizeof(u_int8_t) * IXGB_ETH_LENGTH_OF_ADDRESS *
+	    MAX_NUM_MULTICAST_ADDRESSES);
+
 	if_maddr_rlock(ifp);
 #if __FreeBSD_version < 500000
 	LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {

Modified: stable/8/sys/dev/ixgb/if_ixgb.h
==============================================================================
--- stable/8/sys/dev/ixgb/if_ixgb.h	Mon Sep 27 17:50:56 2010	(r213217)
+++ stable/8/sys/dev/ixgb/if_ixgb.h	Mon Sep 27 17:54:04 2010	(r213218)
@@ -344,6 +344,8 @@ struct adapter {
 	struct sysctl_ctx_list sysctl_ctx;
 	struct sysctl_oid *sysctl_tree;
 
+	/* Multicast array memory */
+	u_int8_t	*mta;
 	/* Misc stats maintained by the driver */
 	unsigned long   dropped_pkts;
 	unsigned long   mbuf_alloc_failed;

Modified: stable/8/sys/dev/ixgbe/ixgbe.c
==============================================================================
--- stable/8/sys/dev/ixgbe/ixgbe.c	Mon Sep 27 17:50:56 2010	(r213217)
+++ stable/8/sys/dev/ixgbe/ixgbe.c	Mon Sep 27 17:54:04 2010	(r213218)
@@ -518,6 +518,15 @@ ixgbe_attach(device_t dev)
 		goto err_out;
 	}
 
+	/* Allocate multicast array memory. */
+	adapter->mta = malloc(sizeof(u8) * IXGBE_ETH_LENGTH_OF_ADDRESS *
+	    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;
+	}
+
 	/* Initialize the shared code */
 	error = ixgbe_init_shared_code(hw);
 	if (error == IXGBE_ERR_SFP_NOT_PRESENT) {
@@ -630,6 +639,7 @@ err_out:
 	if (adapter->ifp != NULL)
 		if_free(adapter->ifp);
 	ixgbe_free_pci_resources(adapter);
+	free(adapter->mta, M_DEVBUF);
 	return (error);
 
 }
@@ -700,6 +710,7 @@ ixgbe_detach(device_t dev)
 
 	ixgbe_free_transmit_structures(adapter);
 	ixgbe_free_receive_structures(adapter);
+	free(adapter->mta, M_DEVBUF);
 
 	IXGBE_CORE_LOCK_DESTROY(adapter);
 	return (0);
@@ -1802,7 +1813,7 @@ static void
 ixgbe_set_multi(struct adapter *adapter)
 {
 	u32	fctrl;
-	u8	mta[MAX_NUM_MULTICAST_ADDRESSES * IXGBE_ETH_LENGTH_OF_ADDRESS];
+	u8	*mta;
 	u8	*update_ptr;
 	struct	ifmultiaddr *ifma;
 	int	mcnt = 0;
@@ -1810,6 +1821,10 @@ ixgbe_set_multi(struct adapter *adapter)
 
 	IOCTL_DEBUGOUT("ixgbe_set_multi: begin");
 
+	mta = adapter->mta;
+	bzero(mta, sizeof(u8) * IXGBE_ETH_LENGTH_OF_ADDRESS *
+	    MAX_NUM_MULTICAST_ADDRESSES);
+
 	fctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
 	fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
 	if (ifp->if_flags & IFF_PROMISC)

Modified: stable/8/sys/dev/ixgbe/ixgbe.h
==============================================================================
--- stable/8/sys/dev/ixgbe/ixgbe.h	Mon Sep 27 17:50:56 2010	(r213217)
+++ stable/8/sys/dev/ixgbe/ixgbe.h	Mon Sep 27 17:54:04 2010	(r213218)
@@ -420,6 +420,8 @@ struct adapter {
 	u64			que_mask;
 	u32			rx_process_limit;
 
+	/* Multicast array memory */
+	u8			*mta;
 	/* Misc stats maintained by the driver */
 	unsigned long   	dropped_pkts;
 	unsigned long   	mbuf_defrag_failed;


More information about the svn-src-stable-8 mailing list