2 ###############################################################################
4 # IPFire.org - A linux based firewall #
5 # Copyright (C) 2016 IPFire Network Development Team #
7 # This program is free software: you can redistribute it and/or modify #
8 # it under the terms of the GNU General Public License as published by #
9 # the Free Software Foundation, either version 3 of the License, or #
10 # (at your option) any later version. #
12 # This program is distributed in the hope that it will be useful, #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15 # GNU General Public License for more details. #
17 # You should have received a copy of the GNU General Public License #
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
20 ###############################################################################
24 for interrupt
in /proc
/irq
/*; do
25 [ -d "${interrupt}" ] ||
continue
27 basename "${interrupt}"
33 interrupt_use_smp_affinity
() {
34 local processors
=$
(system_get_processors
)
36 # There is no point in this feature when there is only one processor
37 [ ${processors} -eq 1 ] && return ${EXIT_FALSE}
47 [ -d "${f}" ] ||
continue
49 local interrupt
=$
(dirname ${f})
54 interrupts_for_device
() {
59 __interrupts_for
"/proc/irq/*/${device}"
62 interrupts_for_device_queue
() {
68 __interrupts_for
"/proc/irq/*/${device}-[rt]x${queue}"
71 interrupt_get_smp_affinity
() {
76 local path
="/proc/irq/${interrupt}/smp_affinity"
77 assert
[ -r "${path}" ]
79 # Convert bitmap to list of processors
80 __bitmap_to_processor_ids $
(<${path})
83 __bitmap_to_processor_ids
() {
86 # This function shifts the bit map to the right
87 # and if the least significant bit equals one
88 # the index of that bit is returned.
91 while [ $
(( 0x
${bitmap} )) -gt 0 ]; do
92 if [ $
(( 0x
${bitmap} & 0x1 )) -eq 1 ]; then
96 bitmap
=$
(( 0x
${bitmap} >> 1 ))
101 __processor_id_to_bitmap
() {
105 interrupt_set_smp_affinity
() {
111 # Processor ID must be greater or equal than zero
112 # and not larger than the highest processor index
113 local num_processors
=$
(system_get_processors
)
114 if [ ${processor} -ge ${num_processors} ]; then
115 error
"Invalid processor ID ${processor}"
119 local path
="/proc/irq/${interrupt}/smp_affinity"
120 assert
[ -w "${path}" ]
122 log DEBUG
"Setting SMP affinity for interrupt ${interrupt} to processor ${processor}"
124 # Write processor ID as hex value
125 __processor_id_to_bitmap
${processor} > ${path}
128 interrupt_choose_least_busy_processor
() {
129 local processors
=$
(system_get_processors
)
132 # Create an array with the number of interrupts
133 # already handled by each processor
136 for i
in $
(range
${processors}); do
140 local processor interrupt
141 for interrupt
in $
(interrupts_list
); do
142 for processor
in $
(interrupt_get_smp_affinity
${interrupt}); do
143 interrupts
[${processor}]=$(( ${interrupts[${processor}]} + 1 ))
147 # Walk through that map and find the first processor with the
148 # smallest number of interrupts handled so far
150 local least_busy_index
=0
151 for i
in $
(range
${processors}); do
152 if [ ${interrupts[${least_busy_index}]} -gt ${interrupts[${i}]} ]; then
153 least_busy_index
=${i}
157 print
"${least_busy_index}"