Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  vhca_event.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
/* Copyright (c) 2020 Mellanox Technologies Ltd */

#include <linux/mlx5/driver.h>
#include "mlx5_ifc_vhca_event.h"
#include "mlx5_core.h"
#include "vhca_event.h"
#include "ecpf.h"
#define CREATE_TRACE_POINTS
#include "diag/vhca_tracepoint.h"

struct mlx5_vhca_state_notifier {
 struct mlx5_core_dev *dev;
 struct mlx5_nb nb;
 struct blocking_notifier_head n_head;
};

struct mlx5_vhca_event_work {
 struct work_struct work;
 struct mlx5_vhca_state_notifier *notifier;
 struct mlx5_vhca_state_event event;
};

struct mlx5_vhca_event_handler {
 struct workqueue_struct *wq;
};

struct mlx5_vhca_events {
 struct mlx5_core_dev *dev;
 struct mlx5_vhca_event_handler handler[MLX5_DEV_MAX_WQS];
};

int mlx5_cmd_query_vhca_state(struct mlx5_core_dev *dev, u16 function_id, u32 *out, u32 outlen)
{
 u32 in[MLX5_ST_SZ_DW(query_vhca_state_in)] = {};

 MLX5_SET(query_vhca_state_in, in, opcode, MLX5_CMD_OP_QUERY_VHCA_STATE);
 MLX5_SET(query_vhca_state_in, in, function_id, function_id);
 MLX5_SET(query_vhca_state_in, in, embedded_cpu_function, 0);

 return mlx5_cmd_exec(dev, in, sizeof(in), out, outlen);
}

static int mlx5_cmd_modify_vhca_state(struct mlx5_core_dev *dev, u16 function_id,
          u32 *in, u32 inlen)
{
 u32 out[MLX5_ST_SZ_DW(modify_vhca_state_out)] = {};

 MLX5_SET(modify_vhca_state_in, in, opcode, MLX5_CMD_OP_MODIFY_VHCA_STATE);
 MLX5_SET(modify_vhca_state_in, in, function_id, function_id);
 MLX5_SET(modify_vhca_state_in, in, embedded_cpu_function, 0);

 return mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
}

int mlx5_modify_vhca_sw_id(struct mlx5_core_dev *dev, u16 function_id, u32 sw_fn_id)
{
 u32 out[MLX5_ST_SZ_DW(modify_vhca_state_out)] = {};
 u32 in[MLX5_ST_SZ_DW(modify_vhca_state_in)] = {};

 MLX5_SET(modify_vhca_state_in, in, opcode, MLX5_CMD_OP_MODIFY_VHCA_STATE);
 MLX5_SET(modify_vhca_state_in, in, function_id, function_id);
 MLX5_SET(modify_vhca_state_in, in, embedded_cpu_function, 0);
 MLX5_SET(modify_vhca_state_in, in, vhca_state_field_select.sw_function_id, 1);
 MLX5_SET(modify_vhca_state_in, in, vhca_state_context.sw_function_id, sw_fn_id);

 return mlx5_cmd_exec_inout(dev, modify_vhca_state, in, out);
}

int mlx5_vhca_event_arm(struct mlx5_core_dev *dev, u16 function_id)
{
 u32 in[MLX5_ST_SZ_DW(modify_vhca_state_in)] = {};

 MLX5_SET(modify_vhca_state_in, in, vhca_state_context.arm_change_event, 1);
 MLX5_SET(modify_vhca_state_in, in, vhca_state_field_select.arm_change_event, 1);

 return mlx5_cmd_modify_vhca_state(dev, function_id, in, sizeof(in));
}

static void
mlx5_vhca_event_notify(struct mlx5_core_dev *dev, struct mlx5_vhca_state_event *event)
{
 u32 out[MLX5_ST_SZ_DW(query_vhca_state_out)] = {};
 int err;

 err = mlx5_cmd_query_vhca_state(dev, event->function_id, out, sizeof(out));
 if (err)
  return;

 event->sw_function_id = MLX5_GET(query_vhca_state_out, out,
      vhca_state_context.sw_function_id);
 event->new_vhca_state = MLX5_GET(query_vhca_state_out, out,
      vhca_state_context.vhca_state);

 mlx5_vhca_event_arm(dev, event->function_id);
 trace_mlx5_sf_vhca_event(dev, event);

 blocking_notifier_call_chain(&dev->priv.vhca_state_notifier->n_head, 0, event);
}

static void mlx5_vhca_state_work_handler(struct work_struct *_work)
{
 struct mlx5_vhca_event_work *work = container_of(_work, struct mlx5_vhca_event_work, work);
 struct mlx5_vhca_state_notifier *notifier = work->notifier;
 struct mlx5_core_dev *dev = notifier->dev;

 mlx5_vhca_event_notify(dev, &work->event);
 kfree(work);
}

void mlx5_vhca_events_work_enqueue(struct mlx5_core_dev *dev, int idx, struct work_struct *work)
{
 queue_work(dev->priv.vhca_events->handler[idx].wq, work);
}

static int
mlx5_vhca_state_change_notifier(struct notifier_block *nb, unsigned long type, void *data)
{
 struct mlx5_vhca_state_notifier *notifier =
    mlx5_nb_cof(nb, struct mlx5_vhca_state_notifier, nb);
 struct mlx5_vhca_event_work *work;
 struct mlx5_eqe *eqe = data;
 int wq_idx;

 work = kzalloc(sizeof(*work), GFP_ATOMIC);
 if (!work)
  return NOTIFY_DONE;
 INIT_WORK(&work->work, &mlx5_vhca_state_work_handler);
 work->notifier = notifier;
 work->event.function_id = be16_to_cpu(eqe->data.vhca_state.function_id);
 wq_idx = work->event.function_id % MLX5_DEV_MAX_WQS;
 mlx5_vhca_events_work_enqueue(notifier->dev, wq_idx, &work->work);
 return NOTIFY_OK;
}

void mlx5_vhca_state_cap_handle(struct mlx5_core_dev *dev, void *set_hca_cap)
{
 if (!mlx5_vhca_event_supported(dev))
  return;

 MLX5_SET(cmd_hca_cap, set_hca_cap, vhca_state, 1);
 MLX5_SET(cmd_hca_cap, set_hca_cap, event_on_vhca_state_allocated, 1);
 MLX5_SET(cmd_hca_cap, set_hca_cap, event_on_vhca_state_active, 1);
 MLX5_SET(cmd_hca_cap, set_hca_cap, event_on_vhca_state_in_use, 1);
 MLX5_SET(cmd_hca_cap, set_hca_cap, event_on_vhca_state_teardown_request, 1);
}

int mlx5_vhca_event_init(struct mlx5_core_dev *dev)
{
 struct mlx5_vhca_state_notifier *notifier;
 char wq_name[MLX5_CMD_WQ_MAX_NAME];
 struct mlx5_vhca_events *events;
 int err, i;

 if (!mlx5_vhca_event_supported(dev))
  return 0;

 events = kzalloc(sizeof(*events), GFP_KERNEL);
 if (!events)
  return -ENOMEM;

 events->dev = dev;
 dev->priv.vhca_events = events;
 for (i = 0; i < MLX5_DEV_MAX_WQS; i++) {
  snprintf(wq_name, MLX5_CMD_WQ_MAX_NAME, "mlx5_vhca_event%d", i);
  events->handler[i].wq = create_singlethread_workqueue(wq_name);
  if (!events->handler[i].wq) {
   err = -ENOMEM;
   goto err_create_wq;
  }
 }

 notifier = kzalloc(sizeof(*notifier), GFP_KERNEL);
 if (!notifier) {
  err = -ENOMEM;
  goto err_notifier;
 }

 dev->priv.vhca_state_notifier = notifier;
 notifier->dev = dev;
 BLOCKING_INIT_NOTIFIER_HEAD(¬ifier->n_head);
 MLX5_NB_INIT(¬ifier->nb, mlx5_vhca_state_change_notifier, VHCA_STATE_CHANGE);
 return 0;

err_notifier:
err_create_wq:
 for (--i; i >= 0; i--)
  destroy_workqueue(events->handler[i].wq);
 kfree(events);
 return err;
}

void mlx5_vhca_event_work_queues_flush(struct mlx5_core_dev *dev)
{
 struct mlx5_vhca_events *vhca_events;
 int i;

 if (!mlx5_vhca_event_supported(dev))
  return;

 vhca_events = dev->priv.vhca_events;
 for (i = 0; i < MLX5_DEV_MAX_WQS; i++)
  flush_workqueue(vhca_events->handler[i].wq);
}

void mlx5_vhca_event_cleanup(struct mlx5_core_dev *dev)
{
 struct mlx5_vhca_events *vhca_events;
 int i;

 if (!mlx5_vhca_event_supported(dev))
  return;

 kfree(dev->priv.vhca_state_notifier);
 dev->priv.vhca_state_notifier = NULL;
 vhca_events = dev->priv.vhca_events;
 for (i = 0; i < MLX5_DEV_MAX_WQS; i++)
  destroy_workqueue(vhca_events->handler[i].wq);
 kvfree(vhca_events);
}

void mlx5_vhca_event_start(struct mlx5_core_dev *dev)
{
 struct mlx5_vhca_state_notifier *notifier;

 if (!dev->priv.vhca_state_notifier)
  return;

 notifier = dev->priv.vhca_state_notifier;
 mlx5_eq_notifier_register(dev, ¬ifier->nb);
}

void mlx5_vhca_event_stop(struct mlx5_core_dev *dev)
{
 struct mlx5_vhca_state_notifier *notifier;

 if (!dev->priv.vhca_state_notifier)
  return;

 notifier = dev->priv.vhca_state_notifier;
 mlx5_eq_notifier_unregister(dev, ¬ifier->nb);
}

int mlx5_vhca_event_notifier_register(struct mlx5_core_dev *dev, struct notifier_block *nb)
{
 if (!dev->priv.vhca_state_notifier)
  return -EOPNOTSUPP;
 return blocking_notifier_chain_register(&dev->priv.vhca_state_notifier->n_head, nb);
}

void mlx5_vhca_event_notifier_unregister(struct mlx5_core_dev *dev, struct notifier_block *nb)
{
 blocking_notifier_chain_unregister(&dev->priv.vhca_state_notifier->n_head, nb);
}

Messung V0.5
C=99 H=89 G=94

¤ Dauer der Verarbeitung: 0.0 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge