diff options
author | Kiran Patil <kiran.patil@intel.com> | 2011-06-20 19:59:20 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-06-29 17:29:36 -0400 |
commit | 064287eee372e8a2effe77fb909a40da9e7a1fd7 (patch) | |
tree | 0cfda86145d0bae9dedc70206c1ff1f4bb773480 /drivers/scsi | |
parent | 1ff9918b625457ce20d450d00f9ed0a12ba191b7 (diff) |
[SCSI] fcoe: Round-robin based selection of CPU for post-processing of incoming commands
Problem: Earlier mechanism of selection of CPU was, to select the same CPU
which has received incoming request. Hence in case of rx_id = 0xFFFF,
request was always posted to same NetRx queue, hence only 1 CPU is utilized
for handling the command. It was also causing problem of "running out of
exchanges from per CPU pool of exchanges (in case of DDP offload)
Fix: Implemented new algo. to select CPU for post-processing of
incoming commands when rx_id is unknown. This is simple Round robin
algo. for CPU selection.
Notes/Dependencies: N/A
Signed-off-by: Kiran Patil <kiran.patil@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 6378c5883514..da73115ddf4d 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -1245,6 +1245,36 @@ static int fcoe_cpu_callback(struct notifier_block *nfb, | |||
1245 | } | 1245 | } |
1246 | 1246 | ||
1247 | /** | 1247 | /** |
1248 | * fcoe_select_cpu() - Selects CPU to handle post-processing of incoming | ||
1249 | * command. | ||
1250 | * @curr_cpu: CPU which received request | ||
1251 | * | ||
1252 | * This routine selects next CPU based on cpumask. | ||
1253 | * | ||
1254 | * Returns: int (CPU number). Caller to verify if returned CPU is online or not. | ||
1255 | */ | ||
1256 | static unsigned int fcoe_select_cpu(unsigned int curr_cpu) | ||
1257 | { | ||
1258 | static unsigned int selected_cpu; | ||
1259 | |||
1260 | if (num_online_cpus() == 1) | ||
1261 | return curr_cpu; | ||
1262 | /* | ||
1263 | * Doing following check, to skip "curr_cpu (smp_processor_id)" | ||
1264 | * from selection of CPU is intentional. This is to avoid same CPU | ||
1265 | * doing post-processing of command. "curr_cpu" to just receive | ||
1266 | * incoming request in case where rx_id is UNKNOWN and all other | ||
1267 | * CPU to actually process the command(s) | ||
1268 | */ | ||
1269 | do { | ||
1270 | selected_cpu = cpumask_next(selected_cpu, cpu_online_mask); | ||
1271 | if (selected_cpu >= nr_cpu_ids) | ||
1272 | selected_cpu = cpumask_first(cpu_online_mask); | ||
1273 | } while (selected_cpu == curr_cpu); | ||
1274 | return selected_cpu; | ||
1275 | } | ||
1276 | |||
1277 | /** | ||
1248 | * fcoe_rcv() - Receive packets from a net device | 1278 | * fcoe_rcv() - Receive packets from a net device |
1249 | * @skb: The received packet | 1279 | * @skb: The received packet |
1250 | * @netdev: The net device that the packet was received on | 1280 | * @netdev: The net device that the packet was received on |
@@ -1320,9 +1350,16 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev, | |||
1320 | */ | 1350 | */ |
1321 | if (ntoh24(fh->fh_f_ctl) & FC_FC_EX_CTX) | 1351 | if (ntoh24(fh->fh_f_ctl) & FC_FC_EX_CTX) |
1322 | cpu = ntohs(fh->fh_ox_id) & fc_cpu_mask; | 1352 | cpu = ntohs(fh->fh_ox_id) & fc_cpu_mask; |
1323 | else | 1353 | else { |
1324 | cpu = smp_processor_id(); | 1354 | cpu = smp_processor_id(); |
1325 | 1355 | ||
1356 | if ((fh->fh_type == FC_TYPE_FCP) && | ||
1357 | (ntohs(fh->fh_rx_id) == FC_XID_UNKNOWN)) { | ||
1358 | do { | ||
1359 | cpu = fcoe_select_cpu(cpu); | ||
1360 | } while (!cpu_online(cpu)); | ||
1361 | } | ||
1362 | } | ||
1326 | fps = &per_cpu(fcoe_percpu, cpu); | 1363 | fps = &per_cpu(fcoe_percpu, cpu); |
1327 | spin_lock_bh(&fps->fcoe_rx_list.lock); | 1364 | spin_lock_bh(&fps->fcoe_rx_list.lock); |
1328 | if (unlikely(!fps->thread)) { | 1365 | if (unlikely(!fps->thread)) { |