wrsm_memseg.c revision a83cadce5d3331b64803bfc641036cec23602c74
b332ea78705d9ed8708bb30eb914c0eb9a8e6361Till Mossakowski/*
b332ea78705d9ed8708bb30eb914c0eb9a8e6361Till Mossakowski * CDDL HEADER START
e6d40133bc9f858308654afb1262b8b483ec5922Till Mossakowski *
b332ea78705d9ed8708bb30eb914c0eb9a8e6361Till Mossakowski * The contents of this file are subject to the terms of the
b332ea78705d9ed8708bb30eb914c0eb9a8e6361Till Mossakowski * Common Development and Distribution License, Version 1.0 only
b332ea78705d9ed8708bb30eb914c0eb9a8e6361Till Mossakowski * (the "License"). You may not use this file except in compliance
2eeec5240b424984e3ee26296da1eeab6c6d739eChristian Maeder * with the License.
b332ea78705d9ed8708bb30eb914c0eb9a8e6361Till Mossakowski *
b332ea78705d9ed8708bb30eb914c0eb9a8e6361Till Mossakowski * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b332ea78705d9ed8708bb30eb914c0eb9a8e6361Till Mossakowski * or http://www.opensolaris.org/os/licensing.
e6d40133bc9f858308654afb1262b8b483ec5922Till Mossakowski * See the License for the specific language governing permissions
0095c7efbddd0ffeed6aaf8ec015346be161d819Till Mossakowski * and limitations under the License.
b332ea78705d9ed8708bb30eb914c0eb9a8e6361Till Mossakowski *
b332ea78705d9ed8708bb30eb914c0eb9a8e6361Till Mossakowski * When distributing Covered Code, include this CDDL HEADER in each
b332ea78705d9ed8708bb30eb914c0eb9a8e6361Till Mossakowski * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b332ea78705d9ed8708bb30eb914c0eb9a8e6361Till Mossakowski * If applicable, add the following below this CDDL HEADER, with the
b332ea78705d9ed8708bb30eb914c0eb9a8e6361Till Mossakowski * fields enclosed by brackets "[]" replaced with your own identifying
b332ea78705d9ed8708bb30eb914c0eb9a8e6361Till Mossakowski * information: Portions Copyright [yyyy] [name of copyright owner]
0ea724a1bbc3c692c3cc4cc572975e51e45f137eTill Mossakowski *
933997b6313fc8fd4711dbc9e01dff7c68f58cd7Till Mossakowski * CDDL HEADER END
0ea724a1bbc3c692c3cc4cc572975e51e45f137eTill Mossakowski */
0ea724a1bbc3c692c3cc4cc572975e51e45f137eTill Mossakowski/*
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
f5c16d70215311c0392b5723f427f714e34ba6b9Till Mossakowski * Use is subject to license terms.
ad270004874ce1d0697fb30d7309f180553bb315Christian Maeder */
ad270004874ce1d0697fb30d7309f180553bb315Christian Maeder
f5c16d70215311c0392b5723f427f714e34ba6b9Till Mossakowski#pragma ident "%Z%%M% %I% %E% SMI"
b332ea78705d9ed8708bb30eb914c0eb9a8e6361Till Mossakowski
e1ca87d857ab0461cbcd260484ba0498ec10e1a4Till Mossakowski/*
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder * This file manages generic RSMPI memory segment management, setup and
f5c16d70215311c0392b5723f427f714e34ba6b9Till Mossakowski * teardown.
933997b6313fc8fd4711dbc9e01dff7c68f58cd7Till Mossakowski */
f5c16d70215311c0392b5723f427f714e34ba6b9Till Mossakowski
f5c16d70215311c0392b5723f427f714e34ba6b9Till Mossakowski#include <sys/param.h>
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder#include <sys/types.h>
e953bea49e7f0e1a43bccf2a66c5e2a2b50848e0Christian Maeder#include <sys/systm.h>
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder#include <sys/vmsystm.h>
e953bea49e7f0e1a43bccf2a66c5e2a2b50848e0Christian Maeder#include <sys/errno.h>
f5c16d70215311c0392b5723f427f714e34ba6b9Till Mossakowski#include <sys/kmem.h>
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder#include <vm/seg_kmem.h>
f5c16d70215311c0392b5723f427f714e34ba6b9Till Mossakowski#include <vm/page.h>
049d1590fff7cde05c68d63547aa7660c2034a0cTill Mossakowski#include <sys/sunddi.h>
049d1590fff7cde05c68d63547aa7660c2034a0cTill Mossakowski#include <sys/ddimapreq.h>
049d1590fff7cde05c68d63547aa7660c2034a0cTill Mossakowski#include <sys/taskq.h>
049d1590fff7cde05c68d63547aa7660c2034a0cTill Mossakowski
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder#include <sys/rsm/rsmpi.h>
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder
e1ca87d857ab0461cbcd260484ba0498ec10e1a4Till Mossakowski#include <sys/wrsm_common.h>
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder#include <sys/wrsm_nc.h>
e1ca87d857ab0461cbcd260484ba0498ec10e1a4Till Mossakowski#include <sys/wrsm_session.h>
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder#include <sys/wrsm_memseg.h>
e953bea49e7f0e1a43bccf2a66c5e2a2b50848e0Christian Maeder#include <sys/wrsm_memseg_impl.h>
e953bea49e7f0e1a43bccf2a66c5e2a2b50848e0Christian Maeder#include <sys/wrsm_intr.h>
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder
933997b6313fc8fd4711dbc9e01dff7c68f58cd7Till Mossakowski
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder#ifdef DEBUG
f5c16d70215311c0392b5723f427f714e34ba6b9Till Mossakowski#define DBG_MEMSEG 0x001
f5c16d70215311c0392b5723f427f714e34ba6b9Till Mossakowski#define DBG_MEMSEG_EXTRA 0x010
f5c16d70215311c0392b5723f427f714e34ba6b9Till Mossakowski
f5c16d70215311c0392b5723f427f714e34ba6b9Till Mossakowskistatic uint_t wrsm_memseg_debug = DBG_MEMSEG;
f5c16d70215311c0392b5723f427f714e34ba6b9Till Mossakowski
f5c16d70215311c0392b5723f427f714e34ba6b9Till Mossakowski#define DPRINTF(a, b) { if (wrsm_memseg_debug & a) wrsmdprintf b; }
f5c16d70215311c0392b5723f427f714e34ba6b9Till Mossakowski
f5c16d70215311c0392b5723f427f714e34ba6b9Till Mossakowski#else /* DEBUG */
f5c16d70215311c0392b5723f427f714e34ba6b9Till Mossakowski#define DPRINTF(a, b) { }
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder#endif /* DEBUG */
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder
f5c16d70215311c0392b5723f427f714e34ba6b9Till Mossakowski
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder/* Non-pageable kernel memory is allocated from the wrsm_arena. */
e953bea49e7f0e1a43bccf2a66c5e2a2b50848e0Christian Maederstatic vmem_t *wrsm_arena;
f5c16d70215311c0392b5723f427f714e34ba6b9Till Mossakowski
f5c16d70215311c0392b5723f427f714e34ba6b9Till Mossakowskistatic boolean_t
f5c16d70215311c0392b5723f427f714e34ba6b9Till Mossakowskimemseg_sess_teardown(wrsm_node_t *node)
f5c16d70215311c0392b5723f427f714e34ba6b9Till Mossakowski{
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder boolean_t teardown_complete = B_TRUE;
933997b6313fc8fd4711dbc9e01dff7c68f58cd7Till Mossakowski
933997b6313fc8fd4711dbc9e01dff7c68f58cd7Till Mossakowski DPRINTF(DBG_MEMSEG, (CE_CONT, "ctlr %d: memseg_sess_teardown node %d\n",
933997b6313fc8fd4711dbc9e01dff7c68f58cd7Till Mossakowski node->network->rsm_ctlr_id, node->config->cnodeid));
933997b6313fc8fd4711dbc9e01dff7c68f58cd7Till Mossakowski /*
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder * it is presumed that at this point the node was removed from the
933997b6313fc8fd4711dbc9e01dff7c68f58cd7Till Mossakowski * cluster_members_bits registers in all wcis
933997b6313fc8fd4711dbc9e01dff7c68f58cd7Till Mossakowski */
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder
049d1590fff7cde05c68d63547aa7660c2034a0cTill Mossakowski mutex_enter(&node->memseg->lock);
049d1590fff7cde05c68d63547aa7660c2034a0cTill Mossakowski
049d1590fff7cde05c68d63547aa7660c2034a0cTill Mossakowski /*
049d1590fff7cde05c68d63547aa7660c2034a0cTill Mossakowski * clean up exports to the remote node
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder */
049d1590fff7cde05c68d63547aa7660c2034a0cTill Mossakowski if (!exportseg_sess_teardown(node)) {
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder teardown_complete = B_FALSE;
933997b6313fc8fd4711dbc9e01dff7c68f58cd7Till Mossakowski }
933997b6313fc8fd4711dbc9e01dff7c68f58cd7Till Mossakowski
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder /*
933997b6313fc8fd4711dbc9e01dff7c68f58cd7Till Mossakowski * clean up iseginfos imported from remote node
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder */
933997b6313fc8fd4711dbc9e01dff7c68f58cd7Till Mossakowski if (!iseginfo_sess_teardown(node)) {
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder teardown_complete = B_FALSE;
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder }
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder mutex_exit(&node->memseg->lock);
adaf5a640e615848c19de372218377a418f954ceFlorian Mossakowski
adaf5a640e615848c19de372218377a418f954ceFlorian Mossakowski return (teardown_complete);
933997b6313fc8fd4711dbc9e01dff7c68f58cd7Till Mossakowski}
933997b6313fc8fd4711dbc9e01dff7c68f58cd7Till Mossakowski
933997b6313fc8fd4711dbc9e01dff7c68f58cd7Till Mossakowski
e57c178845d66be315d6947103db4a14c72a21a9Till Mossakowski
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maederstatic boolean_t
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maedermemseg_sess_notify(wrsm_network_t *network, cnodeid_t cnodeid,
e57c178845d66be315d6947103db4a14c72a21a9Till Mossakowski wrsm_sess_state state)
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder{
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder boolean_t teardown_complete = B_TRUE;
e57c178845d66be315d6947103db4a14c72a21a9Till Mossakowski
adaf5a640e615848c19de372218377a418f954ceFlorian Mossakowski switch (state) {
adaf5a640e615848c19de372218377a418f954ceFlorian Mossakowski /*
e57c178845d66be315d6947103db4a14c72a21a9Till Mossakowski * nothing to do on SESSION_UP
e57c178845d66be315d6947103db4a14c72a21a9Till Mossakowski */
a3f427df6da9439423c5925c4957ae4124ed908cChristian Maeder case SESSION_DOWN:
a3f427df6da9439423c5925c4957ae4124ed908cChristian Maeder teardown_complete = memseg_sess_teardown(
e32a0dc687d36d32f8135d8b7d88e916164ddb5fFlorian Mossakowski network->nodes[cnodeid]);
a3f427df6da9439423c5925c4957ae4124ed908cChristian Maeder break;
a3f427df6da9439423c5925c4957ae4124ed908cChristian Maeder }
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder return (teardown_complete);
f5c16d70215311c0392b5723f427f714e34ba6b9Till Mossakowski}
e32a0dc687d36d32f8135d8b7d88e916164ddb5fFlorian Mossakowski
933997b6313fc8fd4711dbc9e01dff7c68f58cd7Till Mossakowski/*
933997b6313fc8fd4711dbc9e01dff7c68f58cd7Till Mossakowski *
933997b6313fc8fd4711dbc9e01dff7c68f58cd7Till Mossakowski * driver initialization functions
933997b6313fc8fd4711dbc9e01dff7c68f58cd7Till Mossakowski *
933997b6313fc8fd4711dbc9e01dff7c68f58cd7Till Mossakowski */
933997b6313fc8fd4711dbc9e01dff7c68f58cd7Till Mossakowski
933997b6313fc8fd4711dbc9e01dff7c68f58cd7Till Mossakowskivoid
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maederwrsm_memseg_node_init(wrsm_node_t *node)
933997b6313fc8fd4711dbc9e01dff7c68f58cd7Till Mossakowski{
933997b6313fc8fd4711dbc9e01dff7c68f58cd7Till Mossakowski struct wrsm_node_memseg *memseg;
933997b6313fc8fd4711dbc9e01dff7c68f58cd7Till Mossakowski
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder DPRINTF(DBG_MEMSEG_EXTRA, (CE_CONT, "wrsm_memseg_node_init(cnode %d)\n",
47d6bc7bc9a708427f96be8d805f712697ad3d9eChristian Maeder node->config->cnodeid));
memseg = (struct wrsm_node_memseg *)kmem_zalloc(
sizeof (struct wrsm_node_memseg), KM_SLEEP);
mutex_init(&memseg->lock, NULL, MUTEX_DRIVER, NULL);
memseg->removing_session = B_FALSE;
node->memseg = memseg;
}
void
wrsm_memseg_node_fini(wrsm_node_t *node)
{
#ifdef DEBUG
int i;
#endif
DPRINTF(DBG_MEMSEG_EXTRA, (CE_CONT, "wrsm_memseg_node_fini(cnode %d)\n",
node->config->cnodeid));
#ifdef DEBUG
/* verify that the segment is really not in use */
ASSERT(node->memseg->connected == NULL);
ASSERT(node->memseg->wait_for_unmaps == 0);
mutex_enter(&node->memseg->lock);
for (i = 0; i < WRSM_SEGID_HASH_SIZE; i++) {
ASSERT(node->memseg->iseginfo_hash[i] == NULL);
}
mutex_exit(&node->memseg->lock);
#endif
mutex_destroy(&node->memseg->lock);
kmem_free(node->memseg, sizeof (wrsm_node_memseg_t));
node->memseg = NULL;
}
void
wrsm_memseg_network_init(wrsm_network_t *network)
{
DPRINTF(DBG_MEMSEG_EXTRA, (CE_CONT, "wrsm_memseg_init(ctlr %d)\n",
network->rsm_ctlr_id));
/* this initiates all variables to 0 */
network->memseg = kmem_zalloc(sizeof (wrsm_memseg_t), KM_SLEEP);
(void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_CONNECT,
wrsm_tl_txhandler_sessionid, wrsm_memseg_msg_hdlr);
(void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_CONNECT_RESPONSE,
wrsm_tl_txhandler_sessionid, wrsm_tl_rxhandler_sessionid);
(void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_SMALLPUTMAP,
wrsm_tl_txhandler_sessionid, wrsm_memseg_msg_hdlr);
(void) wrsm_tl_add_handler(network,
WRSM_MSG_SEGMENT_SMALLPUTMAP_RESPONSE,
wrsm_tl_txhandler_sessionid, wrsm_tl_rxhandler_sessionid);
(void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_BARRIERMAP,
wrsm_tl_txhandler_sessionid, wrsm_memseg_msg_hdlr);
(void) wrsm_tl_add_handler(network,
WRSM_MSG_SEGMENT_BARRIERMAP_RESPONSE,
wrsm_tl_txhandler_sessionid, wrsm_tl_rxhandler_sessionid);
(void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_SEGMAP,
wrsm_tl_txhandler_sessionid, wrsm_memseg_msg_hdlr);
(void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_SEGMAP_RESPONSE,
wrsm_tl_txhandler_sessionid, wrsm_tl_rxhandler_sessionid);
(void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_DISCONNECT,
wrsm_tl_txhandler_sessionid, wrsm_memseg_msg_hdlr);
(void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_UNPUBLISH,
wrsm_tl_txhandler_sessionid, wrsm_memseg_msg_hdlr);
(void) wrsm_tl_add_handler(network,
WRSM_MSG_SEGMENT_UNPUBLISH_RESPONSE,
wrsm_tl_txhandler_sessionid, wrsm_tl_rxhandler_sessionid);
(void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_ACCESS,
wrsm_tl_txhandler_sessionid, wrsm_memseg_msg_hdlr);
/*
* Register for session teardown calls
*/
wrsm_sess_register(network, memseg_sess_notify);
}
void
wrsm_memseg_network_fini(wrsm_network_t *network)
{
DPRINTF(DBG_MEMSEG_EXTRA, (CE_CONT, "wrsm_memseg_fini(ctlr %d)\n",
network->rsm_ctlr_id));
/*
* If there are importsegs or exportsegs left around which a client
* did not destroy prior to doing release controller, destroy them
* now.
*/
wrsm_free_exportsegs(network);
wrsm_free_importsegs(network);
(void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_CONNECT,
WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER);
(void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_CONNECT_RESPONSE,
WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER);
(void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_SMALLPUTMAP,
WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER);
(void) wrsm_tl_add_handler(network,
WRSM_MSG_SEGMENT_SMALLPUTMAP_RESPONSE,
WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER);
(void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_BARRIERMAP,
WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER);
(void) wrsm_tl_add_handler(network,
WRSM_MSG_SEGMENT_BARRIERMAP_RESPONSE,
WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER);
(void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_SEGMAP,
WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER);
(void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_SEGMAP_RESPONSE,
WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER);
(void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_DISCONNECT,
WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER);
(void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_UNPUBLISH,
WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER);
(void) wrsm_tl_add_handler(network,
WRSM_MSG_SEGMENT_UNPUBLISH_RESPONSE,
WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER);
(void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_ACCESS,
WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER);
wrsm_sess_unregister(network, memseg_sess_notify);
kmem_free(network->memseg, sizeof (wrsm_memseg_t));
}
void
wrsm_memseg_init(void)
{
mutex_init(&all_exportsegs_lock, NULL, MUTEX_DRIVER, NULL);
mutex_init(&all_importsegs_lock, NULL, MUTEX_DRIVER, NULL);
wrsm_arena = vmem_create("wrsm_arena", NULL, 0,
PAGESIZE, vmem_alloc, vmem_free,
static_arena, PAGESIZE, VM_SLEEP);
}
void
wrsm_memseg_fini(void)
{
vmem_destroy(wrsm_arena);
mutex_destroy(&all_exportsegs_lock);
mutex_destroy(&all_importsegs_lock);
}
void
wrsm_memseg_stat(wrsm_network_t *network, wrsm_memseg_stat_data_t *data)
{
mutex_enter(&network->lock);
data->export_count = network->memseg->export_count;
data->export_published = network->memseg->export_published;
data->export_connected = network->memseg->export_connected;
data->bytes_bound = network->memseg->bytes_bound;
data->import_count = network->memseg->import_count;
mutex_exit(&network->lock);
}
/*
* wrsm alloc routine used in place of kmem_{z}alloc()
* as it allocates memory from the non-relocatable heap arena
*/
void *
wrsm_alloc(size_t size, int flags)
{
return (vmem_alloc(wrsm_arena, size, flags));
}
/*
* wrsm free routine used in place of kmem_{z}alloc()
* as it frees memory to the non-relocatable heap arena
*/
void
wrsm_free(void *addr, size_t size)
{
vmem_free(wrsm_arena, addr, size);
}