Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/drivers/infiniband/sw/rdmavt/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 7 kB image not shown  

Quelle  srq.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
 * Copyright(c) 2016 Intel Corporation.
 */


#include <linux/err.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <rdma/uverbs_ioctl.h>

#include "srq.h"
#include "vt.h"
#include "qp.h"
/**
 * rvt_driver_srq_init - init srq resources on a per driver basis
 * @rdi: rvt dev structure
 *
 * Do any initialization needed when a driver registers with rdmavt.
 */

void rvt_driver_srq_init(struct rvt_dev_info *rdi)
{
 spin_lock_init(&rdi->n_srqs_lock);
 rdi->n_srqs_allocated = 0;
}

/**
 * rvt_create_srq - create a shared receive queue
 * @ibsrq: the protection domain of the SRQ to create
 * @srq_init_attr: the attributes of the SRQ
 * @udata: data from libibverbs when creating a user SRQ
 *
 * Return: 0 on success
 */

int rvt_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *srq_init_attr,
     struct ib_udata *udata)
{
 struct rvt_dev_info *dev = ib_to_rvt(ibsrq->device);
 struct rvt_srq *srq = ibsrq_to_rvtsrq(ibsrq);
 u32 sz;
 int ret;

 if (srq_init_attr->srq_type != IB_SRQT_BASIC)
  return -EOPNOTSUPP;

 if (srq_init_attr->attr.max_sge == 0 ||
     srq_init_attr->attr.max_sge > dev->dparms.props.max_srq_sge ||
     srq_init_attr->attr.max_wr == 0 ||
     srq_init_attr->attr.max_wr > dev->dparms.props.max_srq_wr)
  return -EINVAL;

 /*
 * Need to use vmalloc() if we want to support large #s of entries.
 */

 srq->rq.size = srq_init_attr->attr.max_wr + 1;
 srq->rq.max_sge = srq_init_attr->attr.max_sge;
 sz = sizeof(struct ib_sge) * srq->rq.max_sge +
  sizeof(struct rvt_rwqe);
 if (rvt_alloc_rq(&srq->rq, srq->rq.size * sz,
    dev->dparms.node, udata)) {
  ret = -ENOMEM;
  goto bail_srq;
 }

 /*
 * Return the address of the RWQ as the offset to mmap.
 * See rvt_mmap() for details.
 */

 if (udata && udata->outlen >= sizeof(__u64)) {
  u32 s = sizeof(struct rvt_rwq) + srq->rq.size * sz;

  srq->ip = rvt_create_mmap_info(dev, s, udata, srq->rq.wq);
  if (IS_ERR(srq->ip)) {
   ret = PTR_ERR(srq->ip);
   goto bail_wq;
  }

  ret = ib_copy_to_udata(udata, &srq->ip->offset,
           sizeof(srq->ip->offset));
  if (ret)
   goto bail_ip;
 }

 /*
 * ib_create_srq() will initialize srq->ibsrq.
 */

 spin_lock_init(&srq->rq.lock);
 srq->limit = srq_init_attr->attr.srq_limit;

 spin_lock(&dev->n_srqs_lock);
 if (dev->n_srqs_allocated == dev->dparms.props.max_srq) {
  spin_unlock(&dev->n_srqs_lock);
  ret = -ENOMEM;
  goto bail_ip;
 }

 dev->n_srqs_allocated++;
 spin_unlock(&dev->n_srqs_lock);

 if (srq->ip) {
  spin_lock_irq(&dev->pending_lock);
  list_add(&srq->ip->pending_mmaps, &dev->pending_mmaps);
  spin_unlock_irq(&dev->pending_lock);
 }

 return 0;

bail_ip:
 kfree(srq->ip);
bail_wq:
 rvt_free_rq(&srq->rq);
bail_srq:
 return ret;
}

/**
 * rvt_modify_srq - modify a shared receive queue
 * @ibsrq: the SRQ to modify
 * @attr: the new attributes of the SRQ
 * @attr_mask: indicates which attributes to modify
 * @udata: user data for libibverbs.so
 *
 * Return: 0 on success
 */

int rvt_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
     enum ib_srq_attr_mask attr_mask,
     struct ib_udata *udata)
{
 struct rvt_srq *srq = ibsrq_to_rvtsrq(ibsrq);
 struct rvt_dev_info *dev = ib_to_rvt(ibsrq->device);
 struct rvt_rq tmp_rq = {};
 int ret = 0;

 if (attr_mask & IB_SRQ_MAX_WR) {
  struct rvt_krwq *okwq = NULL;
  struct rvt_rwq *owq = NULL;
  struct rvt_rwqe *p;
  u32 sz, size, n, head, tail;

  /* Check that the requested sizes are below the limits. */
  if ((attr->max_wr > dev->dparms.props.max_srq_wr) ||
      ((attr_mask & IB_SRQ_LIMIT) ?
       attr->srq_limit : srq->limit) > attr->max_wr)
   return -EINVAL;
  sz = sizeof(struct rvt_rwqe) +
   srq->rq.max_sge * sizeof(struct ib_sge);
  size = attr->max_wr + 1;
  if (rvt_alloc_rq(&tmp_rq, size * sz, dev->dparms.node,
     udata))
   return -ENOMEM;
  /* Check that we can write the offset to mmap. */
  if (udata && udata->inlen >= sizeof(__u64)) {
   __u64 offset_addr;
   __u64 offset = 0;

   ret = ib_copy_from_udata(&offset_addr, udata,
       sizeof(offset_addr));
   if (ret)
    goto bail_free;
   udata->outbuf = (void __user *)
     (unsigned long)offset_addr;
   ret = ib_copy_to_udata(udata, &offset,
            sizeof(offset));
   if (ret)
    goto bail_free;
  }

  spin_lock_irq(&srq->rq.kwq->c_lock);
  /*
 * validate head and tail pointer values and compute
 * the number of remaining WQEs.
 */

  if (udata) {
   owq = srq->rq.wq;
   head = RDMA_READ_UAPI_ATOMIC(owq->head);
   tail = RDMA_READ_UAPI_ATOMIC(owq->tail);
  } else {
   okwq = srq->rq.kwq;
   head = okwq->head;
   tail = okwq->tail;
  }
  if (head >= srq->rq.size || tail >= srq->rq.size) {
   ret = -EINVAL;
   goto bail_unlock;
  }
  n = head;
  if (n < tail)
   n += srq->rq.size - tail;
  else
   n -= tail;
  if (size <= n) {
   ret = -EINVAL;
   goto bail_unlock;
  }
  n = 0;
  p = tmp_rq.kwq->curr_wq;
  while (tail != head) {
   struct rvt_rwqe *wqe;
   int i;

   wqe = rvt_get_rwqe_ptr(&srq->rq, tail);
   p->wr_id = wqe->wr_id;
   p->num_sge = wqe->num_sge;
   for (i = 0; i < wqe->num_sge; i++)
    p->sg_list[i] = wqe->sg_list[i];
   n++;
   p = (struct rvt_rwqe *)((char *)p + sz);
   if (++tail >= srq->rq.size)
    tail = 0;
  }
  srq->rq.kwq = tmp_rq.kwq;
  if (udata) {
   srq->rq.wq = tmp_rq.wq;
   RDMA_WRITE_UAPI_ATOMIC(tmp_rq.wq->head, n);
   RDMA_WRITE_UAPI_ATOMIC(tmp_rq.wq->tail, 0);
  } else {
   tmp_rq.kwq->head = n;
   tmp_rq.kwq->tail = 0;
  }
  srq->rq.size = size;
  if (attr_mask & IB_SRQ_LIMIT)
   srq->limit = attr->srq_limit;
  spin_unlock_irq(&srq->rq.kwq->c_lock);

  vfree(owq);
  kvfree(okwq);

  if (srq->ip) {
   struct rvt_mmap_info *ip = srq->ip;
   struct rvt_dev_info *dev = ib_to_rvt(srq->ibsrq.device);
   u32 s = sizeof(struct rvt_rwq) + size * sz;

   rvt_update_mmap_info(dev, ip, s, tmp_rq.wq);

   /*
 * Return the offset to mmap.
 * See rvt_mmap() for details.
 */

   if (udata && udata->inlen >= sizeof(__u64)) {
    ret = ib_copy_to_udata(udata, &ip->offset,
             sizeof(ip->offset));
    if (ret)
     return ret;
   }

   /*
 * Put user mapping info onto the pending list
 * unless it already is on the list.
 */

   spin_lock_irq(&dev->pending_lock);
   if (list_empty(&ip->pending_mmaps))
    list_add(&ip->pending_mmaps,
      &dev->pending_mmaps);
   spin_unlock_irq(&dev->pending_lock);
  }
 } else if (attr_mask & IB_SRQ_LIMIT) {
  spin_lock_irq(&srq->rq.kwq->c_lock);
  if (attr->srq_limit >= srq->rq.size)
   ret = -EINVAL;
  else
   srq->limit = attr->srq_limit;
  spin_unlock_irq(&srq->rq.kwq->c_lock);
 }
 return ret;

bail_unlock:
 spin_unlock_irq(&srq->rq.kwq->c_lock);
bail_free:
 rvt_free_rq(&tmp_rq);
 return ret;
}

/**
 * rvt_query_srq - query srq data
 * @ibsrq: srq to query
 * @attr: return info in attr
 *
 * Return: always 0
 */

int rvt_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr)
{
 struct rvt_srq *srq = ibsrq_to_rvtsrq(ibsrq);

 attr->max_wr = srq->rq.size - 1;
 attr->max_sge = srq->rq.max_sge;
 attr->srq_limit = srq->limit;
 return 0;
}

/**
 * rvt_destroy_srq - destory an srq
 * @ibsrq: srq object to destroy
 * @udata: user data for libibverbs.so
 */

int rvt_destroy_srq(struct ib_srq *ibsrq, struct ib_udata *udata)
{
 struct rvt_srq *srq = ibsrq_to_rvtsrq(ibsrq);
 struct rvt_dev_info *dev = ib_to_rvt(ibsrq->device);

 spin_lock(&dev->n_srqs_lock);
 dev->n_srqs_allocated--;
 spin_unlock(&dev->n_srqs_lock);
 if (srq->ip)
  kref_put(&srq->ip->ref, rvt_release_mmap_info);
 kvfree(srq->rq.kwq);
 return 0;
}

Messung V0.5
C=92 H=93 G=92

¤ Dauer der Verarbeitung: 0.1 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.