From patchwork Wed Aug 27 10:24:38 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Ishchuk X-Patchwork-Id: 4787371 Return-Path: X-Original-To: patchwork-linux-rdma@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 8B342C0338 for ; Wed, 27 Aug 2014 10:25:49 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8535C2018B for ; Wed, 27 Aug 2014 10:25:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C4D222015E for ; Wed, 27 Aug 2014 10:25:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933639AbaH0KZh (ORCPT ); Wed, 27 Aug 2014 06:25:37 -0400 Received: from e06smtp11.uk.ibm.com ([195.75.94.107]:57009 "EHLO e06smtp11.uk.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933393AbaH0KZg (ORCPT ); Wed, 27 Aug 2014 06:25:36 -0400 Received: from /spool/local by e06smtp11.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 27 Aug 2014 11:25:35 +0100 Received: from d06dlp01.portsmouth.uk.ibm.com (9.149.20.13) by e06smtp11.uk.ibm.com (192.168.101.141) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 27 Aug 2014 11:25:32 +0100 Received: from b06cxnps4074.portsmouth.uk.ibm.com (d06relay11.portsmouth.uk.ibm.com [9.149.109.196]) by d06dlp01.portsmouth.uk.ibm.com (Postfix) with ESMTP id 0D25D17D805F; Wed, 27 Aug 2014 11:27:27 +0100 (BST) Received: from d06av01.portsmouth.uk.ibm.com (d06av01.portsmouth.uk.ibm.com [9.149.37.212]) by b06cxnps4074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id s7RAPWbp28508322; Wed, 27 Aug 2014 10:25:32 GMT Received: from d06av01.portsmouth.uk.ibm.com (localhost [127.0.0.1]) by d06av01.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id s7RAPTcJ002864; Wed, 27 Aug 2014 04:25:31 -0600 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d06av01.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id s7RAP1jl001480; Wed, 27 Aug 2014 04:25:28 -0600 From: Alexey Ishchuk To: linux-rdma@vger.kernel.org Cc: arlin.r.davis@intel.com, gilr@dev.mellanox.co.il, roland@kernel.org, linux-s390@vger.kernel.org, gmuelas@de.ibm.com, utz.bacher@de.ibm.com, martin.schwidefsky@de.ibm.com, frank.blaschka@de.ibm.com, Alexey Ishchuk Subject: [PATCH 3/5] libmlx4: add support for s390x platform Date: Wed, 27 Aug 2014 12:24:38 +0200 Message-Id: <1409135080-44991-4-git-send-email-aishchuk@linux.vnet.ibm.com> X-Mailer: git-send-email 1.8.5.5 In-Reply-To: <1409135080-44991-1-git-send-email-aishchuk@linux.vnet.ibm.com> References: <1409135080-44991-1-git-send-email-aishchuk@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 14082710-5024-0000-0000-00000119B093 Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Since s390x platform requires execution of privileged CPU instructions to work with PCI I/O memory, the PCI I/O memory cannot be directly accessed from the userspace programs via the mapped memory areas. The current implementation of the Inifiniband verbs uses mapped memory areas to write data to device UAR and Blueflame page to initiate the I/O operations, these verbs cannot be used on the s390x platfrom without modification. This patch contains the changes to the libmlx4 userspace Mellanox device driver library required to provide support for the DAPL API on the s390x platform. The original code that directly used mapped memory areas to access the PCI I/O memory of the Mellanox networking device is replaced with the new system call invocation for writing the data to mapped memory areas. Signed-off-by: Alexey Ishchuk --- src/doorbell.h | 8 +-- src/mlx4.h | 2 src/mmio.h | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/qp.c | 17 ------ 4 files changed, 160 insertions(+), 18 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html --- a/src/doorbell.h +++ b/src/doorbell.h @@ -33,6 +33,8 @@ #ifndef DOORBELL_H #define DOORBELL_H +#include "mmio.h" + #if SIZEOF_LONG == 8 #if __BYTE_ORDER == __LITTLE_ENDIAN @@ -45,7 +47,7 @@ static inline void mlx4_write64(uint32_t val[2], struct mlx4_context *ctx, int offset) { - *(volatile uint64_t *) (ctx->uar + offset) = MLX4_PAIR_TO_64(val); + mmio_writeq((unsigned long)(ctx->uar + offset), MLX4_PAIR_TO_64(val)); } #else @@ -53,8 +55,8 @@ static inline void mlx4_write64(uint32_t static inline void mlx4_write64(uint32_t val[2], struct mlx4_context *ctx, int offset) { pthread_spin_lock(&ctx->uar_lock); - *(volatile uint32_t *) (ctx->uar + offset) = val[0]; - *(volatile uint32_t *) (ctx->uar + offset + 4) = val[1]; + mmio_writel((unsigned long)(ctx->uar + offset), val[0]); + mmio_writel((unsigned long)(ctx->uar + offset + 4), val[1]); pthread_spin_unlock(&ctx->uar_lock); } --- a/src/mlx4.h +++ b/src/mlx4.h @@ -73,6 +73,8 @@ #define wc_wmb() asm volatile("sfence" ::: "memory") #elif defined(__ia64__) #define wc_wmb() asm volatile("fwb" ::: "memory") +#elif defined(__s390x__) +#define wc_wmb { asm volatile("" : : : "memory") } #else #define wc_wmb() wmb() #endif --- /dev/null +++ b/src/mmio.h @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2014 IBM Corporation + */ +#ifndef MMIO_H +#define MMIO_H + +#include +#include +#include +#ifdef __s390x__ + +#define s390_pci_mmio_write_call(addr, value) \ + syscall(__NR_s390_pci_mmio_write, addr, &value, sizeof(value)) + + +static inline long s390_pci_mmio_writeb(const unsigned long mmio_addr, + const uint8_t val) +{ + return s390_pci_mmio_write_call(mmio_addr, val); +} + +static inline long s390_pci_mmio_writew(const unsigned long mmio_addr, + const uint16_t val) +{ + return s390_pci_mmio_write_call(mmio_addr, val); +} + +static inline long s390_pci_mmio_writel(const unsigned long mmio_addr, + const uint32_t val) +{ + return s390_pci_mmio_write_call(mmio_addr, val); +} + +static inline long s390_pci_mmio_writeq(const unsigned long mmio_addr, + const uint64_t val) +{ + return s390_pci_mmio_write_call(mmio_addr, val); +} + +static inline long s390_pci_mmio_write(const unsigned long mmio_addr, + const void *val, + const size_t length) +{ + return syscall(__NR_s390_pci_mmio_write, mmio_addr, val, length); +} + +#define s390_pci_mmio_read_call(addr, value) \ + syscall(__NR_s390_pci_mmio_read, addr, value, sizeof(*value)) + +static inline long s390_pci_mmio_readb(const unsigned long mmio_addr, + uint8_t *val) +{ + return s390_pci_mmio_read_call(mmio_addr, val); +} + +static inline long s390_pci_mmio_readw(const unsigned long mmio_addr, + uint16_t *val) +{ + return s390_pci_mmio_read_call(mmio_addr, val); +} + +static inline long s390_pci_mmio_readl(const unsigned long mmio_addr, + uint32_t *val) +{ + return s390_pci_mmio_read_call(mmio_addr, val); +} + +static inline long s390_pci_mmio_readq(const unsigned long mmio_addr, + uint64_t *val) +{ + return s390_pci_mmio_read_call(mmio_addr, val); +} + +static inline long s390_pci_mmio_read(const unsigned long mmio_addr, + void *val, + const size_t length) +{ + return syscall(__NR_s390_pci_mmio_read, mmio_addr, val, length); +} + +#define mmio_writeb(addr, value) \ + s390_pci_mmio_writeb(addr, value) +#define mmio_writew(addr, value) \ + s390_pci_mmio_writew(addr, value) +#define mmio_writel(addr, value) \ + s390_pci_mmio_writel(addr, value) +#define mmio_writeq(addr, value) \ + s390_pci_mmio_writeq(addr, value) +#define mmio_write(addr, value, length) \ + s390_pci_mmio_write(addr, value, length) + +#define mmio_readb(addr, value) \ + s390_pci_mmio_readb(addr, value) +#define mmio_readw(addr, value) \ + s390_pci_mmio_readw(addr, value) +#define mmio_readl(addr, value) \ + s390_pci_mmio_readl(addr, value) +#define mmio_readq(addr, value) \ + s390_pci_mmio_readq(addr, value) +#define mmio_read(addr, value, length) \ + s390_pci_mmio_read(addr, value, length) + +static inline void mlx4_bf_copy(unsigned long *dst, + unsigned long *src, + unsigned bytecnt) +{ + mmio_write((unsigned long) dst, src, bytecnt); +} + +#else + +#define mmio_writeb(addr, value) \ + (*((uint8_t *)addr) = value) +#define mmio_writeb(addr, value) \ + (*((uint16_t *)addr) = value) +#define mmio_writew(addr, value) \ + (*((uint32_t *)addr) = value) +#define mmio_writeq(addr, value) \ + (*((uint64_t *)addr) = value) +#define mmio_write(addr, value, length) \ + memcpy(addr, value, length) + +#define mmio_readb(addr, value) \ + (value = *((uint8_t *)addr)) +#define mmio_readw(addr, value) \ + (value = *((uint16_t *)addr)) +#define mmio_readl(addr, value) \ + (value = *((uint32_t *)addr)) +#define mmio_readq(addr, value) \ + (value = *((uint64_t *)addr)) +#define mmio_read(addr, value, length) \ + memcpy(value, addr, length) + +/* + * Avoid using memcpy() to copy to BlueFlame page, since memcpy() + * implementations may use move-string-buffer assembler instructions, + * which do not guarantee order of copying. + */ +static inline void mlx4_bf_copy(unsigned long *dst, + unsigned long *src, + unsigned bytecnt) +{ + while (bytecnt > 0) { + *dst++ = *src++; + *dst++ = *src++; + bytecnt -= 2 * sizeof(long); + } +} +#endif + +#endif --- a/src/qp.c +++ b/src/qp.c @@ -173,20 +173,6 @@ static void set_data_seg(struct mlx4_wqe dseg->byte_count = htonl(sg->length); } -/* - * Avoid using memcpy() to copy to BlueFlame page, since memcpy() - * implementations may use move-string-buffer assembler instructions, - * which do not guarantee order of copying. - */ -static void mlx4_bf_copy(unsigned long *dst, unsigned long *src, unsigned bytecnt) -{ - while (bytecnt > 0) { - *dst++ = *src++; - *dst++ = *src++; - bytecnt -= 2 * sizeof (long); - } -} - int mlx4_post_send(struct ibv_qp *ibqp, struct ibv_send_wr *wr, struct ibv_send_wr **bad_wr) { @@ -431,7 +417,8 @@ out: */ wmb(); - *(uint32_t *) (ctx->uar + MLX4_SEND_DOORBELL) = qp->doorbell_qpn; + mmio_writel((unsigned long)(ctx->uar + MLX4_SEND_DOORBELL), + qp->doorbell_qpn); } if (nreq)