* The relevant files have been modified in order to compile with McKernel.
Conflicts: kernel/Makefile.build.in
This commit is contained in:
committed by
Balazs Gerofi
parent
14b360e867
commit
64e2639adc
@ -8,6 +8,7 @@ OBJS += process.o copy.o waitq.o futex.o timer.o plist.o fileobj.o shmobj.o
|
||||
OBJS += zeroobj.o procfs.o devobj.o sysfs.o xpmem.o profile.o freeze.o
|
||||
OBJS += rbtree.o
|
||||
OBJS += pager.o
|
||||
OBJS += file_ops.o user_sdma.o sdma.o
|
||||
# POSTK_DEBUG_ARCH_DEP_18 coredump arch separation.
|
||||
DEPSRCS=$(wildcard $(SRC)/*.c)
|
||||
|
||||
|
||||
@ -44,6 +44,15 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <hfi1/file_ops.h>
|
||||
#include <hfi1/hfi.h>
|
||||
#include <hfi1/user_sdma.h>
|
||||
#include <hfi1/ihk_hfi1_common.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
#include <linux/poll.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/vmalloc.h>
|
||||
@ -404,15 +413,23 @@ static long hfi1_file_ioctl(struct file *fp, unsigned int cmd,
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
static ssize_t hfi1_aio_write(struct kiocb *kiocb, const struct iovec *iovec,
|
||||
unsigned long dim, loff_t offset)
|
||||
{
|
||||
struct hfi1_filedata *fd = kiocb->ki_filp->private_data;
|
||||
#else
|
||||
ssize_t hfi1_aio_write(void *private_data, const struct iovec *iovec, unsigned long dim)
|
||||
{
|
||||
struct hfi1_filedata *fd = private_data;
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
struct hfi1_user_sdma_pkt_q *pq = fd->pq;
|
||||
struct hfi1_user_sdma_comp_q *cq = fd->cq;
|
||||
int done = 0, reqs = 0;
|
||||
|
||||
hfi1_cdbg(AIOWRITE, "+");
|
||||
if (!cq || !pq)
|
||||
return -EIO;
|
||||
|
||||
@ -429,9 +446,15 @@ static ssize_t hfi1_aio_write(struct kiocb *kiocb, const struct iovec *iovec,
|
||||
int ret;
|
||||
unsigned long count = 0;
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
ret = hfi1_user_sdma_process_request(
|
||||
kiocb->ki_filp, (struct iovec *)(iovec + done),
|
||||
dim, &count);
|
||||
#else
|
||||
ret = hfi1_user_sdma_process_request(
|
||||
private_data, (struct iovec *)(iovec + done),
|
||||
dim, &count);
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
if (ret) {
|
||||
reqs = ret;
|
||||
break;
|
||||
@ -440,9 +463,10 @@ static ssize_t hfi1_aio_write(struct kiocb *kiocb, const struct iovec *iovec,
|
||||
done += count;
|
||||
reqs++;
|
||||
}
|
||||
|
||||
hfi1_cdbg(AIOWRITE, "-");
|
||||
return reqs;
|
||||
}
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
static int hfi1_file_mmap(struct file *fp, struct vm_area_struct *vma)
|
||||
{
|
||||
@ -1556,3 +1580,4 @@ void hfi1_device_remove(struct hfi1_devdata *dd)
|
||||
user_remove(dd);
|
||||
hfi1_diag_remove(dd);
|
||||
}
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
@ -48,7 +48,11 @@
|
||||
#ifndef _COMMON_H
|
||||
#define _COMMON_H
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
#include "update/hfi1_user.h"
|
||||
#else
|
||||
#include <hfi1/hfi1_user.h>
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
/*
|
||||
* This file contains defines, structures, etc. that are used
|
||||
|
||||
9
kernel/include/hfi1/file_ops.h
Normal file
9
kernel/include/hfi1/file_ops.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef _HFI1_FILE_OPS_H_
|
||||
#define _HFI1_FILE_OPS_H_
|
||||
|
||||
#include <ihk/types.h>
|
||||
#include <uio.h>
|
||||
|
||||
ssize_t hfi1_aio_write(void *private_data, const struct iovec *iovec, unsigned long dim);
|
||||
|
||||
#endif
|
||||
@ -47,6 +47,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <hfi1/user_sdma.h>
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
@ -92,7 +96,10 @@
|
||||
#define DROP_PACKET_OFF 0
|
||||
#define DROP_PACKET_ON 1
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
extern unsigned long hfi1_cap_mask;
|
||||
|
||||
#define HFI1_CAP_KGET_MASK(mask, cap) ((mask) & HFI1_CAP_##cap)
|
||||
#define HFI1_CAP_UGET_MASK(mask, cap) \
|
||||
(((mask) >> HFI1_CAP_USER_SHIFT) & HFI1_CAP_##cap)
|
||||
@ -125,6 +132,8 @@ extern unsigned long hfi1_cap_mask;
|
||||
#define NUM_SEND_CTXT_ERR_STATUS_COUNTERS 5
|
||||
#define NUM_SEND_DMA_ENG_ERR_STATUS_COUNTERS 24
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
/*
|
||||
* per driver stats, either not device nor port-specific, or
|
||||
* summed over all of the devices and ports.
|
||||
@ -194,7 +203,7 @@ struct tid_queue {
|
||||
u32 enqueue; /* count of tid enqueues */
|
||||
u32 dequeue; /* count of tid dequeues */
|
||||
};
|
||||
|
||||
|
||||
struct hfi1_ctxtdata {
|
||||
/* shadow the ctxt's RcvCtrl register */
|
||||
u64 rcvctrl;
|
||||
@ -358,6 +367,15 @@ struct hfi1_ctxtdata {
|
||||
int (*do_interrupt)(struct hfi1_ctxtdata *rcd, int threaded);
|
||||
};
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
#ifndef __HFI1_ORIG__
|
||||
struct hfi1_ctxtdata {
|
||||
unsigned ctxt;
|
||||
};
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
/*
|
||||
* Represents a single packet at a high level. Put commonly computed things in
|
||||
* here so we do not have to keep doing them over and over. The rule of thumb is
|
||||
@ -584,6 +602,7 @@ struct vl_arb_cache {
|
||||
struct ib_vl_weight_elem table[VL_ARB_TABLE_SIZE];
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* The structure below encapsulates data relevant to a physical IB Port.
|
||||
* Current chips support only one such port, but the separation
|
||||
@ -788,7 +807,15 @@ struct hfi1_pportdata {
|
||||
/* Does this port need to prescan for FECNs */
|
||||
bool cc_prescan;
|
||||
};
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
#ifndef __HFI1_ORIG__
|
||||
struct hfi1_pportdata {
|
||||
|
||||
};
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
typedef int (*rhf_rcv_function_ptr)(struct hfi1_packet *packet);
|
||||
|
||||
typedef void (*opcode_handler)(struct hfi1_packet *packet);
|
||||
@ -857,6 +884,7 @@ struct sdma_vl_map;
|
||||
#define SERIAL_MAX 16 /* length of the serial number */
|
||||
|
||||
typedef int (*send_routine)(struct rvt_qp *, struct hfi1_pkt_state *, u64);
|
||||
|
||||
struct hfi1_devdata {
|
||||
struct hfi1_ibdev verbs_dev; /* must be first */
|
||||
struct list_head list;
|
||||
@ -1169,7 +1197,7 @@ struct hfi1_devdata {
|
||||
/* hfi1_pportdata, points to array of (physical) port-specific
|
||||
* data structs, indexed by pidx (0..n-1)
|
||||
*/
|
||||
struct hfi1_pportdata *pport;
|
||||
struct hfi1_pportdata *pport; //used
|
||||
/* receive context data */
|
||||
struct hfi1_ctxtdata **rcd;
|
||||
u64 __percpu *int_counter;
|
||||
@ -1221,6 +1249,20 @@ struct hfi1_devdata {
|
||||
|
||||
struct kobject kobj;
|
||||
};
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
#ifndef __HFI1_ORIG__
|
||||
struct hfi1_devdata {
|
||||
struct list_head list;
|
||||
/* pointers to related structs for this device */
|
||||
/* pci access data structure */
|
||||
struct pci_dev *pcidev;
|
||||
dma_addr_t sdma_pad_phys;
|
||||
/* array of engines sized by num_sdma */
|
||||
struct sdma_engine *per_sdma;
|
||||
struct hfi1_pportdata *pport;
|
||||
};
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
/* 8051 firmware version helper */
|
||||
#define dc8051_ver(a, b) ((a) << 8 | (b))
|
||||
@ -1230,6 +1272,8 @@ struct hfi1_devdata {
|
||||
#define PT_EAGER 1
|
||||
#define PT_INVALID 2
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
struct tid_rb_node;
|
||||
struct mmu_rb_node;
|
||||
struct mmu_rb_handler;
|
||||
@ -1254,6 +1298,19 @@ struct hfi1_filedata {
|
||||
spinlock_t invalid_lock;
|
||||
struct mm_struct *mm;
|
||||
};
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
#ifndef __HFI1_ORIG__
|
||||
/* Private data for file operations */
|
||||
struct hfi1_filedata {
|
||||
struct hfi1_ctxtdata *uctxt;
|
||||
unsigned subctxt;
|
||||
struct hfi1_user_sdma_comp_q *cq;
|
||||
struct hfi1_user_sdma_pkt_q *pq;
|
||||
};
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
extern struct list_head hfi1_dev_list;
|
||||
extern spinlock_t hfi1_devs_lock;
|
||||
@ -2039,10 +2096,12 @@ void hfi1_format_hwerrors(u64 hwerrs,
|
||||
const struct hfi1_hwerror_msgs *hwerrmsgs,
|
||||
size_t nhwerrmsgs, char *msg, size_t lmsg);
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
#define USER_OPCODE_CHECK_VAL 0xC0
|
||||
#define USER_OPCODE_CHECK_MASK 0xC0
|
||||
#define OPCODE_CHECK_VAL_DISABLED 0x0
|
||||
#define OPCODE_CHECK_MASK_DISABLED 0x0
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
static inline void hfi1_reset_cpu_counters(struct hfi1_devdata *dd)
|
||||
{
|
||||
@ -2149,4 +2208,6 @@ __print_symbolic(opcode, \
|
||||
ib_opcode_name(UD_SEND_ONLY), \
|
||||
ib_opcode_name(UD_SEND_ONLY_WITH_IMMEDIATE), \
|
||||
ib_opcode_name(CNP))
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
#endif /* _HFI1_KERNEL_H */
|
||||
|
||||
@ -56,8 +56,12 @@
|
||||
#ifndef _LINUX__HFI1_USER_H
|
||||
#define _LINUX__HFI1_USER_H
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
/*
|
||||
* This version number is given to the driver by the user code during
|
||||
* initialization in the spu_userversion field of hfi1_user_info, so
|
||||
@ -211,6 +215,8 @@ struct hfi1_cmd;
|
||||
#define HFI1_POLL_TYPE_ANYRCV 0x0
|
||||
#define HFI1_POLL_TYPE_URGENT 0x1
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
/*
|
||||
* This structure is passed to the driver to tell it where
|
||||
* user code buffers are, sizes, etc. The offsets and sizes of the
|
||||
@ -264,6 +270,7 @@ struct hfi1_tid_info {
|
||||
/* length of transfer buffer programmed by this request */
|
||||
__u32 length;
|
||||
};
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
enum hfi1_sdma_comp_state {
|
||||
FREE = 0,
|
||||
@ -280,6 +287,8 @@ struct hfi1_sdma_comp_entry {
|
||||
__u32 errcode;
|
||||
};
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
/*
|
||||
* Device status and notifications from driver to user-space.
|
||||
*/
|
||||
@ -353,6 +362,7 @@ struct hfi1_base_info {
|
||||
__u64 subctxt_rcvegrbuf;
|
||||
__u64 subctxt_rcvhdrbuf;
|
||||
};
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
enum sdma_req_opcode {
|
||||
EXPECTED = 0,
|
||||
@ -391,7 +401,7 @@ struct sdma_req_info {
|
||||
* in charge of managing its own ring.
|
||||
*/
|
||||
__u16 comp_idx;
|
||||
} __packed;
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* SW KDETH header.
|
||||
@ -402,7 +412,7 @@ struct hfi1_kdeth_header {
|
||||
__le16 jkey;
|
||||
__le16 hcrc;
|
||||
__le32 swdata[7];
|
||||
} __packed;
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* Structure describing the headers that User space uses. The
|
||||
@ -413,8 +423,9 @@ struct hfi1_pkt_header {
|
||||
__be16 lrh[4];
|
||||
__be32 bth[3];
|
||||
struct hfi1_kdeth_header kdeth;
|
||||
} __packed;
|
||||
} __attribute__((packed));
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
/*
|
||||
* The list of usermode accessible registers.
|
||||
@ -435,5 +446,5 @@ enum hfi1_ureg {
|
||||
/* (RW) Receive TID flow table */
|
||||
ur_rcvtidflowtable = 256
|
||||
};
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
#endif /* _LINIUX__HFI1_USER_H */
|
||||
|
||||
218
kernel/include/hfi1/ihk_hfi1_common.h
Normal file
218
kernel/include/hfi1/ihk_hfi1_common.h
Normal file
@ -0,0 +1,218 @@
|
||||
#ifndef _IHK_HFI1_COMMON_H_
|
||||
#define _IHK_HFI1_COMMON_H_
|
||||
|
||||
#include <ihk/atomic.h>
|
||||
#include <ihk/types.h>
|
||||
#include <kmalloc.h>
|
||||
#include <lwk/compiler.h>
|
||||
#include <arch-lock.h>
|
||||
#include <page.h>
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#endif
|
||||
|
||||
/* From: mckernel/kernel/include/xpmem_private.h */
|
||||
#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
|
||||
#define min(x, y) ({ \
|
||||
__typeof__(x) _min1 = (x); \
|
||||
__typeof__(y) _min2 = (y); \
|
||||
(void) (&_min1 == &_min2); \
|
||||
_min1 < _min2 ? _min1 : _min2;})
|
||||
|
||||
|
||||
#define BIT_ULL(nr) (1ULL << (nr))
|
||||
|
||||
/* Disable debug macros */
|
||||
#define hfi1_cdbg(...) do {} while(0)
|
||||
#define SDMA_DBG(...) do {} while(0)
|
||||
#define WARN_ON(...) do {} while(0)
|
||||
#define WARN_ON_ONCE WARN_ON // use the local definition
|
||||
#define trace_hfi1_ahg_allocate(...) do {} while(0)
|
||||
#define trace_hfi1_ahg_deallocate(...) do {} while(0)
|
||||
|
||||
/* Byte swapping */
|
||||
#define be32_to_cpu(x) __builtin_bswap32(x)
|
||||
#define be16_to_cpu(x) __builtin_bswap16(x)
|
||||
#define le32_to_cpu(x) x
|
||||
#define le16_to_cpu(x) x
|
||||
#define cpu_to_le16(x) x
|
||||
#define cpu_to_le32(x) x
|
||||
#define cpu_to_le64(x) x
|
||||
#define __cpu_to_le64(x) x
|
||||
#define __le64_to_cpu(x) x
|
||||
#define __le32_to_cpu(x) x
|
||||
#define __le16_to_cpu(x) x
|
||||
//TODO: double-check
|
||||
#define cpu_to_be16(x) __builtin_bswap16(x)
|
||||
#define cpu_to_be32(x) __builtin_bswap32(x)
|
||||
|
||||
/* Compiler */
|
||||
#ifndef likely
|
||||
# define likely(x) __builtin_expect(!!(x), 1)
|
||||
#endif
|
||||
|
||||
#ifndef unlikely
|
||||
# define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
#endif
|
||||
|
||||
/* From: kernel-xppsl_1.5.2/include/linux/compiler.h */
|
||||
#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
|
||||
|
||||
/* Atomic ops */
|
||||
#define atomic_inc ihk_atomic_inc
|
||||
#define atomic_dec ihk_atomic_dec
|
||||
#define atomic_read ihk_atomic_read
|
||||
#define atomic_add ihk_atomic_add
|
||||
#define atomic_t ihk_atomic_t
|
||||
|
||||
/* TODO***********************************/
|
||||
#define spin_lock_irqsave(lock, flags) do {} while(0)
|
||||
#define spin_unlock_irqsave(lock, flags) do {} while(0)
|
||||
#define spin_unlock_irqrestore(lock, flags) do {} while(0)
|
||||
typedef ihk_spinlock_t spinlock_t;
|
||||
#define ____cacheline_aligned_in_smp
|
||||
#define __iomem
|
||||
#define spin_lock(...) do {} while(0)
|
||||
#define spin_unlock(...) do {} while(0)
|
||||
#define smp_wmb() barrier()
|
||||
#define smp_rmb() barrier()
|
||||
/***********************************************/
|
||||
|
||||
/* TODO: Figure the corresponding flag for McKernel-kmalloc()*/
|
||||
#define __GFP_ZERO 0
|
||||
#define GFP_KERNEL 0
|
||||
|
||||
/* kernel-xppsl_1.5.2/include/linux/seqlock.h */
|
||||
/***********************************************/
|
||||
typedef struct seqcount {
|
||||
unsigned sequence;
|
||||
} seqcount_t;
|
||||
|
||||
typedef struct {
|
||||
struct seqcount seqcount;
|
||||
spinlock_t lock;
|
||||
} seqlock_t;
|
||||
|
||||
static inline unsigned raw_seqcount_begin(const seqcount_t *s)
|
||||
{
|
||||
unsigned ret = ACCESS_ONCE(s->sequence);
|
||||
smp_rmb();
|
||||
return ret & ~1;
|
||||
}
|
||||
/***********************************************/
|
||||
|
||||
/* Misc */
|
||||
/* From: kernel-xppsl_1.5.2/include/linux/kernel.h */
|
||||
#define min_t(type, x, y) ({ \
|
||||
type __min1 = (x); \
|
||||
type __min2 = (y); \
|
||||
__min1 < __min2 ? __min1: __min2; })
|
||||
|
||||
#define SIZE_MAX (~(size_t)0)
|
||||
#define MAX_TID_PAIR_ENTRIES 1024 /* max receive expected pairs */
|
||||
#define PIO_BLOCK_SIZE 64 /* bytes */
|
||||
/* From: chip.c/h */
|
||||
//num_vls = HFI1_MAX_VLS_SUPPORTED;
|
||||
//num_vls = dd->chip_sdma_engines;
|
||||
#define HFI1_MAX_VLS_SUPPORTED 8
|
||||
|
||||
|
||||
/* integer typedefs */
|
||||
typedef __signed__ char __s8;
|
||||
typedef unsigned char __u8;
|
||||
|
||||
typedef __signed__ short __s16;
|
||||
typedef unsigned short __u16;
|
||||
|
||||
typedef __signed__ int __s32;
|
||||
typedef unsigned int __u32;
|
||||
|
||||
typedef __signed__ long __s64;
|
||||
typedef unsigned long __u64;
|
||||
|
||||
typedef __u64 u64;
|
||||
typedef __s64 s64;
|
||||
|
||||
typedef __u32 u32;
|
||||
typedef __s32 s32;
|
||||
|
||||
typedef __u16 u16;
|
||||
typedef __s16 s16;
|
||||
|
||||
typedef __u8 u8;
|
||||
typedef __s8 s8;
|
||||
|
||||
typedef __u16 __le16;
|
||||
typedef __u16 __be16;
|
||||
typedef __u32 __le32;
|
||||
typedef __u32 __be32;
|
||||
typedef __u64 __le64;
|
||||
typedef __u64 __be64;
|
||||
|
||||
typedef unsigned int uint;
|
||||
|
||||
/* TODO: There should be a header file that I can include */
|
||||
typedef _Bool bool;
|
||||
#define false 0
|
||||
#define true !false
|
||||
|
||||
/* TODO: double check this typedef */
|
||||
typedef u64 dma_addr_t;
|
||||
|
||||
/* From: kernel-xppsl_1.5.2/include/linux/types.h */
|
||||
typedef unsigned gfp_t;
|
||||
|
||||
/* kernel-xppsl_1.5.2/include/asm-generic/io.h */
|
||||
#ifndef __raw_writeq
|
||||
static inline void __raw_writeq(u64 b, volatile void __iomem *addr)
|
||||
{
|
||||
*(volatile u64 __force *) addr = b;
|
||||
}
|
||||
#endif
|
||||
#define writeq(b, addr) __raw_writeq(__cpu_to_le64(b), addr)
|
||||
|
||||
|
||||
/* TODO: I'm not sure if this definition is correct */
|
||||
#define LOCK_PREFIX "lock; "
|
||||
|
||||
/* From: kernel-xppsl_1.5.2/arch/x86/include/asm/bitops.h */
|
||||
#define BITOP_ADDR(x) "+m" (*(volatile long *) (x))
|
||||
#define LINUX_ADDR BITOP_ADDR(addr)
|
||||
|
||||
/* From: kernel-xppsl_1.5.2/arch/x86/include/asm/bitops.h */
|
||||
static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
|
||||
{
|
||||
int oldbit;
|
||||
|
||||
asm volatile(LOCK_PREFIX "bts %2,%1\n\t"
|
||||
"sbb %0,%0" : "=r" (oldbit), LINUX_ADDR : "Ir" (nr) : "memory");
|
||||
|
||||
return oldbit;
|
||||
}
|
||||
|
||||
/* From: kernel-xppsl_1.5.2/arch/x86/include/asm/atomic.h */
|
||||
static inline int atomic_dec_and_test(atomic_t *v)
|
||||
{
|
||||
unsigned char c;
|
||||
|
||||
asm volatile(LOCK_PREFIX "decl %0; sete %1"
|
||||
: "+m" (v->counter), "=qm" (c)
|
||||
: : "memory");
|
||||
return c != 0;
|
||||
}
|
||||
|
||||
/* From: kernel-xppsl_1.5.2/include/linux/slab.h */
|
||||
static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags)
|
||||
{
|
||||
if (size != 0 && n > SIZE_MAX / size)
|
||||
return NULL;
|
||||
return __kmalloc(n * size, flags);
|
||||
}
|
||||
|
||||
static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
|
||||
{
|
||||
return kmalloc(n * size, flags | __GFP_ZERO);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -47,6 +47,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
#include <linux/list.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/sched.h>
|
||||
@ -58,6 +59,7 @@
|
||||
* @work: pointer to work structure
|
||||
*/
|
||||
typedef void (*restart_t)(struct work_struct *work);
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
#define IOWAIT_PENDING_IB 0x0
|
||||
#define IOWAIT_PENDING_TID 0x1
|
||||
@ -88,7 +90,11 @@ struct sdma_engine;
|
||||
*/
|
||||
struct iowait;
|
||||
struct iowait_work {
|
||||
#ifdef __HFI1_ORIG__
|
||||
struct work_struct iowork;
|
||||
#else
|
||||
//TODO:
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
struct list_head tx_head;
|
||||
struct iowait *iow;
|
||||
};
|
||||
@ -140,9 +146,13 @@ struct iowait {
|
||||
unsigned seq);
|
||||
void (*wakeup)(struct iowait *wait, int reason);
|
||||
void (*sdma_drained)(struct iowait *wait);
|
||||
#ifdef __HFI1_ORIG__
|
||||
seqlock_t *lock;
|
||||
wait_queue_head_t wait_dma;
|
||||
wait_queue_head_t wait_pio;
|
||||
#else
|
||||
//TODO:
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
atomic_t sdma_busy;
|
||||
atomic_t pio_busy;
|
||||
u32 count;
|
||||
@ -154,6 +164,8 @@ struct iowait {
|
||||
|
||||
#define SDMA_AVAIL_REASON 0
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
void iowait_set_flag(struct iowait *wait, u32 flag);
|
||||
bool iowait_flag_set(struct iowait *wait, u32 flag);
|
||||
void iowait_clear_flag(struct iowait *wait, u32 flag);
|
||||
@ -182,6 +194,7 @@ static inline bool iowait_schedule(
|
||||
struct workqueue_struct *wq,
|
||||
int cpu)
|
||||
{
|
||||
hfi1_cdbg(AIOWRITE, ".");
|
||||
return !!queue_work_on(cpu, wq, &wait->wait[IOWAIT_IB_SE].iowork);
|
||||
}
|
||||
|
||||
@ -196,6 +209,7 @@ static inline bool iowait_tid_schedule(
|
||||
struct workqueue_struct *wq,
|
||||
int cpu)
|
||||
{
|
||||
hfi1_cdbg(AIOWRITE, ".");
|
||||
return !!queue_work_on(cpu, wq, &wait->wait[IOWAIT_TID_SE].iowork);
|
||||
}
|
||||
|
||||
@ -208,6 +222,7 @@ static inline bool iowait_tid_schedule(
|
||||
*/
|
||||
static inline void iowait_sdma_drain(struct iowait *wait)
|
||||
{
|
||||
hfi1_cdbg(AIOWRITE, ".");
|
||||
wait_event(wait->wait_dma, !atomic_read(&wait->sdma_busy));
|
||||
}
|
||||
|
||||
@ -219,6 +234,7 @@ static inline void iowait_sdma_drain(struct iowait *wait)
|
||||
*/
|
||||
static inline int iowait_sdma_pending(struct iowait *wait)
|
||||
{
|
||||
hfi1_cdbg(AIOWRITE, ".");
|
||||
return atomic_read(&wait->sdma_busy);
|
||||
}
|
||||
|
||||
@ -228,17 +244,21 @@ static inline int iowait_sdma_pending(struct iowait *wait)
|
||||
*/
|
||||
static inline void iowait_sdma_inc(struct iowait *wait)
|
||||
{
|
||||
hfi1_cdbg(AIOWRITE, ".");
|
||||
atomic_inc(&wait->sdma_busy);
|
||||
}
|
||||
|
||||
#endif
|
||||
/**
|
||||
* iowait_sdma_add - add count to pending
|
||||
* @wait: iowait_work structure
|
||||
*/
|
||||
static inline void iowait_sdma_add(struct iowait *wait, int count)
|
||||
{
|
||||
hfi1_cdbg(AIOWRITE, ".");
|
||||
atomic_add(count, &wait->sdma_busy);
|
||||
}
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
/**
|
||||
* iowait_pio_drain() - wait for pios to drain
|
||||
@ -250,6 +270,7 @@ static inline void iowait_sdma_add(struct iowait *wait, int count)
|
||||
*/
|
||||
static inline void iowait_pio_drain(struct iowait *wait)
|
||||
{
|
||||
hfi1_cdbg(AIOWRITE, ".");
|
||||
wait_event_timeout(wait->wait_pio,
|
||||
!atomic_read(&wait->pio_busy),
|
||||
HZ);
|
||||
@ -263,6 +284,7 @@ static inline void iowait_pio_drain(struct iowait *wait)
|
||||
*/
|
||||
static inline int iowait_pio_pending(struct iowait *w)
|
||||
{
|
||||
hfi1_cdbg(AIOWRITE, ".");
|
||||
return atomic_read(&w->pio_busy);
|
||||
}
|
||||
|
||||
@ -274,6 +296,7 @@ static inline int iowait_pio_pending(struct iowait *w)
|
||||
*/
|
||||
static inline void iowait_drain_wakeup(struct iowait *w)
|
||||
{
|
||||
hfi1_cdbg(AIOWRITE, ".");
|
||||
wake_up(&w->wait_dma);
|
||||
wake_up(&w->wait_pio);
|
||||
if (w->sdma_drained)
|
||||
@ -286,6 +309,7 @@ static inline void iowait_drain_wakeup(struct iowait *w)
|
||||
*/
|
||||
static inline void iowait_pio_inc(struct iowait *wait)
|
||||
{
|
||||
hfi1_cdbg(AIOWRITE, ".");
|
||||
atomic_inc(&wait->pio_busy);
|
||||
}
|
||||
|
||||
@ -295,6 +319,7 @@ static inline void iowait_pio_inc(struct iowait *wait)
|
||||
*/
|
||||
static inline int iowait_pio_dec(struct iowait *wait)
|
||||
{
|
||||
hfi1_cdbg(AIOWRITE, ".");
|
||||
if (!wait)
|
||||
return 0;
|
||||
return atomic_dec_and_test(&wait->pio_busy);
|
||||
@ -306,6 +331,7 @@ static inline int iowait_pio_dec(struct iowait *wait)
|
||||
*/
|
||||
static inline int iowait_sdma_dec(struct iowait *wait)
|
||||
{
|
||||
hfi1_cdbg(AIOWRITE, ".");
|
||||
if (!wait)
|
||||
return 0;
|
||||
return atomic_dec_and_test(&wait->sdma_busy);
|
||||
@ -319,6 +345,7 @@ static inline struct sdma_txreq *iowait_get_txhead(struct iowait_work *wait)
|
||||
{
|
||||
struct sdma_txreq *tx = NULL;
|
||||
|
||||
hfi1_cdbg(AIOWRITE, ".");
|
||||
if (!list_empty(&wait->tx_head)) {
|
||||
tx = list_first_entry(
|
||||
&wait->tx_head,
|
||||
@ -333,6 +360,7 @@ static inline u16 iowait_get_desc(struct iowait_work *w)
|
||||
{
|
||||
u16 num_desc = 0;
|
||||
struct sdma_txreq *tx = NULL;
|
||||
hfi1_cdbg(AIOWRITE, ".");
|
||||
|
||||
if (!list_empty(&w->tx_head)) {
|
||||
tx = list_first_entry(
|
||||
@ -348,6 +376,7 @@ static inline u32 iowait_get_all_desc(struct iowait *w)
|
||||
{
|
||||
u32 num_desc = 0;
|
||||
|
||||
hfi1_cdbg(AIOWRITE, ".");
|
||||
num_desc = iowait_get_desc(&w->wait[IOWAIT_IB_SE]);
|
||||
num_desc += iowait_get_desc(&w->wait[IOWAIT_TID_SE]);
|
||||
return num_desc;
|
||||
@ -359,9 +388,11 @@ static inline u32 iowait_get_all_desc(struct iowait *w)
|
||||
*/
|
||||
static inline bool iowait_packet_queued(struct iowait_work *w)
|
||||
{
|
||||
hfi1_cdbg(AIOWRITE, ".");
|
||||
return !list_empty(&w->tx_head);
|
||||
}
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
/**
|
||||
* inc_wait_count - increment wait counts
|
||||
* @w: the log work struct
|
||||
@ -369,11 +400,13 @@ static inline bool iowait_packet_queued(struct iowait_work *w)
|
||||
*/
|
||||
static inline void iowait_inc_wait_count(struct iowait_work *w, u16 n)
|
||||
{
|
||||
hfi1_cdbg(AIOWRITE, ".");
|
||||
if (!w)
|
||||
return;
|
||||
w->iow->tx_count++;
|
||||
w->iow->count += n;
|
||||
}
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
/**
|
||||
* iowait_get_tid_work - return iowait_work for tid SE
|
||||
@ -381,15 +414,18 @@ static inline void iowait_inc_wait_count(struct iowait_work *w, u16 n)
|
||||
*/
|
||||
static inline struct iowait_work *iowait_get_tid_work(struct iowait *w)
|
||||
{
|
||||
hfi1_cdbg(AIOWRITE, ".");
|
||||
return &w->wait[IOWAIT_TID_SE];
|
||||
}
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
/**
|
||||
* iowait_get_ib_work - return iowait_work for ib SE
|
||||
* @w: the iowait struct
|
||||
*/
|
||||
static inline struct iowait_work *iowait_get_ib_work(struct iowait *w)
|
||||
{
|
||||
hfi1_cdbg(AIOWRITE, ".");
|
||||
return &w->wait[IOWAIT_IB_SE];
|
||||
}
|
||||
|
||||
@ -399,12 +435,15 @@ static inline struct iowait_work *iowait_get_ib_work(struct iowait *w)
|
||||
*/
|
||||
static inline struct iowait *iowait_ioww_to_iow(struct iowait_work *w)
|
||||
{
|
||||
hfi1_cdbg(AIOWRITE, ".");
|
||||
if (likely(w))
|
||||
return w->iow;
|
||||
return NULL;
|
||||
}
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
void iowait_cancel_work(struct iowait *w);
|
||||
int iowait_set_work_flag(struct iowait_work *w);
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
#endif
|
||||
|
||||
@ -47,6 +47,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <hfi1/ihk_hfi1_common.h>
|
||||
#include <hfi1/sdma_txreq.h>
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/list.h>
|
||||
#include <asm/byteorder.h>
|
||||
@ -57,6 +62,11 @@
|
||||
#include "verbs.h"
|
||||
#include "sdma_txreq.h"
|
||||
|
||||
#define hfi1_cdbg(which, fmt, ...) \
|
||||
__hfi1_trace_##which(__func__, fmt, ##__VA_ARGS__)
|
||||
extern void __hfi1_trace_AIOWRITE(const char *func, char *fmt, ...);
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
/* Hardware limit */
|
||||
#define MAX_DESC 64
|
||||
/* Hardware limit for SDMA packet size */
|
||||
@ -192,6 +202,7 @@ struct sdma_set_state_action {
|
||||
unsigned go_s99_running_totrue:1;
|
||||
};
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
struct sdma_state {
|
||||
struct kref kref;
|
||||
struct completion comp;
|
||||
@ -203,6 +214,11 @@ struct sdma_state {
|
||||
unsigned previous_op;
|
||||
enum sdma_events last_event;
|
||||
};
|
||||
#else
|
||||
struct sdma_state {
|
||||
enum sdma_states current_state;
|
||||
};
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
/**
|
||||
* DOC: sdma exported routines
|
||||
@ -394,6 +410,7 @@ struct sdma_engine {
|
||||
/* private: */
|
||||
struct list_head dmawait;
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
/* CONFIG SDMA for now, just blindly duplicate */
|
||||
/* private: */
|
||||
struct tasklet_struct sdma_hw_clean_up_task
|
||||
@ -409,14 +426,20 @@ struct sdma_engine {
|
||||
u32 progress_check_head;
|
||||
/* private: */
|
||||
struct work_struct flush_worker;
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
/* protect flush list */
|
||||
spinlock_t flushlist_lock;
|
||||
/* private: */
|
||||
struct list_head flushlist;
|
||||
#ifdef __HFI1_ORIG__
|
||||
struct cpumask cpu_mask;
|
||||
struct kobject kobj;
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
};
|
||||
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
int sdma_init(struct hfi1_devdata *dd, u8 port);
|
||||
void sdma_start(struct hfi1_devdata *dd);
|
||||
void sdma_exit(struct hfi1_devdata *dd);
|
||||
@ -441,6 +464,7 @@ static inline int sdma_empty(struct sdma_engine *sde)
|
||||
return sde->descq_tail == sde->descq_head;
|
||||
}
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
static inline u16 sdma_descq_freecnt(struct sdma_engine *sde)
|
||||
{
|
||||
return sde->descq_cnt -
|
||||
@ -478,9 +502,11 @@ static inline int sdma_running(struct sdma_engine *engine)
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
hfi1_cdbg(AIOWRITE, "+");
|
||||
spin_lock_irqsave(&engine->tail_lock, flags);
|
||||
ret = __sdma_running(engine);
|
||||
spin_unlock_irqrestore(&engine->tail_lock, flags);
|
||||
hfi1_cdbg(AIOWRITE, "-");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -619,6 +645,7 @@ static inline int sdma_txinit(
|
||||
{
|
||||
return sdma_txinit_ahg(tx, flags, tlen, 0, 0, NULL, 0, cb);
|
||||
}
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
/* helpers - don't use */
|
||||
static inline int sdma_mapping_type(struct sdma_desc *d)
|
||||
@ -639,6 +666,7 @@ static inline dma_addr_t sdma_mapping_addr(struct sdma_desc *d)
|
||||
>> SDMA_DESC0_PHY_ADDR_SHIFT;
|
||||
}
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
static inline void make_tx_sdma_desc(
|
||||
struct sdma_txreq *tx,
|
||||
int type,
|
||||
@ -666,7 +694,6 @@ static inline void make_tx_sdma_desc(
|
||||
int ext_coal_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx,
|
||||
int type, void *kvaddr, struct page *page,
|
||||
unsigned long offset, u16 len);
|
||||
int _pad_sdma_tx_descs(struct hfi1_devdata *, struct sdma_txreq *);
|
||||
void __sdma_txclean(struct hfi1_devdata *, struct sdma_txreq *);
|
||||
|
||||
static inline void sdma_txclean(struct hfi1_devdata *dd, struct sdma_txreq *tx)
|
||||
@ -674,6 +701,8 @@ static inline void sdma_txclean(struct hfi1_devdata *dd, struct sdma_txreq *tx)
|
||||
if (tx->num_desc)
|
||||
__sdma_txclean(dd, tx);
|
||||
}
|
||||
#ifdef __HFI1_ORIG__
|
||||
int _pad_sdma_tx_descs(struct hfi1_devdata *, struct sdma_txreq *);
|
||||
|
||||
/* helpers used by public routines */
|
||||
static inline void _sdma_close_tx(struct hfi1_devdata *dd,
|
||||
@ -689,6 +718,7 @@ static inline void _sdma_close_tx(struct hfi1_devdata *dd,
|
||||
SDMA_DESC1_INT_REQ_FLAG);
|
||||
}
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
static inline int _sdma_txadd_daddr(
|
||||
struct hfi1_devdata *dd,
|
||||
int type,
|
||||
@ -707,11 +737,13 @@ static inline int _sdma_txadd_daddr(
|
||||
/* special cases for last */
|
||||
if (!tx->tlen) {
|
||||
if (tx->packet_len & (sizeof(u32) - 1)) {
|
||||
rval = _pad_sdma_tx_descs(dd, tx);
|
||||
//TODO: _pad_sdma_tx_descs
|
||||
//rval = _pad_sdma_tx_descs(dd, tx);
|
||||
if (rval)
|
||||
return rval;
|
||||
} else {
|
||||
_sdma_close_tx(dd, tx);
|
||||
//TODO: _sdma_close_tx
|
||||
//_sdma_close_tx(dd, tx);
|
||||
}
|
||||
}
|
||||
tx->num_desc++;
|
||||
@ -743,7 +775,7 @@ static inline int sdma_txadd_page(
|
||||
{
|
||||
dma_addr_t addr;
|
||||
int rval;
|
||||
|
||||
hfi1_cdbg(AIOWRITE, "+");
|
||||
if ((unlikely(tx->num_desc == tx->desc_limit))) {
|
||||
rval = ext_coal_sdma_tx_descs(dd, tx, SDMA_MAP_PAGE,
|
||||
NULL, page, offset, len);
|
||||
@ -751,6 +783,7 @@ static inline int sdma_txadd_page(
|
||||
return rval;
|
||||
}
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
addr = dma_map_page(
|
||||
&dd->pcidev->dev,
|
||||
page,
|
||||
@ -762,7 +795,11 @@ static inline int sdma_txadd_page(
|
||||
__sdma_txclean(dd, tx);
|
||||
return -ENOSPC;
|
||||
}
|
||||
#else
|
||||
//TODO: dma_map_page
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
hfi1_cdbg(AIOWRITE, "-");
|
||||
return _sdma_txadd_daddr(
|
||||
dd, SDMA_MAP_PAGE, tx, addr, len);
|
||||
}
|
||||
@ -833,6 +870,7 @@ static inline int sdma_txadd_kvaddr(
|
||||
return rval;
|
||||
}
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
addr = dma_map_single(
|
||||
&dd->pcidev->dev,
|
||||
kvaddr,
|
||||
@ -843,6 +881,9 @@ static inline int sdma_txadd_kvaddr(
|
||||
__sdma_txclean(dd, tx);
|
||||
return -ENOSPC;
|
||||
}
|
||||
#else
|
||||
//TODO: dma_map_single
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
return _sdma_txadd_daddr(
|
||||
dd, SDMA_MAP_SINGLE, tx, addr, len);
|
||||
@ -885,6 +926,7 @@ static inline u32 sdma_build_ahg_descriptor(
|
||||
((data & SDMA_AHG_VALUE_MASK) <<
|
||||
SDMA_AHG_VALUE_SHIFT));
|
||||
}
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
/**
|
||||
* sdma_progress - use seq number of detect head progress
|
||||
@ -1061,6 +1103,7 @@ struct sdma_engine *sdma_select_engine_sc(
|
||||
u32 selector,
|
||||
u8 sc5);
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
struct sdma_engine *sdma_select_engine_vl(
|
||||
struct hfi1_devdata *dd,
|
||||
u32 selector,
|
||||
@ -1068,6 +1111,8 @@ struct sdma_engine *sdma_select_engine_vl(
|
||||
|
||||
struct sdma_engine *sdma_select_user_engine(struct hfi1_devdata *dd,
|
||||
u32 selector, u8 vl);
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
ssize_t sdma_get_cpu_to_sde_map(struct sdma_engine *sde, char *buf);
|
||||
ssize_t sdma_set_cpu_to_sde_map(struct sdma_engine *sde, const char *buf,
|
||||
size_t count);
|
||||
@ -1095,4 +1140,5 @@ extern uint mod_num_sdma;
|
||||
|
||||
void sdma_update_lmc(struct hfi1_devdata *dd, u64 mask, u32 lid);
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
#endif
|
||||
|
||||
@ -48,6 +48,8 @@
|
||||
#ifndef HFI1_SDMA_TXREQ_H
|
||||
#define HFI1_SDMA_TXREQ_H
|
||||
|
||||
#include <hfi1/iowait.h>
|
||||
|
||||
/* increased for AHG */
|
||||
#define NUM_DESC 6
|
||||
|
||||
@ -105,7 +107,7 @@ struct sdma_txreq {
|
||||
/* private: */
|
||||
struct iowait *wait;
|
||||
/* private: */
|
||||
callback_t complete;
|
||||
callback_t complete;
|
||||
#ifdef CONFIG_HFI1_DEBUG_SDMA_ORDER
|
||||
u64 sn;
|
||||
#endif
|
||||
|
||||
@ -46,8 +46,9 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
#include "hfi.h"
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
#define EXP_TID_TIDLEN_MASK 0x7FFULL
|
||||
#define EXP_TID_TIDLEN_SHIFT 0
|
||||
@ -70,6 +71,7 @@
|
||||
(tid) |= EXP_TID_SET(field, (value)); \
|
||||
} while (0)
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
struct tid_group {
|
||||
struct list_head list;
|
||||
unsigned base;
|
||||
@ -154,4 +156,6 @@ int hfi1_user_exp_rcv_setup(struct file *, struct hfi1_tid_info *);
|
||||
int hfi1_user_exp_rcv_clear(struct file *, struct hfi1_tid_info *);
|
||||
int hfi1_user_exp_rcv_invalid(struct file *, struct hfi1_tid_info *);
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
#endif /* _HFI1_USER_EXP_RCV_H */
|
||||
|
||||
@ -1,3 +1,7 @@
|
||||
|
||||
#ifndef _HFI1_USER_SDMA_H
|
||||
#define _HFI1_USER_SDMA_H
|
||||
|
||||
/*
|
||||
* Copyright(c) 2015, 2016 Intel Corporation.
|
||||
*
|
||||
@ -44,6 +48,17 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <hfi1/ihk_hfi1_common.h>
|
||||
#include <hfi1/iowait.h>
|
||||
#include <hfi1/sdma.h>
|
||||
#include <string.h>
|
||||
#include <hfi1/hfi.h>
|
||||
#include <hfi1/hfi1_user.h>
|
||||
#include <uio.h>
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/wait.h>
|
||||
|
||||
@ -53,6 +68,7 @@
|
||||
|
||||
extern uint extended_psn;
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
/*
|
||||
* Define fields in the KDETH header so we can update the header
|
||||
* template.
|
||||
@ -105,16 +121,24 @@ struct hfi1_user_sdma_pkt_q {
|
||||
atomic_t n_reqs;
|
||||
u16 reqidx;
|
||||
struct hfi1_devdata *dd;
|
||||
#ifdef __HFI1_ORIG__
|
||||
struct kmem_cache *txreq_cache;
|
||||
#else
|
||||
void *txreq_cache; //unused
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
struct user_sdma_request *reqs;
|
||||
unsigned long *req_in_use;
|
||||
struct iowait busy;
|
||||
unsigned state;
|
||||
#ifdef __HFI1_ORIG__
|
||||
wait_queue_head_t wait;
|
||||
unsigned long unpinned;
|
||||
struct mmu_rb_handler *handler;
|
||||
atomic_t n_locked;
|
||||
struct mm_struct *mm;
|
||||
#else
|
||||
//TODO:
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
};
|
||||
|
||||
struct hfi1_user_sdma_comp_q {
|
||||
@ -122,7 +146,14 @@ struct hfi1_user_sdma_comp_q {
|
||||
struct hfi1_sdma_comp_entry *comps;
|
||||
};
|
||||
|
||||
int hfi1_user_sdma_process_request(void *private_data, struct iovec *iovec,
|
||||
unsigned long dim, unsigned long *count);
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *, struct file *);
|
||||
int hfi1_user_sdma_free_queues(struct hfi1_filedata *);
|
||||
int hfi1_user_sdma_process_request(struct file *, struct iovec *, unsigned long,
|
||||
unsigned long *);
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
#endif /* _HFI1_SDMA_H */
|
||||
@ -45,6 +45,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <hfi1/ihk_hfi1_common.h>
|
||||
#include <hfi1/user_sdma.h>
|
||||
#include <hfi1/sdma.h>
|
||||
#include <hfi1/common.h>
|
||||
|
||||
unsigned long hfi1_cap_mask = HFI1_CAP_MASK_DEFAULT;
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/seqlock.h>
|
||||
#include <linux/netdevice.h>
|
||||
@ -62,11 +71,15 @@
|
||||
#include "iowait.h"
|
||||
#include "trace.h"
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
/* must be a power of 2 >= 64 <= 32768 */
|
||||
#define SDMA_DESCQ_CNT 2048
|
||||
#define SDMA_DESC_INTR 64
|
||||
#define INVALID_TAIL 0xffff
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
static uint sdma_descq_cnt = SDMA_DESCQ_CNT;
|
||||
module_param(sdma_descq_cnt, uint, S_IRUGO);
|
||||
MODULE_PARM_DESC(sdma_descq_cnt, "Number of SDMA descq entries");
|
||||
@ -226,7 +239,9 @@ static const struct sdma_set_state_action sdma_action_table[] = {
|
||||
},
|
||||
};
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
#define SDMA_TAIL_UPDATE_THRESH 0x1F
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
/* declare all statics here rather than keep sorting */
|
||||
static void sdma_complete(struct kref *);
|
||||
@ -368,7 +383,7 @@ static inline void complete_tx(struct sdma_engine *sde,
|
||||
/* protect against complete modifying */
|
||||
struct iowait *wait = tx->wait;
|
||||
callback_t complete = tx->complete;
|
||||
|
||||
hfi1_cdbg(AIOWRITE, "+");
|
||||
#ifdef CONFIG_HFI1_DEBUG_SDMA_ORDER
|
||||
trace_hfi1_sdma_out_sn(sde, tx->sn);
|
||||
if (WARN_ON_ONCE(sde->head_sn != tx->sn))
|
||||
@ -381,6 +396,7 @@ static inline void complete_tx(struct sdma_engine *sde,
|
||||
(*complete)(tx, res);
|
||||
if (iowait_sdma_dec(wait))
|
||||
iowait_drain_wakeup(wait);
|
||||
hfi1_cdbg(AIOWRITE, "-");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -773,11 +789,16 @@ struct sdma_engine *sdma_select_engine_vl(
|
||||
struct sdma_map_elem *e;
|
||||
struct sdma_engine *rval;
|
||||
|
||||
hfi1_cdbg(AIOWRITE, "+");
|
||||
/* NOTE This should only happen if SC->VL changed after the initial
|
||||
* checks on the QP/AH
|
||||
* Default will return engine 0 below
|
||||
*/
|
||||
#ifdef __HFI1_ORIG__
|
||||
if (vl >= num_vls) {
|
||||
#else
|
||||
if (vl >= HFI1_MAX_VLS_SUPPORTED) {
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
rval = NULL;
|
||||
goto done;
|
||||
}
|
||||
@ -795,6 +816,7 @@ struct sdma_engine *sdma_select_engine_vl(
|
||||
done:
|
||||
rval = !rval ? &dd->per_sdma[0] : rval;
|
||||
trace_hfi1_sdma_engine_select(dd, selector, vl, rval->this_idx);
|
||||
hfi1_cdbg(AIOWRITE, "-");
|
||||
return rval;
|
||||
}
|
||||
|
||||
@ -864,6 +886,7 @@ struct sdma_engine *sdma_select_user_engine(struct hfi1_devdata *dd,
|
||||
const struct cpumask *current_mask = tsk_cpus_allowed(current);
|
||||
unsigned long cpu_id;
|
||||
|
||||
hfi1_cdbg(AIOWRITE, "+");
|
||||
/*
|
||||
* To ensure that always the same sdma engine(s) will be
|
||||
* selected make sure the process is pinned to this CPU only.
|
||||
@ -1658,6 +1681,7 @@ static inline void sdma_unmap_desc(
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
/*
|
||||
* return the mode as indicated by the first
|
||||
@ -1689,13 +1713,15 @@ void __sdma_txclean(
|
||||
if (tx->num_desc) {
|
||||
u8 skip = 0, mode = ahg_mode(tx);
|
||||
|
||||
/* TODO: enable sdma_unmap_desc */
|
||||
/* unmap first */
|
||||
sdma_unmap_desc(dd, &tx->descp[0]);
|
||||
//sdma_unmap_desc(dd, &tx->descp[0]);
|
||||
/* determine number of AHG descriptors to skip */
|
||||
if (mode > SDMA_AHG_APPLY_UPDATE1)
|
||||
skip = mode >> 1;
|
||||
for (i = 1 + skip; i < tx->num_desc; i++)
|
||||
sdma_unmap_desc(dd, &tx->descp[i]);
|
||||
/* TODO: enable sdma_unmap_desc */
|
||||
// for (i = 1 + skip; i < tx->num_desc; i++)
|
||||
// sdma_unmap_desc(dd, &tx->descp[i]);
|
||||
tx->num_desc = 0;
|
||||
}
|
||||
kfree(tx->coalesce_buf);
|
||||
@ -1706,6 +1732,7 @@ void __sdma_txclean(
|
||||
kfree(tx->descp);
|
||||
}
|
||||
}
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
static inline u16 sdma_gethead(struct sdma_engine *sde)
|
||||
{
|
||||
@ -1824,6 +1851,7 @@ static void sdma_make_progress(struct sdma_engine *sde, u64 status)
|
||||
u16 hwhead, swhead;
|
||||
int idle_check_done = 0;
|
||||
|
||||
hfi1_cdbg(AIOWRITE, "+");
|
||||
hwhead = sdma_gethead(sde);
|
||||
|
||||
/* The reason for some of the complexity of this code is that
|
||||
@ -1875,6 +1903,7 @@ retry:
|
||||
sde->last_status = status;
|
||||
if (progress)
|
||||
sdma_desc_avail(sde, sdma_descq_freecnt(sde));
|
||||
hfi1_cdbg(AIOWRITE, "-");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1888,6 +1917,7 @@ retry:
|
||||
*/
|
||||
void sdma_engine_interrupt(struct sdma_engine *sde, u64 status)
|
||||
{
|
||||
hfi1_cdbg(AIOWRITE, "+");
|
||||
trace_hfi1_sdma_engine_interrupt(sde, status);
|
||||
write_seqlock(&sde->head_lock);
|
||||
sdma_set_desc_cnt(sde, sdma_desct_intr);
|
||||
@ -1899,6 +1929,7 @@ void sdma_engine_interrupt(struct sdma_engine *sde, u64 status)
|
||||
sde->sdma_int_cnt++;
|
||||
sdma_make_progress(sde, status);
|
||||
write_sequnlock(&sde->head_lock);
|
||||
hfi1_cdbg(AIOWRITE, "-");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2000,12 +2031,15 @@ static void sdma_setlengen(struct sdma_engine *sde)
|
||||
(4ULL << SD(LEN_GEN_GENERATION_SHIFT)));
|
||||
}
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
static inline void sdma_update_tail(struct sdma_engine *sde, u16 tail)
|
||||
{
|
||||
hfi1_cdbg(AIOWRITE, ".");
|
||||
/* Commit writes to memory and advance the tail on the chip */
|
||||
smp_wmb(); /* see get_txhead() */
|
||||
writeq(tail, sde->tail_csr);
|
||||
}
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
/*
|
||||
* This is called when changing to state s10_hw_start_up_halt_wait as
|
||||
@ -2270,6 +2304,7 @@ void sdma_seqfile_dump_sde(struct seq_file *s, struct sdma_engine *sde)
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
/*
|
||||
* add the generation number into
|
||||
* the qw1 and return
|
||||
@ -2306,12 +2341,12 @@ static inline u16 submit_tx(struct sdma_engine *sde, struct sdma_txreq *tx)
|
||||
u16 tail;
|
||||
struct sdma_desc *descp = tx->descp;
|
||||
u8 skip = 0, mode = ahg_mode(tx);
|
||||
|
||||
hfi1_cdbg(AIOWRITE, "+");
|
||||
tail = sde->descq_tail & sde->sdma_mask;
|
||||
sde->descq[tail].qw[0] = cpu_to_le64(descp->qw[0]);
|
||||
sde->descq[tail].qw[1] = cpu_to_le64(add_gen(sde, descp->qw[1]));
|
||||
trace_hfi1_sdma_descriptor(sde, descp->qw[0], descp->qw[1],
|
||||
tail, &sde->descq[tail]);
|
||||
// trace_hfi1_sdma_descriptor(sde, descp->qw[0], descp->qw[1],
|
||||
// tail, &sde->descq[tail]);
|
||||
tail = ++sde->descq_tail & sde->sdma_mask;
|
||||
descp++;
|
||||
if (mode > SDMA_AHG_APPLY_UPDATE1)
|
||||
@ -2329,18 +2364,19 @@ static inline u16 submit_tx(struct sdma_engine *sde, struct sdma_txreq *tx)
|
||||
qw1 = add_gen(sde, descp->qw[1]);
|
||||
}
|
||||
sde->descq[tail].qw[1] = cpu_to_le64(qw1);
|
||||
trace_hfi1_sdma_descriptor(sde, descp->qw[0], qw1,
|
||||
tail, &sde->descq[tail]);
|
||||
// trace_hfi1_sdma_descriptor(sde, descp->qw[0], qw1,
|
||||
// tail, &sde->descq[tail]);
|
||||
tail = ++sde->descq_tail & sde->sdma_mask;
|
||||
}
|
||||
tx->next_descq_idx = tail;
|
||||
#ifdef CONFIG_HFI1_DEBUG_SDMA_ORDER
|
||||
tx->sn = sde->tail_sn++;
|
||||
trace_hfi1_sdma_in_sn(sde, tx->sn);
|
||||
// trace_hfi1_sdma_in_sn(sde, tx->sn);
|
||||
WARN_ON_ONCE(sde->tx_ring[sde->tx_tail & sde->sdma_mask]);
|
||||
#endif
|
||||
sde->tx_ring[sde->tx_tail++ & sde->sdma_mask] = tx;
|
||||
sde->desc_avail -= tx->num_desc;
|
||||
hfi1_cdbg(AIOWRITE, "-");
|
||||
return tail;
|
||||
}
|
||||
|
||||
@ -2354,6 +2390,7 @@ static int sdma_check_progress(
|
||||
{
|
||||
int ret;
|
||||
|
||||
hfi1_cdbg(AIOWRITE, "+");
|
||||
sde->desc_avail = sdma_descq_freecnt(sde);
|
||||
if (tx->num_desc <= sde->desc_avail)
|
||||
return -EAGAIN;
|
||||
@ -2369,8 +2406,10 @@ static int sdma_check_progress(
|
||||
} else {
|
||||
ret = -EBUSY;
|
||||
}
|
||||
hfi1_cdbg(AIOWRITE, "-");
|
||||
return ret;
|
||||
}
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
/**
|
||||
* sdma_send_txreq() - submit a tx req to ring
|
||||
@ -2394,6 +2433,7 @@ int sdma_send_txreq(struct sdma_engine *sde,
|
||||
u16 tail;
|
||||
unsigned long flags;
|
||||
|
||||
hfi1_cdbg(AIOWRITE, "+");
|
||||
/* user should have supplied entire packet */
|
||||
if (unlikely(tx->tlen))
|
||||
return -EINVAL;
|
||||
@ -2410,6 +2450,7 @@ retry:
|
||||
sdma_update_tail(sde, tail);
|
||||
unlock:
|
||||
spin_unlock_irqrestore(&sde->tail_lock, flags);
|
||||
hfi1_cdbg(AIOWRITE, "-");
|
||||
return ret;
|
||||
unlock_noconn:
|
||||
if (wait)
|
||||
@ -2436,6 +2477,7 @@ nodesc:
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
/**
|
||||
* sdma_send_txlist() - submit a list of tx req to ring
|
||||
* @sde: sdma engine to use
|
||||
@ -2473,6 +2515,7 @@ int sdma_send_txlist(struct sdma_engine *sde, struct iowait_work *wait,
|
||||
u16 tail = INVALID_TAIL;
|
||||
u32 submit_count = 0, flush_count = 0, total_count;
|
||||
|
||||
hfi1_cdbg(AIOWRITE, "+");
|
||||
spin_lock_irqsave(&sde->tail_lock, flags);
|
||||
retry:
|
||||
list_for_each_entry_safe(tx, tx_next, tx_list, list) {
|
||||
@ -2502,6 +2545,7 @@ update_tail:
|
||||
sdma_update_tail(sde, tail);
|
||||
spin_unlock_irqrestore(&sde->tail_lock, flags);
|
||||
*count_out = total_count;
|
||||
hfi1_cdbg(AIOWRITE, "-");
|
||||
return ret;
|
||||
unlock_noconn:
|
||||
spin_lock(&sde->flushlist_lock);
|
||||
@ -2511,14 +2555,15 @@ unlock_noconn:
|
||||
tx->next_descq_idx = 0;
|
||||
#ifdef CONFIG_HFI1_DEBUG_SDMA_ORDER
|
||||
tx->sn = sde->tail_sn++;
|
||||
trace_hfi1_sdma_in_sn(sde, tx->sn);
|
||||
// trace_hfi1_sdma_in_sn(sde, tx->sn);
|
||||
#endif
|
||||
list_add_tail(&tx->list, &sde->flushlist);
|
||||
flush_count++;
|
||||
iowait_inc_wait_count(wait, tx->num_desc);
|
||||
}
|
||||
spin_unlock(&sde->flushlist_lock);
|
||||
schedule_work(&sde->flush_worker);
|
||||
// TODO: schedule_work
|
||||
//schedule_work(&sde->flush_worker);
|
||||
ret = -ECOMM;
|
||||
goto update_tail;
|
||||
nodesc:
|
||||
@ -2530,6 +2575,7 @@ nodesc:
|
||||
sde->descq_full_count++;
|
||||
goto update_tail;
|
||||
}
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
static void sdma_process_event(struct sdma_engine *sde, enum sdma_events event)
|
||||
{
|
||||
@ -3083,6 +3129,7 @@ enomem:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
/*
|
||||
* ext_coal_sdma_tx_descs() - extend or coalesce sdma tx descriptors
|
||||
*
|
||||
@ -3103,6 +3150,8 @@ int ext_coal_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx,
|
||||
int type, void *kvaddr, struct page *page,
|
||||
unsigned long offset, u16 len)
|
||||
{
|
||||
//TODO: ext_coal_sdma_tx_descs
|
||||
#ifdef __HFI1_ORIG__
|
||||
int pad_len, rval;
|
||||
dma_addr_t addr;
|
||||
|
||||
@ -3162,9 +3211,10 @@ int ext_coal_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx,
|
||||
return _sdma_txadd_daddr(dd, SDMA_MAP_SINGLE, tx,
|
||||
addr, tx->tlen);
|
||||
}
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
return 1;
|
||||
}
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
/* Update sdes when the lmc changes */
|
||||
void sdma_update_lmc(struct hfi1_devdata *dd, u64 mask, u32 lid)
|
||||
@ -3209,6 +3259,7 @@ int _pad_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx)
|
||||
return rval;
|
||||
}
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
/*
|
||||
* Add ahg to the sdma_txreq
|
||||
*
|
||||
@ -3316,6 +3367,7 @@ void sdma_ahg_free(struct sdma_engine *sde, int ahg_index)
|
||||
return;
|
||||
clear_bit(ahg_index, &sde->ahg_bits);
|
||||
}
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
/*
|
||||
* SPC freeze handling for SDMA engines. Called when the driver knows
|
||||
@ -3410,3 +3462,5 @@ void _sdma_engine_progress_schedule(
|
||||
CCE_INT_FORCE + (8 * (IS_SDMA_START / 64)),
|
||||
sde->progress_mask);
|
||||
}
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
@ -67,7 +67,7 @@
|
||||
#include <lwk/stddef.h>
|
||||
#include <futex.h>
|
||||
|
||||
//#include <hfi1/hfi.h>
|
||||
#include <hfi1/file_ops.h>
|
||||
|
||||
#define SYSCALL_BY_IKC
|
||||
|
||||
@ -481,7 +481,7 @@ long do_syscall(struct syscall_request *req, int cpu, int pid)
|
||||
#endif // PROFILE_ENABLE
|
||||
|
||||
if (req->number == __NR_open && rc > 0) {
|
||||
if (res.private_data && !strncmp(req->args[0], "/dev/hfi", 8)) {
|
||||
if (res.private_data && !strncmp((const char *)req->args[0], "/dev/hfi", 8)) {
|
||||
thread->proc->fd_priv_table[rc] = res.private_data;
|
||||
kprintf("%s: PID: %d, open fd: %d, filename: %s, private_data: 0x%lx\n",
|
||||
__FUNCTION__, thread->proc->pid, rc, req->args[0], res.private_data);
|
||||
@ -3093,13 +3093,10 @@ SYSCALL_DECLARE(writev)
|
||||
{
|
||||
struct process *proc = cpu_local_var(current)->proc;
|
||||
int fd = ihk_mc_syscall_arg0(ctx);
|
||||
struct iovec *iovec = (struct iovec *)ihk_mc_syscall_arg1(ctx);
|
||||
int iovcnt = ihk_mc_syscall_arg2(ctx);
|
||||
if (fd < 256) {
|
||||
//struct hfi1_filedata *hf = (struct hfi1_filedata *)proc->fd_priv_table[fd];
|
||||
kprintf("%s: fd[%d], 0x%lx, iovcnt[%d]\n", __FUNCTION__, fd, proc->fd_priv_table[fd], iovcnt);
|
||||
} else {
|
||||
kprintf("%s: fd[%d] > 256\n", __FUNCTION__, fd);
|
||||
}
|
||||
void *private_data = proc->fd_priv_table[fd];
|
||||
if (!private_data) hfi1_aio_write(private_data, iovec, iovcnt);
|
||||
return syscall_generic_forwarding(__NR_writev, ctx);
|
||||
}
|
||||
|
||||
|
||||
@ -44,6 +44,13 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <hfi1/user_sdma.h>
|
||||
#include <hfi1/user_exp_rcv.h>
|
||||
#include <hfi1/common.h>
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
#include <linux/mm.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/device.h>
|
||||
@ -69,9 +76,11 @@
|
||||
#include "trace.h"
|
||||
#include "mmu_rb.h"
|
||||
|
||||
static uint hfi1_sdma_comp_ring_size = 128;
|
||||
|
||||
module_param_named(sdma_comp_size, hfi1_sdma_comp_ring_size, uint, S_IRUGO);
|
||||
MODULE_PARM_DESC(sdma_comp_size, "Size of User SDMA completion ring. Default: 128");
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
static uint hfi1_sdma_comp_ring_size = 128;
|
||||
|
||||
/* The maximum number of Data io vectors per message/request */
|
||||
#define MAX_VECTORS_PER_REQ 8
|
||||
@ -133,8 +142,11 @@ static unsigned initial_pkt_count = 8;
|
||||
|
||||
#define SDMA_IOWAIT_TIMEOUT 1000 /* in milliseconds */
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
struct sdma_mmu_node;
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
struct user_sdma_iovec {
|
||||
struct list_head list;
|
||||
struct iovec iov;
|
||||
@ -149,6 +161,7 @@ struct user_sdma_iovec {
|
||||
u64 offset;
|
||||
struct sdma_mmu_node *node;
|
||||
};
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
struct sdma_mmu_node {
|
||||
struct mmu_rb_node rb;
|
||||
@ -164,6 +177,7 @@ struct evict_data {
|
||||
u32 target; /* target count to evict */
|
||||
};
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
struct user_sdma_request {
|
||||
struct sdma_req_info info;
|
||||
struct hfi1_user_sdma_pkt_q *pq;
|
||||
@ -237,6 +251,7 @@ struct user_sdma_txreq {
|
||||
unsigned busycount;
|
||||
u64 seqnum;
|
||||
};
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
#define SDMA_DBG(req, fmt, ...) \
|
||||
hfi1_cdbg(SDMA, "[%u:%u:%u:%u] " fmt, (req)->pq->dd->unit, \
|
||||
@ -246,24 +261,28 @@ struct user_sdma_txreq {
|
||||
hfi1_cdbg(SDMA, "[%u:%u:%u] " fmt, (pq)->dd->unit, (pq)->ctxt, \
|
||||
(pq)->subctxt, ##__VA_ARGS__)
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
static int user_sdma_send_pkts(struct user_sdma_request *, unsigned);
|
||||
static int num_user_pages(const struct iovec *);
|
||||
static void user_sdma_txreq_cb(struct sdma_txreq *, int);
|
||||
static inline void pq_update(struct hfi1_user_sdma_pkt_q *);
|
||||
static void user_sdma_free_request(struct user_sdma_request *, bool);
|
||||
static int pin_vector_pages(struct user_sdma_request *,
|
||||
struct user_sdma_iovec *);
|
||||
static void unpin_vector_pages(struct mm_struct *, struct page **, unsigned,
|
||||
unsigned);
|
||||
static int check_header_template(struct user_sdma_request *,
|
||||
struct hfi1_pkt_header *, u32, u32);
|
||||
static int set_txreq_header(struct user_sdma_request *,
|
||||
struct user_sdma_txreq *, u32);
|
||||
static int set_txreq_header_ahg(struct user_sdma_request *,
|
||||
struct user_sdma_txreq *, u32);
|
||||
static void user_sdma_free_request(struct user_sdma_request *, bool);
|
||||
static inline void set_comp_state(struct hfi1_user_sdma_pkt_q *,
|
||||
struct hfi1_user_sdma_comp_q *,
|
||||
u16, enum hfi1_sdma_comp_state, int);
|
||||
static void user_sdma_txreq_cb(struct sdma_txreq *, int);
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
static int num_user_pages(const struct iovec *);
|
||||
static int pin_vector_pages(struct user_sdma_request *,
|
||||
struct user_sdma_iovec *);
|
||||
static void unpin_vector_pages(struct mm_struct *, struct page **, unsigned,
|
||||
unsigned);
|
||||
static inline u32 set_pkt_bth_psn(__be32, u8, u32);
|
||||
static inline u32 get_lrh_len(struct hfi1_pkt_header, u32 len);
|
||||
|
||||
@ -476,6 +495,8 @@ int hfi1_user_sdma_free_queues(struct hfi1_filedata *fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
static u8 dlid_to_selector(u16 dlid)
|
||||
{
|
||||
static u8 mapping[256];
|
||||
@ -497,11 +518,19 @@ static u8 dlid_to_selector(u16 dlid)
|
||||
return mapping[hash];
|
||||
}
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec,
|
||||
unsigned long dim, unsigned long *count)
|
||||
{
|
||||
int ret = 0, i;
|
||||
struct hfi1_filedata *fd = fp->private_data;
|
||||
#else
|
||||
int hfi1_user_sdma_process_request(void *private_data, struct iovec *iovec,
|
||||
unsigned long dim, unsigned long *count)
|
||||
{
|
||||
int ret = 0, i;
|
||||
struct hfi1_filedata *fd = private_data;
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
struct hfi1_ctxtdata *uctxt = fd->uctxt;
|
||||
struct hfi1_user_sdma_pkt_q *pq = fd->pq;
|
||||
struct hfi1_user_sdma_comp_q *cq = fd->cq;
|
||||
@ -515,6 +544,7 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec,
|
||||
u16 dlid;
|
||||
u32 selector;
|
||||
|
||||
hfi1_cdbg(AIOWRITE, "+");
|
||||
if (iovec[idx].iov_len < sizeof(info) + sizeof(req->hdr)) {
|
||||
hfi1_cdbg(
|
||||
SDMA,
|
||||
@ -530,8 +560,8 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec,
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
trace_hfi1_sdma_user_reqinfo(dd, uctxt->ctxt, fd->subctxt,
|
||||
(u16 *)&info);
|
||||
// trace_hfi1_sdma_user_reqinfo(dd, uctxt->ctxt, fd->subctxt,
|
||||
// (u16 *)&info);
|
||||
|
||||
if (info.comp_idx >= hfi1_sdma_comp_ring_size) {
|
||||
hfi1_cdbg(SDMA,
|
||||
@ -619,6 +649,9 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec,
|
||||
ret = -EINVAL;
|
||||
goto free_req;
|
||||
}
|
||||
|
||||
// TODO: Enable this validation and checking
|
||||
#ifdef __HFI1_ORIG__
|
||||
/*
|
||||
* Validate the vl. Do not trust packets from user space blindly.
|
||||
* VL comes from PBC, SC comes from LRH, and the VL needs to
|
||||
@ -640,6 +673,7 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec,
|
||||
ret = -EINVAL;
|
||||
goto free_req;
|
||||
}
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
/*
|
||||
* Also should check the BTH.lnh. If it says the next header is GRH then
|
||||
@ -667,11 +701,16 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec,
|
||||
for (i = 0; i < req->data_iovs; i++) {
|
||||
INIT_LIST_HEAD(&req->iovs[i].list);
|
||||
memcpy(&req->iovs[i].iov, iovec + idx++, sizeof(struct iovec));
|
||||
#ifdef __HFI1_ORIG__
|
||||
hfi1_cdbg(AIOWRITE, "+pin_vector_pages");
|
||||
// TODO: pin_vector_pages
|
||||
ret = pin_vector_pages(req, &req->iovs[i]);
|
||||
hfi1_cdbg(AIOWRITE, "-pin_vector_pages");
|
||||
if (ret) {
|
||||
req->status = ret;
|
||||
goto free_req;
|
||||
}
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
req->data_len += req->iovs[i].iov.iov_len;
|
||||
}
|
||||
SDMA_DBG(req, "total data length %u", req->data_len);
|
||||
@ -719,7 +758,8 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec,
|
||||
dlid = be16_to_cpu(req->hdr.lrh[1]);
|
||||
selector = dlid_to_selector(dlid);
|
||||
selector += uctxt->ctxt + fd->subctxt;
|
||||
req->sde = sdma_select_user_engine(dd, selector, vl);
|
||||
/* TODO: check the rcu stuff */
|
||||
//req->sde = sdma_select_user_engine(dd, selector, vl);
|
||||
|
||||
if (!req->sde || !sdma_running(req->sde)) {
|
||||
ret = -ECOMM;
|
||||
@ -772,20 +812,28 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec,
|
||||
goto free_req;
|
||||
return ret;
|
||||
}
|
||||
#ifdef __HFI1_ORIG__
|
||||
hfi1_cdbg(AIOWRITE, "+wait_event_interruptible_timeout");
|
||||
wait_event_interruptible_timeout(
|
||||
pq->busy.wait_dma,
|
||||
(pq->state == SDMA_PKT_Q_ACTIVE),
|
||||
msecs_to_jiffies(
|
||||
SDMA_IOWAIT_TIMEOUT));
|
||||
hfi1_cdbg(AIOWRITE, "-wait_event_interruptible_timeout");
|
||||
#else
|
||||
while (pq->state != SDMA_PKT_Q_ACTIVE) cpu_pause();
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
}
|
||||
}
|
||||
*count += idx;
|
||||
hfi1_cdbg(AIOWRITE, "-");
|
||||
return 0;
|
||||
free_req:
|
||||
user_sdma_free_request(req, true);
|
||||
if (req_queued)
|
||||
pq_update(pq);
|
||||
set_comp_state(pq, cq, info.comp_idx, ERROR, req->status);
|
||||
hfi1_cdbg(AIOWRITE, "-");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -862,6 +910,7 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts)
|
||||
struct hfi1_user_sdma_pkt_q *pq = NULL;
|
||||
struct user_sdma_iovec *iovec = NULL;
|
||||
|
||||
hfi1_cdbg(AIOWRITE, "+");
|
||||
if (!req->pq)
|
||||
return -EINVAL;
|
||||
|
||||
@ -899,7 +948,11 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts)
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
#ifdef __HFI1_ORIG__
|
||||
tx = kmem_cache_alloc(pq->txreq_cache, GFP_KERNEL);
|
||||
#else
|
||||
tx = kmalloc(sizeof(struct user_sdma_txreq), GFP_KERNEL | __GFP_ZERO);
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
if (!tx)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1087,14 +1140,21 @@ dosend:
|
||||
if (test_bit(SDMA_REQ_HAVE_AHG, &req->flags))
|
||||
sdma_ahg_free(req->sde, req->ahg_idx);
|
||||
}
|
||||
hfi1_cdbg(AIOWRITE, "-");
|
||||
return ret;
|
||||
|
||||
free_txreq:
|
||||
sdma_txclean(pq->dd, &tx->txreq);
|
||||
free_tx:
|
||||
#ifdef __HFI1_ORIG__
|
||||
kmem_cache_free(pq->txreq_cache, tx);
|
||||
hfi1_cdbg(AIOWRITE, "-");
|
||||
#else
|
||||
kfree(tx);
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
return ret;
|
||||
}
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
/*
|
||||
* How many pages in this iovec element?
|
||||
@ -1212,6 +1272,7 @@ static void unpin_vector_pages(struct mm_struct *mm, struct page **pages,
|
||||
kfree(pages);
|
||||
}
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
static int check_header_template(struct user_sdma_request *req,
|
||||
struct hfi1_pkt_header *hdr, u32 lrhlen,
|
||||
u32 datalen)
|
||||
@ -1388,8 +1449,8 @@ static int set_txreq_header(struct user_sdma_request *req,
|
||||
req->omfactor != KDETH_OM_SMALL);
|
||||
}
|
||||
done:
|
||||
trace_hfi1_sdma_user_header(pq->dd, pq->ctxt, pq->subctxt,
|
||||
req->info.comp_idx, hdr, tidval);
|
||||
// trace_hfi1_sdma_user_header(pq->dd, pq->ctxt, pq->subctxt,
|
||||
// req->info.comp_idx, hdr, tidval);
|
||||
return sdma_txadd_kvaddr(pq->dd, &tx->txreq, hdr, sizeof(*hdr));
|
||||
}
|
||||
|
||||
@ -1475,9 +1536,9 @@ static int set_txreq_header_ahg(struct user_sdma_request *req,
|
||||
AHG_HEADER_SET(req->ahg, diff, 7, 16, 14, val);
|
||||
}
|
||||
|
||||
trace_hfi1_sdma_user_header_ahg(pq->dd, pq->ctxt, pq->subctxt,
|
||||
req->info.comp_idx, req->sde->this_idx,
|
||||
req->ahg_idx, req->ahg, diff, tidval);
|
||||
// trace_hfi1_sdma_user_header_ahg(pq->dd, pq->ctxt, pq->subctxt,
|
||||
// req->info.comp_idx, req->sde->this_idx,
|
||||
// req->ahg_idx, req->ahg, diff, tidval);
|
||||
return diff;
|
||||
}
|
||||
|
||||
@ -1510,7 +1571,8 @@ static void user_sdma_txreq_cb(struct sdma_txreq *txreq, int status)
|
||||
}
|
||||
|
||||
req->seqcomp = tx->seqnum;
|
||||
kmem_cache_free(pq->txreq_cache, tx);
|
||||
//TODO: kmem_cache_free
|
||||
//kmem_cache_free(pq->txreq_cache, tx);
|
||||
tx = NULL;
|
||||
|
||||
idx = req->info.comp_idx;
|
||||
@ -1538,12 +1600,14 @@ static inline void pq_update(struct hfi1_user_sdma_pkt_q *pq)
|
||||
{
|
||||
if (atomic_dec_and_test(&pq->n_reqs)) {
|
||||
xchg(&pq->state, SDMA_PKT_Q_INACTIVE);
|
||||
wake_up(&pq->wait);
|
||||
//TODO: wake_up
|
||||
//wake_up(&pq->wait);
|
||||
}
|
||||
}
|
||||
|
||||
static void user_sdma_free_request(struct user_sdma_request *req, bool unpin)
|
||||
{
|
||||
hfi1_cdbg(AIOWRITE, "+");
|
||||
if (!list_empty(&req->txps)) {
|
||||
struct sdma_txreq *t, *p;
|
||||
|
||||
@ -1552,7 +1616,9 @@ static void user_sdma_free_request(struct user_sdma_request *req, bool unpin)
|
||||
container_of(t, struct user_sdma_txreq, txreq);
|
||||
list_del_init(&t->list);
|
||||
sdma_txclean(req->pq->dd, t);
|
||||
#ifdef __HFI1_ORIG__
|
||||
kmem_cache_free(req->pq->txreq_cache, tx);
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
}
|
||||
}
|
||||
if (req->data_iovs) {
|
||||
@ -1564,17 +1630,20 @@ static void user_sdma_free_request(struct user_sdma_request *req, bool unpin)
|
||||
if (!node)
|
||||
continue;
|
||||
|
||||
//TODO:
|
||||
#ifdef __HFI1_ORIG__
|
||||
if (unpin)
|
||||
hfi1_mmu_rb_remove(req->pq->handler,
|
||||
&node->rb);
|
||||
else
|
||||
atomic_dec(&node->refcount);
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
}
|
||||
}
|
||||
kfree(req->tids);
|
||||
clear_bit(req->info.comp_idx, req->pq->req_in_use);
|
||||
hfi1_cdbg(AIOWRITE, "-");
|
||||
}
|
||||
|
||||
static inline void set_comp_state(struct hfi1_user_sdma_pkt_q *pq,
|
||||
struct hfi1_user_sdma_comp_q *cq,
|
||||
u16 idx, enum hfi1_sdma_comp_state state,
|
||||
@ -1585,9 +1654,10 @@ static inline void set_comp_state(struct hfi1_user_sdma_pkt_q *pq,
|
||||
cq->comps[idx].status = state;
|
||||
if (state == ERROR)
|
||||
cq->comps[idx].errcode = -ret;
|
||||
trace_hfi1_sdma_user_completion(pq->dd, pq->ctxt, pq->subctxt,
|
||||
idx, state, ret);
|
||||
// trace_hfi1_sdma_user_completion(pq->dd, pq->ctxt, pq->subctxt,
|
||||
// idx, state, ret);
|
||||
}
|
||||
#ifdef __HFI1_ORIG__
|
||||
|
||||
static bool sdma_rb_filter(struct mmu_rb_node *node, unsigned long addr,
|
||||
unsigned long len)
|
||||
@ -1651,3 +1721,5 @@ static int sdma_rb_invalidate(void *arg, struct mmu_rb_node *mnode)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
Reference in New Issue
Block a user