/* * cluster.h - Cluster-Manager definition * * authors Ghassan Almaless (2008,2009,2010,2011,2012) * Mohamed Lamine Karaoui (2015) * Alain Greiner (2016,2017) * * 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 #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 structures: * 1) The 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 process descriptors in cluster K. * A process descriptor P is present in K, as soon as P has a thread in cluster K. * * 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. ******************************************************************************************/ typedef struct process_manager_s { xptr_t pref_tbl[CONFIG_MAX_PROCESS_PER_CLUSTER]; /*! reference process */ spinlock_t pref_lock; /*! lock protecting lpid allocation/release */ uint32_t pref_nr; /*! number of processes owned by cluster */ xlist_entry_t local_root; /*! root of list of process in cluster */ remote_spinlock_t local_lock; /*! lock protecting access to 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_spinlock_t copies_lock[CONFIG_MAX_PROCESS_PER_CLUSTER]; /*! one lock per list */ uint32_t copies_nr[CONFIG_MAX_PROCESS_PER_CLUSTER]; /*! number of copies */ } pmgr_t; /******************************************************************************************* * This structure defines a cluster manager. * It contains both global platform information, and cluster specific resources * managed by the local kernel instance. ******************************************************************************************/ typedef struct cluster_s { spinlock_t kcm_lock; /*! local, protect creation of KCM allocators */ // 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[] */ // local parameters uint32_t cores_nr; /*! number of cores in cluster */ uint32_t cores_in_kernel; /*! number of cores currently in kernel mode */ core_t core_tbl[CONFIG_MAX_LOCAL_CORES]; /*! embedded cores */ ppm_t ppm; /*! embedded kernel page manager */ khm_t khm; /*! embedded kernel heap manager */ kcm_t kcm; /*! embedded kernel cache manager (for KCMs) */ kcm_t * kcm_tbl[KMEM_TYPES_NR]; /*! pointers on allocated KCMs */ uint32_t ram_size; /*! physical memory size */ uint32_t ram_base; /*! physical memory base (local address) */ rpc_fifo_t rpc_fifo; /*! cluster RPC fifo (shared) */ list_entry_t devlist; /*! root of list of devices in cluster */ int32_t pages_var; /*! pages number increment from last DQQT update */ int32_t threads_var; /*! threads number increment from last DQDT update */ dqdt_node_t dqdt_tbl[CONFIG_MAX_DQDT_DEPTH]; /*! embedded DQDT nodes */ pmgr_t pmgr; /*! embedded process manager */ char name[CONFIG_SYSFS_NAME_LEN]; // sysfs_entry_t node; } 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) /****************************************************************************************** * This generic function initialises the local cluster manager from information found * in the local boot-info structure. It initializes the following local resources: * - the global platform parameters, * - the specific cluster parameters, * - the lock protecting KCM creation, * - the local DQDT nodes, * - the PPM, KHM, and KCM allocators, * - the local core descriptors, * - the local RPC FIFO, * - the process manager. * It does NOT initialise the local device descriptors. ****************************************************************************************** * @ info : pointer on the local boot_info_t structure build by the bootloader. *****************************************************************************************/ error_t cluster_init( boot_info_t * info ); /****************************************************************************************** * This function checks the validity of a cluster identifier. TODO useful ??? [AG] ****************************************************************************************** * @ cxy : cluster identifier to be checked. * @ returns true if the identified cluster does not exist. *****************************************************************************************/ bool_t cluster_is_undefined( cxy_t cxy ); /****************************************************************************************** * This function register sysfs information in cluster TODO ??? [AG] *****************************************************************************************/ void cluster_sysfs_register(); /*****************************************************************************************/ /*************** Process Management Operations ***************************************/ /*****************************************************************************************/ /****************************************************************************************** * This function returns an extended pointer on the reference process descriptor * from the process PID. This PID can be be different from the calling thread process. * It can be called by any thread running in any cluster, ****************************************************************************************** * @ pid : process identifier. * @ return extended pointer on reference process if success / return XPTR_NULL if error. *****************************************************************************************/ xptr_t cluster_get_reference_process_from_pid( 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. This function is called by the rpc_process_alloc_pid() function for * remote registration, or by the process_init_create() function for local registration. ****************************************************************************************** * @ process : [in] extended pointer on the process descriptor. * @ pid : [out] allocated PID. * @ return 0 if success / return EAGAIN if no PID slot available *****************************************************************************************/ error_t cluster_pid_alloc( xptr_t process_xp, 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. * It uses the RPC * to create a local process descriptor copy if it does not exist yet. ****************************************************************************************** * @ 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 ); /*****************************************************************************************/ /*************** Cores Management Operations *****************************************/ /*****************************************************************************************/ /****************************************************************************************** * This function increments the "cores_in_kernel" variable in cluster descriptor. *****************************************************************************************/ void cluster_core_kernel_enter(); /****************************************************************************************** * This function decrements the "cores_in_kernel" variable in cluster descriptor. *****************************************************************************************/ void cluster_core_kernel_exit(); /****************************************************************************************** * This function returns the core local index that has the lowest usage in local cluster. *****************************************************************************************/ lid_t cluster_select_local_core(); #endif /* _CLUSTER_H_ */