david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[arbel] Optimise ICM layout to reduce overall memory usage

Reduce the amount of ICM space required by choosing to order the
various allocations in approximately descending order of alignment
requirements.

This saves approximately 512kB of host memory.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown 2010-09-17 20:53:29 +01:00
parent d84e4e0575
commit 144a23a852
2 changed files with 150 additions and 89 deletions

View File

@ -2076,7 +2076,6 @@ static int arbel_get_limits ( struct arbel *arbel ) {
arbel->limits.reserved_cqs =
( 1 << MLX_GET ( &dev_lim, log2_rsvd_cqs ) );
arbel->limits.cqc_entry_size = MLX_GET ( &dev_lim, cqc_entry_sz );
arbel->limits.reserved_eqs = MLX_GET ( &dev_lim, num_rsvd_eqs );
arbel->limits.reserved_mtts =
( 1 << MLX_GET ( &dev_lim, log2_rsvd_mtts ) );
arbel->limits.mtt_entry_size = MLX_GET ( &dev_lim, mtt_entry_sz );
@ -2085,8 +2084,33 @@ static int arbel_get_limits ( struct arbel *arbel ) {
arbel->limits.mpt_entry_size = MLX_GET ( &dev_lim, mpt_entry_sz );
arbel->limits.reserved_rdbs =
( 1 << MLX_GET ( &dev_lim, log2_rsvd_rdbs ) );
arbel->limits.reserved_eqs = MLX_GET ( &dev_lim, num_rsvd_eqs );
arbel->limits.eqc_entry_size = MLX_GET ( &dev_lim, eqc_entry_sz );
arbel->limits.reserved_uars = MLX_GET ( &dev_lim, num_rsvd_uars );
arbel->limits.uar_scratch_entry_size =
MLX_GET ( &dev_lim, uar_scratch_entry_sz );
DBGC ( arbel, "Arbel %p reserves %d x %#zx QPC, %d x %#zx EQPC, "
"%d x %#zx SRQC\n", arbel,
arbel->limits.reserved_qps, arbel->limits.qpc_entry_size,
arbel->limits.reserved_qps, arbel->limits.eqpc_entry_size,
arbel->limits.reserved_srqs, arbel->limits.srqc_entry_size );
DBGC ( arbel, "Arbel %p reserves %d x %#zx EEC, %d x %#zx EEEC, "
"%d x %#zx CQC\n", arbel,
arbel->limits.reserved_ees, arbel->limits.eec_entry_size,
arbel->limits.reserved_ees, arbel->limits.eeec_entry_size,
arbel->limits.reserved_cqs, arbel->limits.cqc_entry_size );
DBGC ( arbel, "Arbel %p reserves %d x %#zx EQC, %d x %#zx MTT, "
"%d x %#zx MPT\n", arbel,
arbel->limits.reserved_eqs, arbel->limits.eqc_entry_size,
arbel->limits.reserved_mtts, arbel->limits.mtt_entry_size,
arbel->limits.reserved_mrws, arbel->limits.mpt_entry_size );
DBGC ( arbel, "Arbel %p reserves %d x %#zx RDB, %d x %#zx UAR, "
"%d x %#zx UAR scratchpad\n", arbel,
arbel->limits.reserved_rdbs, ARBEL_RDB_ENTRY_SIZE,
arbel->limits.reserved_uars, ARBEL_PAGE_SIZE,
arbel->limits.reserved_uars,
arbel->limits.uar_scratch_entry_size );
return 0;
}
@ -2120,14 +2144,13 @@ static int arbel_alloc_icm ( struct arbel *arbel,
struct arbelprm_virtual_physical_mapping map_icm;
union arbelprm_doorbell_record *db_rec;
size_t icm_offset = 0;
unsigned int log_num_qps, log_num_srqs, log_num_ees, log_num_cqs;
unsigned int log_num_mtts, log_num_mpts, log_num_rdbs, log_num_eqs;
unsigned int log_num_mcs;
unsigned int log_num_uars, log_num_qps, log_num_srqs, log_num_ees;
unsigned int log_num_cqs, log_num_mtts, log_num_mpts, log_num_rdbs;
unsigned int log_num_eqs, log_num_mcs;
size_t db_rec_offset;
size_t len;
int rc;
icm_offset = ( ( arbel->limits.reserved_uars + 1 ) << 12 );
/* Queue pair contexts */
log_num_qps = fls ( arbel->limits.reserved_qps +
ARBEL_RSVD_SPECIAL_QPS + ARBEL_MAX_QPS - 1 );
@ -2138,8 +2161,9 @@ static int arbel_alloc_icm ( struct arbel *arbel,
( icm_offset >> 7 ),
qpc_eec_cqc_eqc_rdb_parameters.log_num_of_qp,
log_num_qps );
DBGC ( arbel, "Arbel %p ICM QPC at [%zx,%zx)\n",
arbel, icm_offset, ( icm_offset + len ) );
DBGC ( arbel, "Arbel %p ICM QPC is %d x %#zx at [%zx,%zx)\n",
arbel, ( 1 << log_num_qps ), arbel->limits.qpc_entry_size,
icm_offset, ( icm_offset + len ) );
icm_offset += len;
/* Extended queue pair contexts */
@ -2148,44 +2172,9 @@ static int arbel_alloc_icm ( struct arbel *arbel,
MLX_FILL_1 ( init_hca, 25,
qpc_eec_cqc_eqc_rdb_parameters.eqpc_base_addr_l,
icm_offset );
DBGC ( arbel, "Arbel %p ICM EQPC at [%zx,%zx)\n",
arbel, icm_offset, ( icm_offset + len ) );
icm_offset += len;
/* Shared receive queue contexts */
log_num_srqs = fls ( arbel->limits.reserved_srqs - 1 );
len = ( ( 1 << log_num_srqs ) * arbel->limits.srqc_entry_size );
icm_offset = icm_align ( icm_offset, len );
MLX_FILL_2 ( init_hca, 19,
qpc_eec_cqc_eqc_rdb_parameters.srqc_base_addr_l,
( icm_offset >> 5 ),
qpc_eec_cqc_eqc_rdb_parameters.log_num_of_srq,
log_num_srqs );
DBGC ( arbel, "Arbel %p ICM SRQC at [%zx,%zx)\n",
arbel, icm_offset, ( icm_offset + len ) );
icm_offset += len;
/* End-to-end contexts */
log_num_ees = fls ( arbel->limits.reserved_ees - 1 );
len = ( ( 1 << log_num_ees ) * arbel->limits.eec_entry_size );
icm_offset = icm_align ( icm_offset, len );
MLX_FILL_2 ( init_hca, 17,
qpc_eec_cqc_eqc_rdb_parameters.eec_base_addr_l,
( icm_offset >> 7 ),
qpc_eec_cqc_eqc_rdb_parameters.log_num_of_ee,
log_num_ees );
DBGC ( arbel, "Arbel %p ICM EEC at [%zx,%zx)\n",
arbel, icm_offset, ( icm_offset + len ) );
icm_offset += len;
/* Extended end-to-end contexts */
len = ( ( 1 << log_num_ees ) * arbel->limits.eeec_entry_size );
icm_offset = icm_align ( icm_offset, len );
MLX_FILL_1 ( init_hca, 29,
qpc_eec_cqc_eqc_rdb_parameters.eeec_base_addr_l,
icm_offset );
DBGC ( arbel, "Arbel %p ICM EEEC at [%zx,%zx)\n",
arbel, icm_offset, ( icm_offset + len ) );
DBGC ( arbel, "Arbel %p ICM EQPC is %d x %#zx at [%zx,%zx)\n",
arbel, ( 1 << log_num_qps ), arbel->limits.eqpc_entry_size,
icm_offset, ( icm_offset + len ) );
icm_offset += len;
/* Completion queue contexts */
@ -2197,41 +2186,25 @@ static int arbel_alloc_icm ( struct arbel *arbel,
( icm_offset >> 6 ),
qpc_eec_cqc_eqc_rdb_parameters.log_num_of_cq,
log_num_cqs );
DBGC ( arbel, "Arbel %p ICM CQC at [%zx,%zx)\n",
arbel, icm_offset, ( icm_offset + len ) );
DBGC ( arbel, "Arbel %p ICM CQC is %d x %#zx at [%zx,%zx)\n",
arbel, ( 1 << log_num_cqs ), arbel->limits.cqc_entry_size,
icm_offset, ( icm_offset + len ) );
icm_offset += len;
/* Memory translation table */
log_num_mtts = fls ( arbel->limits.reserved_mtts - 1 );
len = ( ( 1 << log_num_mtts ) * arbel->limits.mtt_entry_size );
/* User access region contexts */
log_num_uars = fls ( arbel->limits.reserved_uars +
1 /* single UAR used */ - 1 );
len = ( ( 1 << log_num_uars ) * ARBEL_PAGE_SIZE );
icm_offset = icm_align ( icm_offset, len );
MLX_FILL_1 ( init_hca, 65,
tpt_parameters.mtt_base_addr_l, icm_offset );
DBGC ( arbel, "Arbel %p ICM MTT at [%zx,%zx)\n",
arbel, icm_offset, ( icm_offset + len ) );
icm_offset += len;
/* Memory protection table */
log_num_mpts = fls ( arbel->limits.reserved_mrws + 1 - 1 );
len = ( ( 1 << log_num_mpts ) * arbel->limits.mpt_entry_size );
icm_offset = icm_align ( icm_offset, len );
MLX_FILL_1 ( init_hca, 61,
tpt_parameters.mpt_base_adr_l, icm_offset );
MLX_FILL_1 ( init_hca, 62,
tpt_parameters.log_mpt_sz, log_num_mpts );
DBGC ( arbel, "Arbel %p ICM MTT at [%zx,%zx)\n",
arbel, icm_offset, ( icm_offset + len ) );
icm_offset += len;
/* Remote read data base table */
log_num_rdbs = fls ( arbel->limits.reserved_rdbs - 1 );
len = ( ( 1 << log_num_rdbs ) * ARBEL_RDB_ENTRY_SIZE );
icm_offset = icm_align ( icm_offset, len );
MLX_FILL_1 ( init_hca, 37,
qpc_eec_cqc_eqc_rdb_parameters.rdb_base_addr_l,
icm_offset );
DBGC ( arbel, "Arbel %p ICM RDB at [%zx,%zx)\n",
arbel, icm_offset, ( icm_offset + len ) );
MLX_FILL_1 ( init_hca, 74, uar_parameters.log_max_uars, log_num_uars );
MLX_FILL_1 ( init_hca, 79,
uar_parameters.uar_context_base_addr_l, icm_offset );
db_rec_offset = ( icm_offset +
( arbel->limits.reserved_uars * ARBEL_PAGE_SIZE ) );
DBGC ( arbel, "Arbel %p UAR is %d x %#zx at [%zx,%zx), doorbells "
"[%zx,%zx)\n", arbel, ( 1 << log_num_uars ), ARBEL_PAGE_SIZE,
icm_offset, ( icm_offset + len ), db_rec_offset,
( db_rec_offset + ARBEL_PAGE_SIZE ) );
icm_offset += len;
/* Event queue contexts */
@ -2243,8 +2216,73 @@ static int arbel_alloc_icm ( struct arbel *arbel,
( icm_offset >> 6 ),
qpc_eec_cqc_eqc_rdb_parameters.log_num_eq,
log_num_eqs );
DBGC ( arbel, "Arbel %p ICM EQ at [%zx,%zx)\n",
arbel, icm_offset, ( icm_offset + len ) );
DBGC ( arbel, "Arbel %p ICM EQC is %d x %#zx at [%zx,%zx)\n",
arbel, ( 1 << log_num_eqs ), arbel->limits.eqc_entry_size,
icm_offset, ( icm_offset + len ) );
icm_offset += len;
/* End-to-end contexts */
log_num_ees = fls ( arbel->limits.reserved_ees - 1 );
len = ( ( 1 << log_num_ees ) * arbel->limits.eec_entry_size );
icm_offset = icm_align ( icm_offset, len );
MLX_FILL_2 ( init_hca, 17,
qpc_eec_cqc_eqc_rdb_parameters.eec_base_addr_l,
( icm_offset >> 7 ),
qpc_eec_cqc_eqc_rdb_parameters.log_num_of_ee,
log_num_ees );
DBGC ( arbel, "Arbel %p ICM EEC is %d x %#zx at [%zx,%zx)\n",
arbel, ( 1 << log_num_ees ), arbel->limits.eec_entry_size,
icm_offset, ( icm_offset + len ) );
icm_offset += len;
/* Shared receive queue contexts */
log_num_srqs = fls ( arbel->limits.reserved_srqs - 1 );
len = ( ( 1 << log_num_srqs ) * arbel->limits.srqc_entry_size );
icm_offset = icm_align ( icm_offset, len );
MLX_FILL_2 ( init_hca, 19,
qpc_eec_cqc_eqc_rdb_parameters.srqc_base_addr_l,
( icm_offset >> 5 ),
qpc_eec_cqc_eqc_rdb_parameters.log_num_of_srq,
log_num_srqs );
DBGC ( arbel, "Arbel %p ICM SRQC is %d x %#zx at [%zx,%zx)\n",
arbel, ( 1 << log_num_srqs ), arbel->limits.srqc_entry_size,
icm_offset, ( icm_offset + len ) );
icm_offset += len;
/* Memory protection table */
log_num_mpts = fls ( arbel->limits.reserved_mrws + 1 - 1 );
len = ( ( 1 << log_num_mpts ) * arbel->limits.mpt_entry_size );
icm_offset = icm_align ( icm_offset, len );
MLX_FILL_1 ( init_hca, 61,
tpt_parameters.mpt_base_adr_l, icm_offset );
MLX_FILL_1 ( init_hca, 62,
tpt_parameters.log_mpt_sz, log_num_mpts );
DBGC ( arbel, "Arbel %p ICM MPT is %d x %#zx at [%zx,%zx)\n",
arbel, ( 1 << log_num_mpts ), arbel->limits.mpt_entry_size,
icm_offset, ( icm_offset + len ) );
icm_offset += len;
/* Remote read data base table */
log_num_rdbs = fls ( arbel->limits.reserved_rdbs - 1 );
len = ( ( 1 << log_num_rdbs ) * ARBEL_RDB_ENTRY_SIZE );
icm_offset = icm_align ( icm_offset, len );
MLX_FILL_1 ( init_hca, 37,
qpc_eec_cqc_eqc_rdb_parameters.rdb_base_addr_l,
icm_offset );
DBGC ( arbel, "Arbel %p ICM RDB is %d x %#zx at [%zx,%zx)\n",
arbel, ( 1 << log_num_rdbs ), ARBEL_RDB_ENTRY_SIZE,
icm_offset, ( icm_offset + len ) );
icm_offset += len;
/* Extended end-to-end contexts */
len = ( ( 1 << log_num_ees ) * arbel->limits.eeec_entry_size );
icm_offset = icm_align ( icm_offset, len );
MLX_FILL_1 ( init_hca, 29,
qpc_eec_cqc_eqc_rdb_parameters.eeec_base_addr_l,
icm_offset );
DBGC ( arbel, "Arbel %p ICM EEEC is %d x %#zx at [%zx,%zx)\n",
arbel, ( 1 << log_num_ees ), arbel->limits.eeec_entry_size,
icm_offset, ( icm_offset + len ) );
icm_offset += len;
/* Multicast table */
@ -2262,8 +2300,31 @@ static int arbel_alloc_icm ( struct arbel *arbel,
MLX_FILL_1 ( init_hca, 54,
multicast_parameters.log_mc_table_sz,
log_num_mcs /* Only one entry per hash */ );
DBGC ( arbel, "Arbel %p ICM MC at [%zx,%zx)\n",
arbel, icm_offset, ( icm_offset + len ) );
DBGC ( arbel, "Arbel %p ICM MC is %d x %#zx at [%zx,%zx)\n", arbel,
( 1 << log_num_mcs ), sizeof ( struct arbelprm_mgm_entry ),
icm_offset, ( icm_offset + len ) );
icm_offset += len;
/* Memory translation table */
log_num_mtts = fls ( arbel->limits.reserved_mtts - 1 );
len = ( ( 1 << log_num_mtts ) * arbel->limits.mtt_entry_size );
icm_offset = icm_align ( icm_offset, len );
MLX_FILL_1 ( init_hca, 65,
tpt_parameters.mtt_base_addr_l, icm_offset );
DBGC ( arbel, "Arbel %p ICM MTT is %d x %#zx at [%zx,%zx)\n",
arbel, ( 1 << log_num_mtts ), arbel->limits.mtt_entry_size,
icm_offset, ( icm_offset + len ) );
icm_offset += len;
/* User access region scratchpads */
len = ( ( 1 << log_num_uars ) * arbel->limits.uar_scratch_entry_size );
icm_offset = icm_align ( icm_offset, len );
MLX_FILL_1 ( init_hca, 77,
uar_parameters.uar_scratch_base_addr_l, icm_offset );
DBGC ( arbel, "Arbel %p UAR scratchpad is %d x %#zx at [%zx,%zx)\n",
arbel, ( 1 << log_num_uars ),
arbel->limits.uar_scratch_entry_size,
icm_offset, ( icm_offset + len ) );
icm_offset += len;
/* Round up to a whole number of pages */
@ -2316,10 +2377,9 @@ static int arbel_alloc_icm ( struct arbel *arbel,
goto err_map_icm;
}
/* Initialise UAR context */
arbel->db_rec = phys_to_virt ( user_to_phys ( arbel->icm, 0 ) +
( arbel->limits.reserved_uars *
ARBEL_PAGE_SIZE ) );
/* Initialise doorbell records */
arbel->db_rec =
phys_to_virt ( user_to_phys ( arbel->icm, db_rec_offset ) );
memset ( arbel->db_rec, 0, ARBEL_PAGE_SIZE );
db_rec = &arbel->db_rec[ARBEL_GROUP_SEPARATOR_DOORBELL];
MLX_FILL_1 ( &db_rec->qp, 1, res, ARBEL_UAR_RES_GROUP_SEP );
@ -2502,7 +2562,6 @@ static int arbel_probe ( struct pci_device *pci,
goto err_alloc_icm;
/* Initialise HCA */
MLX_FILL_1 ( &init_hca, 74, uar_parameters.log_max_uars, 1 );
if ( ( rc = arbel_cmd_init_hca ( arbel, &init_hca ) ) != 0 ) {
DBGC ( arbel, "Arbel %p could not initialise HCA: %s\n",
arbel, strerror ( rc ) );

View File

@ -91,9 +91,9 @@ FILE_LICENCE ( GPL2_OR_LATER );
#define ARBEL_INVALID_LKEY 0x00000100UL
#define ARBEL_PAGE_SIZE 4096
#define ARBEL_PAGE_SIZE ( ( size_t ) 4096 )
#define ARBEL_RDB_ENTRY_SIZE 32
#define ARBEL_RDB_ENTRY_SIZE ( ( size_t ) 32 )
#define ARBEL_DB_POST_SND_OFFSET 0x10
#define ARBEL_DB_EQ_OFFSET(_eqn) ( 0x08 * (_eqn) )
@ -308,6 +308,8 @@ struct arbel_dev_limits {
size_t eqc_entry_size;
/** Number of reserved UARs */
unsigned int reserved_uars;
/** UAR scratchpad entry size */
size_t uar_scratch_entry_size;
};
/** Alignment of Arbel send work queue entries */