Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) 2021 Broadcom. All Rights Reserved. The term
0004  * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
0005  */
0006 
0007 /*
0008  * LIBEFC LOCKING
0009  *
0010  * The critical sections protected by the efc's spinlock are quite broad and
0011  * may be improved upon in the future. The libefc code and its locking doesn't
0012  * influence the I/O path, so excessive locking doesn't impact I/O performance.
0013  *
0014  * The strategy is to lock whenever processing a request from user driver. This
0015  * means that the entry points into the libefc library are protected by efc
0016  * lock. So all the state machine transitions are protected.
0017  */
0018 
0019 #include <linux/module.h>
0020 #include <linux/kernel.h>
0021 #include "efc.h"
0022 
0023 int efcport_init(struct efc *efc)
0024 {
0025     u32 rc = 0;
0026 
0027     spin_lock_init(&efc->lock);
0028     INIT_LIST_HEAD(&efc->vport_list);
0029     efc->hold_frames = false;
0030     spin_lock_init(&efc->pend_frames_lock);
0031     INIT_LIST_HEAD(&efc->pend_frames);
0032 
0033     /* Create Node pool */
0034     efc->node_pool = mempool_create_kmalloc_pool(EFC_MAX_REMOTE_NODES,
0035                              sizeof(struct efc_node));
0036     if (!efc->node_pool) {
0037         efc_log_err(efc, "Can't allocate node pool\n");
0038         return -ENOMEM;
0039     }
0040 
0041     efc->node_dma_pool = dma_pool_create("node_dma_pool", &efc->pci->dev,
0042                          NODE_SPARAMS_SIZE, 0, 0);
0043     if (!efc->node_dma_pool) {
0044         efc_log_err(efc, "Can't allocate node dma pool\n");
0045         mempool_destroy(efc->node_pool);
0046         return -ENOMEM;
0047     }
0048 
0049     efc->els_io_pool = mempool_create_kmalloc_pool(EFC_ELS_IO_POOL_SZ,
0050                         sizeof(struct efc_els_io_req));
0051     if (!efc->els_io_pool) {
0052         efc_log_err(efc, "Can't allocate els io pool\n");
0053         return -ENOMEM;
0054     }
0055 
0056     return rc;
0057 }
0058 
0059 static void
0060 efc_purge_pending(struct efc *efc)
0061 {
0062     struct efc_hw_sequence *frame, *next;
0063     unsigned long flags = 0;
0064 
0065     spin_lock_irqsave(&efc->pend_frames_lock, flags);
0066 
0067     list_for_each_entry_safe(frame, next, &efc->pend_frames, list_entry) {
0068         list_del(&frame->list_entry);
0069         efc->tt.hw_seq_free(efc, frame);
0070     }
0071 
0072     spin_unlock_irqrestore(&efc->pend_frames_lock, flags);
0073 }
0074 
0075 void efcport_destroy(struct efc *efc)
0076 {
0077     efc_purge_pending(efc);
0078     mempool_destroy(efc->els_io_pool);
0079     mempool_destroy(efc->node_pool);
0080     dma_pool_destroy(efc->node_dma_pool);
0081 }