/arch/arm/nwfpe/

26 05:21:34 -0400 Add generic helpers for arch IPI function calls' href='/cgit/cgit.cgi/litmus-rt-odroidx.git/commit/kernel/smp.c?id=3d4422332711ef48ef0f132f1fcbfcbd56c7f3d1'>3d442233271
3d442233271
59190f42134
641cd4cfcdc
0b13fda1e09


3d442233271
8969a5ede0f
3d442233271

8969a5ede0f



0b13fda1e09




3d442233271

6e2756376c7
3d442233271


0b13fda1e09



3d442233271


0b13fda1e09

3d442233271

8969a5ede0f
0b13fda1e09
8969a5ede0f










eaa958402ea
8969a5ede0f



69dd647f969
8969a5ede0f













0b13fda1e09
8969a5ede0f

7babe8db99d
3d442233271
8969a5ede0f
3d442233271







8969a5ede0f



7babe8db99d
3d442233271
7babe8db99d
3d442233271
8969a5ede0f
8969a5ede0f

0b13fda1e09


8969a5ede0f
6e2756376c7
8969a5ede0f


6e2756376c7




8969a5ede0f


0b13fda1e09


8969a5ede0f
8969a5ede0f





0b13fda1e09
8969a5ede0f
0b13fda1e09
8969a5ede0f

0b13fda1e09
8969a5ede0f
3d442233271


0b13fda1e09


3d442233271
6e2756376c7

3d442233271

3d442233271
6e2756376c7
3d442233271





561920a0d2b
15d0d3b3371






0b13fda1e09

561920a0d2b
3d442233271



6e2756376c7
3d442233271











269c861baa2




15d0d3b3371







0b13fda1e09

3d442233271
8969a5ede0f
3d442233271

8969a5ede0f


3d442233271
8969a5ede0f


3d442233271



3d442233271
8969a5ede0f





3d442233271




8969a5ede0f
3d442233271
3d442233271




0b13fda1e09

3d442233271



15d0d3b3371
0b13fda1e09
3d442233271
269c861baa2




15d0d3b3371


3d442233271
15d0d3b3371

3d442233271
0b13fda1e09
15d0d3b3371
3d442233271
3d442233271
0b13fda1e09


3d442233271
15d0d3b3371



8969a5ede0f
0b13fda1e09
8969a5ede0f


3d442233271


d7240b98801

3d442233271



3d442233271






8691e5a8f69
3d442233271
8969a5ede0f


3d442233271
0b13fda1e09
f73be6dedf4
3d442233271
0b13fda1e09





269c861baa2







3d442233271
0b13fda1e09
3d442233271


0b13fda1e09


3d442233271
0b13fda1e09

6e2756376c7
0b13fda1e09
3d442233271
0b13fda1e09





3d442233271


0b13fda1e09
f73be6dedf4
3d442233271







0b13fda1e09


3d442233271
6e2756376c7

3d442233271
6e2756376c7

269c861baa2







3d442233271
6e2756376c7
3d442233271

0b13fda1e09

ce47d974f71
0b13fda1e09

ce47d974f71

3d442233271
54b11e6d57a

3d442233271

0b13fda1e09

3d442233271
3d442233271







54b11e6d57a
0b13fda1e09
3d442233271
54b11e6d57a
3d442233271
0b13fda1e09
3d442233271
269c861baa2







3d442233271
0b13fda1e09
54b11e6d57a
0b13fda1e09
54b11e6d57a
0b13fda1e09
54b11e6d57a





0b13fda1e09
54b11e6d57a





3d442233271

8969a5ede0f

3d442233271
8969a5ede0f
3d442233271

8969a5ede0f
0b13fda1e09
8969a5ede0f
3d442233271
8969a5ede0f


0b13fda1e09

8969a5ede0f


0b13fda1e09
8969a5ede0f
3d442233271
561920a0d2b

0b13fda1e09

561920a0d2b


3d442233271
8969a5ede0f
3d442233271
0b13fda1e09
54b11e6d57a
6e2756376c7
3d442233271
54b11e6d57a
3d442233271




0b13fda1e09

3d442233271
54b11e6d57a
3d442233271







8691e5a8f69
3d442233271
3d442233271
54b11e6d57a
3d442233271
0b13fda1e09
54b11e6d57a
3d442233271




8969a5ede0f
3d442233271



8969a5ede0f
3d442233271



8969a5ede0f
3d442233271



8969a5ede0f
3d442233271
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500



                                              
   
                           
                          
                         


                         
                      
                      

                                                                   



                                      




                                                                           

      
                                       


                           



                                        


                          

                                     

  
                                                              
                                                                      










                                                                         
                                                                       



                                                  
                         













                                                                   
                                              

  
                                                
 
                                                     







                                                                             



                                                                
                 
 
                                      
 
  

                                                                        


                                                                        
   
                                                        


                                           




                                                   


                                    


                                                              
           





                                                     
 
          
                                                       

                 
 
                                      


  


                                                         
   

                                                                          

                                                                         
                            
                





                                                  
          






                                                                         

                                                                    
           



                                                        
                                    











                                                                          




                                                                            







                                                                       

                                                                     
           
                                                                       

                         


                                                            
                                 


                                                      



                                               
                                         





                                                         




                                         
                                       
         




                  

                                                                     



                                                                        
                                
                        
 




                                                                            


                                           
 

                                              
 
                                                                            
                                      
 
                  


                                                                      
                   



                                         
                  
                                                                         


                                               


         

                                                         



                                                                  






                                                                            
                                      
 


                                     
                            
                     
                    
 





                                                                  







                                                                             
 
                              


                                         


                                                                    
 

                                                                
 
                                       
 





                                                             


                  
 
                   







                                                              


                                                                  
   

                                                                       
 

                       







                                                                              
 
                                             

 

                                                                           
                                        

                                                  

      
   

                                                                   

                                                                  

                                                                 
  







                                                                          
                                                       
                                                                        
 
                                        
                            
                                                         
 







                                                                             
 
                                                            
                                                       
                            
                                                                   
 





                                                                
                                 





                                                                             

         

                                        
 
                                              

                              
                                                          
                                                   
                                                   
 


                                                                       

                                                                       


                                                            
 
                                                   
 

                                                                 

                                                                  


                 
                                                   
                                                        
 
                                                      
                 
                                          
 
                                      




                                                                  

                                                                 
  
             







                                                                           
                                                                 
 
                          
                                                                  
                         
 
                 




                                 
                                       



                          
                                         



                            
                                           



                              
                                             
 
/*
 * Generic helpers for smp ipi calls
 *
 * (C) Jens Axboe <jens.axboe@oracle.com> 2008
 */
#include <linux/rcupdate.h>
#include <linux/rculist.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/percpu.h>
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/cpu.h>

static DEFINE_PER_CPU(struct call_single_queue, call_single_queue);

static struct {
	struct list_head	queue;
	spinlock_t		lock;
} call_function __cacheline_aligned_in_smp =
	{
		.queue		= LIST_HEAD_INIT(call_function.queue),
		.lock		= __SPIN_LOCK_UNLOCKED(call_function.lock),
	};

enum {
	CSD_FLAG_LOCK		= 0x01,
};

struct call_function_data {
	struct call_single_data	csd;
	spinlock_t		lock;
	unsigned int		refs;
	cpumask_var_t		cpumask;
};

struct call_single_queue {
	struct list_head	list;
	spinlock_t		lock;
};

static DEFINE_PER_CPU(struct call_function_data, cfd_data) = {
	.lock			= __SPIN_LOCK_UNLOCKED(cfd_data.lock),
};

static int
hotplug_cfd(struct notifier_block *nfb, unsigned long action, void *hcpu)
{
	long cpu = (long)hcpu;
	struct call_function_data *cfd = &per_cpu(cfd_data, cpu);

	switch (action) {
	case CPU_UP_PREPARE:
	case CPU_UP_PREPARE_FROZEN:
		if (!zalloc_cpumask_var_node(&cfd->cpumask, GFP_KERNEL,
				cpu_to_node(cpu)))
			return NOTIFY_BAD;
		break;

#ifdef CONFIG_HOTPLUG_CPU
	case CPU_UP_CANCELED:
	case CPU_UP_CANCELED_FROZEN:

	case CPU_DEAD:
	case CPU_DEAD_FROZEN:
		free_cpumask_var(cfd->cpumask);
		break;
#endif
	};

	return NOTIFY_OK;
}

static struct notifier_block __cpuinitdata hotplug_cfd_notifier = {
	.notifier_call		= hotplug_cfd,
};

static int __cpuinit init_call_single_data(void)
{
	void *cpu = (void *)(long)smp_processor_id();
	int i;

	for_each_possible_cpu(i) {
		struct call_single_queue *q = &per_cpu(call_single_queue, i);

		spin_lock_init(&q->lock);
		INIT_LIST_HEAD(&q->list);
	}

	hotplug_cfd(&hotplug_cfd_notifier, CPU_UP_PREPARE, cpu);
	register_cpu_notifier(&hotplug_cfd_notifier);

	return 0;
}
early_initcall(init_call_single_data);

/*
 * csd_lock/csd_unlock used to serialize access to per-cpu csd resources
 *
 * For non-synchronous ipi calls the csd can still be in use by the
 * previous function call. For multi-cpu calls its even more interesting
 * as we'll have to ensure no other cpu is observing our csd.
 */
static void csd_lock_wait(struct call_single_data *data)
{
	while (data->flags & CSD_FLAG_LOCK)
		cpu_relax();
}

static void csd_lock(struct call_single_data *data)
{
	csd_lock_wait(data);
	data->flags = CSD_FLAG_LOCK;

	/*
	 * prevent CPU from reordering the above assignment
	 * to ->flags with any subsequent assignments to other
	 * fields of the specified call_single_data structure:
	 */
	smp_mb();
}

static void csd_unlock(struct call_single_data *data)
{
	WARN_ON(!(data->flags & CSD_FLAG_LOCK));

	/*
	 * ensure we're all done before releasing data:
	 */
	smp_mb();

	data->flags &= ~CSD_FLAG_LOCK;
}

/*
 * Insert a previously allocated call_single_data element
 * for execution on the given CPU. data must already have
 * ->func, ->info, and ->flags set.
 */
static
void generic_exec_single(int cpu, struct call_single_data *data, int wait)
{
	struct call_single_queue *dst = &per_cpu(call_single_queue, cpu);
	unsigned long flags;
	int ipi;

	spin_lock_irqsave(&dst->lock, flags);
	ipi = list_empty(&dst->list);
	list_add_tail(&data->list, &dst->list);
	spin_unlock_irqrestore(&dst->lock, flags);

	/*
	 * The list addition should be visible before sending the IPI
	 * handler locks the list to pull the entry off it because of
	 * normal cache coherency rules implied by spinlocks.
	 *
	 * If IPIs can go out of order to the cache coherency protocol
	 * in an architecture, sufficient synchronisation should be added
	 * to arch code to make it appear to obey cache coherency WRT
	 * locking and barrier primitives. Generic code isn't really
	 * equipped to do the right thing...
	 */
	if (ipi)
		arch_send_call_function_single_ipi(cpu);

	if (wait)
		csd_lock_wait(data);
}

/*
 * Invoked by arch to handle an IPI for call function. Must be called with
 * interrupts disabled.
 */
void generic_smp_call_function_interrupt(void)
{
	struct call_function_data *data;
	int cpu = get_cpu();

	/*
	 * Shouldn't receive this interrupt on a cpu that is not yet online.
	 */
	WARN_ON_ONCE(!cpu_online(cpu));

	/*
	 * Ensure entry is visible on call_function_queue after we have
	 * entered the IPI. See comment in smp_call_function_many.
	 * If we don't have this, then we may miss an entry on the list
	 * and never get another IPI to process it.
	 */
	smp_mb();

	/*
	 * It's ok to use list_for_each_rcu() here even though we may
	 * delete 'pos', since list_del_rcu() doesn't clear ->next
	 */
	list_for_each_entry_rcu(data, &call_function.queue, csd.list) {
		int refs;

		spin_lock(&data->lock);
		if (!cpumask_test_cpu(cpu, data->cpumask)) {
			spin_unlock(&data->lock);
			continue;
		}
		cpumask_clear_cpu(cpu, data->cpumask);
		spin_unlock(&data->lock);

		data->csd.func(data->csd.info);

		spin_lock(&data->lock);
		WARN_ON(data->refs == 0);
		refs = --data->refs;
		if (!refs) {
			spin_lock(&call_function.lock);
			list_del_rcu(&data->csd.list);
			spin_unlock(&call_function.lock);
		}
		spin_unlock(&data->lock);

		if (refs)
			continue;

		csd_unlock(&data->csd);
	}