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 list_directory
"/proc/irq"; do
25 if interrupt_exists
"${interrupt}"; then
32 local interrupt
="${1}"
34 [ -d "/proc/irq/${interrupt}" ]
37 interrupt_use_smp_affinity
() {
38 local processors
=$
(system_get_processors
)
40 # There is no point in this feature when there is only one processor
41 [ ${processors} -eq 1 ] && return ${EXIT_FALSE}
51 [ -d "${f}" ] ||
continue
53 local interrupt
=$
(dirname ${f})
58 interrupts_for_device
() {
63 __interrupts_for
"/proc/irq/*/${device}"
66 interrupts_for_device_queue
() {
72 __interrupts_for
"/proc/irq/*/${device}-[rt]x${queue}"
75 interrupt_get_smp_affinity
() {
80 local path
="/proc/irq/${interrupt}/smp_affinity"
81 assert
[ -r "${path}" ]
83 # Convert bitmap to list of processors
84 __bitmap_to_processor_ids $
(<${path})
87 __bitmap_to_processor_ids
() {
90 # This function shifts the bit map to the right
91 # and if the least significant bit equals one
92 # the index of that bit is returned.
95 while [ $
(( 0x
${bitmap} )) -gt 0 ]; do
96 if [ $
(( 0x
${bitmap} & 0x1 )) -eq 1 ]; then
100 bitmap
=$
(( 0x
${bitmap} >> 1 ))
105 __processor_id_to_bitmap
() {
109 interrupt_set_smp_affinity
() {
115 # Processor ID must be greater or equal than zero
116 # and not larger than the highest processor index
117 local num_processors
=$
(system_get_processors
)
118 if [ ${processor} -ge ${num_processors} ]; then
119 error
"Invalid processor ID ${processor}"
123 local path
="/proc/irq/${interrupt}/smp_affinity"
124 assert
[ -w "${path}" ]
126 log DEBUG
"Setting SMP affinity for interrupt ${interrupt} to processor ${processor}"
128 # Write processor ID as hex value
129 __processor_id_to_bitmap
${processor} > ${path}
132 interrupt_choose_least_busy_processor
() {
133 local processors
=$
(system_get_processors
)
136 # Create an array with the number of interrupts
137 # already handled by each processor
140 for i
in $
(range
${processors}); do
144 local processor interrupt
145 for interrupt
in $
(interrupts_list
); do
146 for processor
in $
(interrupt_get_smp_affinity
${interrupt}); do
147 interrupts
[${processor}]=$(( ${interrupts[${processor}]} + 1 ))
151 # Walk through that map and find the first processor with the
152 # smallest number of interrupts handled so far
154 local least_busy_index
=0
155 for i
in $
(range
${processors}); do
156 if [ ${interrupts[${least_busy_index}]} -gt ${interrupts[${i}]} ]; then
157 least_busy_index
=${i}
161 print
"${least_busy_index}"