@@ -9,23 +9,27 @@ use core2::io::Write;
99use rpc:: rpc:: * ;
1010use rpc:: RPCClient ;
1111
12- use super :: super :: dcm:: resource_alloc:: dcm_resource_alloc;
13- use super :: super :: kernelrpc:: * ;
14- use crate :: arch:: rackscale:: controller:: get_local_pid;
15- use crate :: arch:: rackscale:: controller:: UNFULFILLED_CORE_ASSIGNMENTS ;
1612use crate :: error:: KError ;
1713use crate :: fs:: cnrfs:: MlnrKernelNode ;
1814use crate :: fs:: { cnrfs, NrLock } ;
1915use crate :: memory:: VAddr ;
2016use crate :: nr;
2117use crate :: nr:: KernelNode ;
2218
19+ use super :: super :: client:: { get_local_client_id, get_num_clients} ;
20+ use super :: super :: controller:: {
21+ get_local_pid, HWTHREADS , HWTHREADS_BUSY , UNFULFILLED_CORE_ASSIGNMENTS ,
22+ } ;
23+ use super :: super :: dcm:: resource_alloc:: dcm_resource_alloc;
24+ use super :: super :: kernelrpc:: * ;
25+ use super :: super :: systemops:: { gtid_to_local, local_to_gtid} ;
26+
2327#[ derive( Debug , Clone , Copy ) ]
2428pub ( crate ) struct RequestCoreReq {
2529 pub core_id : u64 ,
2630 pub entry_point : u64 ,
2731}
28- unsafe_abomonate ! ( RequestCoreReq : core_id , entry_point) ;
32+ unsafe_abomonate ! ( RequestCoreReq : entry_point) ;
2933
3034#[ derive( Debug ) ]
3135pub ( crate ) struct RequestCoreWorkRes {
@@ -66,10 +70,6 @@ pub(crate) fn rpc_request_core(
6670 return Err ( RPCError :: ExtraData ) ;
6771 }
6872 info ! ( "RequestCore() {:?}" , res) ;
69-
70- // TODO: could optimize for local case and call local function here
71- // for now, will handle all the same (i.e., client ask for work from controller)
72-
7373 return res. ret ;
7474 } else {
7575 return Err ( RPCError :: MalformedResponse ) ;
@@ -95,24 +95,48 @@ pub(crate) fn handle_request_core(hdr: &mut RPCHeader, payload: &mut [u8]) -> Re
9595 }
9696 } ;
9797
98- let node = dcm_resource_alloc ( local_pid, true ) ;
99-
100- // Add request to be handled later.
101- // TODO: handle local differently? For now, for simplicity, handle all the same
102- // TODO: check capacity of core assignments?
103- log:: info!( "Logged unfulfilled core assignment for {:?}" , node) ;
104- {
105- let mut core_request_vec = UNFULFILLED_CORE_ASSIGNMENTS . lock ( ) ;
106- let mut deque = core_request_vec
107- . get_mut ( node as usize )
108- . expect ( "failed to fetch core assignment deque for node" ) ;
109- deque. push_back ( * core_req) ;
98+ let client_id = dcm_resource_alloc ( local_pid, true ) ;
99+
100+ // controller chooses a core id - right now, sequentially for cores on the client_id.
101+ let num_clients = get_num_clients ( ) ;
102+ let mut rack_hwthreads_busy = HWTHREADS_BUSY . lock ( ) ;
103+ let mut index = 0 ;
104+ loop {
105+ //
106+ match rack_hwthreads_busy[ local_to_gtid ( index, client_id) ] {
107+ // thread is busy, keep looking
108+ Some ( true ) => index += 1 ,
109+ // found an empty thread! set to busy and break
110+ Some ( false ) => {
111+ rack_hwthreads_busy[ index] = Some ( true ) ;
112+ break ;
113+ }
114+ // Ran out of threads for client; DCM should not have allowed this to happen
115+ None => panic ! (
116+ "Should never happen - no empty hwthreads found for client {:?}" ,
117+ client_id
118+ ) ,
119+ }
110120 }
111121
122+ let rack_hwthreads = HWTHREADS . lock ( ) ;
123+ let gtid = rack_hwthreads[ index] . id ;
124+ log:: info!( "Chose thread id {:?} for request" , gtid) ;
125+
112126 // Construct and return result
113127 let res = KernelRpcRes {
114- ret : convert_return ( Ok ( ( node , 0 ) ) ) ,
128+ ret : convert_return ( Ok ( ( gtid as u64 , 0 ) ) ) ,
115129 } ;
130+
131+ // can handle request locally if same node otherwise must queue for remote node to handle
132+ if client_id != hdr. client_id {
133+ log:: info!( "Logged unfulfilled core assignment for {:?}" , client_id) ;
134+ let mut core_request_vec = UNFULFILLED_CORE_ASSIGNMENTS . lock ( ) ;
135+ let mut deque = core_request_vec
136+ . get_mut ( client_id as usize )
137+ . expect ( "failed to fetch core assignment deque for client_id" ) ;
138+ deque. push_back ( * core_req) ;
139+ }
116140 construct_ret ( hdr, payload, res)
117141}
118142
@@ -143,7 +167,10 @@ pub(crate) fn request_core_work(rpc_client: &mut dyn RPCClient) -> () {
143167 // But not sure if we can do that here because 1) client syscalls are ferried to the controller
144168 // and 2) how do you run it in the context of the (correct) remote process?
145169 // for now, copied & modified code from original syscall impl
146- let gtid: usize = core_request. core_id . try_into ( ) . unwrap ( ) ;
170+ let gtid: usize = gtid_to_local (
171+ core_request. core_id . try_into ( ) . unwrap ( ) ,
172+ get_local_client_id ( ) ,
173+ ) ;
147174 let mut affinity = None ;
148175 for thread in atopology:: MACHINE_TOPOLOGY . threads ( ) {
149176 if thread. id == gtid {
0 commit comments