Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/net/ethernet/mellanox/mlx5/core/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 4 kB image not shown  

Quelle  rdma.c   Sprache: C

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

#include <linux/mlx5/vport.h>
#include <rdma/ib_verbs.h>
#include <net/addrconf.h>

#include "lib/mlx5.h"
#include "eswitch.h"
#include "fs_core.h"
#include "rdma.h"

static void mlx5_rdma_disable_roce_steering(struct mlx5_core_dev *dev)
{
 struct mlx5_core_roce *roce = &dev->priv.roce;

 mlx5_del_flow_rules(roce->allow_rule);
 mlx5_destroy_flow_group(roce->fg);
 mlx5_destroy_flow_table(roce->ft);
}

static int mlx5_rdma_enable_roce_steering(struct mlx5_core_dev *dev)
{
 int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
 struct mlx5_core_roce *roce = &dev->priv.roce;
 struct mlx5_flow_handle *flow_rule = NULL;
 struct mlx5_flow_table_attr ft_attr = {};
 struct mlx5_flow_namespace *ns = NULL;
 struct mlx5_flow_act flow_act = {};
 struct mlx5_flow_spec *spec;
 struct mlx5_flow_table *ft;
 struct mlx5_flow_group *fg;
 struct mlx5_eswitch *esw;
 u32 *flow_group_in;
 int err;

 if (!(MLX5_CAP_FLOWTABLE_RDMA_RX(dev, ft_support) &&
       MLX5_CAP_FLOWTABLE_RDMA_RX(dev, table_miss_action_domain)))
  return -EOPNOTSUPP;

 flow_group_in = kvzalloc(inlen, GFP_KERNEL);
 if (!flow_group_in)
  return -ENOMEM;
 spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
 if (!spec) {
  kvfree(flow_group_in);
  return -ENOMEM;
 }

 ns = mlx5_get_flow_namespace(dev, MLX5_FLOW_NAMESPACE_RDMA_RX_KERNEL);
 if (!ns) {
  mlx5_core_err(dev, "Failed to get RDMA RX namespace");
  err = -EOPNOTSUPP;
  goto free;
 }

 ft_attr.max_fte = 1;
 ft = mlx5_create_flow_table(ns, &ft_attr);
 if (IS_ERR(ft)) {
  mlx5_core_err(dev, "Failed to create RDMA RX flow table");
  err = PTR_ERR(ft);
  goto free;
 }

 esw = dev->priv.eswitch;
 mlx5_esw_set_flow_group_source_port(esw, flow_group_in, 0);

 fg = mlx5_create_flow_group(ft, flow_group_in);
 if (IS_ERR(fg)) {
  err = PTR_ERR(fg);
  mlx5_core_err(dev, "Failed to create RDMA RX flow group err(%d)\n", err);
  goto destroy_flow_table;
 }

 mlx5_esw_set_spec_source_port(esw, esw->manager_vport, spec);

 flow_act.action = MLX5_FLOW_CONTEXT_ACTION_ALLOW;
 flow_rule = mlx5_add_flow_rules(ft, spec, &flow_act, NULL, 0);
 if (IS_ERR(flow_rule)) {
  err = PTR_ERR(flow_rule);
  mlx5_core_err(dev, "Failed to add RoCE allow rule, err=%d\n",
         err);
  goto destroy_flow_group;
 }

 kvfree(spec);
 kvfree(flow_group_in);
 roce->ft = ft;
 roce->fg = fg;
 roce->allow_rule = flow_rule;

 return 0;

destroy_flow_group:
 mlx5_destroy_flow_group(fg);
destroy_flow_table:
 mlx5_destroy_flow_table(ft);
free:
 kvfree(spec);
 kvfree(flow_group_in);
 return err;
}

static void mlx5_rdma_del_roce_addr(struct mlx5_core_dev *dev)
{
 mlx5_core_roce_gid_set(dev, 0, MLX5_ROCE_VERSION_2, 0,
          NULL, NULL, false, 0, 1);
}

static void mlx5_rdma_make_default_gid(struct mlx5_core_dev *dev, union ib_gid *gid)
{
 u8 hw_id[ETH_ALEN];

 mlx5_query_mac_address(dev, hw_id);
 gid->global.subnet_prefix = cpu_to_be64(0xfe80000000000000LL);
 addrconf_addr_eui48(&gid->raw[8], hw_id);
}

static int mlx5_rdma_add_roce_addr(struct mlx5_core_dev *dev)
{
 u8 mac[ETH_ALEN] = {};
 union ib_gid gid;

 mlx5_rdma_make_default_gid(dev, &gid);
 return mlx5_core_roce_gid_set(dev, 0,
          MLX5_ROCE_VERSION_2,
          0, gid.raw, mac,
          false, 0, 1);
}

void mlx5_rdma_disable_roce(struct mlx5_core_dev *dev)
{
 struct mlx5_core_roce *roce = &dev->priv.roce;

 if (!roce->ft)
  return;

 mlx5_rdma_disable_roce_steering(dev);
 mlx5_rdma_del_roce_addr(dev);
 mlx5_nic_vport_disable_roce(dev);
}

int mlx5_rdma_enable_roce(struct mlx5_core_dev *dev)
{
 int err;

 if (!MLX5_CAP_GEN(dev, roce))
  return 0;

 err = mlx5_nic_vport_enable_roce(dev);
 if (err) {
  mlx5_core_err(dev, "Failed to enable RoCE: %d\n", err);
  return err;
 }

 err = mlx5_rdma_add_roce_addr(dev);
 if (err) {
  mlx5_core_err(dev, "Failed to add RoCE address: %d\n", err);
  goto disable_roce;
 }

 err = mlx5_rdma_enable_roce_steering(dev);
 if (err) {
  mlx5_core_err(dev, "Failed to enable RoCE steering: %d\n", err);
  goto del_roce_addr;
 }

 return err;

del_roce_addr:
 mlx5_rdma_del_roce_addr(dev);
disable_roce:
 mlx5_nic_vport_disable_roce(dev);
 return err;
}

Messung V0.5
C=99 H=83 G=91

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© 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.