lkml.org 
[lkml]   [2006]   [Oct]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    Subject[PATCH 21/21]: powerpc/cell spidernet DMA coalescing
    From

    The current driver code performs 512 DMA mappns of a bunch of
    32-byte structures. This is silly, as they are all in contiguous
    memory. Ths patch changes the code to DMA map the entie area
    with just one call.

    Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
    Cc: James K Lewis <jklewis@us.ibm.com>
    Cc: Arnd Bergmann <arnd@arndb.de>

    ----
    drivers/net/spider_net.c | 107 +++++++++++++++++++++++------------------------
    drivers/net/spider_net.h | 16 ++-----
    2 files changed, 59 insertions(+), 64 deletions(-)

    Index: linux-2.6.18-mm2/drivers/net/spider_net.c
    ===================================================================
    --- linux-2.6.18-mm2.orig/drivers/net/spider_net.c 2006-10-10 13:40:56.000000000 -0500
    +++ linux-2.6.18-mm2/drivers/net/spider_net.c 2006-10-10 13:42:12.000000000 -0500
    @@ -267,25 +267,6 @@ spider_net_get_descr_status(struct spide
    }

    /**
    - * spider_net_free_chain - free descriptor chain
    - * @card: card structure
    - * @chain: address of chain
    - *
    - */
    -static void
    -spider_net_free_chain(struct spider_net_card *card,
    - struct spider_net_descr_chain *chain)
    -{
    - struct spider_net_descr *descr;
    -
    - for (descr = chain->tail; !descr->bus_addr; descr = descr->next) {
    - pci_unmap_single(card->pdev, descr->bus_addr,
    - SPIDER_NET_DESCR_SIZE, PCI_DMA_BIDIRECTIONAL);
    - descr->bus_addr = 0;
    - }
    -}
    -
    -/**
    * spider_net_init_chain - links descriptor chain
    * @card: card structure
    * @chain: address of chain
    @@ -297,15 +278,15 @@ spider_net_free_chain(struct spider_net_
    *
    * returns 0 on success, <0 on failure
    */
    -static int
    +static void
    spider_net_init_chain(struct spider_net_card *card,
    struct spider_net_descr_chain *chain,
    struct spider_net_descr *start_descr,
    + dma_addr_t buf,
    int no)
    {
    int i;
    struct spider_net_descr *descr;
    - dma_addr_t buf;

    descr = start_descr;
    memset(descr, 0, sizeof(*descr) * no);
    @@ -314,17 +295,12 @@ spider_net_init_chain(struct spider_net_
    for (i=0; i<no; i++, descr++) {
    descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE;

    - buf = pci_map_single(card->pdev, descr,
    - SPIDER_NET_DESCR_SIZE,
    - PCI_DMA_BIDIRECTIONAL);
    -
    - if (pci_dma_mapping_error(buf))
    - goto iommu_error;
    -
    descr->bus_addr = buf;
    + descr->next_descr_addr = 0;
    descr->next = descr + 1;
    descr->prev = descr - 1;

    + buf += sizeof(struct spider_net_descr);
    }
    /* do actual circular list */
    (descr-1)->next = start_descr;
    @@ -333,17 +309,6 @@ spider_net_init_chain(struct spider_net_
    spin_lock_init(&chain->lock);
    chain->head = start_descr;
    chain->tail = start_descr;
    -
    - return 0;
    -
    -iommu_error:
    - descr = start_descr;
    - for (i=0; i < no; i++, descr++)
    - if (descr->bus_addr)
    - pci_unmap_single(card->pdev, descr->bus_addr,
    - SPIDER_NET_DESCR_SIZE,
    - PCI_DMA_BIDIRECTIONAL);
    - return -ENOMEM;
    }

    /**
    @@ -1658,24 +1623,32 @@ spider_net_open(struct net_device *netde
    {
    struct spider_net_card *card = netdev_priv(netdev);
    struct spider_net_descr *descr;
    - int i, result;
    + int result = -ENOMEM;

    - result = -ENOMEM;
    - if (spider_net_init_chain(card, &card->tx_chain, card->descr,
    - card->num_tx_desc))
    - goto alloc_tx_failed;
    + card->descr_dma_addr = pci_map_single(card->pdev, card->descr,
    + (card->num_tx_desc+card->num_rx_desc)*sizeof(struct spider_net_descr),
    + PCI_DMA_BIDIRECTIONAL);
    + if (pci_dma_mapping_error(card->descr_dma_addr))
    + return -ENOMEM;
    +
    + spider_net_init_chain(card, &card->tx_chain, card->descr,
    + card->descr_dma_addr,
    + card->num_tx_desc);

    card->low_watermark = NULL;

    /* rx_chain is after tx_chain, so offset is descr + tx_count */
    - if (spider_net_init_chain(card, &card->rx_chain,
    + spider_net_init_chain(card, &card->rx_chain,
    card->descr + card->num_tx_desc,
    - card->num_rx_desc))
    - goto alloc_rx_failed;
    + card->descr_dma_addr
    + + card->num_tx_desc * sizeof(struct spider_net_descr),
    + card->num_rx_desc);

    descr = card->rx_chain.head;
    - for (i=0; i < card->num_rx_desc; i++, descr++)
    + do {
    descr->next_descr_addr = descr->next->bus_addr;
    + descr = descr->next;
    + } while (descr != card->rx_chain.head);

    /* allocate rx skbs */
    if (spider_net_alloc_rx_skbs(card))
    @@ -1701,10 +1674,21 @@ spider_net_open(struct net_device *netde
    register_int_failed:
    spider_net_free_rx_chain_contents(card);
    alloc_skbs_failed:
    - spider_net_free_chain(card, &card->rx_chain);
    -alloc_rx_failed:
    - spider_net_free_chain(card, &card->tx_chain);
    -alloc_tx_failed:
    + descr = card->rx_chain.head;
    + do {
    + descr->bus_addr = 0;
    + descr = descr->next;
    + } while (descr != card->rx_chain.head);
    +
    + descr = card->tx_chain.head;
    + do {
    + descr->bus_addr = 0;
    + descr = descr->next;
    + } while (descr != card->tx_chain.head);
    +
    + pci_unmap_single(card->pdev, card->descr_dma_addr,
    + (card->num_tx_desc+card->num_rx_desc)*sizeof(struct spider_net_descr),
    + PCI_DMA_BIDIRECTIONAL);
    return result;
    }

    @@ -1907,6 +1891,7 @@ int
    spider_net_stop(struct net_device *netdev)
    {
    struct spider_net_card *card = netdev_priv(netdev);
    + struct spider_net_descr *descr;

    tasklet_kill(&card->rxram_full_tl);
    netif_poll_disable(netdev);
    @@ -1930,9 +1915,23 @@ spider_net_stop(struct net_device *netde

    /* release chains */
    spider_net_release_tx_chain(card, 1);
    + spider_net_free_rx_chain_contents(card);
    +
    + descr = card->rx_chain.head;
    + do {
    + descr->bus_addr = 0;
    + descr = descr->next;
    + } while (descr != card->rx_chain.head);
    +
    + descr = card->tx_chain.head;
    + do {
    + descr->bus_addr = 0;
    + descr = descr->next;
    + } while (descr != card->tx_chain.head);

    - spider_net_free_chain(card, &card->tx_chain);
    - spider_net_free_chain(card, &card->rx_chain);
    + pci_unmap_single(card->pdev, card->descr_dma_addr,
    + (card->num_tx_desc+card->num_rx_desc)*sizeof(struct spider_net_descr),
    + PCI_DMA_BIDIRECTIONAL);

    return 0;
    }
    Index: linux-2.6.18-mm2/drivers/net/spider_net.h
    ===================================================================
    --- linux-2.6.18-mm2.orig/drivers/net/spider_net.h 2006-10-10 13:35:33.000000000 -0500
    +++ linux-2.6.18-mm2/drivers/net/spider_net.h 2006-10-10 13:42:12.000000000 -0500
    @@ -397,8 +397,6 @@ struct spider_net_descr_chain {
    * 701b8000 would be correct, but every packets gets that flag */
    #define SPIDER_NET_DESTROY_RX_FLAGS 0x700b8000

    -#define SPIDER_NET_DESCR_SIZE 32
    -
    /* this will be bigger some time */
    struct spider_net_options {
    int rx_csum; /* for rx: if 0 ip_summed=NONE,
    @@ -437,28 +435,26 @@ struct spider_net_card {

    void __iomem *regs;

    + int num_rx_desc;
    + int num_tx_desc;
    struct spider_net_descr_chain tx_chain;
    struct spider_net_descr_chain rx_chain;
    struct spider_net_descr *low_watermark;
    + dma_addr_t descr_dma_addr;

    - struct net_device_stats netdev_stats;
    -
    - struct spider_net_options options;
    -
    - spinlock_t intmask_lock;
    struct tasklet_struct rxram_full_tl;
    struct timer_list tx_timer;
    -
    struct work_struct tx_timeout_task;
    atomic_t tx_timeout_task_counter;
    wait_queue_head_t waitq;

    /* for ethtool */
    int msg_enable;
    - int num_rx_desc;
    - int num_tx_desc;
    + struct net_device_stats netdev_stats;
    struct spider_net_extra_stats spider_stats;
    + struct spider_net_options options;

    + /* Must be last element in the structure */
    struct spider_net_descr descr[0];
    };

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2006-10-10 23:25    [W:4.734 / U:2.980 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site