Motr  M0
tm_provision.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2012-2020 Seagate Technology LLC and/or its Affiliates
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
410 #include "lib/arith.h" /* M0_CNT_INC */
411 #include "net/net_internal.h"
412 #include "net/buffer_pool.h"
413 
414 M0_INTERNAL int m0_net__tm_provision_buf(struct m0_net_transfer_mc *tm)
415 {
416  struct m0_net_buffer *nb;
417  int rc;
418 
419  M0_PRE(m0_mutex_is_locked(&tm->ntm_mutex));
421 
423  if (nb != NULL) {
428  nb->nb_ep = NULL;
429  M0_ASSERT(nb->nb_pool == tm->ntm_recv_pool);
430  rc = m0_net__buffer_add(nb, tm);
431  } else
432  rc = +1;
433  return rc;
434 }
435 
436 /*
437  Private provisioning routine that assumes all locking is obtained
438  in the correct order prior to invocation.
439  @post If provisioning is enabled:
440  Length of receive queue >= tm->ntm_recv_queue_min_length &&
441  tm->ntm_recv_queue_deficit == 0 ||
442  Length of receive queue + tm->ntm_recv_queue_deficit ==
443  tm->ntm_recv_queue_min_length
444 */
446 {
447  int64_t need;
448  int rc;
449  uint64_t recv_q_len;
450  uint64_t deficit;
451  uint64_t prev_deficit;
452 
453  M0_PRE(m0_mutex_is_locked(&tm->ntm_mutex));
455  if (tm->ntm_state != M0_NET_TM_STARTED || tm->ntm_recv_pool == NULL)
456  return; /* provisioning not required */
458  prev_deficit = m0_atomic64_get(&tm->ntm_recv_queue_deficit);
459  recv_q_len = m0_net_tm_tlist_length(&tm->ntm_q[M0_NET_QT_MSG_RECV]);
460  need = tm->ntm_recv_queue_min_length - recv_q_len;
461  /*
462  * @todo XXX this is incorrect: a buffer can be on M0_NET_QT_MSG_RECV
463  * queue, but ineligible to receive incoming data, because it is busy
464  * accepting data already.
465  */
466  while (need > 0) {
468  if (rc != 0)
469  break;
470  M0_CNT_DEC(need);
471  M0_CNT_INC(recv_q_len);
472  }
473  deficit = need < 0 ? 0 : need;
474  if (deficit > prev_deficit)
476  deficit - prev_deficit;
478  M0_POST((recv_q_len >= tm->ntm_recv_queue_min_length && deficit == 0) ||
479  recv_q_len + deficit == tm->ntm_recv_queue_min_length);
480  return;
481 }
482 
483 M0_INTERNAL void
485 {
486  struct m0_net_domain *dom;
487  struct m0_net_transfer_mc *tm;
488 
490 
491  dom = pool->nbp_ndom;
492  m0_mutex_lock(&dom->nd_mutex);
493  m0_list_for_each_entry(&dom->nd_tms, tm,
496  continue; /* skip if no deficit */
497  m0_mutex_lock(&tm->ntm_mutex);
498  if (tm->ntm_state == M0_NET_TM_STARTED &&
499  tm->ntm_recv_pool == pool &&
502  m0_mutex_unlock(&tm->ntm_mutex);
503  }
504  m0_mutex_unlock(&dom->nd_mutex);
505  return;
506 }
508 
510 {
511  M0_PRE(m0_mutex_is_not_locked(&tm->ntm_mutex));
512  M0_PRE(tm->ntm_callback_counter > 0);
513  M0_PRE(tm->ntm_recv_pool != NULL);
515 
517  m0_mutex_lock(&tm->ntm_mutex);
519  m0_mutex_unlock(&tm->ntm_mutex);
521  return;
522 }
523 
524 /*
525  * Local variables:
526  * c-indentation-style: "K&R"
527  * c-basic-offset: 8
528  * tab-width: 8
529  * fill-column: 79
530  * scroll-step: 1
531  * End:
532  */
uint64_t nqs_num_f_events
Definition: net.h:784
m0_bcount_t ntm_recv_queue_min_recv_size
Definition: net.h:927
#define M0_PRE(cond)
uint32_t ntm_recv_queue_min_length
Definition: net.h:908
M0_INTERNAL void m0_mutex_unlock(struct m0_mutex *mutex)
Definition: mutex.c:66
struct m0_net_buffer_pool * nb_pool
Definition: net.h:1508
#define NULL
Definition: misc.h:38
M0_INTERNAL bool m0_mutex_is_not_locked(const struct m0_mutex *mutex)
Definition: mutex.c:101
M0_INTERNAL struct m0_net_buffer * m0_net_buffer_pool_get(struct m0_net_buffer_pool *pool, uint32_t colour)
Definition: buffer_pool.c:215
M0_INTERNAL void m0_net_buffer_pool_unlock(struct m0_net_buffer_pool *pool)
Definition: buffer_pool.c:203
struct m0_net_qstats ntm_qstats[M0_NET_QT_NR]
Definition: net.h:880
enum m0_net_tm_state ntm_state
Definition: net.h:819
m0_bcount_t nb_min_receive_size
Definition: net.h:1496
M0_INTERNAL void m0_mutex_lock(struct m0_mutex *mutex)
Definition: mutex.c:49
M0_INTERNAL void m0_net_domain_buffer_pool_not_empty(struct m0_net_buffer_pool *pool)
Definition: tm_provision.c:484
M0_INTERNAL void m0_net__tm_provision_recv_q(struct m0_net_transfer_mc *tm)
Definition: tm_provision.c:509
const struct m0_net_buffer_callbacks * ntm_recv_pool_callbacks
Definition: net.h:902
M0_INTERNAL int m0_net__tm_provision_buf(struct m0_net_transfer_mc *tm)
Definition: tm_provision.c:414
M0_INTERNAL bool m0_net_buffer_pool_is_locked(const struct m0_net_buffer_pool *pool)
Definition: buffer_pool.c:191
enum m0_net_queue_type nb_qtype
Definition: net.h:1363
uint32_t ntm_recv_queue_max_recv_msgs
Definition: net.h:933
static void tm_provision_recv_q(struct m0_net_transfer_mc *tm)
Definition: tm_provision.c:445
uint32_t nb_max_receive_msgs
Definition: net.h:1502
#define m0_list_for_each_entry(head, pos, type, member)
Definition: list.h:235
#define M0_ASSERT(cond)
M0_INTERNAL bool m0_mutex_is_locked(const struct m0_mutex *mutex)
Definition: mutex.c:95
M0_INTERNAL bool m0_net_buffer_pool_is_not_locked(const struct m0_net_buffer_pool *pool)
Definition: buffer_pool.c:197
static struct m0_stob_domain * dom
Definition: storage.c:38
struct m0_atomic64 ntm_recv_queue_deficit
Definition: net.h:914
M0_INTERNAL void m0_net_buffer_pool_lock(struct m0_net_buffer_pool *pool)
Definition: buffer_pool.c:186
uint32_t ntm_callback_counter
Definition: net.h:850
struct m0_list_link ntm_dom_linkage
Definition: net.h:883
const struct m0_net_buffer_callbacks * nb_callbacks
Definition: net.h:1369
#define M0_POST(cond)
struct m0_tl ntm_q[M0_NET_QT_NR]
Definition: net.h:877
static struct m0_pool pool
Definition: iter_ut.c:58
static int64_t m0_atomic64_get(const struct m0_atomic64 *a)
#define M0_CNT_INC(cnt)
Definition: arith.h:226
M0_INTERNAL int m0_net__buffer_add(struct m0_net_buffer *buf, struct m0_net_transfer_mc *tm)
Definition: buf.c:130
M0_INTERNAL bool m0_net__tm_invariant(const struct m0_net_transfer_mc *tm)
Definition: tm.c:67
#define M0_CNT_DEC(cnt)
Definition: arith.h:219
uint32_t ntm_pool_colour
Definition: net.h:921
int32_t rc
Definition: trigger_fop.h:47
static void m0_atomic64_set(struct m0_atomic64 *a, int64_t num)
struct m0_net_end_point * nb_ep
Definition: net.h:1424
struct m0_net_buffer_pool * ntm_recv_pool
Definition: net.h:896