Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
[platform/kernel/linux-starfive.git] / drivers / infiniband / ulp / rtrs / rtrs-clt.c
index 5e94686..40f4383 100644 (file)
@@ -103,11 +103,11 @@ static inline void __rtrs_put_permit(struct rtrs_clt *clt,
  *    up earlier.
  *
  * Context:
- *    Can sleep if @wait == RTRS_TAG_WAIT
+ *    Can sleep if @wait == RTRS_PERMIT_WAIT
  */
 struct rtrs_permit *rtrs_clt_get_permit(struct rtrs_clt *clt,
                                          enum rtrs_clt_con_type con_type,
-                                         int can_wait)
+                                         enum wait_type can_wait)
 {
        struct rtrs_permit *permit;
        DEFINE_WAIT(wait);
@@ -174,7 +174,7 @@ struct rtrs_clt_con *rtrs_permit_to_clt_con(struct rtrs_clt_sess *sess,
        int id = 0;
 
        if (likely(permit->con_type == RTRS_IO_CON))
-               id = (permit->cpu_id % (sess->s.con_num - 1)) + 1;
+               id = (permit->cpu_id % (sess->s.irq_con_num - 1)) + 1;
 
        return to_clt_con(sess->s.con[id]);
 }
@@ -1465,23 +1465,29 @@ static void rtrs_clt_close_work(struct work_struct *work);
 static struct rtrs_clt_sess *alloc_sess(struct rtrs_clt *clt,
                                         const struct rtrs_addr *path,
                                         size_t con_num, u16 max_segments,
-                                        size_t max_segment_size)
+                                        u32 nr_poll_queues)
 {
        struct rtrs_clt_sess *sess;
        int err = -ENOMEM;
        int cpu;
+       size_t total_con;
 
        sess = kzalloc(sizeof(*sess), GFP_KERNEL);
        if (!sess)
                goto err;
 
-       /* Extra connection for user messages */
-       con_num += 1;
-
-       sess->s.con = kcalloc(con_num, sizeof(*sess->s.con), GFP_KERNEL);
+       /*
+        * irqmode and poll
+        * +1: Extra connection for user messages
+        */
+       total_con = con_num + nr_poll_queues + 1;
+       sess->s.con = kcalloc(total_con, sizeof(*sess->s.con), GFP_KERNEL);
        if (!sess->s.con)
                goto err_free_sess;
 
+       sess->s.con_num = total_con;
+       sess->s.irq_con_num = con_num + 1;
+
        sess->stats = kzalloc(sizeof(*sess->stats), GFP_KERNEL);
        if (!sess->stats)
                goto err_free_con;
@@ -1500,9 +1506,8 @@ static struct rtrs_clt_sess *alloc_sess(struct rtrs_clt *clt,
                memcpy(&sess->s.src_addr, path->src,
                       rdma_addr_size((struct sockaddr *)path->src));
        strlcpy(sess->s.sessname, clt->sessname, sizeof(sess->s.sessname));
-       sess->s.con_num = con_num;
        sess->clt = clt;
-       sess->max_pages_per_mr = max_segments * max_segment_size >> 12;
+       sess->max_pages_per_mr = max_segments;
        init_waitqueue_head(&sess->state_wq);
        sess->state = RTRS_CLT_CONNECTING;
        atomic_set(&sess->connected_cnt, 0);
@@ -1641,9 +1646,14 @@ static int create_con_cq_qp(struct rtrs_clt_con *con)
        }
        cq_size = max_send_wr + max_recv_wr;
        cq_vector = con->cpu % sess->s.dev->ib_dev->num_comp_vectors;
-       err = rtrs_cq_qp_create(&sess->s, &con->c, sess->max_send_sge,
-                                cq_vector, cq_size, max_send_wr,
-                                max_recv_wr, IB_POLL_SOFTIRQ);
+       if (con->c.cid >= sess->s.irq_con_num)
+               err = rtrs_cq_qp_create(&sess->s, &con->c, sess->max_send_sge,
+                                       cq_vector, cq_size, max_send_wr,
+                                       max_recv_wr, IB_POLL_DIRECT);
+       else
+               err = rtrs_cq_qp_create(&sess->s, &con->c, sess->max_send_sge,
+                                       cq_vector, cq_size, max_send_wr,
+                                       max_recv_wr, IB_POLL_SOFTIRQ);
        /*
         * In case of error we do not bother to clean previous allocations,
         * since destroy_con_cq_qp() must be called.
@@ -2608,7 +2618,6 @@ static struct rtrs_clt *alloc_clt(const char *sessname, size_t paths_num,
                                  void  (*link_ev)(void *priv,
                                                   enum rtrs_clt_link_ev ev),
                                  unsigned int max_segments,
-                                 size_t max_segment_size,
                                  unsigned int reconnect_delay_sec,
                                  unsigned int max_reconnect_attempts)
 {
@@ -2638,7 +2647,6 @@ static struct rtrs_clt *alloc_clt(const char *sessname, size_t paths_num,
        clt->port = port;
        clt->pdu_sz = pdu_sz;
        clt->max_segments = max_segments;
-       clt->max_segment_size = max_segment_size;
        clt->reconnect_delay_sec = reconnect_delay_sec;
        clt->max_reconnect_attempts = max_reconnect_attempts;
        clt->priv = priv;
@@ -2708,9 +2716,9 @@ static void free_clt(struct rtrs_clt *clt)
  * @pdu_sz: Size of extra payload which can be accessed after permit allocation.
  * @reconnect_delay_sec: time between reconnect tries
  * @max_segments: Max. number of segments per IO request
- * @max_segment_size: Max. size of one segment
  * @max_reconnect_attempts: Number of times to reconnect on error before giving
  *                         up, 0 for * disabled, -1 for forever
+ * @nr_poll_queues: number of polling mode connection using IB_POLL_DIRECT flag
  *
  * Starts session establishment with the rtrs_server. The function can block
  * up to ~2000ms before it returns.
@@ -2723,8 +2731,7 @@ struct rtrs_clt *rtrs_clt_open(struct rtrs_clt_ops *ops,
                                 size_t paths_num, u16 port,
                                 size_t pdu_sz, u8 reconnect_delay_sec,
                                 u16 max_segments,
-                                size_t max_segment_size,
-                                s16 max_reconnect_attempts)
+                                s16 max_reconnect_attempts, u32 nr_poll_queues)
 {
        struct rtrs_clt_sess *sess, *tmp;
        struct rtrs_clt *clt;
@@ -2732,7 +2739,7 @@ struct rtrs_clt *rtrs_clt_open(struct rtrs_clt_ops *ops,
 
        clt = alloc_clt(sessname, paths_num, port, pdu_sz, ops->priv,
                        ops->link_ev,
-                       max_segments, max_segment_size, reconnect_delay_sec,
+                       max_segments, reconnect_delay_sec,
                        max_reconnect_attempts);
        if (IS_ERR(clt)) {
                err = PTR_ERR(clt);
@@ -2742,7 +2749,7 @@ struct rtrs_clt *rtrs_clt_open(struct rtrs_clt_ops *ops,
                struct rtrs_clt_sess *sess;
 
                sess = alloc_sess(clt, &paths[i], nr_cpu_ids,
-                                 max_segments, max_segment_size);
+                                 max_segments, nr_poll_queues);
                if (IS_ERR(sess)) {
                        err = PTR_ERR(sess);
                        goto close_all_sess;
@@ -2800,8 +2807,8 @@ void rtrs_clt_close(struct rtrs_clt *clt)
 
        /* Now it is safe to iterate over all paths without locks */
        list_for_each_entry_safe(sess, tmp, &clt->paths_list, s.entry) {
-               rtrs_clt_destroy_sess_files(sess, NULL);
                rtrs_clt_close_conns(sess, true);
+               rtrs_clt_destroy_sess_files(sess, NULL);
                kobject_put(&sess->kobj);
        }
        free_clt(clt);
@@ -2967,6 +2974,31 @@ int rtrs_clt_request(int dir, struct rtrs_clt_req_ops *ops,
 }
 EXPORT_SYMBOL(rtrs_clt_request);
 
+int rtrs_clt_rdma_cq_direct(struct rtrs_clt *clt, unsigned int index)
+{
+       int cnt;
+       struct rtrs_con *con;
+       struct rtrs_clt_sess *sess;
+       struct path_it it;
+
+       rcu_read_lock();
+       for (path_it_init(&it, clt);
+            (sess = it.next_path(&it)) && it.i < it.clt->paths_num; it.i++) {
+               if (READ_ONCE(sess->state) != RTRS_CLT_CONNECTED)
+                       continue;
+
+               con = sess->s.con[index + 1];
+               cnt = ib_process_cq_direct(con->cq, -1);
+               if (cnt)
+                       break;
+       }
+       path_it_deinit(&it);
+       rcu_read_unlock();
+
+       return cnt;
+}
+EXPORT_SYMBOL(rtrs_clt_rdma_cq_direct);
+
 /**
  * rtrs_clt_query() - queries RTRS session attributes
  *@clt: session pointer
@@ -2995,8 +3027,7 @@ int rtrs_clt_create_path_from_sysfs(struct rtrs_clt *clt,
        struct rtrs_clt_sess *sess;
        int err;
 
-       sess = alloc_sess(clt, addr, nr_cpu_ids, clt->max_segments,
-                         clt->max_segment_size);
+       sess = alloc_sess(clt, addr, nr_cpu_ids, clt->max_segments, 0);
        if (IS_ERR(sess))
                return PTR_ERR(sess);