
/* SPDX-License-Identifier: Apache-2.0
 * Copyright (c) 2023 Cisco Systems, Inc.
 */

#include "vppinfra/bitmap.h"
#include "vppinfra/lock.h"
#include <vnet/vnet.h>
#include <vnet/dev/dev.h>
#include <vnet/dev/log.h>

VLIB_REGISTER_LOG_CLASS (dev_log, static) = {
  .class_name = "dev",
  .subclass_name = "runtime",
};

static vnet_dev_rt_op_t *rt_ops;

static void
_vnet_dev_rt_exec_op (vlib_main_t *vm, vnet_dev_rt_op_t *op)
{
  vnet_dev_port_t *port = op->port;
  vnet_dev_rx_queue_t *previous = 0, *first = 0;
  vnet_dev_rx_node_runtime_t *rtd;
  vlib_node_state_t state = VLIB_NODE_STATE_DISABLED;
  u32 node_index = port->intf.rx_node_index;

  rtd = vlib_node_get_runtime_data (vm, node_index);

  foreach_vnet_dev_port_rx_queue (q, port)
    {
      if (q->rx_thread_index != vm->thread_index)
	continue;

      if (q->interrupt_mode == 0)
	state = VLIB_NODE_STATE_POLLING;
      else if (state != VLIB_NODE_STATE_POLLING)
	state = VLIB_NODE_STATE_INTERRUPT;

      q->next_on_thread = 0;
      if (previous == 0)
	first = q;
      else
	previous->next_on_thread = q;

      previous = q;
    }

  rtd->first_rx_queue = first;
  vlib_node_set_state (vm, port->intf.rx_node_index, state);
  __atomic_store_n (&op->completed, 1, __ATOMIC_RELEASE);
}

static uword
vnet_dev_rt_mgmt_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
			  vlib_frame_t *frame)
{
  u16 thread_index = vm->thread_index;
  vnet_dev_rt_op_t *op, *ops = __atomic_load_n (&rt_ops, __ATOMIC_ACQUIRE);
  u32 n_pending = 0;
  uword rv = 0;

  vec_foreach (op, ops)
    {
      if (!op->completed && op->thread_index == thread_index)
	{
	  if (op->in_order == 1 && n_pending)
	    {
	      vlib_node_set_interrupt_pending (vm, node->node_index);
	      return rv;
	    }
	  _vnet_dev_rt_exec_op (vm, op);
	  rv++;
	}

      if (op->completed == 0)
	n_pending++;
    }

  return rv;
}

VLIB_REGISTER_NODE (vnet_dev_rt_mgmt_node, static) = {
  .function = vnet_dev_rt_mgmt_node_fn,
  .name = "dev-rt-mgmt",
  .type = VLIB_NODE_TYPE_PRE_INPUT,
  .state = VLIB_NODE_STATE_INTERRUPT,
};

vnet_dev_rv_t
vnet_dev_rt_exec_ops (vlib_main_t *vm, vnet_dev_t *dev, vnet_dev_rt_op_t *ops,
		      u32 n_ops)
{
  vnet_dev_rt_op_t *op = ops;
  vnet_dev_rt_op_t *remote_ops = 0;
  clib_bitmap_t *remote_bmp = 0;
  u32 i;

  ASSERT (rt_ops == 0);

  if (vlib_worker_thread_barrier_held ())
    {
      for (op = ops; op < (ops + n_ops); op++)
	{
	  vlib_main_t *tvm = vlib_get_main_by_index (op->thread_index);
	  _vnet_dev_rt_exec_op (tvm, op);
	  log_debug (
	    dev,
	    "port %u rx node runtime update on thread %u executed locally",
	    op->port->port_id, op->thread_index);
	}
      return VNET_DEV_OK;
    }

  while (n_ops)
    {
      if (op->thread_index != vm->thread_index)
	break;

      _vnet_dev_rt_exec_op (vm, op);
      log_debug (
	dev, "port %u rx node runtime update on thread %u executed locally",
	op->port->port_id, op->thread_index);
      op++;
      n_ops--;
    }

  if (n_ops == 0)
    return VNET_DEV_OK;

  for (op = ops; op < (ops + n_ops); op++)
    {
      if (op->thread_index == vm->thread_index &&
	  (op->in_order == 0 || vec_len (remote_ops) == 0))
	{
	  _vnet_dev_rt_exec_op (vm, op);
	  log_debug (dev,
		     "port %u rx node runtime update on thread "
		     "%u executed locally",
		     op->port->port_id, op->thread_index);
	}
      else
	{
	  vec_add1 (remote_ops, *op);
	  log_debug (dev,
		     "port %u rx node runtime update on thread %u "
		     "enqueued for remote execution",
		     op->port->port_id, op->thread_index);
	  remote_bmp = clib_bitmap_set (remote_bmp, op->thread_index, 1);
	}
    }

  if (remote_ops == 0)
    return VNET_DEV_OK;

  __atomic_store_n (&rt_ops, remote_ops, __ATOMIC_RELEASE);

  clib_bitmap_foreach (i, remote_bmp)
    {
      vlib_node_set_interrupt_pending (vlib_get_main_by_index (i),
				       vnet_dev_rt_mgmt_node.index);
      log_debug (dev, "interrupt sent to %s node on thread %u",
		 vnet_dev_rt_mgmt_node.name, i);
    }

  vec_foreach (op, remote_ops)
    {
      while (op->completed == 0)
	vlib_process_suspend (vm, 5e-5);

      log_debug (
	dev, "port %u rx node runtime update on thread %u executed locally",
	op->port->port_id, op->thread_index);
    }

  __atomic_store_n (&rt_ops, 0, __ATOMIC_RELAXED);
  vec_free (remote_ops);
  clib_bitmap_free (remote_bmp);
  return VNET_DEV_OK;
}
