ibmvnic: Create init and release routines for the rx pool
authorNathan Fontenot <nfont@linux.vnet.ibm.com>
Thu, 30 Mar 2017 06:49:12 +0000 (02:49 -0400)
committerDavid S. Miller <davem@davemloft.net>
Thu, 30 Mar 2017 22:58:42 +0000 (15:58 -0700)
Move the initialization and the release of the rx pool to their own
routines, and update them to do validation.

Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/ibm/ibmvnic.c

index a9399e96e94238d2c5dbd5f16624a0cb3f3b0aa1..6774b3cbc5f96ca4d3f7e2b65b2a2257c6515f25 100644 (file)
@@ -163,21 +163,6 @@ static long h_reg_sub_crq(unsigned long unit_address, unsigned long token,
        return rc;
 }
 
-/* net_device_ops functions */
-
-static void init_rx_pool(struct ibmvnic_adapter *adapter,
-                        struct ibmvnic_rx_pool *rx_pool, int num, int index,
-                        int buff_size, int active)
-{
-       netdev_dbg(adapter->netdev,
-                  "Initializing rx_pool %d, %d buffs, %d bytes each\n",
-                  index, num, buff_size);
-       rx_pool->size = num;
-       rx_pool->index = index;
-       rx_pool->buff_size = buff_size;
-       rx_pool->active = active;
-}
-
 static int alloc_long_term_buff(struct ibmvnic_adapter *adapter,
                                struct ibmvnic_long_term_buff *ltb, int size)
 {
@@ -214,42 +199,6 @@ static void free_long_term_buff(struct ibmvnic_adapter *adapter,
                send_request_unmap(adapter, ltb->map_id);
 }
 
-static int alloc_rx_pool(struct ibmvnic_adapter *adapter,
-                        struct ibmvnic_rx_pool *pool)
-{
-       struct device *dev = &adapter->vdev->dev;
-       int i;
-
-       pool->free_map = kcalloc(pool->size, sizeof(int), GFP_KERNEL);
-       if (!pool->free_map)
-               return -ENOMEM;
-
-       pool->rx_buff = kcalloc(pool->size, sizeof(struct ibmvnic_rx_buff),
-                               GFP_KERNEL);
-
-       if (!pool->rx_buff) {
-               dev_err(dev, "Couldn't alloc rx buffers\n");
-               kfree(pool->free_map);
-               return -ENOMEM;
-       }
-
-       if (alloc_long_term_buff(adapter, &pool->long_term_buff,
-                                pool->size * pool->buff_size)) {
-               kfree(pool->free_map);
-               kfree(pool->rx_buff);
-               return -ENOMEM;
-       }
-
-       for (i = 0; i < pool->size; ++i)
-               pool->free_map[i] = i;
-
-       atomic_set(&pool->available, 0);
-       pool->next_alloc = 0;
-       pool->next_free = 0;
-
-       return 0;
-}
-
 static void replenish_rx_pool(struct ibmvnic_adapter *adapter,
                              struct ibmvnic_rx_pool *pool)
 {
@@ -354,25 +303,105 @@ static void replenish_pools(struct ibmvnic_adapter *adapter)
        }
 }
 
-static void free_rx_pool(struct ibmvnic_adapter *adapter,
-                        struct ibmvnic_rx_pool *pool)
+static void release_rx_pools(struct ibmvnic_adapter *adapter)
 {
-       int i;
-
-       kfree(pool->free_map);
-       pool->free_map = NULL;
+       struct ibmvnic_rx_pool *rx_pool;
+       int rx_scrqs;
+       int i, j;
 
-       if (!pool->rx_buff)
+       if (!adapter->rx_pool)
                return;
 
-       for (i = 0; i < pool->size; i++) {
-               if (pool->rx_buff[i].skb) {
-                       dev_kfree_skb_any(pool->rx_buff[i].skb);
-                       pool->rx_buff[i].skb = NULL;
+       rx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs);
+       for (i = 0; i < rx_scrqs; i++) {
+               rx_pool = &adapter->rx_pool[i];
+
+               kfree(rx_pool->free_map);
+               free_long_term_buff(adapter, &rx_pool->long_term_buff);
+
+               if (!rx_pool->rx_buff)
+               continue;
+
+               for (j = 0; j < rx_pool->size; j++) {
+                       if (rx_pool->rx_buff[j].skb) {
+                               dev_kfree_skb_any(rx_pool->rx_buff[i].skb);
+                               rx_pool->rx_buff[i].skb = NULL;
+                       }
+               }
+
+               kfree(rx_pool->rx_buff);
+       }
+
+       kfree(adapter->rx_pool);
+       adapter->rx_pool = NULL;
+}
+
+static int init_rx_pools(struct net_device *netdev)
+{
+       struct ibmvnic_adapter *adapter = netdev_priv(netdev);
+       struct device *dev = &adapter->vdev->dev;
+       struct ibmvnic_rx_pool *rx_pool;
+       int rxadd_subcrqs;
+       u64 *size_array;
+       int i, j;
+
+       rxadd_subcrqs =
+               be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs);
+       size_array = (u64 *)((u8 *)(adapter->login_rsp_buf) +
+               be32_to_cpu(adapter->login_rsp_buf->off_rxadd_buff_size));
+
+       adapter->rx_pool = kcalloc(rxadd_subcrqs,
+                                  sizeof(struct ibmvnic_rx_pool),
+                                  GFP_KERNEL);
+       if (!adapter->rx_pool) {
+               dev_err(dev, "Failed to allocate rx pools\n");
+               return -1;
+       }
+
+       for (i = 0; i < rxadd_subcrqs; i++) {
+               rx_pool = &adapter->rx_pool[i];
+
+               netdev_dbg(adapter->netdev,
+                          "Initializing rx_pool %d, %lld buffs, %lld bytes each\n",
+                          i, adapter->req_rx_add_entries_per_subcrq,
+                          be64_to_cpu(size_array[i]));
+
+               rx_pool->size = adapter->req_rx_add_entries_per_subcrq;
+               rx_pool->index = i;
+               rx_pool->buff_size = be64_to_cpu(size_array[i]);
+               rx_pool->active = 1;
+
+               rx_pool->free_map = kcalloc(rx_pool->size, sizeof(int),
+                                           GFP_KERNEL);
+               if (!rx_pool->free_map) {
+                       release_rx_pools(adapter);
+                       return -1;
+               }
+
+               rx_pool->rx_buff = kcalloc(rx_pool->size,
+                                          sizeof(struct ibmvnic_rx_buff),
+                                          GFP_KERNEL);
+               if (!rx_pool->rx_buff) {
+                       dev_err(dev, "Couldn't alloc rx buffers\n");
+                       release_rx_pools(adapter);
+                       return -1;
+               }
+
+               if (alloc_long_term_buff(adapter, &rx_pool->long_term_buff,
+                                        rx_pool->size * rx_pool->buff_size)) {
+                       release_rx_pools(adapter);
+                       return -1;
                }
+
+               for (j = 0; j < rx_pool->size; ++j)
+                       rx_pool->free_map[j] = j;
+
+               atomic_set(&rx_pool->available, 0);
+               rx_pool->next_alloc = 0;
+               rx_pool->next_free = 0;
        }
-       kfree(pool->rx_buff);
-       pool->rx_buff = NULL;
+
+       return 0;
 }
 
 static void release_tx_pools(struct ibmvnic_adapter *adapter)
@@ -526,10 +555,9 @@ static int ibmvnic_open(struct net_device *netdev)
        struct device *dev = &adapter->vdev->dev;
        union ibmvnic_crq crq;
        int rxadd_subcrqs;
-       u64 *size_array;
        int tx_subcrqs;
        int rc = 0;
-       int i, j;
+       int i;
 
        if (adapter->is_closed) {
                rc = ibmvnic_init(adapter);
@@ -557,9 +585,7 @@ static int ibmvnic_open(struct net_device *netdev)
            be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs);
        tx_subcrqs =
            be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs);
-       size_array = (u64 *)((u8 *)(adapter->login_rsp_buf) +
-                                 be32_to_cpu(adapter->login_rsp_buf->
-                                             off_rxadd_buff_size));
+
        adapter->map_id = 1;
        adapter->napi = kcalloc(adapter->req_rx_queues,
                                sizeof(struct napi_struct), GFP_KERNEL);
@@ -570,21 +596,12 @@ static int ibmvnic_open(struct net_device *netdev)
                               NAPI_POLL_WEIGHT);
                napi_enable(&adapter->napi[i]);
        }
-       adapter->rx_pool =
-           kcalloc(rxadd_subcrqs, sizeof(struct ibmvnic_rx_pool), GFP_KERNEL);
 
-       if (!adapter->rx_pool)
-               goto rx_pool_arr_alloc_failed;
        send_map_query(adapter);
-       for (i = 0; i < rxadd_subcrqs; i++) {
-               init_rx_pool(adapter, &adapter->rx_pool[i],
-                            adapter->req_rx_add_entries_per_subcrq, i,
-                            be64_to_cpu(size_array[i]), 1);
-               if (alloc_rx_pool(adapter, &adapter->rx_pool[i])) {
-                       dev_err(dev, "Couldn't alloc rx pool\n");
-                       goto rx_pool_alloc_failed;
-               }
-       }
+
+       rc = init_rx_pools(netdev);
+       if (rc)
+               goto rx_pool_failed;
 
        rc = init_tx_pools(netdev);
        if (rc)
@@ -621,15 +638,7 @@ bounce_init_failed:
        kfree(adapter->tx_pool[i].free_map);
 tx_pool_failed:
        i = rxadd_subcrqs;
-rx_pool_alloc_failed:
-       for (j = 0; j < i; j++) {
-               free_rx_pool(adapter, &adapter->rx_pool[j]);
-               free_long_term_buff(adapter,
-                                   &adapter->rx_pool[j].long_term_buff);
-       }
-       kfree(adapter->rx_pool);
-       adapter->rx_pool = NULL;
-rx_pool_arr_alloc_failed:
+rx_pool_failed:
        for (i = 0; i < adapter->req_rx_queues; i++)
                napi_disable(&adapter->napi[i]);
 alloc_napi_failed:
@@ -640,21 +649,10 @@ alloc_napi_failed:
 static void ibmvnic_release_resources(struct ibmvnic_adapter *adapter)
 {
        struct device *dev = &adapter->vdev->dev;
-       int rx_scrqs;
-       int i;
 
        release_bounce_buffer(adapter);
        release_tx_pools(adapter);
-
-       rx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs);
-       for (i = 0; i < rx_scrqs; i++) {
-               struct ibmvnic_rx_pool *rx_pool = &adapter->rx_pool[i];
-
-               free_rx_pool(adapter, rx_pool);
-               free_long_term_buff(adapter, &rx_pool->long_term_buff);
-       }
-       kfree(adapter->rx_pool);
-       adapter->rx_pool = NULL;
+       release_rx_pools(adapter);
 
        release_sub_crqs(adapter);
        release_crq_queue(adapter);