ehca_cq.c revision c376222960ae91d5ffb9197ee36771aaed1d9f90
1fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick/* 2fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * IBM eServer eHCA Infiniband device driver for Linux on POWER 3fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * 4fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * Completion queue handling 5fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * 6fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * Authors: Waleri Fomin <fomin@de.ibm.com> 7fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * Khadija Souissi <souissi@de.ibm.com> 8fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * Reinhard Ernst <rernst@de.ibm.com> 9fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * Heiko J Schick <schickhj@de.ibm.com> 10fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * Hoang-Nam Nguyen <hnguyen@de.ibm.com> 11fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * 12fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * 13fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * Copyright (c) 2005 IBM Corporation 14fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * 15fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * All rights reserved. 16fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * 17fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * This source code is distributed under a dual license of GPL v2.0 and OpenIB 18fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * BSD. 19fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * 20fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * OpenIB BSD License 21fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * 22fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * Redistribution and use in source and binary forms, with or without 23fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * modification, are permitted provided that the following conditions are met: 24fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * 25fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * Redistributions of source code must retain the above copyright notice, this 26fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * list of conditions and the following disclaimer. 27fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * 28fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * Redistributions in binary form must reproduce the above copyright notice, 29fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * this list of conditions and the following disclaimer in the documentation 30fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * and/or other materials 31fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * provided with the distribution. 32fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * 33fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 34fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 35fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 36fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 37fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 38fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 39fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 40fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 41fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 42fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 43fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * POSSIBILITY OF SUCH DAMAGE. 44fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick */ 45fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 46fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick#include <asm/current.h> 47fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 48fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick#include "ehca_iverbs.h" 49fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick#include "ehca_classes.h" 50fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick#include "ehca_irq.h" 51fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick#include "hcp_if.h" 52fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 53fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic struct kmem_cache *cq_cache; 54fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 55fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickint ehca_cq_assign_qp(struct ehca_cq *cq, struct ehca_qp *qp) 56fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{ 57fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick unsigned int qp_num = qp->real_qp_num; 58fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick unsigned int key = qp_num & (QP_HASHTAB_LEN-1); 59fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick unsigned long spl_flags; 60fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 61fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick spin_lock_irqsave(&cq->spinlock, spl_flags); 62fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick hlist_add_head(&qp->list_entries, &cq->qp_hashtab[key]); 63fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick spin_unlock_irqrestore(&cq->spinlock, spl_flags); 64fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 65fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ehca_dbg(cq->ib_cq.device, "cq_num=%x real_qp_num=%x", 66fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick cq->cq_number, qp_num); 67fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 68fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick return 0; 69fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick} 70fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 71fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickint ehca_cq_unassign_qp(struct ehca_cq *cq, unsigned int real_qp_num) 72fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{ 73fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick int ret = -EINVAL; 74fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick unsigned int key = real_qp_num & (QP_HASHTAB_LEN-1); 75fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick struct hlist_node *iter; 76fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick struct ehca_qp *qp; 77fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick unsigned long spl_flags; 78fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 79fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick spin_lock_irqsave(&cq->spinlock, spl_flags); 80fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick hlist_for_each(iter, &cq->qp_hashtab[key]) { 81fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick qp = hlist_entry(iter, struct ehca_qp, list_entries); 82fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick if (qp->real_qp_num == real_qp_num) { 83fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick hlist_del(iter); 84fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ehca_dbg(cq->ib_cq.device, 85fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick "removed qp from cq .cq_num=%x real_qp_num=%x", 86fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick cq->cq_number, real_qp_num); 87fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ret = 0; 88fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick break; 89fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 90fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 91fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick spin_unlock_irqrestore(&cq->spinlock, spl_flags); 92fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick if (ret) 93fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ehca_err(cq->ib_cq.device, 94fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick "qp not found cq_num=%x real_qp_num=%x", 95fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick cq->cq_number, real_qp_num); 96fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 97fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick return ret; 98fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick} 99fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 100fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstruct ehca_qp* ehca_cq_get_qp(struct ehca_cq *cq, int real_qp_num) 101fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{ 102fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick struct ehca_qp *ret = NULL; 103fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick unsigned int key = real_qp_num & (QP_HASHTAB_LEN-1); 104fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick struct hlist_node *iter; 105fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick struct ehca_qp *qp; 106fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick hlist_for_each(iter, &cq->qp_hashtab[key]) { 107fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick qp = hlist_entry(iter, struct ehca_qp, list_entries); 108fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick if (qp->real_qp_num == real_qp_num) { 109fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ret = qp; 110fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick break; 111fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 112fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 113fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick return ret; 114fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick} 115fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 116fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstruct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, 117fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick struct ib_ucontext *context, 118fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick struct ib_udata *udata) 119fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{ 120fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick static const u32 additional_cqe = 20; 121fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick struct ib_cq *cq; 122fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick struct ehca_cq *my_cq; 123fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick struct ehca_shca *shca = 124fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick container_of(device, struct ehca_shca, ib_device); 125fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick struct ipz_adapter_handle adapter_handle; 126fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick struct ehca_alloc_cq_parms param; /* h_call's out parameters */ 127fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick struct h_galpa gal; 128fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick void *vpage; 129fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick u32 counter; 130fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick u64 rpage, cqx_fec, h_ret; 131fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick int ipz_rc, ret, i; 132fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick unsigned long flags; 133fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 134fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick if (cqe >= 0xFFFFFFFF - 64 - additional_cqe) 135fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick return ERR_PTR(-EINVAL); 136fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 137c376222960ae91d5ffb9197ee36771aaed1d9f90Robert P. J. Day my_cq = kmem_cache_zalloc(cq_cache, GFP_KERNEL); 138fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick if (!my_cq) { 139fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ehca_err(device, "Out of memory for ehca_cq struct device=%p", 140fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick device); 141fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick return ERR_PTR(-ENOMEM); 142fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 143fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 144fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick memset(¶m, 0, sizeof(struct ehca_alloc_cq_parms)); 145fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 146fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick spin_lock_init(&my_cq->spinlock); 147fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick spin_lock_init(&my_cq->cb_lock); 148fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick spin_lock_init(&my_cq->task_lock); 149fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick my_cq->ownpid = current->tgid; 150fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 151fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick cq = &my_cq->ib_cq; 152fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 153fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick adapter_handle = shca->ipz_hca_handle; 154fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick param.eq_handle = shca->eq.ipz_eq_handle; 155fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 156fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick do { 157fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick if (!idr_pre_get(&ehca_cq_idr, GFP_KERNEL)) { 158fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick cq = ERR_PTR(-ENOMEM); 159fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ehca_err(device, "Can't reserve idr nr. device=%p", 160fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick device); 161fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick goto create_cq_exit1; 162fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 163fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 164fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick spin_lock_irqsave(&ehca_cq_idr_lock, flags); 165fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ret = idr_get_new(&ehca_cq_idr, my_cq, &my_cq->token); 166fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick spin_unlock_irqrestore(&ehca_cq_idr_lock, flags); 167fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 168fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } while (ret == -EAGAIN); 169fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 170fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick if (ret) { 171fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick cq = ERR_PTR(-ENOMEM); 172fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ehca_err(device, "Can't allocate new idr entry. device=%p", 173fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick device); 174fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick goto create_cq_exit1; 175fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 176fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 177fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick /* 178fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * CQs maximum depth is 4GB-64, but we need additional 20 as buffer 179fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * for receiving errors CQEs. 180fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick */ 181fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick param.nr_cqe = cqe + additional_cqe; 182fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick h_ret = hipz_h_alloc_resource_cq(adapter_handle, my_cq, ¶m); 183fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 184fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick if (h_ret != H_SUCCESS) { 185fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ehca_err(device, "hipz_h_alloc_resource_cq() failed " 186fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick "h_ret=%lx device=%p", h_ret, device); 187fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick cq = ERR_PTR(ehca2ib_return_code(h_ret)); 188fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick goto create_cq_exit2; 189fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 190fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 191fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ipz_rc = ipz_queue_ctor(&my_cq->ipz_queue, param.act_pages, 192fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick EHCA_PAGESIZE, sizeof(struct ehca_cqe), 0); 193fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick if (!ipz_rc) { 194fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ehca_err(device, "ipz_queue_ctor() failed ipz_rc=%x device=%p", 195fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ipz_rc, device); 196fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick cq = ERR_PTR(-EINVAL); 197fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick goto create_cq_exit3; 198fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 199fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 200fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick for (counter = 0; counter < param.act_pages; counter++) { 201fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick vpage = ipz_qpageit_get_inc(&my_cq->ipz_queue); 202fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick if (!vpage) { 203fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ehca_err(device, "ipz_qpageit_get_inc() " 204fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick "returns NULL device=%p", device); 205fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick cq = ERR_PTR(-EAGAIN); 206fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick goto create_cq_exit4; 207fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 208fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick rpage = virt_to_abs(vpage); 209fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 210fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick h_ret = hipz_h_register_rpage_cq(adapter_handle, 211fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick my_cq->ipz_cq_handle, 212fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick &my_cq->pf, 213fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 0, 214fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 0, 215fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick rpage, 216fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 1, 217fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick my_cq->galpas. 218fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick kernel); 219fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 220fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick if (h_ret < H_SUCCESS) { 221fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ehca_err(device, "hipz_h_register_rpage_cq() failed " 222fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick "ehca_cq=%p cq_num=%x h_ret=%lx counter=%i " 223fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick "act_pages=%i", my_cq, my_cq->cq_number, 224fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick h_ret, counter, param.act_pages); 225fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick cq = ERR_PTR(-EINVAL); 226fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick goto create_cq_exit4; 227fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 228fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 229fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick if (counter == (param.act_pages - 1)) { 230fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick vpage = ipz_qpageit_get_inc(&my_cq->ipz_queue); 231fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick if ((h_ret != H_SUCCESS) || vpage) { 232fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ehca_err(device, "Registration of pages not " 233fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick "complete ehca_cq=%p cq_num=%x " 234fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick "h_ret=%lx", my_cq, my_cq->cq_number, 235fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick h_ret); 236fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick cq = ERR_PTR(-EAGAIN); 237fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick goto create_cq_exit4; 238fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 239fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } else { 240fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick if (h_ret != H_PAGE_REGISTERED) { 241fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ehca_err(device, "Registration of page failed " 242fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick "ehca_cq=%p cq_num=%x h_ret=%lx" 243fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick "counter=%i act_pages=%i", 244fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick my_cq, my_cq->cq_number, 245fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick h_ret, counter, param.act_pages); 246fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick cq = ERR_PTR(-ENOMEM); 247fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick goto create_cq_exit4; 248fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 249fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 250fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 251fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 252fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ipz_qeit_reset(&my_cq->ipz_queue); 253fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 254fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick gal = my_cq->galpas.kernel; 255fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick cqx_fec = hipz_galpa_load(gal, CQTEMM_OFFSET(cqx_fec)); 256fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ehca_dbg(device, "ehca_cq=%p cq_num=%x CQX_FEC=%lx", 257fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick my_cq, my_cq->cq_number, cqx_fec); 258fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 259fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick my_cq->ib_cq.cqe = my_cq->nr_of_entries = 260fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick param.act_nr_of_entries - additional_cqe; 261fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick my_cq->cq_number = (my_cq->ipz_cq_handle.handle) & 0xffff; 262fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 263fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick for (i = 0; i < QP_HASHTAB_LEN; i++) 264fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick INIT_HLIST_HEAD(&my_cq->qp_hashtab[i]); 265fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 266fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick if (context) { 267fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick struct ipz_queue *ipz_queue = &my_cq->ipz_queue; 268fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick struct ehca_create_cq_resp resp; 269fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick memset(&resp, 0, sizeof(resp)); 270fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick resp.cq_number = my_cq->cq_number; 271fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick resp.token = my_cq->token; 272fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick resp.ipz_queue.qe_size = ipz_queue->qe_size; 273fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick resp.ipz_queue.act_nr_of_sg = ipz_queue->act_nr_of_sg; 274fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick resp.ipz_queue.queue_length = ipz_queue->queue_length; 275fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick resp.ipz_queue.pagesize = ipz_queue->pagesize; 276fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick resp.ipz_queue.toggle_state = ipz_queue->toggle_state; 277fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick if (ib_copy_to_udata(udata, &resp, sizeof(resp))) { 278fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ehca_err(device, "Copy to udata failed."); 2794c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen goto create_cq_exit4; 280fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 281fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 282fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 283fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick return cq; 284fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 285fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickcreate_cq_exit4: 286fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ipz_queue_dtor(&my_cq->ipz_queue); 287fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 288fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickcreate_cq_exit3: 289fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick h_ret = hipz_h_destroy_cq(adapter_handle, my_cq, 1); 290fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick if (h_ret != H_SUCCESS) 291fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ehca_err(device, "hipz_h_destroy_cq() failed ehca_cq=%p " 292fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick "cq_num=%x h_ret=%lx", my_cq, my_cq->cq_number, h_ret); 293fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 294fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickcreate_cq_exit2: 295fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick spin_lock_irqsave(&ehca_cq_idr_lock, flags); 296fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick idr_remove(&ehca_cq_idr, my_cq->token); 297fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick spin_unlock_irqrestore(&ehca_cq_idr_lock, flags); 298fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 299fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickcreate_cq_exit1: 300fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick kmem_cache_free(cq_cache, my_cq); 301fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 302fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick return cq; 303fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick} 304fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 305fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickint ehca_destroy_cq(struct ib_cq *cq) 306fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{ 307fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick u64 h_ret; 308fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick struct ehca_cq *my_cq = container_of(cq, struct ehca_cq, ib_cq); 309fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick int cq_num = my_cq->cq_number; 310fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick struct ib_device *device = cq->device; 311fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick struct ehca_shca *shca = container_of(device, struct ehca_shca, 312fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ib_device); 313fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick struct ipz_adapter_handle adapter_handle = shca->ipz_hca_handle; 314fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick u32 cur_pid = current->tgid; 315fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick unsigned long flags; 316fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 3174c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen if (cq->uobject) { 3184c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen if (my_cq->mm_count_galpa || my_cq->mm_count_queue) { 3194c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ehca_err(device, "Resources still referenced in " 3204c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen "user space cq_num=%x", my_cq->cq_number); 3214c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen return -EINVAL; 3224c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen } 3234c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen if (my_cq->ownpid != cur_pid) { 3244c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen ehca_err(device, "Invalid caller pid=%x ownpid=%x " 3254c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen "cq_num=%x", 3264c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen cur_pid, my_cq->ownpid, my_cq->cq_number); 3274c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen return -EINVAL; 3284c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen } 3294c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen } 3304c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen 331fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick spin_lock_irqsave(&ehca_cq_idr_lock, flags); 332ce29d72cc737df3573854a4719f00385adf1c9a6Hoang-Nam Nguyen while (my_cq->nr_callbacks) { 333ce29d72cc737df3573854a4719f00385adf1c9a6Hoang-Nam Nguyen spin_unlock_irqrestore(&ehca_cq_idr_lock, flags); 334fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick yield(); 335ce29d72cc737df3573854a4719f00385adf1c9a6Hoang-Nam Nguyen spin_lock_irqsave(&ehca_cq_idr_lock, flags); 336ce29d72cc737df3573854a4719f00385adf1c9a6Hoang-Nam Nguyen } 337fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 338fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick idr_remove(&ehca_cq_idr, my_cq->token); 339fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick spin_unlock_irqrestore(&ehca_cq_idr_lock, flags); 340fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 341fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick h_ret = hipz_h_destroy_cq(adapter_handle, my_cq, 0); 342fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick if (h_ret == H_R_STATE) { 343fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick /* cq in err: read err data and destroy it forcibly */ 344fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ehca_dbg(device, "ehca_cq=%p cq_num=%x ressource=%lx in err " 345fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick "state. Try to delete it forcibly.", 346fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick my_cq, cq_num, my_cq->ipz_cq_handle.handle); 347fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ehca_error_data(shca, my_cq, my_cq->ipz_cq_handle.handle); 348fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick h_ret = hipz_h_destroy_cq(adapter_handle, my_cq, 1); 349fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick if (h_ret == H_SUCCESS) 350fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ehca_dbg(device, "cq_num=%x deleted successfully.", 351fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick cq_num); 352fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 353fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick if (h_ret != H_SUCCESS) { 354fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ehca_err(device, "hipz_h_destroy_cq() failed h_ret=%lx " 355fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick "ehca_cq=%p cq_num=%x", h_ret, my_cq, cq_num); 356fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick return ehca2ib_return_code(h_ret); 357fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 358fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ipz_queue_dtor(&my_cq->ipz_queue); 359fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick kmem_cache_free(cq_cache, my_cq); 360fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 361fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick return 0; 362fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick} 363fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 364fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickint ehca_resize_cq(struct ib_cq *cq, int cqe, struct ib_udata *udata) 365fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{ 366fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick struct ehca_cq *my_cq = container_of(cq, struct ehca_cq, ib_cq); 367fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick u32 cur_pid = current->tgid; 368fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 3694c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen if (cq->uobject && my_cq->ownpid != cur_pid) { 370fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ehca_err(cq->device, "Invalid caller pid=%x ownpid=%x", 371fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick cur_pid, my_cq->ownpid); 372fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick return -EINVAL; 373fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick } 374fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 375fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick /* TODO: proper resize needs to be done */ 376fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick ehca_err(cq->device, "not implemented yet"); 377fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 378fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick return -EFAULT; 379fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick} 380fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 381fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickint ehca_init_cq_cache(void) 382fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{ 383fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick cq_cache = kmem_cache_create("ehca_cache_cq", 384fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick sizeof(struct ehca_cq), 0, 385fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick SLAB_HWCACHE_ALIGN, 386fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick NULL, NULL); 387fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick if (!cq_cache) 388fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick return -ENOMEM; 389fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick return 0; 390fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick} 391fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick 392fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickvoid ehca_cleanup_cq_cache(void) 393fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{ 394fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick if (cq_cache) 395fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick kmem_cache_destroy(cq_cache); 396fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick} 397