aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVenkata Sandeep Dhanalakota <venkata.s.dhanalakota@intel.com>2017-02-08 08:27:13 -0500
committerDoug Ledford <dledford@redhat.com>2017-02-19 09:18:39 -0500
commit11a10d4bc7b2640da1fce27586a617411b70f5c5 (patch)
tree84f603df164089c5b3dd069b14ad74551d6de101
parent696513e8cf39ccb8ee8010fd2157f095b3af6a91 (diff)
IB/rdmavt: Adding timer logic to rdmavt
To move common code across target to rdmavt for code reuse. Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com> Reviewed-by: Brian Welty <brian.welty@intel.com> Signed-off-by: Venkata Sandeep Dhanalakota <venkata.s.dhanalakota@intel.com> Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r--drivers/infiniband/sw/rdmavt/qp.c183
-rw-r--r--include/rdma/rdma_vt.h19
-rw-r--r--include/rdma/rdmavt_qp.h6
3 files changed, 206 insertions, 2 deletions
diff --git a/drivers/infiniband/sw/rdmavt/qp.c b/drivers/infiniband/sw/rdmavt/qp.c
index 444b06cada22..db4315f8f0c8 100644
--- a/drivers/infiniband/sw/rdmavt/qp.c
+++ b/drivers/infiniband/sw/rdmavt/qp.c
@@ -55,6 +55,46 @@
55#include "vt.h" 55#include "vt.h"
56#include "trace.h" 56#include "trace.h"
57 57
58static void rvt_rc_timeout(unsigned long arg);
59
60/*
61 * Convert the AETH RNR timeout code into the number of microseconds.
62 */
63static const u32 ib_rvt_rnr_table[32] = {
64 655360, /* 00: 655.36 */
65 10, /* 01: .01 */
66 20, /* 02 .02 */
67 30, /* 03: .03 */
68 40, /* 04: .04 */
69 60, /* 05: .06 */
70 80, /* 06: .08 */
71 120, /* 07: .12 */
72 160, /* 08: .16 */
73 240, /* 09: .24 */
74 320, /* 0A: .32 */
75 480, /* 0B: .48 */
76 640, /* 0C: .64 */
77 960, /* 0D: .96 */
78 1280, /* 0E: 1.28 */
79 1920, /* 0F: 1.92 */
80 2560, /* 10: 2.56 */
81 3840, /* 11: 3.84 */
82 5120, /* 12: 5.12 */
83 7680, /* 13: 7.68 */
84 10240, /* 14: 10.24 */
85 15360, /* 15: 15.36 */
86 20480, /* 16: 20.48 */
87 30720, /* 17: 30.72 */
88 40960, /* 18: 40.96 */
89 61440, /* 19: 61.44 */
90 81920, /* 1A: 81.92 */
91 122880, /* 1B: 122.88 */
92 163840, /* 1C: 163.84 */
93 245760, /* 1D: 245.76 */
94 327680, /* 1E: 327.68 */
95 491520 /* 1F: 491.52 */
96};
97
58/* 98/*
59 * Note that it is OK to post send work requests in the SQE and ERR 99 * Note that it is OK to post send work requests in the SQE and ERR
60 * states; rvt_do_send() will process them and generate error 100 * states; rvt_do_send() will process them and generate error
@@ -200,7 +240,8 @@ int rvt_driver_qp_init(struct rvt_dev_info *rdi)
200 if (!rdi->driver_f.free_all_qps || 240 if (!rdi->driver_f.free_all_qps ||
201 !rdi->driver_f.qp_priv_alloc || 241 !rdi->driver_f.qp_priv_alloc ||
202 !rdi->driver_f.qp_priv_free || 242 !rdi->driver_f.qp_priv_free ||
203 !rdi->driver_f.notify_qp_reset) 243 !rdi->driver_f.notify_qp_reset ||
244 !rdi->driver_f.notify_restart_rc)
204 return -EINVAL; 245 return -EINVAL;
205 246
206 /* allocate parent object */ 247 /* allocate parent object */
@@ -587,6 +628,7 @@ static void rvt_reset_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp,
587 628
588 /* Let drivers flush their waitlist */ 629 /* Let drivers flush their waitlist */
589 rdi->driver_f.flush_qp_waiters(qp); 630 rdi->driver_f.flush_qp_waiters(qp);
631 rvt_stop_rc_timers(qp);
590 qp->s_flags &= ~(RVT_S_TIMER | RVT_S_ANY_WAIT); 632 qp->s_flags &= ~(RVT_S_TIMER | RVT_S_ANY_WAIT);
591 spin_unlock(&qp->s_lock); 633 spin_unlock(&qp->s_lock);
592 spin_unlock(&qp->s_hlock); 634 spin_unlock(&qp->s_hlock);
@@ -594,7 +636,7 @@ static void rvt_reset_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp,
594 636
595 /* Stop the send queue and the retry timer */ 637 /* Stop the send queue and the retry timer */
596 rdi->driver_f.stop_send_queue(qp); 638 rdi->driver_f.stop_send_queue(qp);
597 639 rvt_del_timers_sync(qp);
598 /* Wait for things to stop */ 640 /* Wait for things to stop */
599 rdi->driver_f.quiesce_qp(qp); 641 rdi->driver_f.quiesce_qp(qp);
600 642
@@ -730,6 +772,11 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
730 if (!qp->s_ack_queue) 772 if (!qp->s_ack_queue)
731 goto bail_qp; 773 goto bail_qp;
732 } 774 }
775 /* initialize timers needed for rc qp */
776 setup_timer(&qp->s_timer, rvt_rc_timeout, (unsigned long)qp);
777 hrtimer_init(&qp->s_rnr_timer, CLOCK_MONOTONIC,
778 HRTIMER_MODE_REL);
779 qp->s_rnr_timer.function = rvt_rc_rnr_retry;
733 780
734 /* 781 /*
735 * Driver needs to set up it's private QP structure and do any 782 * Driver needs to set up it's private QP structure and do any
@@ -1906,3 +1953,135 @@ void rvt_rc_error(struct rvt_qp *qp, enum ib_wc_status err)
1906 } 1953 }
1907} 1954}
1908EXPORT_SYMBOL(rvt_rc_error); 1955EXPORT_SYMBOL(rvt_rc_error);
1956
1957static inline unsigned long rvt_aeth_to_usec(u32 aeth)
1958{
1959 return ib_rvt_rnr_table[(aeth >> RVT_AETH_CREDIT_SHIFT) &
1960 RVT_AETH_CREDIT_MASK];
1961}
1962
1963/*
1964 * rvt_add_retry_timer - add/start a retry timer
1965 * @qp - the QP
1966 * add a retry timer on the QP
1967 */
1968void rvt_add_retry_timer(struct rvt_qp *qp)
1969{
1970 struct ib_qp *ibqp = &qp->ibqp;
1971 struct rvt_dev_info *rdi = ib_to_rvt(ibqp->device);
1972
1973 lockdep_assert_held(&qp->s_lock);
1974 qp->s_flags |= RVT_S_TIMER;
1975 /* 4.096 usec. * (1 << qp->timeout) */
1976 qp->s_timer.expires = jiffies + qp->timeout_jiffies +
1977 rdi->busy_jiffies;
1978 add_timer(&qp->s_timer);
1979}
1980EXPORT_SYMBOL(rvt_add_retry_timer);
1981
1982/**
1983 * rvt_add_rnr_timer - add/start an rnr timer
1984 * @qp - the QP
1985 * @aeth - aeth of RNR timeout, simulated aeth for loopback
1986 * add an rnr timer on the QP
1987 */
1988void rvt_add_rnr_timer(struct rvt_qp *qp, u32 aeth)
1989{
1990 u32 to;
1991
1992 lockdep_assert_held(&qp->s_lock);
1993 qp->s_flags |= RVT_S_WAIT_RNR;
1994 to = rvt_aeth_to_usec(aeth);
1995 hrtimer_start(&qp->s_rnr_timer,
1996 ns_to_ktime(1000 * to), HRTIMER_MODE_REL);
1997}
1998EXPORT_SYMBOL(rvt_add_rnr_timer);
1999
2000/**
2001 * rvt_stop_rc_timers - stop all timers
2002 * @qp - the QP
2003 * stop any pending timers
2004 */
2005void rvt_stop_rc_timers(struct rvt_qp *qp)
2006{
2007 lockdep_assert_held(&qp->s_lock);
2008 /* Remove QP from all timers */
2009 if (qp->s_flags & (RVT_S_TIMER | RVT_S_WAIT_RNR)) {
2010 qp->s_flags &= ~(RVT_S_TIMER | RVT_S_WAIT_RNR);
2011 del_timer(&qp->s_timer);
2012 hrtimer_try_to_cancel(&qp->s_rnr_timer);
2013 }
2014}
2015EXPORT_SYMBOL(rvt_stop_rc_timers);
2016
2017/**
2018 * rvt_stop_rnr_timer - stop an rnr timer
2019 * @qp - the QP
2020 *
2021 * stop an rnr timer and return if the timer
2022 * had been pending.
2023 */
2024static int rvt_stop_rnr_timer(struct rvt_qp *qp)
2025{
2026 int rval = 0;
2027
2028 lockdep_assert_held(&qp->s_lock);
2029 /* Remove QP from rnr timer */
2030 if (qp->s_flags & RVT_S_WAIT_RNR) {
2031 qp->s_flags &= ~RVT_S_WAIT_RNR;
2032 rval = hrtimer_try_to_cancel(&qp->s_rnr_timer);
2033 }
2034 return rval;
2035}
2036
2037/**
2038 * rvt_del_timers_sync - wait for any timeout routines to exit
2039 * @qp - the QP
2040 */
2041void rvt_del_timers_sync(struct rvt_qp *qp)
2042{
2043 del_timer_sync(&qp->s_timer);
2044 hrtimer_cancel(&qp->s_rnr_timer);
2045}
2046EXPORT_SYMBOL(rvt_del_timers_sync);
2047
2048/**
2049 * This is called from s_timer for missing responses.
2050 */
2051static void rvt_rc_timeout(unsigned long arg)
2052{
2053 struct rvt_qp *qp = (struct rvt_qp *)arg;
2054 struct rvt_dev_info *rdi = ib_to_rvt(qp->ibqp.device);
2055 unsigned long flags;
2056
2057 spin_lock_irqsave(&qp->r_lock, flags);
2058 spin_lock(&qp->s_lock);
2059 if (qp->s_flags & RVT_S_TIMER) {
2060 qp->s_flags &= ~RVT_S_TIMER;
2061 del_timer(&qp->s_timer);
2062 if (rdi->driver_f.notify_restart_rc)
2063 rdi->driver_f.notify_restart_rc(qp,
2064 qp->s_last_psn + 1,
2065 1);
2066 rdi->driver_f.schedule_send(qp);
2067 }
2068 spin_unlock(&qp->s_lock);
2069 spin_unlock_irqrestore(&qp->r_lock, flags);
2070}
2071
2072/*
2073 * This is called from s_timer for RNR timeouts.
2074 */
2075enum hrtimer_restart rvt_rc_rnr_retry(struct hrtimer *t)
2076{
2077 struct rvt_qp *qp = container_of(t, struct rvt_qp, s_rnr_timer);
2078 struct rvt_dev_info *rdi = ib_to_rvt(qp->ibqp.device);
2079 unsigned long flags;
2080
2081 spin_lock_irqsave(&qp->s_lock, flags);
2082 rvt_stop_rnr_timer(qp);
2083 rdi->driver_f.schedule_send(qp);
2084 spin_unlock_irqrestore(&qp->s_lock, flags);
2085 return HRTIMER_NORESTART;
2086}
2087EXPORT_SYMBOL(rvt_rc_rnr_retry);
diff --git a/include/rdma/rdma_vt.h b/include/rdma/rdma_vt.h
index 861e23eaebda..a69dee38365f 100644
--- a/include/rdma/rdma_vt.h
+++ b/include/rdma/rdma_vt.h
@@ -335,6 +335,8 @@ struct rvt_driver_provided {
335 /* Notify driver a mad agent has been removed */ 335 /* Notify driver a mad agent has been removed */
336 void (*notify_free_mad_agent)(struct rvt_dev_info *rdi, int port_idx); 336 void (*notify_free_mad_agent)(struct rvt_dev_info *rdi, int port_idx);
337 337
338 /* Notify driver to restart rc */
339 void (*notify_restart_rc)(struct rvt_qp *qp, u32 psn, int wait);
338}; 340};
339 341
340struct rvt_dev_info { 342struct rvt_dev_info {
@@ -483,6 +485,23 @@ static inline struct rvt_qp *rvt_lookup_qpn(struct rvt_dev_info *rdi,
483 return qp; 485 return qp;
484} 486}
485 487
488/**
489 * rvt_mod_retry_timer - mod a retry timer
490 * @qp - the QP
491 * Modify a potentially already running retry timer
492 */
493static inline void rvt_mod_retry_timer(struct rvt_qp *qp)
494{
495 struct ib_qp *ibqp = &qp->ibqp;
496 struct rvt_dev_info *rdi = ib_to_rvt(ibqp->device);
497
498 lockdep_assert_held(&qp->s_lock);
499 qp->s_flags |= RVT_S_TIMER;
500 /* 4.096 usec. * (1 << qp->timeout) */
501 mod_timer(&qp->s_timer, jiffies + qp->timeout_jiffies +
502 rdi->busy_jiffies);
503}
504
486struct rvt_dev_info *rvt_alloc_device(size_t size, int nports); 505struct rvt_dev_info *rvt_alloc_device(size_t size, int nports);
487void rvt_dealloc_device(struct rvt_dev_info *rdi); 506void rvt_dealloc_device(struct rvt_dev_info *rdi);
488int rvt_register_device(struct rvt_dev_info *rvd); 507int rvt_register_device(struct rvt_dev_info *rvd);
diff --git a/include/rdma/rdmavt_qp.h b/include/rdma/rdmavt_qp.h
index a92e7dcfb5f5..0b1cbffb967c 100644
--- a/include/rdma/rdmavt_qp.h
+++ b/include/rdma/rdmavt_qp.h
@@ -370,6 +370,7 @@ struct rvt_qp {
370 370
371 struct rvt_sge_state s_ack_rdma_sge; 371 struct rvt_sge_state s_ack_rdma_sge;
372 struct timer_list s_timer; 372 struct timer_list s_timer;
373 struct hrtimer s_rnr_timer;
373 374
374 atomic_t local_ops_pending; /* number of fast_reg/local_inv reqs */ 375 atomic_t local_ops_pending; /* number of fast_reg/local_inv reqs */
375 376
@@ -641,5 +642,10 @@ struct rvt_dev_info;
641void rvt_comm_est(struct rvt_qp *qp); 642void rvt_comm_est(struct rvt_qp *qp);
642int rvt_error_qp(struct rvt_qp *qp, enum ib_wc_status err); 643int rvt_error_qp(struct rvt_qp *qp, enum ib_wc_status err);
643void rvt_rc_error(struct rvt_qp *qp, enum ib_wc_status err); 644void rvt_rc_error(struct rvt_qp *qp, enum ib_wc_status err);
645enum hrtimer_restart rvt_rc_rnr_retry(struct hrtimer *t);
646void rvt_add_rnr_timer(struct rvt_qp *qp, u32 aeth);
647void rvt_del_timers_sync(struct rvt_qp *qp);
648void rvt_stop_rc_timers(struct rvt_qp *qp);
649void rvt_add_retry_timer(struct rvt_qp *qp);
644 650
645#endif /* DEF_RDMAVT_INCQP_H */ 651#endif /* DEF_RDMAVT_INCQP_H */