1c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings/*
2c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings * cpu_rmap.c: CPU affinity reverse-map support
3c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings * Copyright 2011 Solarflare Communications Inc.
4c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings *
5c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings * This program is free software; you can redistribute it and/or modify it
6c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings * under the terms of the GNU General Public License version 2 as published
7c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings * by the Free Software Foundation, incorporated herein by reference.
8c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings */
9c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings
10c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings#include <linux/cpumask.h>
11c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings#include <linux/gfp.h>
12c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings#include <linux/slab.h>
13c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings
14c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings/**
15c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings * struct cpu_rmap - CPU affinity reverse-map
16c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings * @size: Number of objects to be reverse-mapped
17c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings * @used: Number of objects added
18c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings * @obj: Pointer to array of object pointers
19c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings * @near: For each CPU, the index and distance to the nearest object,
20c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings *      based on affinity masks
21c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings */
22c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchingsstruct cpu_rmap {
23c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings	u16		size, used;
24c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings	void		**obj;
25c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings	struct {
26c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings		u16	index;
27c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings		u16	dist;
28c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings	}		near[0];
29c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings};
30c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings#define CPU_RMAP_DIST_INF 0xffff
31c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings
32c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchingsextern struct cpu_rmap *alloc_cpu_rmap(unsigned int size, gfp_t flags);
33c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings
34c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings/**
35c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings * free_cpu_rmap - free CPU affinity reverse-map
36c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings * @rmap: Reverse-map allocated with alloc_cpu_rmap(), or %NULL
37c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings */
38c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchingsstatic inline void free_cpu_rmap(struct cpu_rmap *rmap)
39c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings{
40c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings	kfree(rmap);
41c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings}
42c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings
43c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchingsextern int cpu_rmap_add(struct cpu_rmap *rmap, void *obj);
44c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchingsextern int cpu_rmap_update(struct cpu_rmap *rmap, u16 index,
45c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings			   const struct cpumask *affinity);
46c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings
47c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchingsstatic inline u16 cpu_rmap_lookup_index(struct cpu_rmap *rmap, unsigned int cpu)
48c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings{
49c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings	return rmap->near[cpu].index;
50c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings}
51c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings
52c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchingsstatic inline void *cpu_rmap_lookup_obj(struct cpu_rmap *rmap, unsigned int cpu)
53c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings{
54c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings	return rmap->obj[rmap->near[cpu].index];
55c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings}
56c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings
57c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings#ifdef CONFIG_GENERIC_HARDIRQS
58c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings
59c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings/**
60c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings * alloc_irq_cpu_rmap - allocate CPU affinity reverse-map for IRQs
61c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings * @size: Number of objects to be mapped
62c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings *
63c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings * Must be called in process context.
64c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings */
65c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchingsstatic inline struct cpu_rmap *alloc_irq_cpu_rmap(unsigned int size)
66c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings{
67c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings	return alloc_cpu_rmap(size, GFP_KERNEL);
68c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings}
69c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchingsextern void free_irq_cpu_rmap(struct cpu_rmap *rmap);
70c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings
71c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchingsextern int irq_cpu_rmap_add(struct cpu_rmap *rmap, int irq);
72c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings
73c39649c331c70952700f99832b03f87e9d7f5b4bBen Hutchings#endif
74