Linux Audio

Check our new training course

Loading...
  1/*
  2 *  IBM eServer eHCA Infiniband device driver for Linux on POWER
  3 *
  4 *  PD functions
  5 *
  6 *  Authors: Christoph Raisch <raisch@de.ibm.com>
  7 *
  8 *  Copyright (c) 2005 IBM Corporation
  9 *
 10 *  All rights reserved.
 11 *
 12 *  This source code is distributed under a dual license of GPL v2.0 and OpenIB
 13 *  BSD.
 14 *
 15 * OpenIB BSD License
 16 *
 17 * Redistribution and use in source and binary forms, with or without
 18 * modification, are permitted provided that the following conditions are met:
 19 *
 20 * Redistributions of source code must retain the above copyright notice, this
 21 * list of conditions and the following disclaimer.
 22 *
 23 * Redistributions in binary form must reproduce the above copyright notice,
 24 * this list of conditions and the following disclaimer in the documentation
 25 * and/or other materials
 26 * provided with the distribution.
 27 *
 28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 29 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 31 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 32 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 35 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 36 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 38 * POSSIBILITY OF SUCH DAMAGE.
 39 */
 40
 41#include <linux/slab.h>
 42
 43#include "ehca_tools.h"
 44#include "ehca_iverbs.h"
 45
 46static struct kmem_cache *pd_cache;
 47
 48struct ib_pd *ehca_alloc_pd(struct ib_device *device,
 49			    struct ib_ucontext *context, struct ib_udata *udata)
 50{
 51	struct ehca_pd *pd;
 52	int i;
 53
 54	pd = kmem_cache_zalloc(pd_cache, GFP_KERNEL);
 55	if (!pd) {
 56		ehca_err(device, "device=%p context=%p out of memory",
 57			 device, context);
 58		return ERR_PTR(-ENOMEM);
 59	}
 60
 61	for (i = 0; i < 2; i++) {
 62		INIT_LIST_HEAD(&pd->free[i]);
 63		INIT_LIST_HEAD(&pd->full[i]);
 64	}
 65	mutex_init(&pd->lock);
 66
 67	/*
 68	 * Kernel PD: when device = -1, 0
 69	 * User   PD: when context != -1
 70	 */
 71	if (!context) {
 72		/*
 73		 * Kernel PDs after init reuses always
 74		 * the one created in ehca_shca_reopen()
 75		 */
 76		struct ehca_shca *shca = container_of(device, struct ehca_shca,
 77						      ib_device);
 78		pd->fw_pd.value = shca->pd->fw_pd.value;
 79	} else
 80		pd->fw_pd.value = (u64)pd;
 81
 82	return &pd->ib_pd;
 83}
 84
 85int ehca_dealloc_pd(struct ib_pd *pd)
 86{
 87	struct ehca_pd *my_pd = container_of(pd, struct ehca_pd, ib_pd);
 88	int i, leftovers = 0;
 89	struct ipz_small_queue_page *page, *tmp;
 90
 91	for (i = 0; i < 2; i++) {
 92		list_splice(&my_pd->full[i], &my_pd->free[i]);
 93		list_for_each_entry_safe(page, tmp, &my_pd->free[i], list) {
 94			leftovers = 1;
 95			free_page(page->page);
 96			kmem_cache_free(small_qp_cache, page);
 97		}
 98	}
 99
100	if (leftovers)
101		ehca_warn(pd->device,
102			  "Some small queue pages were not freed");
103
104	kmem_cache_free(pd_cache, my_pd);
105
106	return 0;
107}
108
109int ehca_init_pd_cache(void)
110{
111	pd_cache = kmem_cache_create("ehca_cache_pd",
112				     sizeof(struct ehca_pd), 0,
113				     SLAB_HWCACHE_ALIGN,
114				     NULL);
115	if (!pd_cache)
116		return -ENOMEM;
117	return 0;
118}
119
120void ehca_cleanup_pd_cache(void)
121{
122	if (pd_cache)
123		kmem_cache_destroy(pd_cache);
124}