Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/1124830/?format=api
{ "id": 1124830, "url": "http://patchwork.ozlabs.org/api/patches/1124830/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20190629185405.1601-9-shiraz.saleem@intel.com/", "project": { "id": 46, "url": "http://patchwork.ozlabs.org/api/projects/46/?format=api", "name": "Intel Wired Ethernet development", "link_name": "intel-wired-lan", "list_id": "intel-wired-lan.osuosl.org", "list_email": "intel-wired-lan@osuosl.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20190629185405.1601-9-shiraz.saleem@intel.com>", "list_archive_url": null, "date": "2019-06-29T18:53:56", "name": "[rdma-next,08/17] RDMA/irdma: Add PBLE resource manager", "commit_ref": null, "pull_url": null, "state": "rejected", "archived": false, "hash": "4feb2c7b7909204c5b01f3ba32f503a692835048", "submitter": { "id": 69500, "url": "http://patchwork.ozlabs.org/api/people/69500/?format=api", "name": "Saleem, Shiraz", "email": "shiraz.saleem@intel.com" }, "delegate": { "id": 68, "url": "http://patchwork.ozlabs.org/api/users/68/?format=api", "username": "jtkirshe", "first_name": "Jeff", "last_name": "Kirsher", "email": "jeffrey.t.kirsher@intel.com" }, "mbox": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20190629185405.1601-9-shiraz.saleem@intel.com/mbox/", "series": [ { "id": 116886, "url": "http://patchwork.ozlabs.org/api/series/116886/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/list/?series=116886", "date": "2019-06-29T18:53:48", "name": "Add unified Intel Ethernet RDMA driver (irdma)", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/116886/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/1124830/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/1124830/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<intel-wired-lan-bounces@osuosl.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Delivered-To": [ "patchwork-incoming@bilbo.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Authentication-Results": [ "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=osuosl.org\n\t(client-ip=140.211.166.137; helo=fraxinus.osuosl.org;\n\tenvelope-from=intel-wired-lan-bounces@osuosl.org;\n\treceiver=<UNKNOWN>)", "ozlabs.org;\n\tdmarc=fail (p=none dis=none) header.from=intel.com" ], "Received": [ "from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 45bjVF0WMSz9s4Y\n\tfor <incoming@patchwork.ozlabs.org>;\n\tSun, 30 Jun 2019 04:54:28 +1000 (AEST)", "from localhost (localhost [127.0.0.1])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id D8EE585691;\n\tSat, 29 Jun 2019 18:54:26 +0000 (UTC)", "from fraxinus.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id s8B-2ZaIPvKT; Sat, 29 Jun 2019 18:54:24 +0000 (UTC)", "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby fraxinus.osuosl.org (Postfix) with ESMTP id BF63485629;\n\tSat, 29 Jun 2019 18:54:24 +0000 (UTC)", "from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133])\n\tby ash.osuosl.org (Postfix) with ESMTP id AD61C1BF3AD\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tSat, 29 Jun 2019 18:54:22 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n\tby hemlock.osuosl.org (Postfix) with ESMTP id AAE3687E58\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tSat, 29 Jun 2019 18:54:22 +0000 (UTC)", "from hemlock.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id GyHgTfymyBDY for <intel-wired-lan@lists.osuosl.org>;\n\tSat, 29 Jun 2019 18:54:20 +0000 (UTC)", "from mga14.intel.com (mga14.intel.com [192.55.52.115])\n\tby hemlock.osuosl.org (Postfix) with ESMTPS id 0F06487D7C\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tSat, 29 Jun 2019 18:54:20 +0000 (UTC)", "from fmsmga004.fm.intel.com ([10.253.24.48])\n\tby fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t29 Jun 2019 11:54:19 -0700", "from ssaleem-mobl.amr.corp.intel.com ([10.254.177.95])\n\tby fmsmga004.fm.intel.com with ESMTP; 29 Jun 2019 11:54:19 -0700" ], "X-Virus-Scanned": [ "amavisd-new at osuosl.org", "amavisd-new at osuosl.org" ], "X-Greylist": "domain auto-whitelisted by SQLgrey-1.7.6", "X-Amp-Result": "SKIPPED(no attachment in message)", "X-Amp-File-Uploaded": "False", "X-ExtLoop1": "1", "X-IronPort-AV": "E=Sophos;i=\"5.63,432,1557212400\"; d=\"scan'208\";a=\"185972875\"", "From": "Shiraz Saleem <shiraz.saleem@intel.com>", "To": "intel-wired-lan@lists.osuosl.org", "Date": "Sat, 29 Jun 2019 13:53:56 -0500", "Message-Id": "<20190629185405.1601-9-shiraz.saleem@intel.com>", "X-Mailer": "git-send-email 2.21.0", "In-Reply-To": "<20190629185405.1601-1-shiraz.saleem@intel.com>", "References": "<20190629185405.1601-1-shiraz.saleem@intel.com>", "MIME-Version": "1.0", "Subject": "[Intel-wired-lan] [PATCH rdma-next 08/17] RDMA/irdma: Add PBLE\n\tresource manager", "X-BeenThere": "intel-wired-lan@osuosl.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "Intel Wired Ethernet Linux Kernel Driver Development\n\t<intel-wired-lan.osuosl.org>", "List-Unsubscribe": "<https://lists.osuosl.org/mailman/options/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@osuosl.org?subject=unsubscribe>", "List-Archive": "<http://lists.osuosl.org/pipermail/intel-wired-lan/>", "List-Post": "<mailto:intel-wired-lan@osuosl.org>", "List-Help": "<mailto:intel-wired-lan-request@osuosl.org?subject=help>", "List-Subscribe": "<https://lists.osuosl.org/mailman/listinfo/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@osuosl.org?subject=subscribe>", "Cc": "Mustafa Ismail <mustafa.ismail@intel.com>,\n\tShiraz Saleem <shiraz.saleem@intel.com>", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Errors-To": "intel-wired-lan-bounces@osuosl.org", "Sender": "\"Intel-wired-lan\" <intel-wired-lan-bounces@osuosl.org>" }, "content": "From: Mustafa Ismail <mustafa.ismail@intel.com>\n\nImplement a Physical Buffer List Entry (PBLE) resource manager\nto manage a pool of PBLE HMC resource objects.\n\nSigned-off-by: Mustafa Ismail <mustafa.ismail@intel.com>\nSigned-off-by: Shiraz Saleem <shiraz.saleem@intel.com>\n---\n drivers/infiniband/hw/irdma/pble.c | 511 +++++++++++++++++++++++++++++++++++++\n drivers/infiniband/hw/irdma/pble.h | 136 ++++++++++\n 2 files changed, 647 insertions(+)\n create mode 100644 drivers/infiniband/hw/irdma/pble.c\n create mode 100644 drivers/infiniband/hw/irdma/pble.h", "diff": "diff --git a/drivers/infiniband/hw/irdma/pble.c b/drivers/infiniband/hw/irdma/pble.c\nnew file mode 100644\nindex 0000000..7237651\n--- /dev/null\n+++ b/drivers/infiniband/hw/irdma/pble.c\n@@ -0,0 +1,511 @@\n+// SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB\n+/* Copyright (c) 2019, Intel Corporation. */\n+\n+#include \"osdep.h\"\n+#include \"status.h\"\n+#include \"hmc.h\"\n+#include \"defs.h\"\n+#include \"type.h\"\n+#include \"protos.h\"\n+#include \"pble.h\"\n+\n+static enum irdma_status_code\n+add_pble_prm(struct irdma_hmc_pble_rsrc *pble_rsrc);\n+\n+/**\n+ * irdma_destroy_pble_prm - destroy prm during module unload\n+ * @pble_rsrc: pble resources\n+ */\n+void irdma_destroy_pble_prm(struct irdma_hmc_pble_rsrc *pble_rsrc)\n+{\n+\tstruct irdma_chunk *chunk;\n+\tstruct irdma_pble_prm *pinfo = &pble_rsrc->pinfo;\n+\n+\twhile (!list_empty(&pinfo->clist)) {\n+\t\tchunk = (struct irdma_chunk *) pinfo->clist.next;\n+\t\tlist_del(&chunk->list);\n+\t\tif (chunk->type == PBLE_SD_PAGED)\n+\t\t\tirdma_pble_free_paged_mem(chunk);\n+\t\tif (chunk->bitmapbuf)\n+\t\t\tkfree(chunk->bitmapmem.va);\n+\t\tkfree(chunk->chunkmem.va);\n+\t}\n+}\n+\n+/**\n+ * irdma_hmc_init_pble - Initialize pble resources during module load\n+ * @dev: irdma_sc_dev struct\n+ * @pble_rsrc: pble resources\n+ */\n+enum irdma_status_code\n+irdma_hmc_init_pble(struct irdma_sc_dev *dev,\n+\t\t struct irdma_hmc_pble_rsrc *pble_rsrc)\n+{\n+\tstruct irdma_hmc_info *hmc_info;\n+\tu32 fpm_idx = 0;\n+\tenum irdma_status_code status = 0;\n+\n+\thmc_info = dev->hmc_info;\n+\tpble_rsrc->dev = dev;\n+\tpble_rsrc->fpm_base_addr = hmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].base;\n+\t/* Start pble' on 4k boundary */\n+\tif (pble_rsrc->fpm_base_addr & 0xfff)\n+\t\tfpm_idx = (4096 - (pble_rsrc->fpm_base_addr & 0xfff)) >> 3;\n+\tpble_rsrc->unallocated_pble =\n+\t\thmc_info->hmc_obj[IRDMA_HMC_IW_PBLE].cnt - fpm_idx;\n+\tpble_rsrc->next_fpm_addr = pble_rsrc->fpm_base_addr + (fpm_idx << 3);\n+\tpble_rsrc->pinfo.pble_shift = PBLE_SHIFT;\n+\n+\tspin_lock_init(&pble_rsrc->pinfo.prm_lock);\n+\tINIT_LIST_HEAD(&pble_rsrc->pinfo.clist);\n+\tif (add_pble_prm(pble_rsrc)) {\n+\t\tirdma_destroy_pble_prm(pble_rsrc);\n+\t\tstatus = IRDMA_ERR_NO_MEMORY;\n+\t}\n+\n+\treturn status;\n+}\n+\n+/**\n+ * get_sd_pd_idx - Returns sd index, pd index and rel_pd_idx from fpm address\n+ * @pble_rsrc: structure containing fpm address\n+ * @idx: where to return indexes\n+ */\n+static void get_sd_pd_idx(struct irdma_hmc_pble_rsrc *pble_rsrc,\n+\t\t\t struct sd_pd_idx *idx)\n+{\n+\tidx->sd_idx = (u32)pble_rsrc->next_fpm_addr / IRDMA_HMC_DIRECT_BP_SIZE;\n+\tidx->pd_idx = (u32)(pble_rsrc->next_fpm_addr / IRDMA_HMC_PAGED_BP_SIZE);\n+\tidx->rel_pd_idx = (idx->pd_idx % IRDMA_HMC_PD_CNT_IN_SD);\n+}\n+\n+/**\n+ * add_sd_direct - add sd direct for pble\n+ * @pble_rsrc: pble resource ptr\n+ * @info: page info for sd\n+ */\n+static enum irdma_status_code\n+add_sd_direct(struct irdma_hmc_pble_rsrc *pble_rsrc,\n+\t struct irdma_add_page_info *info)\n+{\n+\tstruct irdma_sc_dev *dev = pble_rsrc->dev;\n+\tenum irdma_status_code ret_code = 0;\n+\tstruct sd_pd_idx *idx = &info->idx;\n+\tstruct irdma_chunk *chunk = info->chunk;\n+\tstruct irdma_hmc_info *hmc_info = info->hmc_info;\n+\tstruct irdma_hmc_sd_entry *sd_entry = info->sd_entry;\n+\tu32 offset = 0;\n+\n+\tif (!sd_entry->valid) {\n+\t\tret_code = irdma_add_sd_table_entry(dev->hw, hmc_info,\n+\t\t\t\t\t\t info->idx.sd_idx,\n+\t\t\t\t\t\t IRDMA_SD_TYPE_DIRECT,\n+\t\t\t\t\t\t IRDMA_HMC_DIRECT_BP_SIZE);\n+\t\tif (ret_code)\n+\t\t\treturn ret_code;\n+\n+\t\tchunk->type = PBLE_SD_CONTIGOUS;\n+\t}\n+\n+\toffset = idx->rel_pd_idx << HMC_PAGED_BP_SHIFT;\n+\tchunk->size = info->pages << HMC_PAGED_BP_SHIFT;\n+\tchunk->vaddr = (uintptr_t)(sd_entry->u.bp.addr.va + offset);\n+\tchunk->fpm_addr = pble_rsrc->next_fpm_addr;\n+\tdev_dbg(rfdev_to_dev(dev),\n+\t\t\"PBLE: chunk_size[%lld] = 0x%llx vaddr=0x%llx fpm_addr = %llx\\n\",\n+\t\tchunk->size, chunk->size, chunk->vaddr, chunk->fpm_addr);\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * fpm_to_idx - given fpm address, get pble index\n+ * @pble_rsrc: pble resource management\n+ * @addr: fpm address for index\n+ */\n+static u32 fpm_to_idx(struct irdma_hmc_pble_rsrc *pble_rsrc, u64 addr)\n+{\n+\tu64 idx;\n+\n+\tidx = (addr - (pble_rsrc->fpm_base_addr)) >> 3;\n+\n+\treturn (u32)idx;\n+}\n+\n+/**\n+ * add_bp_pages - add backing pages for sd\n+ * @pble_rsrc: pble resource management\n+ * @info: page info for sd\n+ */\n+static enum irdma_status_code\n+add_bp_pages(struct irdma_hmc_pble_rsrc *pble_rsrc,\n+\t struct irdma_add_page_info *info)\n+{\n+\tstruct irdma_sc_dev *dev = pble_rsrc->dev;\n+\tu8 *addr;\n+\tstruct irdma_dma_mem mem;\n+\tstruct irdma_hmc_pd_entry *pd_entry;\n+\tstruct irdma_hmc_sd_entry *sd_entry = info->sd_entry;\n+\tstruct irdma_hmc_info *hmc_info = info->hmc_info;\n+\tstruct irdma_chunk *chunk = info->chunk;\n+\tenum irdma_status_code status = 0;\n+\tu32 rel_pd_idx = info->idx.rel_pd_idx;\n+\tu32 pd_idx = info->idx.pd_idx;\n+\tu32 i;\n+\n+\tif (irdma_pble_get_paged_mem(chunk, info->pages))\n+\t\treturn IRDMA_ERR_NO_MEMORY;\n+\n+\tstatus = irdma_add_sd_table_entry(dev->hw, hmc_info, info->idx.sd_idx,\n+\t\t\t\t\t IRDMA_SD_TYPE_PAGED,\n+\t\t\t\t\t IRDMA_HMC_DIRECT_BP_SIZE);\n+\n+\tif (status)\n+\t\tgoto error;\n+\n+\taddr = (u8 *)(uintptr_t)chunk->vaddr;\n+\tfor (i = 0; i < info->pages; i++) {\n+\t\tmem.pa = (u64)chunk->dmainfo.dmaaddrs[i];\n+\t\tmem.size = 4096;\n+\t\tmem.va = addr;\n+\t\tpd_entry = &sd_entry->u.pd_table.pd_entry[rel_pd_idx++];\n+\t\tif (!pd_entry->valid) {\n+\t\t\tstatus = irdma_add_pd_table_entry(dev, hmc_info,\n+\t\t\t\t\t\t\t pd_idx++, &mem);\n+\t\t\tif (status)\n+\t\t\t\tgoto error;\n+\n+\t\t\taddr += 4096;\n+\t\t}\n+\t}\n+\n+\tchunk->fpm_addr = pble_rsrc->next_fpm_addr;\n+\treturn 0;\n+\n+error:\n+\tirdma_pble_free_paged_mem(chunk);\n+\n+\treturn status;\n+}\n+\n+/**\n+ * add_pble_prm - add a sd entry for pble resoure\n+ * @pble_rsrc: pble resource management\n+ */\n+static enum irdma_status_code\n+add_pble_prm(struct irdma_hmc_pble_rsrc *pble_rsrc)\n+{\n+\tstruct irdma_sc_dev *dev = pble_rsrc->dev;\n+\tstruct irdma_hmc_sd_entry *sd_entry;\n+\tstruct irdma_hmc_info *hmc_info;\n+\tstruct irdma_chunk *chunk;\n+\tstruct irdma_add_page_info info;\n+\tstruct sd_pd_idx *idx = &info.idx;\n+\tenum irdma_status_code ret_code = 0;\n+\tenum irdma_sd_entry_type sd_entry_type;\n+\tu64 sd_reg_val = 0;\n+\tstruct irdma_virt_mem chunkmem;\n+\tu32 pages;\n+\n+\tif (pble_rsrc->unallocated_pble < PBLE_PER_PAGE)\n+\t\treturn IRDMA_ERR_NO_MEMORY;\n+\n+\tif (pble_rsrc->next_fpm_addr & 0xfff)\n+\t\treturn IRDMA_ERR_INVALID_PAGE_DESC_INDEX;\n+\n+\tchunkmem.size = sizeof(*chunk);\n+\tchunkmem.va = kzalloc(chunkmem.size, GFP_ATOMIC);\n+\tif (!chunkmem.va)\n+\t\treturn IRDMA_ERR_NO_MEMORY;\n+\n+\tchunk = chunkmem.va;\n+\tchunk->chunkmem = chunkmem;\n+\thmc_info = dev->hmc_info;\n+\tchunk->dev = dev;\n+\tchunk->fpm_addr = pble_rsrc->next_fpm_addr;\n+\tget_sd_pd_idx(pble_rsrc, idx);\n+\tsd_entry = &hmc_info->sd_table.sd_entry[idx->sd_idx];\n+\tpages = (idx->rel_pd_idx) ? (IRDMA_HMC_PD_CNT_IN_SD - idx->rel_pd_idx) :\n+\t\t\t\t IRDMA_HMC_PD_CNT_IN_SD;\n+\tpages = min(pages, pble_rsrc->unallocated_pble >> PBLE_512_SHIFT);\n+\tinfo.chunk = chunk;\n+\tinfo.hmc_info = hmc_info;\n+\tinfo.pages = pages;\n+\tinfo.sd_entry = sd_entry;\n+\tif (!sd_entry->valid)\n+\t\tsd_entry_type = (!idx->rel_pd_idx &&\n+\t\t\t\t (pages == IRDMA_HMC_PD_CNT_IN_SD) &&\n+\t\t\t\t dev->is_pf) ?\n+\t\t\t\t IRDMA_SD_TYPE_DIRECT : IRDMA_SD_TYPE_PAGED;\n+\telse\n+\t\tsd_entry_type = sd_entry->entry_type;\n+\n+\tdev_dbg(rfdev_to_dev(dev),\n+\t\t\"PBLE: pages = %d, unallocated_pble[%d] current_fpm_addr = %llx\\n\",\n+\t\tpages, pble_rsrc->unallocated_pble, pble_rsrc->next_fpm_addr);\n+\tdev_dbg(rfdev_to_dev(dev), \"PBLE: sd_entry_type = %d\\n\",\n+\t\tsd_entry_type);\n+\tif (sd_entry_type == IRDMA_SD_TYPE_DIRECT)\n+\t\tret_code = add_sd_direct(pble_rsrc, &info);\n+\n+\tif (ret_code)\n+\t\tsd_entry_type = IRDMA_SD_TYPE_PAGED;\n+\telse\n+\t\tpble_rsrc->stats_direct_sds++;\n+\n+\tif (sd_entry_type == IRDMA_SD_TYPE_PAGED) {\n+\t\tret_code = add_bp_pages(pble_rsrc, &info);\n+\t\tif (ret_code)\n+\t\t\tgoto error;\n+\t\telse\n+\t\t\tpble_rsrc->stats_paged_sds++;\n+\t}\n+\n+\tret_code = irdma_prm_add_pble_mem(&pble_rsrc->pinfo, chunk);\n+\tif (ret_code)\n+\t\tgoto error;\n+\n+\tpble_rsrc->next_fpm_addr += chunk->size;\n+\tdev_dbg(rfdev_to_dev(dev),\n+\t\t\"PBLE: next_fpm_addr = %llx chunk_size[%llu] = 0x%llx\\n\",\n+\t\tpble_rsrc->next_fpm_addr, chunk->size, chunk->size);\n+\tpble_rsrc->unallocated_pble -= (u32)(chunk->size >> 3);\n+\tlist_add(&chunk->list, &pble_rsrc->pinfo.clist);\n+\tsd_reg_val = (sd_entry_type == IRDMA_SD_TYPE_PAGED) ?\n+\t\t\t sd_entry->u.pd_table.pd_page_addr.pa :\n+\t\t\t sd_entry->u.bp.addr.pa;\n+\tif (sd_entry->valid)\n+\t\treturn 0;\n+\n+\tif (dev->is_pf) {\n+\t\tret_code = irdma_hmc_sd_one(dev, hmc_info->hmc_fn_id,\n+\t\t\t\t\t sd_reg_val, idx->sd_idx,\n+\t\t\t\t\t sd_entry->entry_type, true);\n+\t\tif (ret_code)\n+\t\t\tgoto error;\n+\t}\n+\n+\tsd_entry->valid = true;\n+\treturn 0;\n+\n+error:\n+\tif (chunk->bitmapbuf)\n+\t\tkfree(chunk->bitmapmem.va);\n+\n+\tkfree(chunk->chunkmem.va);\n+\n+\treturn ret_code;\n+}\n+\n+/**\n+ * free_lvl2 - fee level 2 pble\n+ * @pble_rsrc: pble resource management\n+ * @palloc: level 2 pble allocation\n+ */\n+static void free_lvl2(struct irdma_hmc_pble_rsrc *pble_rsrc,\n+\t\t struct irdma_pble_alloc *palloc)\n+{\n+\tu32 i;\n+\tstruct irdma_pble_level2 *lvl2 = &palloc->level2;\n+\tstruct irdma_pble_info *root = &lvl2->root;\n+\tstruct irdma_pble_info *leaf = lvl2->leaf;\n+\n+\tfor (i = 0; i < lvl2->leaf_cnt; i++, leaf++) {\n+\t\tif (leaf->addr)\n+\t\t\tirdma_prm_return_pbles(&pble_rsrc->pinfo,\n+\t\t\t\t\t &leaf->chunkinfo);\n+\t\telse\n+\t\t\tbreak;\n+\t}\n+\n+\tif (root->addr)\n+\t\tirdma_prm_return_pbles(&pble_rsrc->pinfo, &root->chunkinfo);\n+\n+\tkfree(lvl2->leafmem.va);\n+\tlvl2->leaf = NULL;\n+}\n+\n+/**\n+ * get_lvl2_pble - get level 2 pble resource\n+ * @pble_rsrc: pble resource management\n+ * @palloc: level 2 pble allocation\n+ */\n+static enum irdma_status_code\n+get_lvl2_pble(struct irdma_hmc_pble_rsrc *pble_rsrc,\n+\t struct irdma_pble_alloc *palloc)\n+{\n+\tu32 lf4k, lflast, total, i;\n+\tu32 pblcnt = PBLE_PER_PAGE;\n+\tu64 *addr;\n+\tstruct irdma_pble_level2 *lvl2 = &palloc->level2;\n+\tstruct irdma_pble_info *root = &lvl2->root;\n+\tstruct irdma_pble_info *leaf;\n+\tenum irdma_status_code ret_code;\n+\tu64 fpm_addr;\n+\n+\t/* number of full 512 (4K) leafs) */\n+\tlf4k = palloc->total_cnt >> 9;\n+\tlflast = palloc->total_cnt % PBLE_PER_PAGE;\n+\ttotal = (lflast == 0) ? lf4k : lf4k + 1;\n+\tlvl2->leaf_cnt = total;\n+\n+\tlvl2->leafmem.size = (sizeof(*leaf) * total);\n+\tlvl2->leafmem.va = kzalloc(lvl2->leafmem.size, GFP_ATOMIC);\n+\tif (!lvl2->leafmem.va)\n+\t\treturn IRDMA_ERR_NO_MEMORY;\n+\n+\tlvl2->leaf = lvl2->leafmem.va;\n+\tleaf = lvl2->leaf;\n+\tret_code = irdma_prm_get_pbles(&pble_rsrc->pinfo, &root->chunkinfo,\n+\t\t\t\t total << 3, &root->addr, &fpm_addr);\n+\tif (ret_code) {\n+\t\tkfree(lvl2->leafmem.va);\n+\t\tlvl2->leaf = NULL;\n+\t\treturn IRDMA_ERR_NO_MEMORY;\n+\t}\n+\n+\troot->idx = fpm_to_idx(pble_rsrc, fpm_addr);\n+\troot->cnt = total;\n+\taddr = (u64 *)(uintptr_t)root->addr;\n+\tfor (i = 0; i < total; i++, leaf++) {\n+\t\tpblcnt = (lflast && ((i + 1) == total)) ?\n+\t\t\t\tlflast : PBLE_PER_PAGE;\n+\t\tret_code = irdma_prm_get_pbles(&pble_rsrc->pinfo,\n+\t\t\t\t\t &leaf->chunkinfo, pblcnt << 3,\n+\t\t\t\t\t &leaf->addr, &fpm_addr);\n+\t\tif (ret_code)\n+\t\t\tgoto error;\n+\n+\t\tleaf->idx = fpm_to_idx(pble_rsrc, fpm_addr);\n+\n+\t\tleaf->cnt = pblcnt;\n+\t\t*addr = (u64)leaf->idx;\n+\t\taddr++;\n+\t}\n+\n+\tpalloc->level = PBLE_LEVEL_2;\n+\tpble_rsrc->stats_lvl2++;\n+\treturn 0;\n+\n+error:\n+\tfree_lvl2(pble_rsrc, palloc);\n+\n+\treturn IRDMA_ERR_NO_MEMORY;\n+}\n+\n+/**\n+ * get_lvl1_pble - get level 1 pble resource\n+ * @pble_rsrc: pble resource management\n+ * @palloc: level 1 pble allocation\n+ */\n+static enum irdma_status_code\n+get_lvl1_pble(struct irdma_hmc_pble_rsrc *pble_rsrc,\n+\t struct irdma_pble_alloc *palloc)\n+{\n+\tenum irdma_status_code ret_code;\n+\tu64 fpm_addr, vaddr;\n+\tstruct irdma_pble_info *lvl1 = &palloc->level1;\n+\n+\tret_code = irdma_prm_get_pbles(&pble_rsrc->pinfo, &lvl1->chunkinfo,\n+\t\t\t\t palloc->total_cnt << 3, &vaddr,\n+\t\t\t\t &fpm_addr);\n+\tif (ret_code)\n+\t\treturn IRDMA_ERR_NO_MEMORY;\n+\n+\tlvl1->addr = vaddr;\n+\tpalloc->level = PBLE_LEVEL_1;\n+\tlvl1->idx = fpm_to_idx(pble_rsrc, fpm_addr);\n+\tlvl1->cnt = palloc->total_cnt;\n+\tpble_rsrc->stats_lvl1++;\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * get_lvl1_lvl2_pble - calls get_lvl1 and get_lvl2 pble routine\n+ * @pble_rsrc: pble resources\n+ * @palloc: contains all inforamtion regarding pble (idx + pble addr)\n+ * @level1_only: flag for a level 1 PBLE\n+ */\n+static enum irdma_status_code\n+get_lvl1_lvl2_pble(struct irdma_hmc_pble_rsrc *pble_rsrc,\n+\t\t struct irdma_pble_alloc *palloc, bool level1_only)\n+{\n+\tenum irdma_status_code status = 0;\n+\n+\tstatus = get_lvl1_pble(pble_rsrc, palloc);\n+\tif (!status || level1_only || palloc->total_cnt <= PBLE_PER_PAGE)\n+\t\treturn status;\n+\n+\tstatus = get_lvl2_pble(pble_rsrc, palloc);\n+\n+\treturn status;\n+}\n+\n+/**\n+ * irdma_get_pble - allocate pbles from the prm\n+ * @pble_rsrc: pble resources\n+ * @palloc: contains all inforamtion regarding pble (idx + pble addr)\n+ * @pble_cnt: #of pbles requested\n+ * @level1_only: true if only pble level 1 to acquire\n+ */\n+enum irdma_status_code irdma_get_pble(struct irdma_hmc_pble_rsrc *pble_rsrc,\n+\t\t\t\t struct irdma_pble_alloc *palloc,\n+\t\t\t\t u32 pble_cnt, bool level1_only)\n+{\n+\tenum irdma_status_code status = 0;\n+\tunsigned long flags;\n+\tint max_sds = 0;\n+\tint i;\n+\n+\tpalloc->total_cnt = pble_cnt;\n+\tpalloc->level = PBLE_LEVEL_0;\n+\tspin_lock_irqsave(&pble_rsrc->pble_lock, flags);\n+\t/*check first to see if we can get pble's without acquiring\n+\t * additional sd's\n+\t */\n+\tstatus = get_lvl1_lvl2_pble(pble_rsrc, palloc, level1_only);\n+\tif (!status)\n+\t\tgoto exit;\n+\n+\tmax_sds = (palloc->total_cnt >> 18) + 1;\n+\tfor (i = 0; i < max_sds; i++) {\n+\t\tstatus = add_pble_prm(pble_rsrc);\n+\t\tif (status)\n+\t\t\tbreak;\n+\n+\t\tstatus = get_lvl1_lvl2_pble(pble_rsrc, palloc, level1_only);\n+\t\t/* if level1_only, only go through it once */\n+\t\tif (!status || level1_only)\n+\t\t\tbreak;\n+\t}\n+\n+exit:\n+\tif (!status) {\n+\t\tpble_rsrc->allocdpbles += pble_cnt;\n+\t\tpble_rsrc->stats_alloc_ok++;\n+\t} else {\n+\t\tpble_rsrc->stats_alloc_fail++;\n+\t}\n+\tspin_unlock_irqrestore(&pble_rsrc->pble_lock, flags);\n+\n+\treturn status;\n+}\n+\n+/**\n+ * irdma_free_pble - put pbles back into prm\n+ * @pble_rsrc: pble resources\n+ * @palloc: contains all information regarding pble resource being freed\n+ */\n+void irdma_free_pble(struct irdma_hmc_pble_rsrc *pble_rsrc,\n+\t\t struct irdma_pble_alloc *palloc)\n+{\n+\tpble_rsrc->freedpbles += palloc->total_cnt;\n+\n+\tif (palloc->level == PBLE_LEVEL_2)\n+\t\tfree_lvl2(pble_rsrc, palloc);\n+\telse\n+\t\tirdma_prm_return_pbles(&pble_rsrc->pinfo,\n+\t\t\t\t &palloc->level1.chunkinfo);\n+\tpble_rsrc->stats_alloc_freed++;\n+}\ndiff --git a/drivers/infiniband/hw/irdma/pble.h b/drivers/infiniband/hw/irdma/pble.h\nnew file mode 100644\nindex 0000000..6f54ea4\n--- /dev/null\n+++ b/drivers/infiniband/hw/irdma/pble.h\n@@ -0,0 +1,136 @@\n+/* SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB */\n+/* Copyright (c) 2019, Intel Corporation. */\n+\n+#ifndef IRDMA_PBLE_H\n+#define IRDMA_PBLE_H\n+\n+#define PBLE_SHIFT\t\t6\n+#define PBLE_PER_PAGE\t\t512\n+#define HMC_PAGED_BP_SHIFT\t12\n+#define PBLE_512_SHIFT\t\t9\n+#define PBLE_INVALID_IDX\t0xffffffff\n+\n+enum irdma_pble_level {\n+\tPBLE_LEVEL_0 = 0,\n+\tPBLE_LEVEL_1 = 1,\n+\tPBLE_LEVEL_2 = 2,\n+};\n+\n+enum irdma_alloc_type {\n+\tPBLE_NO_ALLOC\t = 0,\n+\tPBLE_SD_CONTIGOUS = 1,\n+\tPBLE_SD_PAGED\t = 2,\n+};\n+\n+struct irdma_chunk;\n+\n+struct irdma_pble_chunkinfo {\n+\tstruct irdma_chunk *pchunk;\n+\tu64 bit_idx;\n+\tu64 bits_used;\n+};\n+\n+struct irdma_pble_info {\n+\tu64 addr;\n+\tu32 idx;\n+\tu32 cnt;\n+\tstruct irdma_pble_chunkinfo chunkinfo;\n+};\n+\n+struct irdma_pble_level2 {\n+\tstruct irdma_pble_info root;\n+\tstruct irdma_pble_info *leaf;\n+\tstruct irdma_virt_mem leafmem;\n+\tu32 leaf_cnt;\n+};\n+\n+struct irdma_pble_alloc {\n+\tu32 total_cnt;\n+\tenum irdma_pble_level level;\n+\tunion {\n+\t\tstruct irdma_pble_info level1;\n+\t\tstruct irdma_pble_level2 level2;\n+\t};\n+};\n+\n+struct sd_pd_idx {\n+\tu32 sd_idx;\n+\tu32 pd_idx;\n+\tu32 rel_pd_idx;\n+};\n+\n+struct irdma_add_page_info {\n+\tstruct irdma_chunk *chunk;\n+\tstruct irdma_hmc_sd_entry *sd_entry;\n+\tstruct irdma_hmc_info *hmc_info;\n+\tstruct sd_pd_idx idx;\n+\tu32 pages;\n+};\n+\n+struct irdma_chunk {\n+\tstruct list_head list;\n+\tstruct irdma_dma_info dmainfo;\n+\tvoid *bitmapbuf;\n+\n+\tu32 sizeofbitmap;\n+\tu64 size;\n+\tu64 vaddr;\n+\tu64 fpm_addr;\n+\tu32 pg_cnt;\n+\tenum irdma_alloc_type type;\n+\tstruct irdma_sc_dev *dev;\n+\tstruct irdma_virt_mem bitmapmem;\n+\tstruct irdma_virt_mem chunkmem;\n+};\n+\n+struct irdma_pble_prm {\n+\tstruct list_head clist;\n+\tspinlock_t prm_lock; /* protect prm bitmap */\n+\tu64 total_pble_alloc;\n+\tu64 free_pble_cnt;\n+\tu8 pble_shift;\n+};\n+\n+struct irdma_hmc_pble_rsrc {\n+\tu32 unallocated_pble;\n+\tspinlock_t pble_lock; /* to serialize PBLE resource acquisition */\n+\tstruct irdma_sc_dev *dev;\n+\tu64 fpm_base_addr;\n+\tu64 next_fpm_addr;\n+\tstruct irdma_pble_prm pinfo;\n+\tu64 allocdpbles;\n+\tu64 freedpbles;\n+\tu32 stats_direct_sds;\n+\tu32 stats_paged_sds;\n+\tu64 stats_alloc_ok;\n+\tu64 stats_alloc_fail;\n+\tu64 stats_alloc_freed;\n+\tu64 stats_lvl1;\n+\tu64 stats_lvl2;\n+};\n+\n+void irdma_destroy_pble_prm(struct irdma_hmc_pble_rsrc *pble_rsrc);\n+enum irdma_status_code\n+irdma_hmc_init_pble(struct irdma_sc_dev *dev,\n+\t\t struct irdma_hmc_pble_rsrc *pble_rsrc);\n+void irdma_free_pble(struct irdma_hmc_pble_rsrc *pble_rsrc,\n+\t\t struct irdma_pble_alloc *palloc);\n+enum irdma_status_code irdma_get_pble(struct irdma_hmc_pble_rsrc *pble_rsrc,\n+\t\t\t\t struct irdma_pble_alloc *palloc,\n+\t\t\t\t u32 pble_cnt, bool level1_only);\n+enum irdma_status_code irdma_prm_add_pble_mem(struct irdma_pble_prm *pprm,\n+\t\t\t\t\t struct irdma_chunk *pchunk);\n+enum irdma_status_code\n+irdma_prm_get_pbles(struct irdma_pble_prm *pprm,\n+\t\t struct irdma_pble_chunkinfo *chunkinfo, u32 mem_size,\n+\t\t u64 *vaddr, u64 *fpm_addr);\n+void irdma_prm_return_pbles(struct irdma_pble_prm *pprm,\n+\t\t\t struct irdma_pble_chunkinfo *chunkinfo);\n+void irdma_pble_acquire_lock(struct irdma_hmc_pble_rsrc *pble_rsrc,\n+\t\t\t unsigned long *flags);\n+void irdma_pble_release_lock(struct irdma_hmc_pble_rsrc *pble_rsrc,\n+\t\t\t unsigned long *flags);\n+void irdma_pble_free_paged_mem(struct irdma_chunk *chunk);\n+enum irdma_status_code irdma_pble_get_paged_mem(struct irdma_chunk *chunk,\n+\t\t\t\t\t\tint pg_cnt);\n+#endif /* IRDMA_PBLE_H */\n", "prefixes": [ "rdma-next", "08/17" ] }