/* * cluster.h - Cluster-Manager definition * * authors Ghassan Almaless (2008,2009,2010,2011,2012) * Mohamed Lamine Karaoui (2015) * Alain Greiner (2016,2017,2018,2019,2019,2020) * * Copyright (c) UPMC Sorbonne Universites * * This file is part of ALMOS-MKH. * * ALMOS-MKH is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2.0 of the License. * * ALMOS-MKH is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ALMOS-MKH; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _CLUSTER_H_ #define _CLUSTER_H_ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /**** Forward declarations ****/ struct core_s; struct process_s; /******************************************************************************************* * This structure defines the process manager, that is part of the cluster manager. * For any process P, the process descriptor is replicated in all clusters containing * at least one thread of process P, but only the "reference" cluster descriptor contains * the reference (complete) GPT, VSL, and FDT structures. * The "owner" cluster K is in charge to allocate a lpid (local process index), * to the owned processes, and to register the "reference" cluster for these processes. * * Warning : the "owner" cluster, and the "reference" cluster can be different clusters. * * The process manager of a cluster K maintains three sets of process descriptors: * * 1) pref_tbl[] is an array indexed by lpid. There is one entry per owned process. * Each entry contains an extended pointer on the reference process descriptor. * * 2) The local_root is the root of the local list of all process descriptors in cluster K. * A process descriptor P is present in K, as soon as P has a thread in cluster K. * We use an xlist, because this list can be traversed by remote threads. * * 3) The copies_root[] array is indexed by lpid. There is one entry per owned process, * and each each entry contains the root of the xlist of copies for this process. $ We use an xlist, because process copies are distributed in all clusters. ******************************************************************************************/ typedef struct process_manager_s { xptr_t pref_tbl[CONFIG_MAX_PROCESS_PER_CLUSTER]; /*! owned processes */ queuelock_t pref_lock; /*! lock protecting pref_tbl */ uint32_t pref_nr; /*! number of processes owned by cluster */ xlist_entry_t local_root; /*! root of list of process in cluster */ remote_queuelock_t local_lock; /*! lock protecting local list */ uint32_t local_nr; /*! number of process in cluster */ xlist_entry_t copies_root[CONFIG_MAX_PROCESS_PER_CLUSTER]; /*! roots of lists */ remote_queuelock_t copies_lock[CONFIG_MAX_PROCESS_PER_CLUSTER]; /*! one per list */ uint32_t copies_nr[CONFIG_MAX_PROCESS_PER_CLUSTER]; /*! number of copie */ } pmgr_t; /******************************************************************************************* * This structure defines a cluster manager. * It contains both global platform information, and cluster specific resources * controled by the local kernel instance. ******************************************************************************************/ typedef struct cluster_s { // global parameters uint32_t paddr_width; /*! numer of bits in physical address */ uint32_t x_width; /*! number of bits to code x_size (can be 0) */ uint32_t y_width; /*! number of bits to code y_size (can be 0) */ uint32_t x_size; /*! number of clusters in a row (can be 1) */ uint32_t y_size; /*! number of clusters in a column (can be 1) */ cxy_t io_cxy; /*! io cluster identifier */ uint32_t dqdt_root_level; /*! index of root node in dqdt_tbl[] */ uint32_t nb_txt_channels; /*! number of TXT channels */ uint32_t nb_nic_channels; /*! number of NIC channels */ uint32_t nb_ioc_channels; /*! number of IOC channels */ uint32_t nb_fbf_channels; /*! number of FBF channels */ // number of cores for each cluster in the mesh uint8_t cluster_info[CONFIG_MAX_CLUSTERS_X][CONFIG_MAX_CLUSTERS_Y]; // local parameters uint32_t cores_nr; /*! actual number of cores in cluster */ uint32_t ram_size; /*! physical memory size */ uint32_t ram_base; /*! physical memory base (local address) */ core_t core_tbl[CONFIG_MAX_LOCAL_CORES]; /*! embedded cores */ list_entry_t dev_root; /*! root of list of devices in cluster */ // memory allocators ppm_t ppm; /*! embedded kernel page manager */ khm_t khm; /*! embedded kernel heap manager */ kcm_t kcm[6]; /*! embedded kernel cache managers [6:11] */ // RPC remote_fifo_t rpc_fifo[CONFIG_MAX_LOCAL_CORES]; /*! one RPC FIFO per core */ uint32_t rpc_threads[CONFIG_MAX_LOCAL_CORES]; /*! RPC threads per core */ // DQDT dqdt_node_t dqdt_tbl[CONFIG_DQDT_LEVELS_NR]; /*! embedded DQDT nodes */ xptr_t dqdt_root_xp; /*! extended pointer on DQDT root node */ // Local process manager pmgr_t pmgr; /*! embedded process manager */ void * pic_extend; /*! PIC implementation specific extension */ } cluster_t; /****************************************************************************************** * This global variable is allocated in the kernel_init.c file. * There is one cluster_manager per cluster, with the same local address, * but different content, in all clusters containing a kernel instance. *****************************************************************************************/ extern cluster_t cluster_manager; /****************************************************************************************** * This macro returns a local pointer on the local cluster manager. *****************************************************************************************/ #define LOCAL_CLUSTER (&cluster_manager) /****************************************************************************************** * These two functions initialise the local cluster manager from information found * in the local boot-info structure build by the boot-loader. * 1) the cluster_info_init() function is called first, to initialize the structural * constants, including the cluster_info[x][y] array. * It cannot use the TXT0 kernel terminal. * 2) the cluster_manager_init() function initializes various complex structures: * - the local DQDT nodes, * - the PPM, KHM, and KCM allocators, * - the local core descriptors, * - the local RPC FIFO, * - the process manager. * It can use the TXT0 kernel terminal. ****************************************************************************************** * @ info : pointer on the local boot_info_t structure build by the bootloader. *****************************************************************************************/ void cluster_info_init( boot_info_t * info ); error_t cluster_manager_init( boot_info_t * info ); /****************************************************************************************** * This debug function displays the current values stored in the cluster_info[][] array * of a remote cluster identified by the argument. * It can be called by a thread running in any cluster. ****************************************************************************************** * @ cxy : remote cluster identifier. *****************************************************************************************/ void cluster_info_display( cxy_t cxy ); /****************************************************************************************** * This function access the local cluster_info[][] array and returns true when the * cluster identified by the argument is active (contains a kernel instance). ****************************************************************************************** * @ cxy : checked cluster identifier. * @ return true if cluster contains a kernel instance. *****************************************************************************************/ bool_t cluster_is_active( cxy_t cxy ); /****************************************************************************************** * This function selects (pseudo) randomly a valid cluster. * It is called by the vfs_cluster_lookup() function to place a new (missing) inode. * It is called by the vmm_page_allocate() function to place a distributed vseg page. * It is called by the dev_nic_accept() function to place a new server socket. ****************************************************************************************** * @ returns the selected cluster identifier. *****************************************************************************************/ cxy_t cluster_random_select( void ); /****************************************************************************************** * This function returns an extended pointer on the process descriptor in owner cluster * from the process . This PID can be be different from the calling process PID. * It can be called by any thread running in any cluster, ****************************************************************************************** * @ pid : process identifier. * @ return extended pointer on owner process if found / XPTR_NULL if not found. *****************************************************************************************/ xptr_t cluster_get_owner_process_from_pid( pid_t pid ); /****************************************************************************************** * This function returns an extended pointer on the reference process descriptor * from the process . This PID can be be different from the calling process PID. * It can be called by any thread running in any cluster, ****************************************************************************************** * @ pid : process identifier. * @ return extended pointer on reference process if found / XPTR_NULL if not found. *****************************************************************************************/ xptr_t cluster_get_reference_process_from_pid( pid_t pid ); /****************************************************************************************** * This function returns an extended pointer on the process descriptor copy for the * process identified by in cluster defined by argument. * This PID can be be different from the calling process PID. * It can be called by any thread running in any cluster, ****************************************************************************************** * @ cxy : target cluster identifier. * @ pid : process identifier. * @ return extended pointer on reference process if found / XPTR_NULL if not found. *****************************************************************************************/ xptr_t cluster_get_process_from_pid_in_cxy( cxy_t cxy, pid_t pid ); /****************************************************************************************** * This function allocates a new PID in local cluster, that becomes the process owner. * It registers the process descriptor extended pointer in the local processs manager * pref_tbl[] array. The process descriptor itself is not modified. * This function is called by the process_make_fork() function, * by the process_make_exec() function, and by the process_init_create() function. ****************************************************************************************** * @ process : pointer on process descriptor. * @ pid : [out] allocated PID. * @ return 0 if success / return -1 if no PID slot available. *****************************************************************************************/ error_t cluster_pid_alloc( struct process_s * process, pid_t * pid ); /****************************************************************************************** * This function removes a PID from the local process manager pref_tbl[] array. * It checks that removed process is owned by the local cluster and the lpid is legal. * No memory is released by this function. ****************************************************************************************** * @ pid : allocated PID. *****************************************************************************************/ void cluster_pid_release( pid_t pid ); /****************************************************************************************** * This function returns a pointer on the local process descriptor from the PID. ****************************************************************************************** * @ pid : searched process identifier. * @ returns process descriptor pointer if found / returns NULL if not found. *****************************************************************************************/ struct process_s * cluster_get_local_process_from_pid( pid_t pid ); /****************************************************************************************** * This function registers a local process descriptor in the process manager local_list. ****************************************************************************************** * @ process : pointer on local process descriptor. *****************************************************************************************/ void cluster_process_local_link( struct process_s * process ); /****************************************************************************************** * This function removes a local process descriptor from the process manager local_list. ****************************************************************************************** * @ process : pointer on local process descriptor. *****************************************************************************************/ void cluster_process_local_unlink( struct process_s * process ); /****************************************************************************************** * This function registers a local process descriptor in the owner process manager * copies_list, that can be in a remote cluster. ****************************************************************************************** * @ process : pointer on local process descriptor. *****************************************************************************************/ void cluster_process_copies_link( struct process_s * process ); /****************************************************************************************** * This function removes a local process descriptor from the owner process manager * copies_list, that can be in a remote cluster. ****************************************************************************************** * @ process : pointer on local process descriptor. *****************************************************************************************/ void cluster_process_copies_unlink( struct process_s * process ); /****************************************************************************************** * This function displays on the kernel terminal TXT0 all user processes registered * in the cluster defined by the argument. * It can be called by a thread running in any cluster. ****************************************************************************************** * @ cxy : cluster identifier. * @ owned : only owned process if non zero. *****************************************************************************************/ void cluster_processes_display( cxy_t cxy, bool_t owned ); /****************************************************************************************** * This function selects the core that has the lowest usage in a - possibly remote - * cluster identified by the argument. * It can be called by a thread running in any cluster. ****************************************************************************************** * @ cxy : target cluster identifier. * @ return the selected core local index. *****************************************************************************************/ lid_t cluster_select_local_core( cxy_t cxy ); #endif /* _CLUSTER_H_ */