diff options
Diffstat (limited to 'drivers/infiniband/hw/qib/qib_verbs.h')
| -rw-r--r-- | drivers/infiniband/hw/qib/qib_verbs.h | 265 | 
1 files changed, 169 insertions, 96 deletions
diff --git a/drivers/infiniband/hw/qib/qib_verbs.h b/drivers/infiniband/hw/qib/qib_verbs.h index bd57c127322..bfc8948fdd3 100644 --- a/drivers/infiniband/hw/qib/qib_verbs.h +++ b/drivers/infiniband/hw/qib/qib_verbs.h @@ -1,6 +1,6 @@  /* - * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation. - * All rights reserved. + * Copyright (c) 2012, 2013 Intel Corporation.  All rights reserved. + * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved.   * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.   *   * This software is available to you under a choice of one of two @@ -41,6 +41,8 @@  #include <linux/interrupt.h>  #include <linux/kref.h>  #include <linux/workqueue.h> +#include <linux/kthread.h> +#include <linux/completion.h>  #include <rdma/ib_pack.h>  #include <rdma/ib_user_verbs.h> @@ -148,14 +150,14 @@ struct ib_reth {  	__be64 vaddr;  	__be32 rkey;  	__be32 length; -} __attribute__ ((packed)); +} __packed;  struct ib_atomic_eth {  	__be32 vaddr[2];        /* unaligned so access as 2 32-bit words */  	__be32 rkey;  	__be64 swap_data;  	__be64 compare_data; -} __attribute__ ((packed)); +} __packed;  struct qib_other_headers {  	__be32 bth[3]; @@ -176,7 +178,7 @@ struct qib_other_headers {  		__be32 aeth;  		struct ib_atomic_eth atomic_eth;  	} u; -} __attribute__ ((packed)); +} __packed;  /*   * Note that UD packets with a GRH header are 8+40+12+8 = 68 bytes @@ -193,12 +195,12 @@ struct qib_ib_header {  		} l;  		struct qib_other_headers oth;  	} u; -} __attribute__ ((packed)); +} __packed;  struct qib_pio_header {  	__le32 pbc[2];  	struct qib_ib_header hdr; -} __attribute__ ((packed)); +} __packed;  /*   * There is one struct qib_mcast for each multicast GID. @@ -266,7 +268,8 @@ struct qib_cq_wc {   */  struct qib_cq {  	struct ib_cq ibcq; -	struct work_struct comptask; +	struct kthread_work comptask; +	struct qib_devdata *dd;  	spinlock_t lock; /* protect changes in this struct */  	u8 notify;  	u8 triggered; @@ -301,6 +304,10 @@ struct qib_mregion {  	int access_flags;  	u32 max_segs;           /* number of qib_segs in all the arrays */  	u32 mapsz;              /* size of the map array */ +	u8  page_shift;         /* 0 - non unform/non powerof2 sizes */ +	u8  lkey_published;     /* in global table */ +	struct completion comp; /* complete when refcount goes to zero */ +	struct rcu_head list;  	atomic_t refcount;  	struct qib_segarray *map[0];    /* the segments */  }; @@ -366,9 +373,10 @@ struct qib_rwq {  struct qib_rq {  	struct qib_rwq *wq; -	spinlock_t lock; /* protect changes in this struct */  	u32 size;               /* size of RWQE array */  	u8 max_sge; +	spinlock_t lock /* protect changes in this struct */ +		____cacheline_aligned_in_smp;  };  struct qib_srq { @@ -411,32 +419,75 @@ struct qib_ack_entry {   */  struct qib_qp {  	struct ib_qp ibqp; -	struct qib_qp *next;            /* link list for QPN hash table */ -	struct qib_qp *timer_next;      /* link list for qib_ib_timer() */ -	struct list_head iowait;        /* link for wait PIO buf */ -	struct list_head rspwait;       /* link for waititing to respond */ +	/* read mostly fields above and below */  	struct ib_ah_attr remote_ah_attr;  	struct ib_ah_attr alt_ah_attr; -	struct qib_ib_header s_hdr;     /* next packet header to send */ -	atomic_t refcount; -	wait_queue_head_t wait; -	wait_queue_head_t wait_dma; -	struct timer_list s_timer; -	struct work_struct s_work; +	struct qib_qp __rcu *next;            /* link list for QPN hash table */ +	struct qib_swqe *s_wq;  /* send work queue */  	struct qib_mmap_info *ip; +	struct qib_ib_header *s_hdr;     /* next packet header to send */ +	unsigned long timeout_jiffies;  /* computed from timeout */ + +	enum ib_mtu path_mtu; +	u32 remote_qpn; +	u32 pmtu;		/* decoded from path_mtu */ +	u32 qkey;               /* QKEY for this QP (for UD or RD) */ +	u32 s_size;             /* send work queue size */ +	u32 s_rnr_timeout;      /* number of milliseconds for RNR timeout */ + +	u8 state;               /* QP state */ +	u8 qp_access_flags; +	u8 alt_timeout;         /* Alternate path timeout for this QP */ +	u8 timeout;             /* Timeout for this QP */ +	u8 s_srate; +	u8 s_mig_state; +	u8 port_num; +	u8 s_pkey_index;        /* PKEY index to use */ +	u8 s_alt_pkey_index;    /* Alternate path PKEY index to use */ +	u8 r_max_rd_atomic;     /* max number of RDMA read/atomic to receive */ +	u8 s_max_rd_atomic;     /* max number of RDMA read/atomic to send */ +	u8 s_retry_cnt;         /* number of times to retry */ +	u8 s_rnr_retry_cnt; +	u8 r_min_rnr_timer;     /* retry timeout value for RNR NAKs */ +	u8 s_max_sge;           /* size of s_wq->sg_list */ +	u8 s_draining; + +	/* start of read/write fields */ + +	atomic_t refcount ____cacheline_aligned_in_smp; +	wait_queue_head_t wait; + + +	struct qib_ack_entry s_ack_queue[QIB_MAX_RDMA_ATOMIC + 1] +		____cacheline_aligned_in_smp; +	struct qib_sge_state s_rdma_read_sge; + +	spinlock_t r_lock ____cacheline_aligned_in_smp;      /* used for APM */ +	unsigned long r_aflags; +	u64 r_wr_id;            /* ID for current receive WQE */ +	u32 r_ack_psn;          /* PSN for next ACK or atomic ACK */ +	u32 r_len;              /* total length of r_sge */ +	u32 r_rcv_len;          /* receive data len processed */ +	u32 r_psn;              /* expected rcv packet sequence number */ +	u32 r_msn;              /* message sequence number */ + +	u8 r_state;             /* opcode of last packet received */ +	u8 r_flags; +	u8 r_head_ack_queue;    /* index into s_ack_queue[] */ + +	struct list_head rspwait;       /* link for waititing to respond */ + +	struct qib_sge_state r_sge;     /* current receive data */ +	struct qib_rq r_rq;             /* receive work queue */ + +	spinlock_t s_lock ____cacheline_aligned_in_smp;  	struct qib_sge_state *s_cur_sge; +	u32 s_flags;  	struct qib_verbs_txreq *s_tx; -	struct qib_mregion *s_rdma_mr; +	struct qib_swqe *s_wqe;  	struct qib_sge_state s_sge;     /* current send request data */ -	struct qib_ack_entry s_ack_queue[QIB_MAX_RDMA_ATOMIC + 1]; -	struct qib_sge_state s_ack_rdma_sge; -	struct qib_sge_state s_rdma_read_sge; -	struct qib_sge_state r_sge;     /* current receive data */ -	spinlock_t r_lock;      /* used for APM */ -	spinlock_t s_lock; +	struct qib_mregion *s_rdma_mr;  	atomic_t s_dma_busy; -	unsigned processor_id;	/* Processor ID QP is bound to */ -	u32 s_flags;  	u32 s_cur_size;         /* size of send packet in bytes */  	u32 s_len;              /* total length of s_sge */  	u32 s_rdma_read_len;    /* total length of s_rdma_read_sge */ @@ -447,58 +498,34 @@ struct qib_qp {  	u32 s_psn;              /* current packet sequence number */  	u32 s_ack_rdma_psn;     /* PSN for sending RDMA read responses */  	u32 s_ack_psn;          /* PSN for acking sends and RDMA writes */ -	u32 s_rnr_timeout;      /* number of milliseconds for RNR timeout */ -	u32 r_ack_psn;          /* PSN for next ACK or atomic ACK */ -	u64 r_wr_id;            /* ID for current receive WQE */ -	unsigned long r_aflags; -	u32 r_len;              /* total length of r_sge */ -	u32 r_rcv_len;          /* receive data len processed */ -	u32 r_psn;              /* expected rcv packet sequence number */ -	u32 r_msn;              /* message sequence number */ +	u32 s_head;             /* new entries added here */ +	u32 s_tail;             /* next entry to process */ +	u32 s_cur;              /* current work queue entry */ +	u32 s_acked;            /* last un-ACK'ed entry */ +	u32 s_last;             /* last completed entry */ +	u32 s_ssn;              /* SSN of tail entry */ +	u32 s_lsn;              /* limit sequence number (credit) */  	u16 s_hdrwords;         /* size of s_hdr in 32 bit words */  	u16 s_rdma_ack_cnt; -	u8 state;               /* QP state */  	u8 s_state;             /* opcode of last packet sent */  	u8 s_ack_state;         /* opcode of packet to ACK */  	u8 s_nak_state;         /* non-zero if NAK is pending */ -	u8 r_state;             /* opcode of last packet received */  	u8 r_nak_state;         /* non-zero if NAK is pending */ -	u8 r_min_rnr_timer;     /* retry timeout value for RNR NAKs */ -	u8 r_flags; -	u8 r_max_rd_atomic;     /* max number of RDMA read/atomic to receive */ -	u8 r_head_ack_queue;    /* index into s_ack_queue[] */ -	u8 qp_access_flags; -	u8 s_max_sge;           /* size of s_wq->sg_list */ -	u8 s_retry_cnt;         /* number of times to retry */ -	u8 s_rnr_retry_cnt;  	u8 s_retry;             /* requester retry counter */  	u8 s_rnr_retry;         /* requester RNR retry counter */ -	u8 s_pkey_index;        /* PKEY index to use */ -	u8 s_alt_pkey_index;    /* Alternate path PKEY index to use */ -	u8 s_max_rd_atomic;     /* max number of RDMA read/atomic to send */  	u8 s_num_rd_atomic;     /* number of RDMA read/atomic pending */  	u8 s_tail_ack_queue;    /* index into s_ack_queue[] */ -	u8 s_srate; -	u8 s_draining; -	u8 s_mig_state; -	u8 timeout;             /* Timeout for this QP */ -	u8 alt_timeout;         /* Alternate path timeout for this QP */ -	u8 port_num; -	enum ib_mtu path_mtu; -	u32 remote_qpn; -	u32 qkey;               /* QKEY for this QP (for UD or RD) */ -	u32 s_size;             /* send work queue size */ -	u32 s_head;             /* new entries added here */ -	u32 s_tail;             /* next entry to process */ -	u32 s_cur;              /* current work queue entry */ -	u32 s_acked;            /* last un-ACK'ed entry */ -	u32 s_last;             /* last completed entry */ -	u32 s_ssn;              /* SSN of tail entry */ -	u32 s_lsn;              /* limit sequence number (credit) */ -	struct qib_swqe *s_wq;  /* send work queue */ -	struct qib_swqe *s_wqe; -	struct qib_rq r_rq;             /* receive work queue */ -	struct qib_sge r_sg_list[0];    /* verified SGEs */ + +	struct qib_sge_state s_ack_rdma_sge; +	struct timer_list s_timer; +	struct list_head iowait;        /* link for wait PIO buf */ + +	struct work_struct s_work; + +	wait_queue_head_t wait_dma; + +	struct qib_sge r_sg_list[0] /* verified SGEs */ +		____cacheline_aligned_in_smp;  };  /* @@ -625,7 +652,7 @@ struct qib_lkey_table {  	u32 next;               /* next unused index (speeds search) */  	u32 gen;                /* generation count */  	u32 max;                /* size of the table */ -	struct qib_mregion **table; +	struct qib_mregion __rcu **table;  };  struct qib_opcode_stats { @@ -633,9 +660,20 @@ struct qib_opcode_stats {  	u64 n_bytes;            /* total number of bytes */  }; +struct qib_opcode_stats_perctx { +	struct qib_opcode_stats stats[128]; +}; + +struct qib_pma_counters { +	u64 n_unicast_xmit;     /* total unicast packets sent */ +	u64 n_unicast_rcv;      /* total unicast packets received */ +	u64 n_multicast_xmit;   /* total multicast packets sent */ +	u64 n_multicast_rcv;    /* total multicast packets received */ +}; +  struct qib_ibport { -	struct qib_qp *qp0; -	struct qib_qp *qp1; +	struct qib_qp __rcu *qp0; +	struct qib_qp __rcu *qp1;  	struct ib_mad_agent *send_agent;	/* agent for SMI (traps) */  	struct qib_ah *sm_ah;  	struct qib_ah *smi_ah; @@ -649,10 +687,11 @@ struct qib_ibport {  	__be64 mkey;  	__be64 guids[QIB_GUIDS_PER_PORT	- 1];	/* writable GUIDs */  	u64 tid;		/* TID for traps */ -	u64 n_unicast_xmit;     /* total unicast packets sent */ -	u64 n_unicast_rcv;      /* total unicast packets received */ -	u64 n_multicast_xmit;   /* total multicast packets sent */ -	u64 n_multicast_rcv;    /* total multicast packets received */ +	struct qib_pma_counters __percpu *pmastats; +	u64 z_unicast_xmit;     /* starting count for PMA */ +	u64 z_unicast_rcv;      /* starting count for PMA */ +	u64 z_multicast_xmit;   /* starting count for PMA */ +	u64 z_multicast_rcv;    /* starting count for PMA */  	u64 z_symbol_error_counter;             /* starting count for PMA */  	u64 z_link_error_recovery_counter;      /* starting count for PMA */  	u64 z_link_downed_counter;              /* starting count for PMA */ @@ -699,15 +738,15 @@ struct qib_ibport {  	u8 vl_high_limit;  	u8 sl_to_vl[16]; -	struct qib_opcode_stats opstats[128];  }; +  struct qib_ibdev {  	struct ib_device ibdev;  	struct list_head pending_mmaps;  	spinlock_t mmap_offset_lock; /* protect mmap_offset */  	u32 mmap_offset; -	struct qib_mregion *dma_mr; +	struct qib_mregion __rcu *dma_mr;  	/* QP numbers are shared by all IB ports */  	struct qib_qpn_table qpn_table; @@ -718,12 +757,13 @@ struct qib_ibdev {  	struct list_head memwait;       /* list for wait kernel memory */  	struct list_head txreq_free;  	struct timer_list mem_timer; -	struct qib_qp **qp_table; +	struct qib_qp __rcu **qp_table;  	struct qib_pio_header *pio_hdrs;  	dma_addr_t pio_hdrs_phys;  	/* list of QPs waiting for RNR timer */  	spinlock_t pending_lock; /* protect wait lists, PMA counters, etc. */ -	unsigned qp_table_size; /* size of the hash table */ +	u32 qp_table_size; /* size of the hash table */ +	u32 qp_rnd; /* random bytes for hash */  	spinlock_t qpt_lock;  	u32 n_piowait; @@ -741,6 +781,10 @@ struct qib_ibdev {  	spinlock_t n_srqs_lock;  	u32 n_mcast_grps_allocated; /* number of mcast groups allocated */  	spinlock_t n_mcast_grps_lock; +#ifdef CONFIG_DEBUG_FS +	/* per HCA debugfs */ +	struct dentry *qib_ibdev_dbg; +#endif  };  struct qib_verbs_counters { @@ -805,22 +849,10 @@ static inline int qib_send_ok(struct qib_qp *qp)  		 !(qp->s_flags & QIB_S_ANY_WAIT_SEND));  } -extern struct workqueue_struct *qib_wq; -extern struct workqueue_struct *qib_cq_wq; -  /*   * This must be called with s_lock held.   */ -static inline void qib_schedule_send(struct qib_qp *qp) -{ -	if (qib_send_ok(qp)) { -		if (qp->processor_id == smp_processor_id()) -			queue_work(qib_wq, &qp->s_work); -		else -			queue_work_on(qp->processor_id, -				      qib_wq, &qp->s_work); -	} -} +void qib_schedule_send(struct qib_qp *qp);  static inline int qib_pkey_ok(u16 pkey1, u16 pkey2)  { @@ -893,6 +925,18 @@ void qib_init_qpn_table(struct qib_devdata *dd, struct qib_qpn_table *qpt);  void qib_free_qpn_table(struct qib_qpn_table *qpt); +#ifdef CONFIG_DEBUG_FS + +struct qib_qp_iter; + +struct qib_qp_iter *qib_qp_iter_init(struct qib_ibdev *dev); + +int qib_qp_iter_next(struct qib_qp_iter *iter); + +void qib_qp_iter_print(struct seq_file *s, struct qib_qp_iter *iter); + +#endif +  void qib_get_credit(struct qib_qp *qp, u32 aeth);  unsigned qib_pkt_delay(u32 plen, u8 snd_mult, u8 rcv_mult); @@ -917,6 +961,8 @@ void qib_rc_rcv(struct qib_ctxtdata *rcd, struct qib_ib_header *hdr,  int qib_check_ah(struct ib_device *ibdev, struct ib_ah_attr *ah_attr); +struct ib_ah *qib_create_qp0_ah(struct qib_ibport *ibp, u16 dlid); +  void qib_rc_rnr_retry(unsigned long arg);  void qib_rc_send_complete(struct qib_qp *qp, struct qib_ib_header *hdr); @@ -928,9 +974,9 @@ int qib_post_ud_send(struct qib_qp *qp, struct ib_send_wr *wr);  void qib_ud_rcv(struct qib_ibport *ibp, struct qib_ib_header *hdr,  		int has_grh, void *data, u32 tlen, struct qib_qp *qp); -int qib_alloc_lkey(struct qib_lkey_table *rkt, struct qib_mregion *mr); +int qib_alloc_lkey(struct qib_mregion *mr, int dma_region); -int qib_free_lkey(struct qib_ibdev *dev, struct qib_mregion *mr); +void qib_free_lkey(struct qib_mregion *mr);  int qib_lkey_ok(struct qib_lkey_table *rkt, struct qib_pd *pd,  		struct qib_sge *isge, struct ib_sge *sge, int acc); @@ -953,6 +999,10 @@ int qib_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr);  int qib_destroy_srq(struct ib_srq *ibsrq); +int qib_cq_init(struct qib_devdata *dd); + +void qib_cq_exit(struct qib_devdata *dd); +  void qib_cq_enter(struct qib_cq *cq, struct ib_wc *entry, int sig);  int qib_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry); @@ -998,6 +1048,29 @@ int qib_unmap_fmr(struct list_head *fmr_list);  int qib_dealloc_fmr(struct ib_fmr *ibfmr); +static inline void qib_get_mr(struct qib_mregion *mr) +{ +	atomic_inc(&mr->refcount); +} + +void mr_rcu_callback(struct rcu_head *list); + +static inline void qib_put_mr(struct qib_mregion *mr) +{ +	if (unlikely(atomic_dec_and_test(&mr->refcount))) +		call_rcu(&mr->list, mr_rcu_callback); +} + +static inline void qib_put_ss(struct qib_sge_state *ss) +{ +	while (ss->num_sge) { +		qib_put_mr(ss->sge.mr); +		if (--ss->num_sge) +			ss->sge = *ss->sg_list++; +	} +} + +  void qib_release_mmap_info(struct kref *ref);  struct qib_mmap_info *qib_create_mmap_info(struct qib_ibdev *dev, u32 size,  | 
