1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2021 Broadcom. All Rights Reserved. The term 4 * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 5 */ 6 7 /* 8 * LIBEFC LOCKING 9 * 10 * The critical sections protected by the efc's spinlock are quite broad and 11 * may be improved upon in the future. The libefc code and its locking doesn't 12 * influence the I/O path, so excessive locking doesn't impact I/O performance. 13 * 14 * The strategy is to lock whenever processing a request from user driver. This 15 * means that the entry points into the libefc library are protected by efc 16 * lock. So all the state machine transitions are protected. 17 */ 18 19 #include <linux/module.h> 20 #include <linux/kernel.h> 21 #include "efc.h" 22 23 int efcport_init(struct efc *efc) 24 { 25 u32 rc = 0; 26 27 spin_lock_init(&efc->lock); 28 INIT_LIST_HEAD(&efc->vport_list); 29 efc->hold_frames = false; 30 spin_lock_init(&efc->pend_frames_lock); 31 INIT_LIST_HEAD(&efc->pend_frames); 32 33 /* Create Node pool */ 34 efc->node_pool = mempool_create_kmalloc_pool(EFC_MAX_REMOTE_NODES, 35 sizeof(struct efc_node)); 36 if (!efc->node_pool) { 37 efc_log_err(efc, "Can't allocate node pool\n"); 38 return -ENOMEM; 39 } 40 41 efc->node_dma_pool = dma_pool_create("node_dma_pool", &efc->pci->dev, 42 NODE_SPARAMS_SIZE, 0, 0); 43 if (!efc->node_dma_pool) { 44 efc_log_err(efc, "Can't allocate node dma pool\n"); 45 mempool_destroy(efc->node_pool); 46 return -ENOMEM; 47 } 48 49 efc->els_io_pool = mempool_create_kmalloc_pool(EFC_ELS_IO_POOL_SZ, 50 sizeof(struct efc_els_io_req)); 51 if (!efc->els_io_pool) { 52 efc_log_err(efc, "Can't allocate els io pool\n"); 53 return -ENOMEM; 54 } 55 56 return rc; 57 } 58 59 static void 60 efc_purge_pending(struct efc *efc) 61 { 62 struct efc_hw_sequence *frame, *next; 63 unsigned long flags = 0; 64 65 spin_lock_irqsave(&efc->pend_frames_lock, flags); 66 67 list_for_each_entry_safe(frame, next, &efc->pend_frames, list_entry) { 68 list_del(&frame->list_entry); 69 efc->tt.hw_seq_free(efc, frame); 70 } 71 72 spin_unlock_irqrestore(&efc->pend_frames_lock, flags); 73 } 74 75 void efcport_destroy(struct efc *efc) 76 { 77 efc_purge_pending(efc); 78 mempool_destroy(efc->els_io_pool); 79 mempool_destroy(efc->node_pool); 80 dma_pool_destroy(efc->node_dma_pool); 81 } 82