Changeset 632 for trunk/kernel/libk


Ignore:
Timestamp:
May 28, 2019, 2:56:04 PM (5 years ago)
Author:
alain
Message:

This version replace the RPC by direct remote memory access
for physical pages allacation/release.
It is commited before being tested.

Location:
trunk/kernel/libk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/libk/list.h

    r612 r632  
    11/*
    2  * list.h - Double circular chained lists, inspired from linux
     2 * list.h - Double circular linked list
    33 *
    44 * Authors Ghassan Almaless  (2008,2009,2010,2011,2012)
    5  *         Alain Greiner     (2016,2017,2018)
     5 *         Alain Greiner     (2016,2017,2018i,2019)
    66 *
    77 * Copyright (c) UPMC Sorbonne Universites
     
    2828#include <kernel_config.h>
    2929#include <hal_kernel_types.h>
     30#include <hal_remote.h>
    3031#include <printk.h>
    3132
     
    3435#endif
    3536
     37
     38////////////////////////////////////////////////////////////////////////////
     39//          Double circular linked list functions & macros
     40//
     41// It defines a generic local list, as all elements are in the same cluster.
     42//
     43// There is two sets of access functions, because these local lists can be
     44// accessed by local threads, using local pointers, but they can also be
     45// accessed by remote threads running in any cluster, with specific access
     46// functions using extended pointers.
     47////////////////////////////////////////////////////////////////////////////
     48
     49/***************************************************************************
     50 * This structure defines a Double Circular Linked List entry.
     51 * Note : The list root is an extra list-entry_t, that is NOT part
     52 *            of the set of linked elements.
     53 **************************************************************************/
     54
     55typedef struct list_entry_s
     56{
     57        struct list_entry_s * next;
     58        struct list_entry_s * pred;
     59}
     60list_entry_t;
    3661
    3762/***************************************************************************
     
    4671#endif
    4772
    48 ////////////////////////////////////////////////////////////////////////////
    49 ////////////////////////////////////////////////////////////////////////////
    50 //          Double circular linked list functions & macros
    51 ////////////////////////////////////////////////////////////////////////////
    52 ////////////////////////////////////////////////////////////////////////////
    53 
    54 /***************************************************************************
    55  * This structure defines a Double Circular Linked List entry.
    56  * Note : The list root is an extra list-entry_t, that is NOT part
    57  *            of the set of linked elements.
    58  **************************************************************************/
    59 
    60 typedef struct list_entry_s
    61 {
    62         struct list_entry_s * next;
    63         struct list_entry_s * pred;
    64 }
    65 list_entry_t;
    66 
    6773/***************************************************************************
    6874 * This macro returns a pointer on a structure containing a list_entry_t.
     
    7783        (container_type *)( (char*)__member_ptr - OFFSETOF( container_type , member_name ));})
    7884
     85
     86////////////////////////////////////////////////////////////////////////////
     87// These functions and macros mus be called by a thread running
     88// in the local cluster to access the local list.
     89////////////////////////////////////////////////////////////////////////////
     90
    7991/***************************************************************************
    8092 * This macro returns t pointer on the first element of a list.
     
    101113/***************************************************************************
    102114 * This macro traverse a rooted double linked list in forward order.
    103  * WARNING : Don't use 2 LIST_FOREACH in the same function, because the
    104  * variable __ptr will be defined twice, wich result in a compilation error.
     115 * WARNING : Don't use this macro when you want to remove one or several
     116 * item(s) from the traversed list.     
    105117 ***************************************************************************
    106118 * @ root      : pointer on the root list_entry
     
    149161
    150162/***************************************************************************
    151  * This function inserts a new entry in first place of a double linked list.
     163 * This function must be called by a thread running in local cluster.
     164 * It inserts a new entry in first place of a double linked list.
    152165 ***************************************************************************
    153166 * @ root    : pointer on the list root
     
    157170                                   list_entry_t * entry )
    158171{
    159     list_entry_t * pred_entry;
    160     list_entry_t * next_entry;
    161  
    162         pred_entry = root;
    163         next_entry = root->next;
    164        
    165         entry->next = next_entry;
    166         entry->pred = pred_entry;
    167  
    168         pred_entry->next = entry;
    169         next_entry->pred = entry;
    170 }
    171 
    172 /***************************************************************************
    173  * This function inserts a new entry in last place of a double linked list.
     172    list_entry_t * next = root->next; 
     173
     174        entry->next = next;
     175        entry->pred = root;
     176 
     177        root->next = entry;
     178        next->pred = entry;
     179}
     180
     181/***************************************************************************
     182 * This function must be called by a thread running in local cluster.
     183 * It inserts a new entry in last place of a double linked list.
    174184 ***************************************************************************
    175185 * @ root    : pointer on the list root
     
    179189                                  list_entry_t * entry )
    180190{
    181     list_entry_t * pred_entry;
    182     list_entry_t * next_entry;
    183 
    184         pred_entry = root->pred;
    185         next_entry = root;
    186        
    187         entry->next = next_entry;
    188         entry->pred = pred_entry;
    189  
    190         pred_entry->next = entry;
    191         next_entry->pred = entry;
    192 }
    193 
    194 /***************************************************************************
    195  * This function returns true if the list is empty.
     191    list_entry_t * pred = root->pred;
     192
     193        entry->next = root;
     194        entry->pred = pred;
     195 
     196        root->pred = entry;
     197        pred->next = entry;
     198}
     199
     200/***************************************************************************
     201 * This function must be called by a thread running in local cluster.
     202 * It returns true if the list is empty.
    196203 ***************************************************************************
    197204 * @ root    : pointer on the list root
     
    202209}
    203210
    204 /***************************************************************************
    205  * This function remove an entry from a rooted double linked list.
     211
     212/***************************************************************************
     213 * This function must be called by a thread running in local cluster.
     214 * It removes an entry from the list.
    206215 ***************************************************************************
    207216 * @ entry : pointer on the entry to be removed.
     
    209218static inline void list_unlink( list_entry_t * entry )
    210219{
    211         list_entry_t * pred_entry;
    212     list_entry_t * next_entry;
    213 
    214         pred_entry = entry->pred;
    215         next_entry = entry->next;
    216 
    217         pred_entry->next = entry->next;
    218         next_entry->pred = entry->pred;
     220        list_entry_t * pred;
     221    list_entry_t * next;
     222
     223        pred = entry->pred;
     224        next = entry->next;
     225
     226        pred->next = next;
     227        next->pred = pred;
    219228}
    220229
     
    278287
    279288
     289
     290////////////////////////////////////////////////////////////////////////////
     291// These functions and macros can be used by any thread running
     292// in any cluster to access a remote local list.
     293////////////////////////////////////////////////////////////////////////////
     294
     295/***************************************************************************
     296 * This macro can be used by a thread running in any cluster to access
     297 * a remote local list. It returns a local pointer on the first element
     298 * of the remote list in the remote cluster.
     299 ***************************************************************************
     300 * @ cxy     : remote list cluster identifier
     301 * @ root    : local pointer on the list root
     302 * @ type    : type of the linked element
     303 * @ member  : name of the list_entry_t field
     304 **************************************************************************/
     305
     306#define LIST_REMOTE_FIRST( cxy , root , type , member )                       \
     307    ({ list_entry_t * __first = hal_remote_lpt( XPTR( cxy , &root->next ) );  \
     308           LIST_ELEMENT( __first , type , member ); })
     309
     310/***************************************************************************
     311 * This macro can be used by a thread running in any cluster to access
     312 * a remote local list. It traverse the list in forward order.
     313 * WARNING : Don't use this macro when you want to remove one or several
     314 * item(s) from the traversed list.     
     315 ***************************************************************************
     316 * @ cxy     : remote list cluster identifier
     317 * @ root    : pointer on the root list_entry
     318 * @ iter    : pointer on the current list_entry
     319 **************************************************************************/
     320
     321#define LIST_REMOTE_FOREACH( cxy , root , iter )               \
     322for( (iter) = hal_remote_lpt( XPTR( cxy , &(root)->next ) ) ;  \
     323     (iter) != (root) ;                         \
     324     (iter) = hal_remote_lpt( XPTR( cxy , &(iter)->next ) ) )
     325       
     326/***************************************************************************
     327 * This function can be called by a thread running in any cluster to access
     328 * a remote local list. It returns true if the list is empty.
     329 ***************************************************************************
     330 * @ cxy     : remote list cluster identifier
     331 * @ root    : local pointer on the remote list root
     332 **************************************************************************/
     333static inline bool_t list_remote_is_empty( cxy_t          cxy,
     334                                           list_entry_t * root )
     335{
     336    list_entry_t * next = hal_remote_lpt( XPTR( cxy , &root->next ) );
     337    return( root == next );
     338}
     339
     340/***************************************************************************
     341 * This function can be called by a thread running in any cluster to access
     342 * a remote local list. It inserts a new entry in first place of the list.
     343 ***************************************************************************
     344 * @ cxy     : remote list cluster identifier
     345 * @ root    : local pointer on the remote list root
     346 * @ entry   : local pointer on the remote entry to be inserted
     347 **************************************************************************/
     348static inline void list_remote_add_first( cxy_t          cxy,
     349                                          list_entry_t * root,
     350                                          list_entry_t * entry )
     351{
     352    list_entry_t * first;    // local pointer on current first entry
     353    list_entry_t * next;     // local pointer on current first->next entry
     354 
     355        first  = hal_remote_lpt( XPTR( cxy , &root->next ) );
     356    next   = hal_remote_lpt( XPTR( cxy , &first->next ) );
     357       
     358        hal_remote_spt( XPTR( cxy , &entry->next ) , first );
     359        hal_remote_spt( XPTR( cxy , &entry->pred ) , root );
     360 
     361        hal_remote_spt( XPTR( cxy , &root->next ) , entry );
     362        hal_remote_spt( XPTR( cxy , &next->pred ) , entry );
     363}
     364
     365/***************************************************************************
     366 * This function can be called by a thread running in any cluster to access
     367 * a remote local list. It inserts a new entry in last place of the list.
     368 ***************************************************************************
     369 * @ cxy     : remote list cluster identifier
     370 * @ root    : local pointer on the remote list root
     371 * @ entry   : local pointer on the remote entry to be inserted
     372 **************************************************************************/
     373static inline void list_remote_add_last( cxy_t          cxy,
     374                                         list_entry_t * root,
     375                                         list_entry_t * entry )
     376{
     377    list_entry_t * last;     // local pointer on current last entry
     378    list_entry_t * pred;     // local pointer on current last->pred entry
     379 
     380        last   = hal_remote_lpt( XPTR( cxy , &root->pred ) );
     381    pred   = hal_remote_lpt( XPTR( cxy , &last->pred ) );
     382       
     383        hal_remote_spt( XPTR( cxy , &entry->next ) , root );
     384        hal_remote_spt( XPTR( cxy , &entry->pred ) , pred );
     385 
     386        hal_remote_spt( XPTR( cxy , &root->pred ) , entry );
     387        hal_remote_spt( XPTR( cxy , &pred->next ) , entry );
     388}
     389
     390/***************************************************************************
     391 * This function can be called by a thread running in any cluster to access
     392 * a remote local list. It removes an entry from the list.
     393 ***************************************************************************
     394 * @ cxy     : remote list cluster identifier
     395 * @ entry   : pointer on the entry to be removed.
     396 **************************************************************************/
     397static inline void list_remote_unlink( cxy_t          cxy,
     398                                       list_entry_t * entry )
     399{
     400        list_entry_t * pred;
     401    list_entry_t * next;
     402
     403        pred = hal_remote_lpt( XPTR( cxy , &entry->pred ) );
     404        next = hal_remote_lpt( XPTR( cxy , &entry->next ) );
     405
     406        hal_remote_spt( XPTR( cxy , &pred->next ) , next );
     407        hal_remote_spt( XPTR( cxy , &next->pred ) , pred );
     408}
     409
     410
     411
    280412#endif  /* _LIST_H_ */
  • trunk/kernel/libk/remote_barrier.c

    r629 r632  
    506506                                    uint32_t    nthreads )
    507507{
    508     page_t        * dqt_page;
    509508    xptr_t          dqt_page_xp;     
    510509    page_t        * rpc_page;
     
    514513    uint32_t        z;             // actual DQT size == max(x_size,y_size)
    515514    uint32_t        levels;        // actual number of DQT levels
    516     kmem_req_t      req;           // kmem request
    517515    xptr_t          rpc_xp;        // extended pointer on RPC descriptors array
    518516    rpc_desc_t    * rpc;           // pointer on RPC descriptors array
     
    522520    uint32_t        y;             // Y coordinate in QDT mesh
    523521    uint32_t        l;             // level coordinate
     522    kmem_req_t      req;           // kmem request
    524523
    525524    // compute size and number of DQT levels
     
    554553    cxy_t          ref_cxy = GET_CXY( ref_xp );
    555554
    556     // 1. allocate memory for DQT barrier descriptor in reference cluster
    557     if( ref_cxy == local_cxy )                   
    558      {
    559         req.type     = KMEM_PAGE;
    560         req.size     = 2;               // 4 pages == 16 Kbytes
    561         req.flags    = AF_ZERO;
    562         dqt_page     = kmem_alloc( &req );
    563         dqt_page_xp  = XPTR( local_cxy , dqt_page );
    564     }
    565     else                                         
    566     {
    567         rpc_pmem_get_pages_client( ref_cxy,
    568                                    2,
    569                                    &dqt_page );
    570         dqt_page_xp  = XPTR( ref_cxy , dqt_page );
    571     }
    572 
    573     if( dqt_page == NULL ) return NULL;
     555    // 1. allocate 4 4 Kbytes pages for DQT barrier descriptor in reference cluster
     556    dqt_page_xp = ppm_remote_alloc_pages( ref_cxy , 2 );
     557
     558    if( dqt_page_xp == XPTR_NULL ) return NULL;
    574559
    575560    // get pointers on DQT barrier descriptor
     
    948933
    949934    // 4. release memory allocated for barrier descriptor
    950     xptr_t   page_xp = ppm_base2page( barrier_xp );
    951     page_t * page    = GET_PTR( page_xp );
    952 
    953     if( barrier_cxy == local_cxy )                   
    954     {
    955         req.type      = KMEM_PAGE;
    956         req.ptr       = page;
    957         kmem_free( &req );
    958     }
    959     else                                         
    960     {
    961         rpc_pmem_release_pages_client( barrier_cxy,
    962                                        page );
    963     }
     935    xptr_t   page_xp  = ppm_base2page( barrier_xp );
     936    cxy_t    page_cxy = GET_CXY( page_xp );
     937    page_t * page_ptr = GET_PTR( page_xp );
     938
     939    ppm_remote_free_pages( page_cxy , page_ptr );
    964940
    965941#if DEBUG_BARRIER_DESTROY
Note: See TracChangeset for help on using the changeset viewer.