#ifndef _PIO_H #define _PIO_H /* send context types */ #define SC_KERNEL 0 #define SC_VL15 1 #define SC_ACK 2 #define SC_USER 3 /* must be the last one: it may take all left */ #define SC_MAX 4 /* count of send context types */
/* invalid send context index */ #define INVALID_SCI 0xff
/* PIO buffer release callback function */ typedefvoid (*pio_release_cb)(void *arg, int code);
/* PIO release codes - in bits, as there could more than one that apply */ #define PRC_OK 0 /* no known error */ #define PRC_STATUS_ERR 0x01 /* credit return due to status error */ #define PRC_PBC 0x02 /* credit return due to PBC */ #define PRC_THRESHOLD 0x04 /* credit return due to threshold */ #define PRC_FILL_ERR 0x08 /* credit return due fill error */ #define PRC_FORCE 0x10 /* credit return due credit force */ #define PRC_SC_DISABLE 0x20 /* clean-up after a context disable */
/* an allocated PIO buffer */ struct pio_buf { struct send_context *sc;/* back pointer to owning send context */
pio_release_cb cb; /* called when the buffer is released */ void *arg; /* argument for cb */ void __iomem *start; /* buffer start address */ void __iomem *end; /* context end address */ unsignedlong sent_at; /* buffer is sent when <= free */ union mix carry; /* pending unwritten bytes */
u16 qw_written; /* QW written so far */
u8 carry_bytes; /* number of valid bytes in carry */
};
/* cache line aligned pio buffer array */ union pio_shadow_ring { struct pio_buf pbuf;
} ____cacheline_aligned;
/* per-NUMA send context */ struct send_context { /* read-only after init */ struct hfi1_devdata *dd; /* device */ union pio_shadow_ring *sr; /* shadow ring */ void __iomem *base_addr; /* start of PIO memory */
u32 __percpu *buffers_allocated;/* count of buffers allocated */
u32 size; /* context size, in bytes */
int node; /* context home node */
u32 sr_size; /* size of the shadow ring */
u16 flags; /* flags */
u8 type; /* context type */
u8 sw_index; /* software index number */
u8 hw_context; /* hardware context number */
u8 group; /* credit return group */
/* allocator fields */
spinlock_t alloc_lock ____cacheline_aligned_in_smp;
u32 sr_head; /* shadow ring head */ unsignedlong fill; /* official alloc count */ unsignedlong alloc_free; /* copy of free (less cache thrash) */
u32 fill_wrap; /* tracks fill within ring */
u32 credits; /* number of blocks in context */ /* adding a new field here would make it part of this cacheline */
/* releaser fields */
spinlock_t release_lock ____cacheline_aligned_in_smp;
u32 sr_tail; /* shadow ring tail */ unsignedlong free; /* official free count */ volatile __le64 *hw_free; /* HW free counter */ /* list for PIO waiters */ struct list_head piowait ____cacheline_aligned_in_smp;
seqlock_t waitlock;
spinlock_t credit_ctrl_lock ____cacheline_aligned_in_smp;
u32 credit_intr_count; /* count of credit intr users */
u64 credit_ctrl; /* cache for credit control */
wait_queue_head_t halt_wait; /* wait until kernel sees interrupt */ struct work_struct halt_work; /* halted context work queue entry */
};
struct send_context_info { struct send_context *sc; /* allocated working context */
u16 allocated; /* has this been allocated? */
u16 type; /* context type */
u16 base; /* base in PIO array */
u16 credits; /* size in PIO array */
};
/* DMA credit return, index is always (context & 0x7) */ struct credit_return { volatile __le64 cr[8];
};
/* * The diagram below details the relationship of the mapping structures * * Since the mapping now allows for non-uniform send contexts per vl, the * number of send contexts for a vl is either the vl_scontexts[vl] or * a computation based on num_kernel_send_contexts/num_vls: * * For example: * nactual = vl_scontexts ? vl_scontexts[vl] : num_kernel_send_contexts/num_vls * * n = roundup to next highest power of 2 using nactual * * In the case where there are num_kernel_send_contexts/num_vls doesn't divide * evenly, the extras are added from the last vl downward. * * For the case where n > nactual, the send contexts are assigned * in a round robin fashion wrapping back to the first send context * for a particular vl. * * dd->pio_map * | pio_map_elem[0] * | +--------------------+ * v | mask | * pio_vl_map |--------------------| * +--------------------------+ | ksc[0] -> sc 1 | * | list (RCU) | |--------------------| * |--------------------------| ->| ksc[1] -> sc 2 | * | mask | --/ |--------------------| * |--------------------------| -/ | * | * | actual_vls (max 8) | -/ |--------------------| * |--------------------------| --/ | ksc[n-1] -> sc n | * | vls (max 8) | -/ +--------------------+ * |--------------------------| --/ * | map[0] |-/ * |--------------------------| +--------------------+ * | map[1] |--- | mask | * |--------------------------| \---- |--------------------| * | * | \-- | ksc[0] -> sc 1+n | * | * | \---- |--------------------| * | * | \->| ksc[1] -> sc 2+n | * |--------------------------| |--------------------| * | map[vls - 1] |- | * | * +--------------------------+ \- |--------------------| * \- | ksc[m-1] -> sc m+n | * \ +--------------------+ * \- * \ * \- +----------------------+ * \- | mask | * \ |----------------------| * \- | ksc[0] -> sc 1+m+n | * \- |----------------------| * >| ksc[1] -> sc 2+m+n | * |----------------------| * | * | * |----------------------| * | ksc[o-1] -> sc o+m+n | * +----------------------+ *
*/
/* Initial number of send contexts per VL */ #define INIT_SC_PER_VL 2
/* * struct pio_map_elem - mapping for a vl * @mask - selector mask * @ksc - array of kernel send contexts for this vl * * The mask is used to "mod" the selector to * produce index into the trailing array of * kscs
*/ struct pio_map_elem {
u32 mask; struct send_context *ksc[];
};
/* * struct pio_vl_map - mapping for a vl * @list - rcu head for free callback * @mask - vl mask to "mod" the vl to produce an index to map array * @actual_vls - number of vls * @vls - numbers of vls rounded to next power of 2 * @map - array of pio_map_elem entries * * This is the parent mapping structure. The trailing members of the * struct point to pio_map_elem entries, which in turn point to an * array of kscs for that vl.
*/ struct pio_vl_map { struct rcu_head list;
u32 mask;
u8 actual_vls;
u8 vls; struct pio_map_elem *map[];
};
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.