* [PATCH 1/9] pasemi_mac: Fix TX interrupt threshold [not found] <20070622194720.614405000@lixom.net> @ 2007-06-22 20:04 ` Olof Johansson 2007-07-02 12:37 ` Jeff Garzik 2007-06-22 20:05 ` [PATCH 2/9] pasemi_mac: Clean TX ring in poll Olof Johansson ` (7 subsequent siblings) 8 siblings, 1 reply; 14+ messages in thread From: Olof Johansson @ 2007-06-22 20:04 UTC (permalink / raw) To: jgarzik; +Cc: netdev [-- Attachment #1: pasemi_mac-rx-intr-fix --] [-- Type: text/plain, Size: 779 bytes --] It was mistakenly set to interrupt on the second packet instead of first, causing some interesting latency behaviour. Signed-off-by: Olof Johansson <olof@lixom.net> Index: netdev-2.6/drivers/net/pasemi_mac.c =================================================================== --- netdev-2.6.orig/drivers/net/pasemi_mac.c +++ netdev-2.6/drivers/net/pasemi_mac.c @@ -755,7 +755,7 @@ static int pasemi_mac_open(struct net_de flags |= PAS_MAC_CFG_PCFG_TSR_1G | PAS_MAC_CFG_PCFG_SPD_1G; pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_RXCH_CFG(mac->dma_rxch), - PAS_IOB_DMA_RXCH_CFG_CNTTH(1)); + PAS_IOB_DMA_RXCH_CFG_CNTTH(0)); pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_CFG(mac->dma_txch), PAS_IOB_DMA_TXCH_CFG_CNTTH(32)); -- ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/9] pasemi_mac: Fix TX interrupt threshold 2007-06-22 20:04 ` [PATCH 1/9] pasemi_mac: Fix TX interrupt threshold Olof Johansson @ 2007-07-02 12:37 ` Jeff Garzik 0 siblings, 0 replies; 14+ messages in thread From: Jeff Garzik @ 2007-07-02 12:37 UTC (permalink / raw) To: Olof Johansson; +Cc: netdev Olof Johansson wrote: > It was mistakenly set to interrupt on the second packet instead of first, causing > some interesting latency behaviour. > > > Signed-off-by: Olof Johansson <olof@lixom.net> applied ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 2/9] pasemi_mac: Clean TX ring in poll [not found] <20070622194720.614405000@lixom.net> 2007-06-22 20:04 ` [PATCH 1/9] pasemi_mac: Fix TX interrupt threshold Olof Johansson @ 2007-06-22 20:05 ` Olof Johansson 2007-07-02 12:34 ` Jeff Garzik 2007-06-22 20:05 ` [PATCH 3/9] pasemi_mac: Abstract out register access Olof Johansson ` (6 subsequent siblings) 8 siblings, 1 reply; 14+ messages in thread From: Olof Johansson @ 2007-06-22 20:05 UTC (permalink / raw) To: jgarzik; +Cc: netdev [-- Attachment #1: pasemi_mac-clean-tx-in-poll --] [-- Type: text/plain, Size: 635 bytes --] Clean the TX ring in the poll call, to avoid sitting on mapped buffers for a long time. NFS doesn't seem to like it much, for example. Signed-off-by: Olof Johansson <olof@lixom.net> Index: netdev-2.6/drivers/net/pasemi_mac.c =================================================================== --- netdev-2.6.orig/drivers/net/pasemi_mac.c +++ netdev-2.6/drivers/net/pasemi_mac.c @@ -1052,6 +1052,7 @@ static int pasemi_mac_poll(struct net_de int pkts, limit = min(*budget, dev->quota); struct pasemi_mac *mac = netdev_priv(dev); + pasemi_mac_clean_tx(mac); pkts = pasemi_mac_clean_rx(mac, limit); dev->quota -= pkts; -- ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/9] pasemi_mac: Clean TX ring in poll 2007-06-22 20:05 ` [PATCH 2/9] pasemi_mac: Clean TX ring in poll Olof Johansson @ 2007-07-02 12:34 ` Jeff Garzik 2007-07-03 20:31 ` Olof Johansson 0 siblings, 1 reply; 14+ messages in thread From: Jeff Garzik @ 2007-07-02 12:34 UTC (permalink / raw) To: Olof Johansson; +Cc: netdev Olof Johansson wrote: > Clean the TX ring in the poll call, to avoid sitting on mapped buffers > for a long time. NFS doesn't seem to like it much, for example. > > > Signed-off-by: Olof Johansson <olof@lixom.net> > > Index: netdev-2.6/drivers/net/pasemi_mac.c > =================================================================== > --- netdev-2.6.orig/drivers/net/pasemi_mac.c > +++ netdev-2.6/drivers/net/pasemi_mac.c > @@ -1052,6 +1052,7 @@ static int pasemi_mac_poll(struct net_de > int pkts, limit = min(*budget, dev->quota); > struct pasemi_mac *mac = netdev_priv(dev); > > + pasemi_mac_clean_tx(mac); > pkts = pasemi_mac_clean_rx(mac, limit); Why is this needed? Is your TX interrupt mitigated or delayed somehow? In general, drivers should only clean TX in one place. Doing so in multiple places tends to indicate a bug somewhere. You are correct that you should not sit on buffers for too long -- that increases latency of all who are waiting on those buffers to be sent. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/9] pasemi_mac: Clean TX ring in poll 2007-07-02 12:34 ` Jeff Garzik @ 2007-07-03 20:31 ` Olof Johansson 0 siblings, 0 replies; 14+ messages in thread From: Olof Johansson @ 2007-07-03 20:31 UTC (permalink / raw) To: Jeff Garzik; +Cc: netdev On Mon, Jul 02, 2007 at 08:34:22AM -0400, Jeff Garzik wrote: > >Index: netdev-2.6/drivers/net/pasemi_mac.c > >=================================================================== > >--- netdev-2.6.orig/drivers/net/pasemi_mac.c > >+++ netdev-2.6/drivers/net/pasemi_mac.c > >@@ -1052,6 +1052,7 @@ static int pasemi_mac_poll(struct net_de > > int pkts, limit = min(*budget, dev->quota); > > struct pasemi_mac *mac = netdev_priv(dev); > > > >+ pasemi_mac_clean_tx(mac); > > pkts = pasemi_mac_clean_rx(mac, limit); > > Why is this needed? Is your TX interrupt mitigated or delayed somehow? On some level hardware, we only have the possibility of taking the TX interrupt after a certain number of packets, and no way of doing a (hw) timer-based one (i.e. after no packets have been sent for x ms, interrupt). Taking an interrupt for every TX packet isn't an interesting proposal, and doing it solely based on count > 1 can leave stale packets there for a long time when the network is otherwise idle. So, I would need to do a software based timer. The poll function seemed like a good enough solution for now though, since it's called periodically even when the NAPI mode is such that interrupts are enabled. > In general, drivers should only clean TX in one place. Doing so in > multiple places tends to indicate a bug somewhere. Yes, I wish I could just do it in the interrupt handler. I could do it with a dedicated timer if you prefer, but I'd still need to have two ways of entering the tx clean function. -Olof ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 3/9] pasemi_mac: Abstract out register access [not found] <20070622194720.614405000@lixom.net> 2007-06-22 20:04 ` [PATCH 1/9] pasemi_mac: Fix TX interrupt threshold Olof Johansson 2007-06-22 20:05 ` [PATCH 2/9] pasemi_mac: Clean TX ring in poll Olof Johansson @ 2007-06-22 20:05 ` Olof Johansson 2007-07-02 12:32 ` Jeff Garzik 2007-06-22 20:05 ` [PATCH 4/9] pasemi_mac: Use MMIO instead of pci config accessors Olof Johansson ` (5 subsequent siblings) 8 siblings, 1 reply; 14+ messages in thread From: Olof Johansson @ 2007-06-22 20:05 UTC (permalink / raw) To: jgarzik; +Cc: netdev [-- Attachment #1: pasemi_mac-regaccess --] [-- Type: text/plain, Size: 13443 bytes --] Abstract out the PCI config read/write accesses into reg read/write ones, still calling the pci accessors on the back end. Signed-off-by: Olof Johansson <olof@lixom.net> Index: netdev-2.6/drivers/net/pasemi_mac.c =================================================================== --- netdev-2.6.orig/drivers/net/pasemi_mac.c +++ netdev-2.6/drivers/net/pasemi_mac.c @@ -81,6 +81,48 @@ MODULE_PARM_DESC(debug, "PA Semi MAC bit static struct pasdma_status *dma_status; +static unsigned int read_iob_reg(struct pasemi_mac *mac, unsigned int reg) +{ + unsigned int val; + + pci_read_config_dword(mac->iob_pdev, reg, &val); + return val; +} + +static void write_iob_reg(struct pasemi_mac *mac, unsigned int reg, + unsigned int val) +{ + pci_write_config_dword(mac->iob_pdev, reg, val); +} + +static unsigned int read_mac_reg(struct pasemi_mac *mac, unsigned int reg) +{ + unsigned int val; + + pci_read_config_dword(mac->pdev, reg, &val); + return val; +} + +static void write_mac_reg(struct pasemi_mac *mac, unsigned int reg, + unsigned int val) +{ + pci_write_config_dword(mac->pdev, reg, val); +} + +static unsigned int read_dma_reg(struct pasemi_mac *mac, unsigned int reg) +{ + unsigned int val; + + pci_read_config_dword(mac->dma_pdev, reg, &val); + return val; +} + +static void write_dma_reg(struct pasemi_mac *mac, unsigned int reg, + unsigned int val) +{ + pci_write_config_dword(mac->dma_pdev, reg, val); +} + static int pasemi_get_mac_addr(struct pasemi_mac *mac) { struct pci_dev *pdev = mac->pdev; @@ -166,22 +208,21 @@ static int pasemi_mac_setup_rx_resources memset(ring->buffers, 0, RX_RING_SIZE * sizeof(u64)); - pci_write_config_dword(mac->dma_pdev, PAS_DMA_RXCHAN_BASEL(chan_id), - PAS_DMA_RXCHAN_BASEL_BRBL(ring->dma)); + write_dma_reg(mac, PAS_DMA_RXCHAN_BASEL(chan_id), PAS_DMA_RXCHAN_BASEL_BRBL(ring->dma)); + + write_dma_reg(mac, PAS_DMA_RXCHAN_BASEU(chan_id), + PAS_DMA_RXCHAN_BASEU_BRBH(ring->dma >> 32) | + PAS_DMA_RXCHAN_BASEU_SIZ(RX_RING_SIZE >> 2)); + + write_dma_reg(mac, PAS_DMA_RXCHAN_CFG(chan_id), + PAS_DMA_RXCHAN_CFG_HBU(1)); - pci_write_config_dword(mac->dma_pdev, PAS_DMA_RXCHAN_BASEU(chan_id), - PAS_DMA_RXCHAN_BASEU_BRBH(ring->dma >> 32) | - PAS_DMA_RXCHAN_BASEU_SIZ(RX_RING_SIZE >> 2)); - - pci_write_config_dword(mac->dma_pdev, PAS_DMA_RXCHAN_CFG(chan_id), - PAS_DMA_RXCHAN_CFG_HBU(1)); - - pci_write_config_dword(mac->dma_pdev, PAS_DMA_RXINT_BASEL(mac->dma_if), - PAS_DMA_RXINT_BASEL_BRBL(__pa(ring->buffers))); - - pci_write_config_dword(mac->dma_pdev, PAS_DMA_RXINT_BASEU(mac->dma_if), - PAS_DMA_RXINT_BASEU_BRBH(__pa(ring->buffers) >> 32) | - PAS_DMA_RXINT_BASEU_SIZ(RX_RING_SIZE >> 3)); + write_dma_reg(mac, PAS_DMA_RXINT_BASEL(mac->dma_if), + PAS_DMA_RXINT_BASEL_BRBL(__pa(ring->buffers))); + + write_dma_reg(mac, PAS_DMA_RXINT_BASEU(mac->dma_if), + PAS_DMA_RXINT_BASEU_BRBH(__pa(ring->buffers) >> 32) | + PAS_DMA_RXINT_BASEU_SIZ(RX_RING_SIZE >> 3)); ring->next_to_fill = 0; ring->next_to_clean = 0; @@ -233,18 +274,18 @@ static int pasemi_mac_setup_tx_resources memset(ring->desc, 0, TX_RING_SIZE * sizeof(struct pas_dma_xct_descr)); - pci_write_config_dword(mac->dma_pdev, PAS_DMA_TXCHAN_BASEL(chan_id), - PAS_DMA_TXCHAN_BASEL_BRBL(ring->dma)); + write_dma_reg(mac, PAS_DMA_TXCHAN_BASEL(chan_id), + PAS_DMA_TXCHAN_BASEL_BRBL(ring->dma)); val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->dma >> 32); val |= PAS_DMA_TXCHAN_BASEU_SIZ(TX_RING_SIZE >> 2); - pci_write_config_dword(mac->dma_pdev, PAS_DMA_TXCHAN_BASEU(chan_id), val); + write_dma_reg(mac, PAS_DMA_TXCHAN_BASEU(chan_id), val); - pci_write_config_dword(mac->dma_pdev, PAS_DMA_TXCHAN_CFG(chan_id), - PAS_DMA_TXCHAN_CFG_TY_IFACE | - PAS_DMA_TXCHAN_CFG_TATTR(mac->dma_if) | - PAS_DMA_TXCHAN_CFG_UP | - PAS_DMA_TXCHAN_CFG_WT(2)); + write_dma_reg(mac, PAS_DMA_TXCHAN_CFG(chan_id), + PAS_DMA_TXCHAN_CFG_TY_IFACE | + PAS_DMA_TXCHAN_CFG_TATTR(mac->dma_if) | + PAS_DMA_TXCHAN_CFG_UP | + PAS_DMA_TXCHAN_CFG_WT(2)); ring->next_to_use = 0; ring->next_to_clean = 0; @@ -383,12 +424,8 @@ static void pasemi_mac_replenish_rx_ring wmb(); - pci_write_config_dword(mac->dma_pdev, - PAS_DMA_RXCHAN_INCR(mac->dma_rxch), - limit - count); - pci_write_config_dword(mac->dma_pdev, - PAS_DMA_RXINT_INCR(mac->dma_if), - limit - count); + write_dma_reg(mac, PAS_DMA_RXCHAN_INCR(mac->dma_rxch), limit - count); + write_dma_reg(mac, PAS_DMA_RXINT_INCR(mac->dma_if), limit - count); mac->rx->next_to_fill += limit - count; } @@ -404,9 +441,7 @@ static void pasemi_mac_restart_rx_intr(s reg = PAS_IOB_DMA_RXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_RXCH_RESET_PINTC; - pci_write_config_dword(mac->iob_pdev, - PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), - reg); + write_iob_reg(mac, PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), reg); } static void pasemi_mac_restart_tx_intr(struct pasemi_mac *mac) @@ -418,8 +453,7 @@ static void pasemi_mac_restart_tx_intr(s reg = PAS_IOB_DMA_TXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_TXCH_RESET_PINTC; - pci_write_config_dword(mac->iob_pdev, - PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg); + write_iob_reg(mac, PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg); } @@ -574,8 +608,6 @@ static irqreturn_t pasemi_mac_rx_intr(in * all others. */ - pci_read_config_dword(mac->dma_pdev, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), ®); - reg = 0; if (*mac->rx_status & PAS_STATUS_SOFT) reg |= PAS_IOB_DMA_RXCH_RESET_SINTC; @@ -586,9 +618,7 @@ static irqreturn_t pasemi_mac_rx_intr(in netif_rx_schedule(dev); - pci_write_config_dword(mac->iob_pdev, - PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), reg); - + write_iob_reg(mac, PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), reg); return IRQ_HANDLED; } @@ -613,9 +643,7 @@ static irqreturn_t pasemi_mac_tx_intr(in if (*mac->tx_status & PAS_STATUS_ERROR) reg |= PAS_IOB_DMA_TXCH_RESET_DINTC; - pci_write_config_dword(mac->iob_pdev, - PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), - reg); + write_iob_reg(mac, PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg); return IRQ_HANDLED; } @@ -641,7 +669,7 @@ static void pasemi_adjust_link(struct ne } else netif_carrier_on(dev); - pci_read_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, &flags); + flags = read_mac_reg(mac, PAS_MAC_CFG_PCFG); new_flags = flags & ~(PAS_MAC_CFG_PCFG_HD | PAS_MAC_CFG_PCFG_SPD_M | PAS_MAC_CFG_PCFG_TSR_M); @@ -673,7 +701,7 @@ static void pasemi_adjust_link(struct ne mac->link = mac->phydev->link; if (new_flags != flags) - pci_write_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, new_flags); + write_mac_reg(mac, PAS_MAC_CFG_PCFG, new_flags); if (msg && netif_msg_link(mac)) printk(KERN_INFO "%s: Link is up at %d Mbps, %s duplex.\n", @@ -736,39 +764,37 @@ static int pasemi_mac_open(struct net_de int ret; /* enable rx section */ - pci_write_config_dword(mac->dma_pdev, PAS_DMA_COM_RXCMD, - PAS_DMA_COM_RXCMD_EN); + write_dma_reg(mac, PAS_DMA_COM_RXCMD, PAS_DMA_COM_RXCMD_EN); /* enable tx section */ - pci_write_config_dword(mac->dma_pdev, PAS_DMA_COM_TXCMD, - PAS_DMA_COM_TXCMD_EN); + write_dma_reg(mac, PAS_DMA_COM_TXCMD, PAS_DMA_COM_TXCMD_EN); flags = PAS_MAC_CFG_TXP_FCE | PAS_MAC_CFG_TXP_FPC(3) | PAS_MAC_CFG_TXP_SL(3) | PAS_MAC_CFG_TXP_COB(0xf) | PAS_MAC_CFG_TXP_TIFT(8) | PAS_MAC_CFG_TXP_TIFG(12); - pci_write_config_dword(mac->pdev, PAS_MAC_CFG_TXP, flags); + write_mac_reg(mac, PAS_MAC_CFG_TXP, flags); flags = PAS_MAC_CFG_PCFG_S1 | PAS_MAC_CFG_PCFG_PE | PAS_MAC_CFG_PCFG_PR | PAS_MAC_CFG_PCFG_CE; flags |= PAS_MAC_CFG_PCFG_TSR_1G | PAS_MAC_CFG_PCFG_SPD_1G; - pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_RXCH_CFG(mac->dma_rxch), - PAS_IOB_DMA_RXCH_CFG_CNTTH(0)); + write_iob_reg(mac, PAS_IOB_DMA_RXCH_CFG(mac->dma_rxch), + PAS_IOB_DMA_RXCH_CFG_CNTTH(0)); - pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_CFG(mac->dma_txch), - PAS_IOB_DMA_TXCH_CFG_CNTTH(32)); + write_iob_reg(mac, PAS_IOB_DMA_TXCH_CFG(mac->dma_txch), + PAS_IOB_DMA_TXCH_CFG_CNTTH(32)); /* Clear out any residual packet count state from firmware */ pasemi_mac_restart_rx_intr(mac); pasemi_mac_restart_tx_intr(mac); /* 0xffffff is max value, about 16ms */ - pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_COM_TIMEOUTCFG, - PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0xffffff)); + write_iob_reg(mac, PAS_IOB_DMA_COM_TIMEOUTCFG, + PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0xffffff)); - pci_write_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, flags); + write_mac_reg(mac, PAS_MAC_CFG_PCFG, flags); ret = pasemi_mac_setup_rx_resources(dev); if (ret) @@ -778,25 +804,22 @@ static int pasemi_mac_open(struct net_de if (ret) goto out_tx_resources; - pci_write_config_dword(mac->pdev, PAS_MAC_IPC_CHNL, - PAS_MAC_IPC_CHNL_DCHNO(mac->dma_rxch) | - PAS_MAC_IPC_CHNL_BCH(mac->dma_rxch)); + write_mac_reg(mac, PAS_MAC_IPC_CHNL, + PAS_MAC_IPC_CHNL_DCHNO(mac->dma_rxch) | + PAS_MAC_IPC_CHNL_BCH(mac->dma_rxch)); /* enable rx if */ - pci_write_config_dword(mac->dma_pdev, - PAS_DMA_RXINT_RCMDSTA(mac->dma_if), - PAS_DMA_RXINT_RCMDSTA_EN); + write_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), + PAS_DMA_RXINT_RCMDSTA_EN); /* enable rx channel */ - pci_write_config_dword(mac->dma_pdev, - PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), - PAS_DMA_RXCHAN_CCMDSTA_EN | - PAS_DMA_RXCHAN_CCMDSTA_DU); + write_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), + PAS_DMA_RXCHAN_CCMDSTA_EN | + PAS_DMA_RXCHAN_CCMDSTA_DU); /* enable tx channel */ - pci_write_config_dword(mac->dma_pdev, - PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch), - PAS_DMA_TXCHAN_TCMDSTA_EN); + write_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch), + PAS_DMA_TXCHAN_TCMDSTA_EN); pasemi_mac_replenish_rx_ring(dev); @@ -875,20 +898,12 @@ static int pasemi_mac_close(struct net_d pasemi_mac_clean_rx(mac, RX_RING_SIZE); /* Disable interface */ - pci_write_config_dword(mac->dma_pdev, - PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch), - PAS_DMA_TXCHAN_TCMDSTA_ST); - pci_write_config_dword(mac->dma_pdev, - PAS_DMA_RXINT_RCMDSTA(mac->dma_if), - PAS_DMA_RXINT_RCMDSTA_ST); - pci_write_config_dword(mac->dma_pdev, - PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), - PAS_DMA_RXCHAN_CCMDSTA_ST); + write_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch), PAS_DMA_TXCHAN_TCMDSTA_ST); + write_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), PAS_DMA_RXINT_RCMDSTA_ST); + write_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), PAS_DMA_RXCHAN_CCMDSTA_ST); for (retries = 0; retries < MAX_RETRIES; retries++) { - pci_read_config_dword(mac->dma_pdev, - PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch), - &stat); + stat = read_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch)); if (!(stat & PAS_DMA_TXCHAN_TCMDSTA_ACT)) break; cond_resched(); @@ -898,9 +913,7 @@ static int pasemi_mac_close(struct net_d dev_err(&mac->dma_pdev->dev, "Failed to stop tx channel\n"); for (retries = 0; retries < MAX_RETRIES; retries++) { - pci_read_config_dword(mac->dma_pdev, - PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), - &stat); + stat = read_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch)); if (!(stat & PAS_DMA_RXCHAN_CCMDSTA_ACT)) break; cond_resched(); @@ -910,9 +923,7 @@ static int pasemi_mac_close(struct net_d dev_err(&mac->dma_pdev->dev, "Failed to stop rx channel\n"); for (retries = 0; retries < MAX_RETRIES; retries++) { - pci_read_config_dword(mac->dma_pdev, - PAS_DMA_RXINT_RCMDSTA(mac->dma_if), - &stat); + stat = read_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if)); if (!(stat & PAS_DMA_RXINT_RCMDSTA_ACT)) break; cond_resched(); @@ -925,12 +936,9 @@ static int pasemi_mac_close(struct net_d * stopping, since you can't disable when active. */ - pci_write_config_dword(mac->dma_pdev, - PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch), 0); - pci_write_config_dword(mac->dma_pdev, - PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), 0); - pci_write_config_dword(mac->dma_pdev, - PAS_DMA_RXINT_RCMDSTA(mac->dma_if), 0); + write_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch), 0); + write_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), 0); + write_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), 0); free_irq(mac->tx_irq, dev); free_irq(mac->rx_irq, dev); @@ -1011,8 +1019,7 @@ static int pasemi_mac_start_tx(struct sk spin_unlock_irqrestore(&txring->lock, flags); - pci_write_config_dword(mac->dma_pdev, - PAS_DMA_TXCHAN_INCR(mac->dma_txch), 1); + write_dma_reg(mac, PAS_DMA_TXCHAN_INCR(mac->dma_txch), 1); return NETDEV_TX_OK; @@ -1035,7 +1042,7 @@ static void pasemi_mac_set_rx_mode(struc struct pasemi_mac *mac = netdev_priv(dev); unsigned int flags; - pci_read_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, &flags); + flags = read_mac_reg(mac, PAS_MAC_CFG_PCFG); /* Set promiscuous */ if (dev->flags & IFF_PROMISC) @@ -1043,7 +1050,7 @@ static void pasemi_mac_set_rx_mode(struc else flags &= ~PAS_MAC_CFG_PCFG_PR; - pci_write_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, flags); + write_mac_reg(mac, PAS_MAC_CFG_PCFG, flags); } -- ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 3/9] pasemi_mac: Abstract out register access 2007-06-22 20:05 ` [PATCH 3/9] pasemi_mac: Abstract out register access Olof Johansson @ 2007-07-02 12:32 ` Jeff Garzik 0 siblings, 0 replies; 14+ messages in thread From: Jeff Garzik @ 2007-07-02 12:32 UTC (permalink / raw) To: Olof Johansson; +Cc: netdev Olof Johansson wrote: > Abstract out the PCI config read/write accesses into reg read/write ones, still > calling the pci accessors on the back end. > > Signed-off-by: Olof Johansson <olof@lixom.net> > > > Index: netdev-2.6/drivers/net/pasemi_mac.c > =================================================================== > --- netdev-2.6.orig/drivers/net/pasemi_mac.c > +++ netdev-2.6/drivers/net/pasemi_mac.c > @@ -81,6 +81,48 @@ MODULE_PARM_DESC(debug, "PA Semi MAC bit > > static struct pasdma_status *dma_status; > > +static unsigned int read_iob_reg(struct pasemi_mac *mac, unsigned int reg) > +{ > + unsigned int val; > + > + pci_read_config_dword(mac->iob_pdev, reg, &val); > + return val; > +} > + > +static void write_iob_reg(struct pasemi_mac *mac, unsigned int reg, > + unsigned int val) > +{ > + pci_write_config_dword(mac->iob_pdev, reg, val); > +} > + > +static unsigned int read_mac_reg(struct pasemi_mac *mac, unsigned int reg) > +{ > + unsigned int val; > + > + pci_read_config_dword(mac->pdev, reg, &val); > + return val; > +} > + > +static void write_mac_reg(struct pasemi_mac *mac, unsigned int reg, > + unsigned int val) > +{ > + pci_write_config_dword(mac->pdev, reg, val); > +} > + > +static unsigned int read_dma_reg(struct pasemi_mac *mac, unsigned int reg) > +{ > + unsigned int val; > + > + pci_read_config_dword(mac->dma_pdev, reg, &val); > + return val; > +} > + > +static void write_dma_reg(struct pasemi_mac *mac, unsigned int reg, > + unsigned int val) > +{ > + pci_write_config_dword(mac->dma_pdev, reg, val); > +} The general concept is fine, but you should use 'u32' and similar size-based types for your input and output values. ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 4/9] pasemi_mac: Use MMIO instead of pci config accessors [not found] <20070622194720.614405000@lixom.net> ` (2 preceding siblings ...) 2007-06-22 20:05 ` [PATCH 3/9] pasemi_mac: Abstract out register access Olof Johansson @ 2007-06-22 20:05 ` Olof Johansson 2007-07-02 12:37 ` Jeff Garzik 2007-06-22 20:05 ` [PATCH 5/9] pasemi_mac: Enable L2 caching of packet headers Olof Johansson ` (4 subsequent siblings) 8 siblings, 1 reply; 14+ messages in thread From: Olof Johansson @ 2007-06-22 20:05 UTC (permalink / raw) To: jgarzik; +Cc: netdev [-- Attachment #1: pasemi_mac-kill-pci-config-access --] [-- Type: text/plain, Size: 6918 bytes --] Move away from using the pci config access functions for simple register access. Our device has all of the registers in the config space (hey, from the hardware point of view it looks reasonable :-), so we need to somehow get to it. Newer firmwares have it in the device tree such that we can just get it and ioremap it there (in case it ever moves in future products). For now, provide a hardcoded fallback for older firmwares. Signed-off-by: Olof Johansson <olof@lixom.net> Index: netdev-2.6/drivers/net/pasemi_mac.c =================================================================== --- netdev-2.6.orig/drivers/net/pasemi_mac.c +++ netdev-2.6/drivers/net/pasemi_mac.c @@ -81,46 +81,47 @@ MODULE_PARM_DESC(debug, "PA Semi MAC bit static struct pasdma_status *dma_status; -static unsigned int read_iob_reg(struct pasemi_mac *mac, unsigned int reg) +static inline unsigned int read_iob_reg(struct pasemi_mac *mac, unsigned int reg) { unsigned int val; - pci_read_config_dword(mac->iob_pdev, reg, &val); + val = in_le32(mac->iob_regs+reg); + return val; } -static void write_iob_reg(struct pasemi_mac *mac, unsigned int reg, +static inline void write_iob_reg(struct pasemi_mac *mac, unsigned int reg, unsigned int val) { - pci_write_config_dword(mac->iob_pdev, reg, val); + out_le32(mac->iob_regs+reg, val); } -static unsigned int read_mac_reg(struct pasemi_mac *mac, unsigned int reg) +static inline unsigned int read_mac_reg(struct pasemi_mac *mac, unsigned int reg) { unsigned int val; - pci_read_config_dword(mac->pdev, reg, &val); + val = in_le32(mac->regs+reg); return val; } -static void write_mac_reg(struct pasemi_mac *mac, unsigned int reg, +static inline void write_mac_reg(struct pasemi_mac *mac, unsigned int reg, unsigned int val) { - pci_write_config_dword(mac->pdev, reg, val); + out_le32(mac->regs+reg, val); } -static unsigned int read_dma_reg(struct pasemi_mac *mac, unsigned int reg) +static inline unsigned int read_dma_reg(struct pasemi_mac *mac, unsigned int reg) { unsigned int val; - pci_read_config_dword(mac->dma_pdev, reg, &val); + val = in_le32(mac->dma_regs+reg); return val; } -static void write_dma_reg(struct pasemi_mac *mac, unsigned int reg, +static inline void write_dma_reg(struct pasemi_mac *mac, unsigned int reg, unsigned int val) { - pci_write_config_dword(mac->dma_pdev, reg, val); + out_le32(mac->dma_regs+reg, val); } static int pasemi_get_mac_addr(struct pasemi_mac *mac) @@ -585,7 +586,6 @@ static int pasemi_mac_clean_tx(struct pa } mac->tx->next_to_clean += count; spin_unlock_irqrestore(&mac->tx->lock, flags); - netif_wake_queue(mac->netdev); return count; @@ -1077,6 +1077,73 @@ static int pasemi_mac_poll(struct net_de } } +static inline void __iomem * __devinit map_onedev(struct pci_dev *p, int index) +{ + struct device_node *dn; + void __iomem *ret; + + dn = pci_device_to_OF_node(p); + if (!dn) + goto fallback; + + ret = of_iomap(dn, index); + if (!ret) + goto fallback; + + return ret; +fallback: + /* This is hardcoded and ugly, but we have some firmware versions + * who don't provide the register space in the device tree. Luckily + * they are at well-known locations so we can just do the math here. + */ + return ioremap(0xe0000000 + (p->devfn << 12), 0x1000); +} + +static int __devinit pasemi_mac_map_regs(struct pasemi_mac *mac) +{ + struct resource res; + struct device_node *dn; + int err; + + mac->dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL); + if (!mac->dma_pdev) { + dev_err(&mac->pdev->dev, "Can't find DMA Controller\n"); + return -ENODEV; + } + + mac->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL); + if (!mac->iob_pdev) { + dev_err(&mac->pdev->dev, "Can't find I/O Bridge\n"); + return -ENODEV; + } + + mac->regs = map_onedev(mac->pdev, 0); + mac->dma_regs = map_onedev(mac->dma_pdev, 0); + mac->iob_regs = map_onedev(mac->iob_pdev, 0); + + if (!mac->regs || !mac->dma_regs || !mac->iob_regs) { + dev_err(&mac->pdev->dev, "Can't map registers\n"); + return -ENODEV; + } + + /* The dma status structure is located in the I/O bridge, and + * is cache coherent. + */ + if (!dma_status) { + dn = pci_device_to_OF_node(mac->iob_pdev); + if (dn) + err = of_address_to_resource(dn, 1, &res); + if (!dn || err) { + /* Fallback for old firmware */ + res.start = 0xfd800000; + res.end = res.start + 0x1000; + } + dma_status = __ioremap(res.start, res.end-res.start, 0); + } + + return 0; +} + static int __devinit pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -1105,21 +1172,6 @@ pasemi_mac_probe(struct pci_dev *pdev, c mac->pdev = pdev; mac->netdev = dev; - mac->dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL); - - if (!mac->dma_pdev) { - dev_err(&pdev->dev, "Can't find DMA Controller\n"); - err = -ENODEV; - goto out_free_netdev; - } - - mac->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL); - - if (!mac->iob_pdev) { - dev_err(&pdev->dev, "Can't find I/O Bridge\n"); - err = -ENODEV; - goto out_put_dma_pdev; - } /* These should come out of the device tree eventually */ mac->dma_txch = index; @@ -1162,12 +1214,9 @@ pasemi_mac_probe(struct pci_dev *pdev, c dev->poll = pasemi_mac_poll; dev->features = NETIF_F_HW_CSUM; - /* The dma status structure is located in the I/O bridge, and - * is cache coherent. - */ - if (!dma_status) - /* XXXOJN This should come from the device tree */ - dma_status = __ioremap(0xfd800000, 0x1000, 0); + err = pasemi_mac_map_regs(mac); + if (err) + goto out; mac->rx_status = &dma_status->rx_sta[mac->dma_rxch]; mac->tx_status = &dma_status->tx_sta[mac->dma_txch]; @@ -1194,10 +1243,17 @@ pasemi_mac_probe(struct pci_dev *pdev, c return err; out: - pci_dev_put(mac->iob_pdev); -out_put_dma_pdev: - pci_dev_put(mac->dma_pdev); -out_free_netdev: + if (mac->iob_pdev) + pci_dev_put(mac->iob_pdev); + if (mac->dma_pdev) + pci_dev_put(mac->dma_pdev); + if (mac->dma_regs) + iounmap(mac->dma_regs); + if (mac->iob_regs) + iounmap(mac->iob_regs); + if (mac->regs) + iounmap(mac->regs); + free_netdev(dev); out_disable_device: pci_disable_device(pdev); @@ -1221,6 +1277,10 @@ static void __devexit pasemi_mac_remove( pci_dev_put(mac->dma_pdev); pci_dev_put(mac->iob_pdev); + iounmap(mac->regs); + iounmap(mac->dma_regs); + iounmap(mac->iob_regs); + pci_set_drvdata(pdev, NULL); free_netdev(netdev); } Index: netdev-2.6/drivers/net/pasemi_mac.h =================================================================== --- netdev-2.6.orig/drivers/net/pasemi_mac.h +++ netdev-2.6/drivers/net/pasemi_mac.h @@ -52,6 +52,9 @@ struct pasemi_mac_rxring { struct pasemi_mac { struct net_device *netdev; + void __iomem *regs; + void __iomem *dma_regs; + void __iomem *iob_regs; struct pci_dev *pdev; struct pci_dev *dma_pdev; struct pci_dev *iob_pdev; -- ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 4/9] pasemi_mac: Use MMIO instead of pci config accessors 2007-06-22 20:05 ` [PATCH 4/9] pasemi_mac: Use MMIO instead of pci config accessors Olof Johansson @ 2007-07-02 12:37 ` Jeff Garzik 0 siblings, 0 replies; 14+ messages in thread From: Jeff Garzik @ 2007-07-02 12:37 UTC (permalink / raw) To: Olof Johansson; +Cc: netdev Olof Johansson wrote: > Move away from using the pci config access functions for simple register > access. Our device has all of the registers in the config space (hey, > from the hardware point of view it looks reasonable :-), so we need to > somehow get to it. Newer firmwares have it in the device tree such that > we can just get it and ioremap it there (in case it ever moves in future > products). For now, provide a hardcoded fallback for older firmwares. > > > Signed-off-by: Olof Johansson <olof@lixom.net> patches 4-9 seen sane. dropped due to previous patches being dropped ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 5/9] pasemi_mac: Enable L2 caching of packet headers [not found] <20070622194720.614405000@lixom.net> ` (3 preceding siblings ...) 2007-06-22 20:05 ` [PATCH 4/9] pasemi_mac: Use MMIO instead of pci config accessors Olof Johansson @ 2007-06-22 20:05 ` Olof Johansson 2007-06-22 20:05 ` [PATCH 6/9] pasemi_mac: Simplify memcpy for short receives Olof Johansson ` (3 subsequent siblings) 8 siblings, 0 replies; 14+ messages in thread From: Olof Johansson @ 2007-06-22 20:05 UTC (permalink / raw) To: jgarzik; +Cc: netdev [-- Attachment #1: pasemi_mac-cache-headers --] [-- Type: text/plain, Size: 1923 bytes --] Enable settings to target L2 for the first few cachelines of the packet, since we'll access them to get to the various headers. Signed-off-by: Olof Johansson <olof@lixom.net> Index: netdev-2.6/drivers/net/pasemi_mac.c =================================================================== --- netdev-2.6.orig/drivers/net/pasemi_mac.c +++ netdev-2.6/drivers/net/pasemi_mac.c @@ -216,7 +216,7 @@ static int pasemi_mac_setup_rx_resources PAS_DMA_RXCHAN_BASEU_SIZ(RX_RING_SIZE >> 2)); write_dma_reg(mac, PAS_DMA_RXCHAN_CFG(chan_id), - PAS_DMA_RXCHAN_CFG_HBU(1)); + PAS_DMA_RXCHAN_CFG_HBU(2)); write_dma_reg(mac, PAS_DMA_RXINT_BASEL(mac->dma_if), PAS_DMA_RXINT_BASEL_BRBL(__pa(ring->buffers))); @@ -225,6 +225,9 @@ static int pasemi_mac_setup_rx_resources PAS_DMA_RXINT_BASEU_BRBH(__pa(ring->buffers) >> 32) | PAS_DMA_RXINT_BASEU_SIZ(RX_RING_SIZE >> 3)); + write_dma_reg(mac, PAS_DMA_RXINT_CFG(mac->dma_if), + PAS_DMA_RXINT_CFG_DHL(2)); + ring->next_to_fill = 0; ring->next_to_clean = 0; Index: netdev-2.6/drivers/net/pasemi_mac.h =================================================================== --- netdev-2.6.orig/drivers/net/pasemi_mac.h +++ netdev-2.6/drivers/net/pasemi_mac.h @@ -218,6 +218,14 @@ enum { #define PAS_DMA_RXINT_RCMDSTA_ACT 0x00010000 #define PAS_DMA_RXINT_RCMDSTA_DROPS_M 0xfffe0000 #define PAS_DMA_RXINT_RCMDSTA_DROPS_S 17 +#define PAS_DMA_RXINT_CFG(i) (0x204+(i)*_PAS_DMA_RXINT_STRIDE) +#define PAS_DMA_RXINT_CFG_DHL_M 0x07000000 +#define PAS_DMA_RXINT_CFG_DHL_S 24 +#define PAS_DMA_RXINT_CFG_DHL(x) (((x) << PAS_DMA_RXINT_CFG_DHL_S) & \ + PAS_DMA_RXINT_CFG_DHL_M) +#define PAS_DMA_RXINT_CFG_WIF 0x00000002 +#define PAS_DMA_RXINT_CFG_WIL 0x00000001 + #define PAS_DMA_RXINT_INCR(i) (0x210+(i)*_PAS_DMA_RXINT_STRIDE) #define PAS_DMA_RXINT_INCR_INCR_M 0x0000ffff #define PAS_DMA_RXINT_INCR_INCR_S 0 -- ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 6/9] pasemi_mac: Simplify memcpy for short receives [not found] <20070622194720.614405000@lixom.net> ` (4 preceding siblings ...) 2007-06-22 20:05 ` [PATCH 5/9] pasemi_mac: Enable L2 caching of packet headers Olof Johansson @ 2007-06-22 20:05 ` Olof Johansson 2007-06-22 20:05 ` [PATCH 7/9] pasemi_mac: Minor performance tweaks Olof Johansson ` (2 subsequent siblings) 8 siblings, 0 replies; 14+ messages in thread From: Olof Johansson @ 2007-06-22 20:05 UTC (permalink / raw) To: jgarzik; +Cc: netdev [-- Attachment #1: pasemi_mac-bugfix --] [-- Type: text/plain, Size: 732 bytes --] No need to copy over the skipped align bytes (besides, NET_IP_ALIGN is 0 on ppc64). Signed-off-by: Olof Johansson <olof@lixom.net> Index: netdev-2.6/drivers/net/pasemi_mac.c =================================================================== --- netdev-2.6.orig/drivers/net/pasemi_mac.c +++ netdev-2.6/drivers/net/pasemi_mac.c @@ -516,9 +516,7 @@ static int pasemi_mac_clean_rx(struct pa netdev_alloc_skb(mac->netdev, len + NET_IP_ALIGN); if (new_skb) { skb_reserve(new_skb, NET_IP_ALIGN); - memcpy(new_skb->data - NET_IP_ALIGN, - skb->data - NET_IP_ALIGN, - len + NET_IP_ALIGN); + memcpy(new_skb->data, skb->data, len); /* save the skb in buffer_info as good */ skb = new_skb; } -- ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 7/9] pasemi_mac: Minor performance tweaks [not found] <20070622194720.614405000@lixom.net> ` (5 preceding siblings ...) 2007-06-22 20:05 ` [PATCH 6/9] pasemi_mac: Simplify memcpy for short receives Olof Johansson @ 2007-06-22 20:05 ` Olof Johansson 2007-06-22 20:05 ` [PATCH 8/9] pasemi_mac: Reduce locking when cleaning TX ring Olof Johansson 2007-06-22 20:05 ` [PATCH 9/9] pasemi_mac: Enable LLTX Olof Johansson 8 siblings, 0 replies; 14+ messages in thread From: Olof Johansson @ 2007-06-22 20:05 UTC (permalink / raw) To: jgarzik; +Cc: netdev [-- Attachment #1: pasemi_mac-rxperf --] [-- Type: text/plain, Size: 2471 bytes --] Various minor performance tweaks, do some explicit prefetching of packet data, etc. Signed-off-by: Olof Johansson <olof@lixom.net> Index: netdev-2.6/drivers/net/pasemi_mac.c =================================================================== --- netdev-2.6.orig/drivers/net/pasemi_mac.c +++ netdev-2.6/drivers/net/pasemi_mac.c @@ -481,6 +481,7 @@ static int pasemi_mac_clean_rx(struct pa rmb(); dp = &RX_DESC(mac, n); + prefetchw(dp); macrx = dp->macrx; if (!(macrx & XCT_MACRX_O)) @@ -502,8 +503,10 @@ static int pasemi_mac_clean_rx(struct pa if (info->dma == dma) break; } + prefetchw(info); skb = info->skb; + prefetchw(skb); info->dma = 0; pci_unmap_single(mac->dma_pdev, dma, skb->len, @@ -526,9 +529,7 @@ static int pasemi_mac_clean_rx(struct pa skb_put(skb, len); - skb->protocol = eth_type_trans(skb, mac->netdev); - - if ((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK) { + if (likely((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK)) { skb->ip_summed = CHECKSUM_COMPLETE; skb->csum = (macrx & XCT_MACRX_CSUM_M) >> XCT_MACRX_CSUM_S; @@ -538,6 +539,7 @@ static int pasemi_mac_clean_rx(struct pa mac->stats.rx_bytes += len; mac->stats.rx_packets++; + skb->protocol = eth_type_trans(skb, mac->netdev); netif_receive_skb(skb); dp->ptr = 0; @@ -569,7 +571,7 @@ static int pasemi_mac_clean_tx(struct pa for (i = start; i < mac->tx->next_to_use; i++) { dp = &TX_DESC(mac, i); - if (!dp || (dp->mactx & XCT_MACTX_O)) + if (unlikely(dp->mactx & XCT_MACTX_O)) break; count++; @@ -957,7 +959,7 @@ static int pasemi_mac_start_tx(struct sk struct pasemi_mac_txring *txring; struct pasemi_mac_buffer *info; struct pas_dma_xct_descr *dp; - u64 dflags; + u64 dflags, mactx, ptr; dma_addr_t map; int flags; @@ -985,6 +987,9 @@ static int pasemi_mac_start_tx(struct sk if (dma_mapping_error(map)) return NETDEV_TX_BUSY; + mactx = dflags | XCT_MACTX_LLEN(skb->len); + ptr = XCT_PTR_LEN(skb->len) | XCT_PTR_ADDR(map); + txring = mac->tx; spin_lock_irqsave(&txring->lock, flags); @@ -1005,12 +1010,11 @@ static int pasemi_mac_start_tx(struct sk } } - dp = &TX_DESC(mac, txring->next_to_use); info = &TX_DESC_INFO(mac, txring->next_to_use); - dp->mactx = dflags | XCT_MACTX_LLEN(skb->len); - dp->ptr = XCT_PTR_LEN(skb->len) | XCT_PTR_ADDR(map); + dp->mactx = mactx; + dp->ptr = ptr; info->dma = map; info->skb = skb; -- ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 8/9] pasemi_mac: Reduce locking when cleaning TX ring [not found] <20070622194720.614405000@lixom.net> ` (6 preceding siblings ...) 2007-06-22 20:05 ` [PATCH 7/9] pasemi_mac: Minor performance tweaks Olof Johansson @ 2007-06-22 20:05 ` Olof Johansson 2007-06-22 20:05 ` [PATCH 9/9] pasemi_mac: Enable LLTX Olof Johansson 8 siblings, 0 replies; 14+ messages in thread From: Olof Johansson @ 2007-06-22 20:05 UTC (permalink / raw) To: jgarzik; +Cc: netdev [-- Attachment #1: pasemi_mac-tx-lock-reduction --] [-- Type: text/plain, Size: 1780 bytes --] Postpone pci unmap and skb free of the transmitted buffers to outside of the tx ring lock, batching them up 32 at a time. Signed-off-by: Olof Johansson <olof@lixom.net> Index: netdev-2.6/drivers/net/pasemi_mac.c =================================================================== --- netdev-2.6.orig/drivers/net/pasemi_mac.c +++ netdev-2.6/drivers/net/pasemi_mac.c @@ -562,37 +562,56 @@ static int pasemi_mac_clean_tx(struct pa int i; struct pasemi_mac_buffer *info; struct pas_dma_xct_descr *dp; - int start, count; + unsigned int start, count, limit; + unsigned int total_count; int flags; + struct sk_buff *skbs[32]; + dma_addr_t dmas[32]; + total_count = 0; +restart: spin_lock_irqsave(&mac->tx->lock, flags); start = mac->tx->next_to_clean; + limit = min(mac->tx->next_to_use, start+32); + count = 0; - for (i = start; i < mac->tx->next_to_use; i++) { + for (i = start; i < limit; i++) { dp = &TX_DESC(mac, i); + if (unlikely(dp->mactx & XCT_MACTX_O)) + /* Not yet transmitted */ break; - count++; - info = &TX_DESC_INFO(mac, i); - - pci_unmap_single(mac->dma_pdev, info->dma, - info->skb->len, PCI_DMA_TODEVICE); - dev_kfree_skb_irq(info->skb); + skbs[count] = info->skb; + dmas[count] = info->dma; info->skb = NULL; info->dma = 0; dp->mactx = 0; dp->ptr = 0; + + count++; } mac->tx->next_to_clean += count; spin_unlock_irqrestore(&mac->tx->lock, flags); netif_wake_queue(mac->netdev); - return count; + for (i = 0; i < count; i++) { + pci_unmap_single(mac->dma_pdev, dmas[i], + skbs[i]->len, PCI_DMA_TODEVICE); + dev_kfree_skb_irq(skbs[i]); + } + + total_count += count; + + /* If the batch was full, try to clean more */ + if (count == 32) + goto restart; + + return total_count; } -- ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 9/9] pasemi_mac: Enable LLTX [not found] <20070622194720.614405000@lixom.net> ` (7 preceding siblings ...) 2007-06-22 20:05 ` [PATCH 8/9] pasemi_mac: Reduce locking when cleaning TX ring Olof Johansson @ 2007-06-22 20:05 ` Olof Johansson 8 siblings, 0 replies; 14+ messages in thread From: Olof Johansson @ 2007-06-22 20:05 UTC (permalink / raw) To: jgarzik; +Cc: netdev [-- Attachment #1: pasemi_mac-enable-lltx --] [-- Type: text/plain, Size: 642 bytes --] Enable LLTX on pasemi_mac: we're already doing sufficient locking in the driver to enable it. Signed-off-by: Olof Johansson <olof@lixom.net> Index: netdev-2.6/drivers/net/pasemi_mac.c =================================================================== --- netdev-2.6.orig/drivers/net/pasemi_mac.c +++ netdev-2.6/drivers/net/pasemi_mac.c @@ -1239,7 +1239,7 @@ pasemi_mac_probe(struct pci_dev *pdev, c dev->set_multicast_list = pasemi_mac_set_rx_mode; dev->weight = 64; dev->poll = pasemi_mac_poll; - dev->features = NETIF_F_HW_CSUM; + dev->features = NETIF_F_HW_CSUM | NETIF_F_LLTX; err = pasemi_mac_map_regs(mac); if (err) -- ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2007-07-03 20:21 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20070622194720.614405000@lixom.net>
2007-06-22 20:04 ` [PATCH 1/9] pasemi_mac: Fix TX interrupt threshold Olof Johansson
2007-07-02 12:37 ` Jeff Garzik
2007-06-22 20:05 ` [PATCH 2/9] pasemi_mac: Clean TX ring in poll Olof Johansson
2007-07-02 12:34 ` Jeff Garzik
2007-07-03 20:31 ` Olof Johansson
2007-06-22 20:05 ` [PATCH 3/9] pasemi_mac: Abstract out register access Olof Johansson
2007-07-02 12:32 ` Jeff Garzik
2007-06-22 20:05 ` [PATCH 4/9] pasemi_mac: Use MMIO instead of pci config accessors Olof Johansson
2007-07-02 12:37 ` Jeff Garzik
2007-06-22 20:05 ` [PATCH 5/9] pasemi_mac: Enable L2 caching of packet headers Olof Johansson
2007-06-22 20:05 ` [PATCH 6/9] pasemi_mac: Simplify memcpy for short receives Olof Johansson
2007-06-22 20:05 ` [PATCH 7/9] pasemi_mac: Minor performance tweaks Olof Johansson
2007-06-22 20:05 ` [PATCH 8/9] pasemi_mac: Reduce locking when cleaning TX ring Olof Johansson
2007-06-22 20:05 ` [PATCH 9/9] pasemi_mac: Enable LLTX Olof Johansson
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).