Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'sfc-filter-locking'

Edward Cree says:

====================
sfc: rework locking around filter management

The use of a spinlock to protect filter state combined with the need for a
sleeping operation (MCDI) to apply that state to the NIC (on EF10) led to
unfixable race conditions, around the handling of filter restoration after
an MC reboot.
So, this patch series removes the requirement to be able to modify the SW
filter table from atomic context, by using a workqueue to request
asynchronous filter operations (which are needed for ARFS). Then, the
filter table locks are changed to mutexes, replacing the dance of spinlocks
and 'busy' flags. Also, a mutex is added to protect the RSS context state,
since otherwise a similar race is possible around restoring that after an
MC reboot. While we're at it, fix a couple of other related bugs.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+402 -486
+192 -357
drivers/net/ethernet/sfc/ef10.c
··· 96 96 MC_CMD_GET_PARSER_DISP_INFO_OUT_SUPPORTED_MATCHES_MAXNUM * 2]; 97 97 unsigned int rx_match_count; 98 98 99 + struct rw_semaphore lock; /* Protects entries */ 99 100 struct { 100 101 unsigned long spec; /* pointer to spec plus flag bits */ 101 - /* BUSY flag indicates that an update is in progress. AUTO_OLD is 102 - * used to mark and sweep MAC filters for the device address lists. 103 - */ 104 - #define EFX_EF10_FILTER_FLAG_BUSY 1UL 102 + /* AUTO_OLD is used to mark and sweep MAC filters for the device address lists. */ 103 + /* unused flag 1UL */ 105 104 #define EFX_EF10_FILTER_FLAG_AUTO_OLD 2UL 106 105 #define EFX_EF10_FILTER_FLAGS 3UL 107 106 u64 handle; /* firmware handle */ 108 107 } *entry; 109 - wait_queue_head_t waitq; 110 108 /* Shadow of net_device address lists, guarded by mac_lock */ 111 109 struct efx_ef10_dev_addr dev_uc_list[EFX_EF10_FILTER_DEV_UC_MAX]; 112 110 struct efx_ef10_dev_addr dev_mc_list[EFX_EF10_FILTER_DEV_MC_MAX]; ··· 1499 1501 1500 1502 /* All our allocations have been reset */ 1501 1503 nic_data->must_realloc_vis = true; 1504 + nic_data->must_restore_rss_contexts = true; 1502 1505 nic_data->must_restore_filters = true; 1503 1506 nic_data->must_restore_piobufs = true; 1504 1507 efx_ef10_forget_old_piobufs(efx); ··· 2900 2901 { 2901 2902 int rc; 2902 2903 2904 + WARN_ON(!mutex_is_locked(&efx->rss_lock)); 2905 + 2903 2906 if (ctx->context_id == EFX_EF10_RSS_CONTEXT_INVALID) { 2904 2907 rc = efx_ef10_alloc_rss_context(efx, true, ctx, NULL); 2905 2908 if (rc) ··· 2931 2930 MCDI_DECLARE_BUF(keybuf, MC_CMD_RSS_CONTEXT_GET_KEY_OUT_LEN); 2932 2931 size_t outlen; 2933 2932 int rc, i; 2933 + 2934 + WARN_ON(!mutex_is_locked(&efx->rss_lock)); 2934 2935 2935 2936 BUILD_BUG_ON(MC_CMD_RSS_CONTEXT_GET_TABLE_IN_LEN != 2936 2937 MC_CMD_RSS_CONTEXT_GET_KEY_IN_LEN); ··· 2977 2974 2978 2975 static int efx_ef10_rx_pull_rss_config(struct efx_nic *efx) 2979 2976 { 2980 - return efx_ef10_rx_pull_rss_context_config(efx, &efx->rss_context); 2977 + int rc; 2978 + 2979 + mutex_lock(&efx->rss_lock); 2980 + rc = efx_ef10_rx_pull_rss_context_config(efx, &efx->rss_context); 2981 + mutex_unlock(&efx->rss_lock); 2982 + return rc; 2981 2983 } 2982 2984 2983 2985 static void efx_ef10_rx_restore_rss_contexts(struct efx_nic *efx) 2984 2986 { 2987 + struct efx_ef10_nic_data *nic_data = efx->nic_data; 2985 2988 struct efx_rss_context *ctx; 2986 2989 int rc; 2990 + 2991 + WARN_ON(!mutex_is_locked(&efx->rss_lock)); 2992 + 2993 + if (!nic_data->must_restore_rss_contexts) 2994 + return; 2987 2995 2988 2996 list_for_each_entry(ctx, &efx->rss_context.list, list) { 2989 2997 /* previous NIC RSS context is gone */ ··· 3009 2995 "; RSS filters may fail to be applied\n", 3010 2996 ctx->user_id, rc); 3011 2997 } 2998 + nic_data->must_restore_rss_contexts = false; 3012 2999 } 3013 3000 3014 3001 static int efx_ef10_pf_rx_push_rss_config(struct efx_nic *efx, bool user, ··· 4317 4302 struct efx_filter_spec *spec, 4318 4303 bool replace_equal) 4319 4304 { 4320 - struct efx_ef10_filter_table *table = efx->filter_state; 4321 4305 DECLARE_BITMAP(mc_rem_map, EFX_EF10_FILTER_SEARCH_LIMIT); 4306 + struct efx_ef10_nic_data *nic_data = efx->nic_data; 4307 + struct efx_ef10_filter_table *table; 4322 4308 struct efx_filter_spec *saved_spec; 4323 4309 struct efx_rss_context *ctx = NULL; 4324 4310 unsigned int match_pri, hash; 4325 4311 unsigned int priv_flags; 4312 + bool rss_locked = false; 4326 4313 bool replacing = false; 4314 + unsigned int depth, i; 4327 4315 int ins_index = -1; 4328 4316 DEFINE_WAIT(wait); 4329 4317 bool is_mc_recip; 4330 4318 s32 rc; 4331 4319 4320 + down_read(&efx->filter_sem); 4321 + table = efx->filter_state; 4322 + down_write(&table->lock); 4323 + 4332 4324 /* For now, only support RX filters */ 4333 4325 if ((spec->flags & (EFX_FILTER_FLAG_RX | EFX_FILTER_FLAG_TX)) != 4334 - EFX_FILTER_FLAG_RX) 4335 - return -EINVAL; 4326 + EFX_FILTER_FLAG_RX) { 4327 + rc = -EINVAL; 4328 + goto out_unlock; 4329 + } 4336 4330 4337 4331 rc = efx_ef10_filter_pri(table, spec); 4338 4332 if (rc < 0) 4339 - return rc; 4333 + goto out_unlock; 4340 4334 match_pri = rc; 4341 4335 4342 4336 hash = efx_ef10_filter_hash(spec); ··· 4354 4330 bitmap_zero(mc_rem_map, EFX_EF10_FILTER_SEARCH_LIMIT); 4355 4331 4356 4332 if (spec->flags & EFX_FILTER_FLAG_RX_RSS) { 4333 + mutex_lock(&efx->rss_lock); 4334 + rss_locked = true; 4357 4335 if (spec->rss_context) 4358 - ctx = efx_find_rss_context_entry(spec->rss_context, 4359 - &efx->rss_context.list); 4336 + ctx = efx_find_rss_context_entry(efx, spec->rss_context); 4360 4337 else 4361 4338 ctx = &efx->rss_context; 4362 - if (!ctx) 4363 - return -ENOENT; 4364 - if (ctx->context_id == EFX_EF10_RSS_CONTEXT_INVALID) 4365 - return -EOPNOTSUPP; 4339 + if (!ctx) { 4340 + rc = -ENOENT; 4341 + goto out_unlock; 4342 + } 4343 + if (ctx->context_id == EFX_EF10_RSS_CONTEXT_INVALID) { 4344 + rc = -EOPNOTSUPP; 4345 + goto out_unlock; 4346 + } 4366 4347 } 4367 4348 4368 4349 /* Find any existing filters with the same match tuple or 4369 - * else a free slot to insert at. If any of them are busy, 4370 - * we have to wait and retry. 4350 + * else a free slot to insert at. 4371 4351 */ 4372 - for (;;) { 4373 - unsigned int depth = 1; 4374 - unsigned int i; 4352 + for (depth = 1; depth < EFX_EF10_FILTER_SEARCH_LIMIT; depth++) { 4353 + i = (hash + depth) & (HUNT_FILTER_TBL_ROWS - 1); 4354 + saved_spec = efx_ef10_filter_entry_spec(table, i); 4375 4355 4376 - spin_lock_bh(&efx->filter_lock); 4377 - 4378 - for (;;) { 4379 - i = (hash + depth) & (HUNT_FILTER_TBL_ROWS - 1); 4380 - saved_spec = efx_ef10_filter_entry_spec(table, i); 4381 - 4382 - if (!saved_spec) { 4356 + if (!saved_spec) { 4357 + if (ins_index < 0) 4358 + ins_index = i; 4359 + } else if (efx_ef10_filter_equal(spec, saved_spec)) { 4360 + if (spec->priority < saved_spec->priority && 4361 + spec->priority != EFX_FILTER_PRI_AUTO) { 4362 + rc = -EPERM; 4363 + goto out_unlock; 4364 + } 4365 + if (!is_mc_recip) { 4366 + /* This is the only one */ 4367 + if (spec->priority == 4368 + saved_spec->priority && 4369 + !replace_equal) { 4370 + rc = -EEXIST; 4371 + goto out_unlock; 4372 + } 4373 + ins_index = i; 4374 + break; 4375 + } else if (spec->priority > 4376 + saved_spec->priority || 4377 + (spec->priority == 4378 + saved_spec->priority && 4379 + replace_equal)) { 4383 4380 if (ins_index < 0) 4384 4381 ins_index = i; 4385 - } else if (efx_ef10_filter_equal(spec, saved_spec)) { 4386 - if (table->entry[i].spec & 4387 - EFX_EF10_FILTER_FLAG_BUSY) 4388 - break; 4389 - if (spec->priority < saved_spec->priority && 4390 - spec->priority != EFX_FILTER_PRI_AUTO) { 4391 - rc = -EPERM; 4392 - goto out_unlock; 4393 - } 4394 - if (!is_mc_recip) { 4395 - /* This is the only one */ 4396 - if (spec->priority == 4397 - saved_spec->priority && 4398 - !replace_equal) { 4399 - rc = -EEXIST; 4400 - goto out_unlock; 4401 - } 4402 - ins_index = i; 4403 - goto found; 4404 - } else if (spec->priority > 4405 - saved_spec->priority || 4406 - (spec->priority == 4407 - saved_spec->priority && 4408 - replace_equal)) { 4409 - if (ins_index < 0) 4410 - ins_index = i; 4411 - else 4412 - __set_bit(depth, mc_rem_map); 4413 - } 4382 + else 4383 + __set_bit(depth, mc_rem_map); 4414 4384 } 4415 - 4416 - /* Once we reach the maximum search depth, use 4417 - * the first suitable slot or return -EBUSY if 4418 - * there was none 4419 - */ 4420 - if (depth == EFX_EF10_FILTER_SEARCH_LIMIT) { 4421 - if (ins_index < 0) { 4422 - rc = -EBUSY; 4423 - goto out_unlock; 4424 - } 4425 - goto found; 4426 - } 4427 - 4428 - ++depth; 4429 4385 } 4430 - 4431 - prepare_to_wait(&table->waitq, &wait, TASK_UNINTERRUPTIBLE); 4432 - spin_unlock_bh(&efx->filter_lock); 4433 - schedule(); 4434 4386 } 4435 4387 4436 - found: 4437 - /* Create a software table entry if necessary, and mark it 4438 - * busy. We might yet fail to insert, but any attempt to 4439 - * insert a conflicting filter while we're waiting for the 4440 - * firmware must find the busy entry. 4388 + /* Once we reach the maximum search depth, use the first suitable 4389 + * slot, or return -EBUSY if there was none 4441 4390 */ 4391 + if (ins_index < 0) { 4392 + rc = -EBUSY; 4393 + goto out_unlock; 4394 + } 4395 + 4396 + /* Create a software table entry if necessary. */ 4442 4397 saved_spec = efx_ef10_filter_entry_spec(table, ins_index); 4443 4398 if (saved_spec) { 4444 4399 if (spec->priority == EFX_FILTER_PRI_AUTO && ··· 4441 4438 *saved_spec = *spec; 4442 4439 priv_flags = 0; 4443 4440 } 4444 - efx_ef10_filter_set_entry(table, ins_index, saved_spec, 4445 - priv_flags | EFX_EF10_FILTER_FLAG_BUSY); 4441 + efx_ef10_filter_set_entry(table, ins_index, saved_spec, priv_flags); 4446 4442 4447 - /* Mark lower-priority multicast recipients busy prior to removal */ 4448 - if (is_mc_recip) { 4449 - unsigned int depth, i; 4450 - 4451 - for (depth = 0; depth < EFX_EF10_FILTER_SEARCH_LIMIT; depth++) { 4452 - i = (hash + depth) & (HUNT_FILTER_TBL_ROWS - 1); 4453 - if (test_bit(depth, mc_rem_map)) 4454 - table->entry[i].spec |= 4455 - EFX_EF10_FILTER_FLAG_BUSY; 4456 - } 4457 - } 4458 - 4459 - spin_unlock_bh(&efx->filter_lock); 4460 - 4443 + /* Actually insert the filter on the HW */ 4461 4444 rc = efx_ef10_filter_push(efx, spec, &table->entry[ins_index].handle, 4462 4445 ctx, replacing); 4463 4446 4447 + if (rc == -EINVAL && nic_data->must_realloc_vis) 4448 + /* The MC rebooted under us, causing it to reject our filter 4449 + * insertion as pointing to an invalid VI (spec->dmaq_id). 4450 + */ 4451 + rc = -EAGAIN; 4452 + 4464 4453 /* Finalise the software table entry */ 4465 - spin_lock_bh(&efx->filter_lock); 4466 4454 if (rc == 0) { 4467 4455 if (replacing) { 4468 4456 /* Update the fields that may differ */ ··· 4469 4475 } else if (!replacing) { 4470 4476 kfree(saved_spec); 4471 4477 saved_spec = NULL; 4478 + } else { 4479 + /* We failed to replace, so the old filter is still present. 4480 + * Roll back the software table to reflect this. In fact the 4481 + * efx_ef10_filter_set_entry() call below will do the right 4482 + * thing, so nothing extra is needed here. 4483 + */ 4472 4484 } 4473 4485 efx_ef10_filter_set_entry(table, ins_index, saved_spec, priv_flags); 4474 4486 ··· 4496 4496 priv_flags = efx_ef10_filter_entry_flags(table, i); 4497 4497 4498 4498 if (rc == 0) { 4499 - spin_unlock_bh(&efx->filter_lock); 4500 4499 MCDI_SET_DWORD(inbuf, FILTER_OP_IN_OP, 4501 4500 MC_CMD_FILTER_OP_IN_OP_UNSUBSCRIBE); 4502 4501 MCDI_SET_QWORD(inbuf, FILTER_OP_IN_HANDLE, ··· 4503 4504 rc = efx_mcdi_rpc(efx, MC_CMD_FILTER_OP, 4504 4505 inbuf, sizeof(inbuf), 4505 4506 NULL, 0, NULL); 4506 - spin_lock_bh(&efx->filter_lock); 4507 4507 } 4508 4508 4509 4509 if (rc == 0) { 4510 4510 kfree(saved_spec); 4511 4511 saved_spec = NULL; 4512 4512 priv_flags = 0; 4513 - } else { 4514 - priv_flags &= ~EFX_EF10_FILTER_FLAG_BUSY; 4515 4513 } 4516 4514 efx_ef10_filter_set_entry(table, i, saved_spec, 4517 4515 priv_flags); ··· 4519 4523 if (rc == 0) 4520 4524 rc = efx_ef10_make_filter_id(match_pri, ins_index); 4521 4525 4522 - wake_up_all(&table->waitq); 4523 4526 out_unlock: 4524 - spin_unlock_bh(&efx->filter_lock); 4525 - finish_wait(&table->waitq, &wait); 4527 + if (rss_locked) 4528 + mutex_unlock(&efx->rss_lock); 4529 + up_write(&table->lock); 4530 + up_read(&efx->filter_sem); 4526 4531 return rc; 4527 4532 } 4528 4533 ··· 4536 4539 * If !by_index, remove by ID 4537 4540 * If by_index, remove by index 4538 4541 * Filter ID may come from userland and must be range-checked. 4542 + * Caller must hold efx->filter_sem for read, and efx->filter_state->lock 4543 + * for write. 4539 4544 */ 4540 4545 static int efx_ef10_filter_remove_internal(struct efx_nic *efx, 4541 4546 unsigned int priority_mask, ··· 4552 4553 DEFINE_WAIT(wait); 4553 4554 int rc; 4554 4555 4555 - /* Find the software table entry and mark it busy. Don't 4556 - * remove it yet; any attempt to update while we're waiting 4557 - * for the firmware must find the busy entry. 4558 - */ 4559 - for (;;) { 4560 - spin_lock_bh(&efx->filter_lock); 4561 - if (!(table->entry[filter_idx].spec & 4562 - EFX_EF10_FILTER_FLAG_BUSY)) 4563 - break; 4564 - prepare_to_wait(&table->waitq, &wait, TASK_UNINTERRUPTIBLE); 4565 - spin_unlock_bh(&efx->filter_lock); 4566 - schedule(); 4567 - } 4568 - 4569 4556 spec = efx_ef10_filter_entry_spec(table, filter_idx); 4570 4557 if (!spec || 4571 4558 (!by_index && 4572 4559 efx_ef10_filter_pri(table, spec) != 4573 - efx_ef10_filter_get_unsafe_pri(filter_id))) { 4574 - rc = -ENOENT; 4575 - goto out_unlock; 4576 - } 4560 + efx_ef10_filter_get_unsafe_pri(filter_id))) 4561 + return -ENOENT; 4577 4562 4578 4563 if (spec->flags & EFX_FILTER_FLAG_RX_OVER_AUTO && 4579 4564 priority_mask == (1U << EFX_FILTER_PRI_AUTO)) { 4580 4565 /* Just remove flags */ 4581 4566 spec->flags &= ~EFX_FILTER_FLAG_RX_OVER_AUTO; 4582 4567 table->entry[filter_idx].spec &= ~EFX_EF10_FILTER_FLAG_AUTO_OLD; 4583 - rc = 0; 4584 - goto out_unlock; 4568 + return 0; 4585 4569 } 4586 4570 4587 - if (!(priority_mask & (1U << spec->priority))) { 4588 - rc = -ENOENT; 4589 - goto out_unlock; 4590 - } 4591 - 4592 - table->entry[filter_idx].spec |= EFX_EF10_FILTER_FLAG_BUSY; 4593 - spin_unlock_bh(&efx->filter_lock); 4571 + if (!(priority_mask & (1U << spec->priority))) 4572 + return -ENOENT; 4594 4573 4595 4574 if (spec->flags & EFX_FILTER_FLAG_RX_OVER_AUTO) { 4596 4575 /* Reset to an automatic filter */ ··· 4586 4609 &efx->rss_context, 4587 4610 true); 4588 4611 4589 - spin_lock_bh(&efx->filter_lock); 4590 4612 if (rc == 0) 4591 4613 *spec = new_spec; 4592 4614 } else { ··· 4600 4624 rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FILTER_OP, 4601 4625 inbuf, sizeof(inbuf), NULL, 0, NULL); 4602 4626 4603 - spin_lock_bh(&efx->filter_lock); 4604 4627 if ((rc == 0) || (rc == -ENOENT)) { 4605 4628 /* Filter removed OK or didn't actually exist */ 4606 4629 kfree(spec); ··· 4611 4636 } 4612 4637 } 4613 4638 4614 - table->entry[filter_idx].spec &= ~EFX_EF10_FILTER_FLAG_BUSY; 4615 - wake_up_all(&table->waitq); 4616 - out_unlock: 4617 - spin_unlock_bh(&efx->filter_lock); 4618 - finish_wait(&table->waitq, &wait); 4619 4639 return rc; 4620 4640 } 4621 4641 ··· 4618 4648 enum efx_filter_priority priority, 4619 4649 u32 filter_id) 4620 4650 { 4621 - return efx_ef10_filter_remove_internal(efx, 1U << priority, 4622 - filter_id, false); 4651 + struct efx_ef10_filter_table *table; 4652 + int rc; 4653 + 4654 + down_read(&efx->filter_sem); 4655 + table = efx->filter_state; 4656 + down_write(&table->lock); 4657 + rc = efx_ef10_filter_remove_internal(efx, 1U << priority, filter_id, 4658 + false); 4659 + up_write(&table->lock); 4660 + up_read(&efx->filter_sem); 4661 + return rc; 4623 4662 } 4624 4663 4664 + /* Caller must hold efx->filter_sem for read */ 4625 4665 static void efx_ef10_filter_remove_unsafe(struct efx_nic *efx, 4626 4666 enum efx_filter_priority priority, 4627 4667 u32 filter_id) 4628 4668 { 4669 + struct efx_ef10_filter_table *table = efx->filter_state; 4670 + 4629 4671 if (filter_id == EFX_EF10_FILTER_ID_INVALID) 4630 4672 return; 4631 - efx_ef10_filter_remove_internal(efx, 1U << priority, filter_id, true); 4673 + 4674 + down_write(&table->lock); 4675 + efx_ef10_filter_remove_internal(efx, 1U << priority, filter_id, 4676 + true); 4677 + up_write(&table->lock); 4632 4678 } 4633 4679 4634 4680 static int efx_ef10_filter_get_safe(struct efx_nic *efx, ··· 4652 4666 u32 filter_id, struct efx_filter_spec *spec) 4653 4667 { 4654 4668 unsigned int filter_idx = efx_ef10_filter_get_unsafe_id(filter_id); 4655 - struct efx_ef10_filter_table *table = efx->filter_state; 4656 4669 const struct efx_filter_spec *saved_spec; 4670 + struct efx_ef10_filter_table *table; 4657 4671 int rc; 4658 4672 4659 - spin_lock_bh(&efx->filter_lock); 4673 + down_read(&efx->filter_sem); 4674 + table = efx->filter_state; 4675 + down_read(&table->lock); 4660 4676 saved_spec = efx_ef10_filter_entry_spec(table, filter_idx); 4661 4677 if (saved_spec && saved_spec->priority == priority && 4662 4678 efx_ef10_filter_pri(table, saved_spec) == ··· 4668 4680 } else { 4669 4681 rc = -ENOENT; 4670 4682 } 4671 - spin_unlock_bh(&efx->filter_lock); 4683 + up_read(&table->lock); 4684 + up_read(&efx->filter_sem); 4672 4685 return rc; 4673 4686 } 4674 4687 4675 4688 static int efx_ef10_filter_clear_rx(struct efx_nic *efx, 4676 - enum efx_filter_priority priority) 4689 + enum efx_filter_priority priority) 4677 4690 { 4691 + struct efx_ef10_filter_table *table; 4678 4692 unsigned int priority_mask; 4679 4693 unsigned int i; 4680 4694 int rc; ··· 4684 4694 priority_mask = (((1U << (priority + 1)) - 1) & 4685 4695 ~(1U << EFX_FILTER_PRI_AUTO)); 4686 4696 4697 + down_read(&efx->filter_sem); 4698 + table = efx->filter_state; 4699 + down_write(&table->lock); 4687 4700 for (i = 0; i < HUNT_FILTER_TBL_ROWS; i++) { 4688 4701 rc = efx_ef10_filter_remove_internal(efx, priority_mask, 4689 4702 i, true); 4690 4703 if (rc && rc != -ENOENT) 4691 - return rc; 4704 + break; 4705 + rc = 0; 4692 4706 } 4693 4707 4694 - return 0; 4708 + up_write(&table->lock); 4709 + up_read(&efx->filter_sem); 4710 + return rc; 4695 4711 } 4696 4712 4697 4713 static u32 efx_ef10_filter_count_rx_used(struct efx_nic *efx, 4698 4714 enum efx_filter_priority priority) 4699 4715 { 4700 - struct efx_ef10_filter_table *table = efx->filter_state; 4716 + struct efx_ef10_filter_table *table; 4701 4717 unsigned int filter_idx; 4702 4718 s32 count = 0; 4703 4719 4704 - spin_lock_bh(&efx->filter_lock); 4720 + down_read(&efx->filter_sem); 4721 + table = efx->filter_state; 4722 + down_read(&table->lock); 4705 4723 for (filter_idx = 0; filter_idx < HUNT_FILTER_TBL_ROWS; filter_idx++) { 4706 4724 if (table->entry[filter_idx].spec && 4707 4725 efx_ef10_filter_entry_spec(table, filter_idx)->priority == 4708 4726 priority) 4709 4727 ++count; 4710 4728 } 4711 - spin_unlock_bh(&efx->filter_lock); 4729 + up_read(&table->lock); 4730 + up_read(&efx->filter_sem); 4712 4731 return count; 4713 4732 } 4714 4733 ··· 4732 4733 enum efx_filter_priority priority, 4733 4734 u32 *buf, u32 size) 4734 4735 { 4735 - struct efx_ef10_filter_table *table = efx->filter_state; 4736 + struct efx_ef10_filter_table *table; 4736 4737 struct efx_filter_spec *spec; 4737 4738 unsigned int filter_idx; 4738 4739 s32 count = 0; 4739 4740 4740 - spin_lock_bh(&efx->filter_lock); 4741 + down_read(&efx->filter_sem); 4742 + table = efx->filter_state; 4743 + down_read(&table->lock); 4744 + 4741 4745 for (filter_idx = 0; filter_idx < HUNT_FILTER_TBL_ROWS; filter_idx++) { 4742 4746 spec = efx_ef10_filter_entry_spec(table, filter_idx); 4743 4747 if (spec && spec->priority == priority) { ··· 4754 4752 filter_idx); 4755 4753 } 4756 4754 } 4757 - spin_unlock_bh(&efx->filter_lock); 4755 + up_read(&table->lock); 4756 + up_read(&efx->filter_sem); 4758 4757 return count; 4759 4758 } 4760 4759 4761 4760 #ifdef CONFIG_RFS_ACCEL 4762 4761 4763 - static efx_mcdi_async_completer efx_ef10_filter_rfs_insert_complete; 4764 - 4765 - static s32 efx_ef10_filter_rfs_insert(struct efx_nic *efx, 4766 - struct efx_filter_spec *spec) 4767 - { 4768 - struct efx_ef10_filter_table *table = efx->filter_state; 4769 - MCDI_DECLARE_BUF(inbuf, MC_CMD_FILTER_OP_EXT_IN_LEN); 4770 - struct efx_filter_spec *saved_spec; 4771 - unsigned int hash, i, depth = 1; 4772 - bool replacing = false; 4773 - int ins_index = -1; 4774 - u64 cookie; 4775 - s32 rc; 4776 - 4777 - /* Must be an RX filter without RSS and not for a multicast 4778 - * destination address (RFS only works for connected sockets). 4779 - * These restrictions allow us to pass only a tiny amount of 4780 - * data through to the completion function. 4781 - */ 4782 - EFX_WARN_ON_PARANOID(spec->flags != 4783 - (EFX_FILTER_FLAG_RX | EFX_FILTER_FLAG_RX_SCATTER)); 4784 - EFX_WARN_ON_PARANOID(spec->priority != EFX_FILTER_PRI_HINT); 4785 - EFX_WARN_ON_PARANOID(efx_filter_is_mc_recipient(spec)); 4786 - 4787 - hash = efx_ef10_filter_hash(spec); 4788 - 4789 - spin_lock_bh(&efx->filter_lock); 4790 - 4791 - /* Find any existing filter with the same match tuple or else 4792 - * a free slot to insert at. If an existing filter is busy, 4793 - * we have to give up. 4794 - */ 4795 - for (;;) { 4796 - i = (hash + depth) & (HUNT_FILTER_TBL_ROWS - 1); 4797 - saved_spec = efx_ef10_filter_entry_spec(table, i); 4798 - 4799 - if (!saved_spec) { 4800 - if (ins_index < 0) 4801 - ins_index = i; 4802 - } else if (efx_ef10_filter_equal(spec, saved_spec)) { 4803 - if (table->entry[i].spec & EFX_EF10_FILTER_FLAG_BUSY) { 4804 - rc = -EBUSY; 4805 - goto fail_unlock; 4806 - } 4807 - if (spec->priority < saved_spec->priority) { 4808 - rc = -EPERM; 4809 - goto fail_unlock; 4810 - } 4811 - ins_index = i; 4812 - break; 4813 - } 4814 - 4815 - /* Once we reach the maximum search depth, use the 4816 - * first suitable slot or return -EBUSY if there was 4817 - * none 4818 - */ 4819 - if (depth == EFX_EF10_FILTER_SEARCH_LIMIT) { 4820 - if (ins_index < 0) { 4821 - rc = -EBUSY; 4822 - goto fail_unlock; 4823 - } 4824 - break; 4825 - } 4826 - 4827 - ++depth; 4828 - } 4829 - 4830 - /* Create a software table entry if necessary, and mark it 4831 - * busy. We might yet fail to insert, but any attempt to 4832 - * insert a conflicting filter while we're waiting for the 4833 - * firmware must find the busy entry. 4834 - */ 4835 - saved_spec = efx_ef10_filter_entry_spec(table, ins_index); 4836 - if (saved_spec) { 4837 - replacing = true; 4838 - } else { 4839 - saved_spec = kmalloc(sizeof(*spec), GFP_ATOMIC); 4840 - if (!saved_spec) { 4841 - rc = -ENOMEM; 4842 - goto fail_unlock; 4843 - } 4844 - *saved_spec = *spec; 4845 - } 4846 - efx_ef10_filter_set_entry(table, ins_index, saved_spec, 4847 - EFX_EF10_FILTER_FLAG_BUSY); 4848 - 4849 - spin_unlock_bh(&efx->filter_lock); 4850 - 4851 - /* Pack up the variables needed on completion */ 4852 - cookie = replacing << 31 | ins_index << 16 | spec->dmaq_id; 4853 - 4854 - efx_ef10_filter_push_prep(efx, spec, inbuf, 4855 - table->entry[ins_index].handle, NULL, 4856 - replacing); 4857 - efx_mcdi_rpc_async(efx, MC_CMD_FILTER_OP, inbuf, sizeof(inbuf), 4858 - MC_CMD_FILTER_OP_OUT_LEN, 4859 - efx_ef10_filter_rfs_insert_complete, cookie); 4860 - 4861 - return ins_index; 4862 - 4863 - fail_unlock: 4864 - spin_unlock_bh(&efx->filter_lock); 4865 - return rc; 4866 - } 4867 - 4868 - static void 4869 - efx_ef10_filter_rfs_insert_complete(struct efx_nic *efx, unsigned long cookie, 4870 - int rc, efx_dword_t *outbuf, 4871 - size_t outlen_actual) 4872 - { 4873 - struct efx_ef10_filter_table *table = efx->filter_state; 4874 - unsigned int ins_index, dmaq_id; 4875 - struct efx_filter_spec *spec; 4876 - bool replacing; 4877 - 4878 - /* Unpack the cookie */ 4879 - replacing = cookie >> 31; 4880 - ins_index = (cookie >> 16) & (HUNT_FILTER_TBL_ROWS - 1); 4881 - dmaq_id = cookie & 0xffff; 4882 - 4883 - spin_lock_bh(&efx->filter_lock); 4884 - spec = efx_ef10_filter_entry_spec(table, ins_index); 4885 - if (rc == 0) { 4886 - table->entry[ins_index].handle = 4887 - MCDI_QWORD(outbuf, FILTER_OP_OUT_HANDLE); 4888 - if (replacing) 4889 - spec->dmaq_id = dmaq_id; 4890 - } else if (!replacing) { 4891 - kfree(spec); 4892 - spec = NULL; 4893 - } 4894 - efx_ef10_filter_set_entry(table, ins_index, spec, 0); 4895 - spin_unlock_bh(&efx->filter_lock); 4896 - 4897 - wake_up_all(&table->waitq); 4898 - } 4899 - 4900 - static void 4901 - efx_ef10_filter_rfs_expire_complete(struct efx_nic *efx, 4902 - unsigned long filter_idx, 4903 - int rc, efx_dword_t *outbuf, 4904 - size_t outlen_actual); 4905 - 4906 4762 static bool efx_ef10_filter_rfs_expire_one(struct efx_nic *efx, u32 flow_id, 4907 4763 unsigned int filter_idx) 4908 4764 { 4909 - struct efx_ef10_filter_table *table = efx->filter_state; 4910 - struct efx_filter_spec *spec = 4911 - efx_ef10_filter_entry_spec(table, filter_idx); 4912 - MCDI_DECLARE_BUF(inbuf, 4913 - MC_CMD_FILTER_OP_IN_HANDLE_OFST + 4914 - MC_CMD_FILTER_OP_IN_HANDLE_LEN); 4765 + struct efx_ef10_filter_table *table; 4766 + struct efx_filter_spec *spec; 4767 + bool ret; 4915 4768 4916 - if (!spec || 4917 - (table->entry[filter_idx].spec & EFX_EF10_FILTER_FLAG_BUSY) || 4918 - spec->priority != EFX_FILTER_PRI_HINT || 4919 - !rps_may_expire_flow(efx->net_dev, spec->dmaq_id, 4920 - flow_id, filter_idx)) 4921 - return false; 4769 + down_read(&efx->filter_sem); 4770 + table = efx->filter_state; 4771 + down_write(&table->lock); 4772 + spec = efx_ef10_filter_entry_spec(table, filter_idx); 4922 4773 4923 - MCDI_SET_DWORD(inbuf, FILTER_OP_IN_OP, 4924 - MC_CMD_FILTER_OP_IN_OP_REMOVE); 4925 - MCDI_SET_QWORD(inbuf, FILTER_OP_IN_HANDLE, 4926 - table->entry[filter_idx].handle); 4927 - if (efx_mcdi_rpc_async(efx, MC_CMD_FILTER_OP, inbuf, sizeof(inbuf), 0, 4928 - efx_ef10_filter_rfs_expire_complete, filter_idx)) 4929 - return false; 4930 - 4931 - table->entry[filter_idx].spec |= EFX_EF10_FILTER_FLAG_BUSY; 4932 - return true; 4933 - } 4934 - 4935 - static void 4936 - efx_ef10_filter_rfs_expire_complete(struct efx_nic *efx, 4937 - unsigned long filter_idx, 4938 - int rc, efx_dword_t *outbuf, 4939 - size_t outlen_actual) 4940 - { 4941 - struct efx_ef10_filter_table *table = efx->filter_state; 4942 - struct efx_filter_spec *spec = 4943 - efx_ef10_filter_entry_spec(table, filter_idx); 4944 - 4945 - spin_lock_bh(&efx->filter_lock); 4946 - if (rc == 0) { 4947 - kfree(spec); 4948 - efx_ef10_filter_set_entry(table, filter_idx, NULL, 0); 4774 + if (!spec || spec->priority != EFX_FILTER_PRI_HINT) { 4775 + ret = true; 4776 + goto out_unlock; 4949 4777 } 4950 - table->entry[filter_idx].spec &= ~EFX_EF10_FILTER_FLAG_BUSY; 4951 - wake_up_all(&table->waitq); 4952 - spin_unlock_bh(&efx->filter_lock); 4778 + 4779 + if (!rps_may_expire_flow(efx->net_dev, spec->dmaq_id, 4780 + flow_id, filter_idx)) { 4781 + ret = false; 4782 + goto out_unlock; 4783 + } 4784 + 4785 + ret = efx_ef10_filter_remove_internal(efx, 1U << spec->priority, 4786 + filter_idx, true) == 0; 4787 + out_unlock: 4788 + up_write(&table->lock); 4789 + up_read(&efx->filter_sem); 4790 + return ret; 4953 4791 } 4954 4792 4955 4793 #endif /* CONFIG_RFS_ACCEL */ ··· 4984 5142 table->vlan_filter = 4985 5143 !!(efx->net_dev->features & NETIF_F_HW_VLAN_CTAG_FILTER); 4986 5144 INIT_LIST_HEAD(&table->vlan_list); 5145 + init_rwsem(&table->lock); 4987 5146 4988 5147 efx->filter_state = table; 4989 - init_waitqueue_head(&table->waitq); 4990 5148 4991 5149 list_for_each_entry(vlan, &nic_data->vlan_list, list) { 4992 5150 rc = efx_ef10_filter_add_vlan(efx, vlan->vid); ··· 5028 5186 if (!table) 5029 5187 return; 5030 5188 5031 - spin_lock_bh(&efx->filter_lock); 5189 + down_write(&table->lock); 5190 + mutex_lock(&efx->rss_lock); 5032 5191 5033 5192 for (filter_idx = 0; filter_idx < HUNT_FILTER_TBL_ROWS; filter_idx++) { 5034 5193 spec = efx_ef10_filter_entry_spec(table, filter_idx); ··· 5046 5203 goto not_restored; 5047 5204 } 5048 5205 if (spec->rss_context) 5049 - ctx = efx_find_rss_context_entry(spec->rss_context, 5050 - &efx->rss_context.list); 5206 + ctx = efx_find_rss_context_entry(efx, spec->rss_context); 5051 5207 else 5052 5208 ctx = &efx->rss_context; 5053 5209 if (spec->flags & EFX_FILTER_FLAG_RX_RSS) { ··· 5066 5224 } 5067 5225 } 5068 5226 5069 - table->entry[filter_idx].spec |= EFX_EF10_FILTER_FLAG_BUSY; 5070 - spin_unlock_bh(&efx->filter_lock); 5071 - 5072 5227 rc = efx_ef10_filter_push(efx, spec, 5073 5228 &table->entry[filter_idx].handle, 5074 5229 ctx, false); 5075 5230 if (rc) 5076 5231 failed++; 5077 - spin_lock_bh(&efx->filter_lock); 5078 5232 5079 5233 if (rc) { 5080 5234 not_restored: ··· 5082 5244 5083 5245 kfree(spec); 5084 5246 efx_ef10_filter_set_entry(table, filter_idx, NULL, 0); 5085 - } else { 5086 - table->entry[filter_idx].spec &= 5087 - ~EFX_EF10_FILTER_FLAG_BUSY; 5088 5247 } 5089 5248 } 5090 5249 5091 - spin_unlock_bh(&efx->filter_lock); 5250 + mutex_unlock(&efx->rss_lock); 5251 + up_write(&table->lock); 5092 5252 5093 5253 /* This can happen validly if the MC's capabilities have changed, so 5094 5254 * is not an error. ··· 5154 5318 struct efx_ef10_filter_table *table = efx->filter_state; 5155 5319 unsigned int filter_idx; 5156 5320 5321 + efx_rwsem_assert_write_locked(&table->lock); 5322 + 5157 5323 if (*id != EFX_EF10_FILTER_ID_INVALID) { 5158 5324 filter_idx = efx_ef10_filter_get_unsafe_id(*id); 5159 5325 if (!table->entry[filter_idx].spec) ··· 5191 5353 struct efx_ef10_filter_table *table = efx->filter_state; 5192 5354 struct efx_ef10_filter_vlan *vlan; 5193 5355 5194 - spin_lock_bh(&efx->filter_lock); 5356 + down_write(&table->lock); 5195 5357 list_for_each_entry(vlan, &table->vlan_list, list) 5196 5358 _efx_ef10_filter_vlan_mark_old(efx, vlan); 5197 - spin_unlock_bh(&efx->filter_lock); 5359 + up_write(&table->lock); 5198 5360 } 5199 5361 5200 5362 static void efx_ef10_filter_uc_addr_list(struct efx_nic *efx) ··· 5471 5633 return rc; 5472 5634 } 5473 5635 5474 - /* Remove filters that weren't renewed. Since nothing else changes the AUTO_OLD 5475 - * flag or removes these filters, we don't need to hold the filter_lock while 5476 - * scanning for these filters. 5477 - */ 5636 + /* Remove filters that weren't renewed. */ 5478 5637 static void efx_ef10_filter_remove_old(struct efx_nic *efx) 5479 5638 { 5480 5639 struct efx_ef10_filter_table *table = efx->filter_state; ··· 5480 5645 int rc; 5481 5646 int i; 5482 5647 5648 + down_write(&table->lock); 5483 5649 for (i = 0; i < HUNT_FILTER_TBL_ROWS; i++) { 5484 5650 if (READ_ONCE(table->entry[i].spec) & 5485 5651 EFX_EF10_FILTER_FLAG_AUTO_OLD) { ··· 5492 5656 remove_failed++; 5493 5657 } 5494 5658 } 5659 + up_write(&table->lock); 5495 5660 5496 5661 if (remove_failed) 5497 5662 netif_info(efx, drv, efx->net_dev, ··· 6621 6784 .filter_get_rx_id_limit = efx_ef10_filter_get_rx_id_limit, 6622 6785 .filter_get_rx_ids = efx_ef10_filter_get_rx_ids, 6623 6786 #ifdef CONFIG_RFS_ACCEL 6624 - .filter_rfs_insert = efx_ef10_filter_rfs_insert, 6625 6787 .filter_rfs_expire_one = efx_ef10_filter_rfs_expire_one, 6626 6788 #endif 6627 6789 #ifdef CONFIG_SFC_MTD ··· 6733 6897 .filter_get_rx_id_limit = efx_ef10_filter_get_rx_id_limit, 6734 6898 .filter_get_rx_ids = efx_ef10_filter_get_rx_ids, 6735 6899 #ifdef CONFIG_RFS_ACCEL 6736 - .filter_rfs_insert = efx_ef10_filter_rfs_insert, 6737 6900 .filter_rfs_expire_one = efx_ef10_filter_rfs_expire_one, 6738 6901 #endif 6739 6902 #ifdef CONFIG_SFC_MTD
+26 -4
drivers/net/ethernet/sfc/efx.c
··· 340 340 efx_update_irq_mod(efx, channel); 341 341 } 342 342 343 - efx_filter_rfs_expire(channel); 343 + #ifdef CONFIG_RFS_ACCEL 344 + /* Perhaps expire some ARFS filters */ 345 + schedule_work(&channel->filter_work); 346 + #endif 344 347 345 348 /* There is no race here; although napi_disable() will 346 349 * only wait for napi_complete(), this isn't a problem ··· 473 470 tx_queue->channel = channel; 474 471 } 475 472 473 + #ifdef CONFIG_RFS_ACCEL 474 + INIT_WORK(&channel->filter_work, efx_filter_rfs_expire); 475 + #endif 476 + 476 477 rx_queue = &channel->rx_queue; 477 478 rx_queue->efx = efx; 478 479 timer_setup(&rx_queue->slow_fill, efx_rx_slow_fill, 0); ··· 519 512 rx_queue->buffer = NULL; 520 513 memset(&rx_queue->rxd, 0, sizeof(rx_queue->rxd)); 521 514 timer_setup(&rx_queue->slow_fill, efx_rx_slow_fill, 0); 515 + #ifdef CONFIG_RFS_ACCEL 516 + INIT_WORK(&channel->filter_work, efx_filter_rfs_expire); 517 + #endif 522 518 523 519 return channel; 524 520 } ··· 1783 1773 { 1784 1774 int rc; 1785 1775 1786 - spin_lock_init(&efx->filter_lock); 1787 1776 init_rwsem(&efx->filter_sem); 1788 1777 mutex_lock(&efx->mac_lock); 1789 1778 down_write(&efx->filter_sem); ··· 2657 2648 efx_disable_interrupts(efx); 2658 2649 2659 2650 mutex_lock(&efx->mac_lock); 2651 + mutex_lock(&efx->rss_lock); 2660 2652 if (efx->port_initialized && method != RESET_TYPE_INVISIBLE && 2661 2653 method != RESET_TYPE_DATAPATH) 2662 2654 efx->phy_op->fini(efx); ··· 2713 2703 2714 2704 if (efx->type->rx_restore_rss_contexts) 2715 2705 efx->type->rx_restore_rss_contexts(efx); 2706 + mutex_unlock(&efx->rss_lock); 2716 2707 down_read(&efx->filter_sem); 2717 2708 efx_restore_filters(efx); 2718 2709 up_read(&efx->filter_sem); ··· 2732 2721 fail: 2733 2722 efx->port_initialized = false; 2734 2723 2724 + mutex_unlock(&efx->rss_lock); 2735 2725 mutex_unlock(&efx->mac_lock); 2736 2726 2737 2727 return rc; ··· 3019 3007 efx->rx_packet_ts_offset = 3020 3008 efx->type->rx_ts_offset - efx->type->rx_prefix_size; 3021 3009 INIT_LIST_HEAD(&efx->rss_context.list); 3010 + mutex_init(&efx->rss_lock); 3022 3011 spin_lock_init(&efx->stats_lock); 3023 3012 efx->vi_stride = EFX_DEFAULT_VI_STRIDE; 3024 3013 efx->num_mac_stats = MC_CMD_MAC_NSTATS; 3025 3014 BUILD_BUG_ON(MC_CMD_MAC_NSTATS - 1 != MC_CMD_MAC_GENERATION_END); 3026 3015 mutex_init(&efx->mac_lock); 3016 + #ifdef CONFIG_RFS_ACCEL 3017 + mutex_init(&efx->rps_mutex); 3018 + #endif 3027 3019 efx->phy_op = &efx_dummy_phy_operations; 3028 3020 efx->mdio.dev = net_dev; 3029 3021 INIT_WORK(&efx->mac_work, efx_mac_work); ··· 3095 3079 /* RSS contexts. We're using linked lists and crappy O(n) algorithms, because 3096 3080 * (a) this is an infrequent control-plane operation and (b) n is small (max 64) 3097 3081 */ 3098 - struct efx_rss_context *efx_alloc_rss_context_entry(struct list_head *head) 3082 + struct efx_rss_context *efx_alloc_rss_context_entry(struct efx_nic *efx) 3099 3083 { 3084 + struct list_head *head = &efx->rss_context.list; 3100 3085 struct efx_rss_context *ctx, *new; 3101 3086 u32 id = 1; /* Don't use zero, that refers to the master RSS context */ 3087 + 3088 + WARN_ON(!mutex_is_locked(&efx->rss_lock)); 3102 3089 3103 3090 /* Search for first gap in the numbering */ 3104 3091 list_for_each_entry(ctx, head, list) { ··· 3128 3109 return new; 3129 3110 } 3130 3111 3131 - struct efx_rss_context *efx_find_rss_context_entry(u32 id, struct list_head *head) 3112 + struct efx_rss_context *efx_find_rss_context_entry(struct efx_nic *efx, u32 id) 3132 3113 { 3114 + struct list_head *head = &efx->rss_context.list; 3133 3115 struct efx_rss_context *ctx; 3116 + 3117 + WARN_ON(!mutex_is_locked(&efx->rss_lock)); 3134 3118 3135 3119 list_for_each_entry(ctx, head, list) 3136 3120 if (ctx->user_id == id)
+7 -4
drivers/net/ethernet/sfc/efx.h
··· 170 170 int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb, 171 171 u16 rxq_index, u32 flow_id); 172 172 bool __efx_filter_rfs_expire(struct efx_nic *efx, unsigned quota); 173 - static inline void efx_filter_rfs_expire(struct efx_channel *channel) 173 + static inline void efx_filter_rfs_expire(struct work_struct *data) 174 174 { 175 + struct efx_channel *channel = container_of(data, struct efx_channel, 176 + filter_work); 177 + 175 178 if (channel->rfs_filters_added >= 60 && 176 179 __efx_filter_rfs_expire(channel->efx, 100)) 177 180 channel->rfs_filters_added -= 60; 178 181 } 179 182 #define efx_filter_rfs_enabled() 1 180 183 #else 181 - static inline void efx_filter_rfs_expire(struct efx_channel *channel) {} 184 + static inline void efx_filter_rfs_expire(struct work_struct *data) {} 182 185 #define efx_filter_rfs_enabled() 0 183 186 #endif 184 187 bool efx_filter_is_mc_recipient(const struct efx_filter_spec *spec); 185 188 186 189 /* RSS contexts */ 187 - struct efx_rss_context *efx_alloc_rss_context_entry(struct list_head *list); 188 - struct efx_rss_context *efx_find_rss_context_entry(u32 id, struct list_head *list); 190 + struct efx_rss_context *efx_alloc_rss_context_entry(struct efx_nic *efx); 191 + struct efx_rss_context *efx_find_rss_context_entry(struct efx_nic *efx, u32 id); 189 192 void efx_free_rss_context_entry(struct efx_rss_context *ctx); 190 193 static inline bool efx_rss_active(struct efx_rss_context *ctx) 191 194 {
+49 -28
drivers/net/ethernet/sfc/ethtool.c
··· 979 979 { 980 980 struct efx_nic *efx = netdev_priv(net_dev); 981 981 u32 rss_context = 0; 982 - s32 rc; 982 + s32 rc = 0; 983 983 984 984 switch (info->cmd) { 985 985 case ETHTOOL_GRXRINGS: ··· 989 989 case ETHTOOL_GRXFH: { 990 990 struct efx_rss_context *ctx = &efx->rss_context; 991 991 992 + mutex_lock(&efx->rss_lock); 992 993 if (info->flow_type & FLOW_RSS && info->rss_context) { 993 - ctx = efx_find_rss_context_entry(info->rss_context, 994 - &efx->rss_context.list); 995 - if (!ctx) 996 - return -ENOENT; 994 + ctx = efx_find_rss_context_entry(efx, info->rss_context); 995 + if (!ctx) { 996 + rc = -ENOENT; 997 + goto out_unlock; 998 + } 997 999 } 998 1000 info->data = 0; 999 1001 if (!efx_rss_active(ctx)) /* No RSS */ 1000 - return 0; 1002 + goto out_unlock; 1001 1003 switch (info->flow_type & ~FLOW_RSS) { 1002 1004 case UDP_V4_FLOW: 1003 1005 if (ctx->rx_hash_udp_4tuple) ··· 1026 1024 default: 1027 1025 break; 1028 1026 } 1029 - return 0; 1027 + out_unlock: 1028 + mutex_unlock(&efx->rss_lock); 1029 + return rc; 1030 1030 } 1031 1031 1032 1032 case ETHTOOL_GRXCLSRLCNT: ··· 1088 1084 struct ethtool_tcpip6_spec *ip6_mask = &rule->m_u.tcp_ip6_spec; 1089 1085 struct ethtool_usrip6_spec *uip6_entry = &rule->h_u.usr_ip6_spec; 1090 1086 struct ethtool_usrip6_spec *uip6_mask = &rule->m_u.usr_ip6_spec; 1087 + u32 flow_type = rule->flow_type & ~(FLOW_EXT | FLOW_RSS); 1091 1088 struct ethhdr *mac_entry = &rule->h_u.ether_spec; 1092 1089 struct ethhdr *mac_mask = &rule->m_u.ether_spec; 1093 1090 enum efx_filter_flags flags = 0; ··· 1122 1117 if (rule->flow_type & FLOW_RSS) 1123 1118 spec.rss_context = rss_context; 1124 1119 1125 - switch (rule->flow_type & ~(FLOW_EXT | FLOW_RSS)) { 1120 + switch (flow_type) { 1126 1121 case TCP_V4_FLOW: 1127 1122 case UDP_V4_FLOW: 1128 1123 spec.match_flags = (EFX_FILTER_MATCH_ETHER_TYPE | 1129 1124 EFX_FILTER_MATCH_IP_PROTO); 1130 1125 spec.ether_type = htons(ETH_P_IP); 1131 - spec.ip_proto = ((rule->flow_type & ~FLOW_EXT) == TCP_V4_FLOW ? 1132 - IPPROTO_TCP : IPPROTO_UDP); 1126 + spec.ip_proto = flow_type == TCP_V4_FLOW ? IPPROTO_TCP 1127 + : IPPROTO_UDP; 1133 1128 if (ip_mask->ip4dst) { 1134 1129 if (ip_mask->ip4dst != IP4_ADDR_FULL_MASK) 1135 1130 return -EINVAL; ··· 1163 1158 spec.match_flags = (EFX_FILTER_MATCH_ETHER_TYPE | 1164 1159 EFX_FILTER_MATCH_IP_PROTO); 1165 1160 spec.ether_type = htons(ETH_P_IPV6); 1166 - spec.ip_proto = ((rule->flow_type & ~FLOW_EXT) == TCP_V6_FLOW ? 1167 - IPPROTO_TCP : IPPROTO_UDP); 1161 + spec.ip_proto = flow_type == TCP_V6_FLOW ? IPPROTO_TCP 1162 + : IPPROTO_UDP; 1168 1163 if (!ip6_mask_is_empty(ip6_mask->ip6dst)) { 1169 1164 if (!ip6_mask_is_full(ip6_mask->ip6dst)) 1170 1165 return -EINVAL; ··· 1371 1366 { 1372 1367 struct efx_nic *efx = netdev_priv(net_dev); 1373 1368 struct efx_rss_context *ctx; 1374 - int rc; 1369 + int rc = 0; 1375 1370 1376 1371 if (!efx->type->rx_pull_rss_context_config) 1377 1372 return -EOPNOTSUPP; 1378 - ctx = efx_find_rss_context_entry(rss_context, &efx->rss_context.list); 1379 - if (!ctx) 1380 - return -ENOENT; 1373 + 1374 + mutex_lock(&efx->rss_lock); 1375 + ctx = efx_find_rss_context_entry(efx, rss_context); 1376 + if (!ctx) { 1377 + rc = -ENOENT; 1378 + goto out_unlock; 1379 + } 1381 1380 rc = efx->type->rx_pull_rss_context_config(efx, ctx); 1382 1381 if (rc) 1383 - return rc; 1382 + goto out_unlock; 1384 1383 1385 1384 if (hfunc) 1386 1385 *hfunc = ETH_RSS_HASH_TOP; ··· 1392 1383 memcpy(indir, ctx->rx_indir_table, sizeof(ctx->rx_indir_table)); 1393 1384 if (key) 1394 1385 memcpy(key, ctx->rx_hash_key, efx->type->rx_hash_key_size); 1395 - return 0; 1386 + out_unlock: 1387 + mutex_unlock(&efx->rss_lock); 1388 + return rc; 1396 1389 } 1397 1390 1398 1391 static int efx_ethtool_set_rxfh_context(struct net_device *net_dev, ··· 1412 1401 /* Hash function is Toeplitz, cannot be changed */ 1413 1402 if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) 1414 1403 return -EOPNOTSUPP; 1404 + 1405 + mutex_lock(&efx->rss_lock); 1406 + 1415 1407 if (*rss_context == ETH_RXFH_CONTEXT_ALLOC) { 1416 - if (delete) 1408 + if (delete) { 1417 1409 /* alloc + delete == Nothing to do */ 1418 - return -EINVAL; 1419 - ctx = efx_alloc_rss_context_entry(&efx->rss_context.list); 1420 - if (!ctx) 1421 - return -ENOMEM; 1410 + rc = -EINVAL; 1411 + goto out_unlock; 1412 + } 1413 + ctx = efx_alloc_rss_context_entry(efx); 1414 + if (!ctx) { 1415 + rc = -ENOMEM; 1416 + goto out_unlock; 1417 + } 1422 1418 ctx->context_id = EFX_EF10_RSS_CONTEXT_INVALID; 1423 1419 /* Initialise indir table and key to defaults */ 1424 1420 efx_set_default_rx_indir_table(efx, ctx); 1425 1421 netdev_rss_key_fill(ctx->rx_hash_key, sizeof(ctx->rx_hash_key)); 1426 1422 allocated = true; 1427 1423 } else { 1428 - ctx = efx_find_rss_context_entry(*rss_context, 1429 - &efx->rss_context.list); 1430 - if (!ctx) 1431 - return -ENOENT; 1424 + ctx = efx_find_rss_context_entry(efx, *rss_context); 1425 + if (!ctx) { 1426 + rc = -ENOENT; 1427 + goto out_unlock; 1428 + } 1432 1429 } 1433 1430 1434 1431 if (delete) { ··· 1444 1425 rc = efx->type->rx_push_rss_context_config(efx, ctx, NULL, NULL); 1445 1426 if (!rc) 1446 1427 efx_free_rss_context_entry(ctx); 1447 - return rc; 1428 + goto out_unlock; 1448 1429 } 1449 1430 1450 1431 if (!key) ··· 1457 1438 efx_free_rss_context_entry(ctx); 1458 1439 else 1459 1440 *rss_context = ctx->user_id; 1441 + out_unlock: 1442 + mutex_unlock(&efx->rss_lock); 1460 1443 return rc; 1461 1444 } 1462 1445
+38 -42
drivers/net/ethernet/sfc/farch.c
··· 1878 1878 }; 1879 1879 1880 1880 struct efx_farch_filter_state { 1881 + struct rw_semaphore lock; /* Protects table contents */ 1881 1882 struct efx_farch_filter_table table[EFX_FARCH_FILTER_TABLE_COUNT]; 1882 1883 }; 1883 1884 ··· 2398 2397 if (rc) 2399 2398 return rc; 2400 2399 2400 + down_write(&state->lock); 2401 + 2401 2402 table = &state->table[efx_farch_filter_spec_table_id(&spec)]; 2402 - if (table->size == 0) 2403 - return -EINVAL; 2403 + if (table->size == 0) { 2404 + rc = -EINVAL; 2405 + goto out_unlock; 2406 + } 2404 2407 2405 2408 netif_vdbg(efx, hw, efx->net_dev, 2406 2409 "%s: type %d search_limit=%d", __func__, spec.type, ··· 2417 2412 EFX_FARCH_FILTER_MC_DEF - EFX_FARCH_FILTER_UC_DEF); 2418 2413 rep_index = spec.type - EFX_FARCH_FILTER_UC_DEF; 2419 2414 ins_index = rep_index; 2420 - 2421 - spin_lock_bh(&efx->filter_lock); 2422 2415 } else { 2423 2416 /* Search concurrently for 2424 2417 * (1) a filter to be replaced (rep_index): any filter ··· 2446 2443 ins_index = -1; 2447 2444 depth = 1; 2448 2445 2449 - spin_lock_bh(&efx->filter_lock); 2450 - 2451 2446 for (;;) { 2452 2447 if (!test_bit(i, table->used_bitmap)) { 2453 2448 if (ins_index < 0) ··· 2464 2463 /* Case (b) */ 2465 2464 if (ins_index < 0) { 2466 2465 rc = -EBUSY; 2467 - goto out; 2466 + goto out_unlock; 2468 2467 } 2469 2468 rep_index = -1; 2470 2469 break; ··· 2484 2483 2485 2484 if (spec.priority == saved_spec->priority && !replace_equal) { 2486 2485 rc = -EEXIST; 2487 - goto out; 2486 + goto out_unlock; 2488 2487 } 2489 2488 if (spec.priority < saved_spec->priority) { 2490 2489 rc = -EPERM; 2491 - goto out; 2490 + goto out_unlock; 2492 2491 } 2493 2492 if (saved_spec->priority == EFX_FILTER_PRI_AUTO || 2494 2493 saved_spec->flags & EFX_FILTER_FLAG_RX_OVER_AUTO) ··· 2529 2528 __func__, spec.type, ins_index, spec.dmaq_id); 2530 2529 rc = efx_farch_filter_make_id(&spec, ins_index); 2531 2530 2532 - out: 2533 - spin_unlock_bh(&efx->filter_lock); 2531 + out_unlock: 2532 + up_write(&state->lock); 2534 2533 return rc; 2535 2534 } 2536 2535 ··· 2605 2604 filter_idx = efx_farch_filter_id_index(filter_id); 2606 2605 if (filter_idx >= table->size) 2607 2606 return -ENOENT; 2607 + down_write(&state->lock); 2608 2608 spec = &table->spec[filter_idx]; 2609 2609 2610 - spin_lock_bh(&efx->filter_lock); 2611 2610 rc = efx_farch_filter_remove(efx, table, filter_idx, priority); 2612 - spin_unlock_bh(&efx->filter_lock); 2611 + up_write(&state->lock); 2613 2612 2614 2613 return rc; 2615 2614 } ··· 2623 2622 struct efx_farch_filter_table *table; 2624 2623 struct efx_farch_filter_spec *spec; 2625 2624 unsigned int filter_idx; 2626 - int rc; 2625 + int rc = -ENOENT; 2626 + 2627 + down_read(&state->lock); 2627 2628 2628 2629 table_id = efx_farch_filter_id_table_id(filter_id); 2629 2630 if ((unsigned int)table_id >= EFX_FARCH_FILTER_TABLE_COUNT) 2630 - return -ENOENT; 2631 + goto out_unlock; 2631 2632 table = &state->table[table_id]; 2632 2633 2633 2634 filter_idx = efx_farch_filter_id_index(filter_id); 2634 2635 if (filter_idx >= table->size) 2635 - return -ENOENT; 2636 + goto out_unlock; 2636 2637 spec = &table->spec[filter_idx]; 2637 - 2638 - spin_lock_bh(&efx->filter_lock); 2639 2638 2640 2639 if (test_bit(filter_idx, table->used_bitmap) && 2641 2640 spec->priority == priority) { 2642 2641 efx_farch_filter_to_gen_spec(spec_buf, spec); 2643 2642 rc = 0; 2644 - } else { 2645 - rc = -ENOENT; 2646 2643 } 2647 2644 2648 - spin_unlock_bh(&efx->filter_lock); 2649 - 2645 + out_unlock: 2646 + up_read(&state->lock); 2650 2647 return rc; 2651 2648 } 2652 2649 ··· 2657 2658 struct efx_farch_filter_table *table = &state->table[table_id]; 2658 2659 unsigned int filter_idx; 2659 2660 2660 - spin_lock_bh(&efx->filter_lock); 2661 + down_write(&state->lock); 2661 2662 for (filter_idx = 0; filter_idx < table->size; ++filter_idx) { 2662 2663 if (table->spec[filter_idx].priority != EFX_FILTER_PRI_AUTO) 2663 2664 efx_farch_filter_remove(efx, table, 2664 2665 filter_idx, priority); 2665 2666 } 2666 - spin_unlock_bh(&efx->filter_lock); 2667 + up_write(&state->lock); 2667 2668 } 2668 2669 2669 2670 int efx_farch_filter_clear_rx(struct efx_nic *efx, ··· 2687 2688 unsigned int filter_idx; 2688 2689 u32 count = 0; 2689 2690 2690 - spin_lock_bh(&efx->filter_lock); 2691 + down_read(&state->lock); 2691 2692 2692 2693 for (table_id = EFX_FARCH_FILTER_TABLE_RX_IP; 2693 2694 table_id <= EFX_FARCH_FILTER_TABLE_RX_DEF; ··· 2700 2701 } 2701 2702 } 2702 2703 2703 - spin_unlock_bh(&efx->filter_lock); 2704 + up_read(&state->lock); 2704 2705 2705 2706 return count; 2706 2707 } ··· 2715 2716 unsigned int filter_idx; 2716 2717 s32 count = 0; 2717 2718 2718 - spin_lock_bh(&efx->filter_lock); 2719 + down_read(&state->lock); 2719 2720 2720 2721 for (table_id = EFX_FARCH_FILTER_TABLE_RX_IP; 2721 2722 table_id <= EFX_FARCH_FILTER_TABLE_RX_DEF; ··· 2734 2735 } 2735 2736 } 2736 2737 out: 2737 - spin_unlock_bh(&efx->filter_lock); 2738 + up_read(&state->lock); 2738 2739 2739 2740 return count; 2740 2741 } ··· 2748 2749 efx_oword_t filter; 2749 2750 unsigned int filter_idx; 2750 2751 2751 - spin_lock_bh(&efx->filter_lock); 2752 + down_write(&state->lock); 2752 2753 2753 2754 for (table_id = 0; table_id < EFX_FARCH_FILTER_TABLE_COUNT; table_id++) { 2754 2755 table = &state->table[table_id]; ··· 2769 2770 efx_farch_filter_push_rx_config(efx); 2770 2771 efx_farch_filter_push_tx_limits(efx); 2771 2772 2772 - spin_unlock_bh(&efx->filter_lock); 2773 + up_write(&state->lock); 2773 2774 } 2774 2775 2775 2776 void efx_farch_filter_table_remove(struct efx_nic *efx) ··· 2863 2864 efx_oword_t filter; 2864 2865 unsigned int filter_idx; 2865 2866 2866 - spin_lock_bh(&efx->filter_lock); 2867 + down_write(&state->lock); 2867 2868 2868 2869 for (table_id = EFX_FARCH_FILTER_TABLE_RX_IP; 2869 2870 table_id <= EFX_FARCH_FILTER_TABLE_RX_DEF; ··· 2895 2896 2896 2897 efx_farch_filter_push_rx_config(efx); 2897 2898 2898 - spin_unlock_bh(&efx->filter_lock); 2899 + up_write(&state->lock); 2899 2900 } 2900 2901 2901 2902 #ifdef CONFIG_RFS_ACCEL 2902 - 2903 - s32 efx_farch_filter_rfs_insert(struct efx_nic *efx, 2904 - struct efx_filter_spec *gen_spec) 2905 - { 2906 - return efx_farch_filter_insert(efx, gen_spec, true); 2907 - } 2908 2903 2909 2904 bool efx_farch_filter_rfs_expire_one(struct efx_nic *efx, u32 flow_id, 2910 2905 unsigned int index) 2911 2906 { 2912 2907 struct efx_farch_filter_state *state = efx->filter_state; 2913 - struct efx_farch_filter_table *table = 2914 - &state->table[EFX_FARCH_FILTER_TABLE_RX_IP]; 2908 + struct efx_farch_filter_table *table; 2909 + bool ret = false; 2915 2910 2911 + down_write(&state->lock); 2912 + table = &state->table[EFX_FARCH_FILTER_TABLE_RX_IP]; 2916 2913 if (test_bit(index, table->used_bitmap) && 2917 2914 table->spec[index].priority == EFX_FILTER_PRI_HINT && 2918 2915 rps_may_expire_flow(efx->net_dev, table->spec[index].dmaq_id, 2919 2916 flow_id, index)) { 2920 2917 efx_farch_filter_table_clear_entry(efx, table, index); 2921 - return true; 2918 + ret = true; 2922 2919 } 2923 2920 2924 - return false; 2921 + up_write(&state->lock); 2922 + return ret; 2925 2923 } 2926 2924 2927 2925 #endif /* CONFIG_RFS_ACCEL */
+7 -9
drivers/net/ethernet/sfc/net_driver.h
··· 430 430 * @event_test_cpu: Last CPU to handle interrupt or test event for this channel 431 431 * @irq_count: Number of IRQs since last adaptive moderation decision 432 432 * @irq_mod_score: IRQ moderation score 433 + * @filter_work: Work item for efx_filter_rfs_expire() 433 434 * @rps_flow_id: Flow IDs of filters allocated for accelerated RFS, 434 435 * indexed by filter ID 435 436 * @n_rx_tobe_disc: Count of RX_TOBE_DISC errors ··· 476 475 unsigned int irq_mod_score; 477 476 #ifdef CONFIG_RFS_ACCEL 478 477 unsigned int rfs_filters_added; 478 + struct work_struct filter_work; 479 479 #define RPS_FLOW_ID_INVALID 0xFFFFFFFF 480 480 u32 *rps_flow_id; 481 481 #endif ··· 796 794 * @rx_scatter: Scatter mode enabled for receives 797 795 * @rss_context: Main RSS context. Its @list member is the head of the list of 798 796 * RSS contexts created by user requests 797 + * @rss_lock: Protects custom RSS context software state in @rss_context.list 799 798 * @int_error_count: Number of internal errors seen recently 800 799 * @int_error_expire: Time at which error count will be expired 801 800 * @irq_soft_enabled: Are IRQs soft-enabled? If not, IRQ handler will ··· 844 841 * @loopback_mode: Loopback status 845 842 * @loopback_modes: Supported loopback mode bitmask 846 843 * @loopback_selftest: Offline self-test private state 847 - * @filter_sem: Filter table rw_semaphore, for freeing the table 848 - * @filter_lock: Filter table lock, for mere content changes 844 + * @filter_sem: Filter table rw_semaphore, protects existence of @filter_state 849 845 * @filter_state: Architecture-dependent filter table state 846 + * @rps_mutex: Protects RPS state of all channels 850 847 * @rps_expire_channel: Next channel to check for expiry 851 848 * @rps_expire_index: Next index to check for expiry in 852 849 * @rps_expire_channel's @rps_flow_id ··· 941 938 int rx_packet_ts_offset; 942 939 bool rx_scatter; 943 940 struct efx_rss_context rss_context; 941 + struct mutex rss_lock; 944 942 945 943 unsigned int_error_count; 946 944 unsigned long int_error_expire; ··· 999 995 void *loopback_selftest; 1000 996 1001 997 struct rw_semaphore filter_sem; 1002 - spinlock_t filter_lock; 1003 998 void *filter_state; 1004 999 #ifdef CONFIG_RFS_ACCEL 1000 + struct mutex rps_mutex; 1005 1001 unsigned int rps_expire_channel; 1006 1002 unsigned int rps_expire_index; 1007 1003 #endif ··· 1156 1152 * @filter_count_rx_used: Get the number of filters in use at a given priority 1157 1153 * @filter_get_rx_id_limit: Get maximum value of a filter id, plus 1 1158 1154 * @filter_get_rx_ids: Get list of RX filters at a given priority 1159 - * @filter_rfs_insert: Add or replace a filter for RFS. This must be 1160 - * atomic. The hardware change may be asynchronous but should 1161 - * not be delayed for long. It may fail if this can't be done 1162 - * atomically. 1163 1155 * @filter_rfs_expire_one: Consider expiring a filter inserted for RFS. 1164 1156 * This must check whether the specified table entry is used by RFS 1165 1157 * and that rps_may_expire_flow() returns true for it. ··· 1306 1306 enum efx_filter_priority priority, 1307 1307 u32 *buf, u32 size); 1308 1308 #ifdef CONFIG_RFS_ACCEL 1309 - s32 (*filter_rfs_insert)(struct efx_nic *efx, 1310 - struct efx_filter_spec *spec); 1311 1309 bool (*filter_rfs_expire_one)(struct efx_nic *efx, u32 flow_id, 1312 1310 unsigned int index); 1313 1311 #endif
+3 -2
drivers/net/ethernet/sfc/nic.h
··· 365 365 * @vi_base: Absolute index of first VI in this function 366 366 * @n_allocated_vis: Number of VIs allocated to this function 367 367 * @must_realloc_vis: Flag: VIs have yet to be reallocated after MC reboot 368 + * @must_restore_rss_contexts: Flag: RSS contexts have yet to be restored after 369 + * MC reboot 368 370 * @must_restore_filters: Flag: filters have yet to be restored after MC reboot 369 371 * @n_piobufs: Number of PIO buffers allocated to this function 370 372 * @wc_membase: Base address of write-combining mapping of the memory BAR ··· 409 407 unsigned int vi_base; 410 408 unsigned int n_allocated_vis; 411 409 bool must_realloc_vis; 410 + bool must_restore_rss_contexts; 412 411 bool must_restore_filters; 413 412 unsigned int n_piobufs; 414 413 void __iomem *wc_membase, *pio_write_base; ··· 604 601 enum efx_filter_priority priority, u32 *buf, 605 602 u32 size); 606 603 #ifdef CONFIG_RFS_ACCEL 607 - s32 efx_farch_filter_rfs_insert(struct efx_nic *efx, 608 - struct efx_filter_spec *spec); 609 604 bool efx_farch_filter_rfs_expire_one(struct efx_nic *efx, u32 flow_id, 610 605 unsigned int index); 611 606 #endif
+80 -39
drivers/net/ethernet/sfc/rx.c
··· 827 827 828 828 #ifdef CONFIG_RFS_ACCEL 829 829 830 + /** 831 + * struct efx_async_filter_insertion - Request to asynchronously insert a filter 832 + * @net_dev: Reference to the netdevice 833 + * @spec: The filter to insert 834 + * @work: Workitem for this request 835 + * @rxq_index: Identifies the channel for which this request was made 836 + * @flow_id: Identifies the kernel-side flow for which this request was made 837 + */ 838 + struct efx_async_filter_insertion { 839 + struct net_device *net_dev; 840 + struct efx_filter_spec spec; 841 + struct work_struct work; 842 + u16 rxq_index; 843 + u32 flow_id; 844 + }; 845 + 846 + static void efx_filter_rfs_work(struct work_struct *data) 847 + { 848 + struct efx_async_filter_insertion *req = container_of(data, struct efx_async_filter_insertion, 849 + work); 850 + struct efx_nic *efx = netdev_priv(req->net_dev); 851 + struct efx_channel *channel = efx_get_channel(efx, req->rxq_index); 852 + int rc; 853 + 854 + rc = efx->type->filter_insert(efx, &req->spec, false); 855 + if (rc >= 0) { 856 + /* Remember this so we can check whether to expire the filter 857 + * later. 858 + */ 859 + mutex_lock(&efx->rps_mutex); 860 + channel->rps_flow_id[rc] = req->flow_id; 861 + ++channel->rfs_filters_added; 862 + mutex_unlock(&efx->rps_mutex); 863 + 864 + if (req->spec.ether_type == htons(ETH_P_IP)) 865 + netif_info(efx, rx_status, efx->net_dev, 866 + "steering %s %pI4:%u:%pI4:%u to queue %u [flow %u filter %d]\n", 867 + (req->spec.ip_proto == IPPROTO_TCP) ? "TCP" : "UDP", 868 + req->spec.rem_host, ntohs(req->spec.rem_port), 869 + req->spec.loc_host, ntohs(req->spec.loc_port), 870 + req->rxq_index, req->flow_id, rc); 871 + else 872 + netif_info(efx, rx_status, efx->net_dev, 873 + "steering %s [%pI6]:%u:[%pI6]:%u to queue %u [flow %u filter %d]\n", 874 + (req->spec.ip_proto == IPPROTO_TCP) ? "TCP" : "UDP", 875 + req->spec.rem_host, ntohs(req->spec.rem_port), 876 + req->spec.loc_host, ntohs(req->spec.loc_port), 877 + req->rxq_index, req->flow_id, rc); 878 + } 879 + 880 + /* Release references */ 881 + dev_put(req->net_dev); 882 + kfree(req); 883 + } 884 + 830 885 int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb, 831 886 u16 rxq_index, u32 flow_id) 832 887 { 833 888 struct efx_nic *efx = netdev_priv(net_dev); 834 - struct efx_channel *channel; 835 - struct efx_filter_spec spec; 889 + struct efx_async_filter_insertion *req; 836 890 struct flow_keys fk; 837 - int rc; 838 891 839 892 if (flow_id == RPS_FLOW_ID_INVALID) 840 893 return -EINVAL; ··· 900 847 if (fk.control.flags & FLOW_DIS_IS_FRAGMENT) 901 848 return -EPROTONOSUPPORT; 902 849 903 - efx_filter_init_rx(&spec, EFX_FILTER_PRI_HINT, 850 + req = kmalloc(sizeof(*req), GFP_ATOMIC); 851 + if (!req) 852 + return -ENOMEM; 853 + 854 + efx_filter_init_rx(&req->spec, EFX_FILTER_PRI_HINT, 904 855 efx->rx_scatter ? EFX_FILTER_FLAG_RX_SCATTER : 0, 905 856 rxq_index); 906 - spec.match_flags = 857 + req->spec.match_flags = 907 858 EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO | 908 859 EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT | 909 860 EFX_FILTER_MATCH_REM_HOST | EFX_FILTER_MATCH_REM_PORT; 910 - spec.ether_type = fk.basic.n_proto; 911 - spec.ip_proto = fk.basic.ip_proto; 861 + req->spec.ether_type = fk.basic.n_proto; 862 + req->spec.ip_proto = fk.basic.ip_proto; 912 863 913 864 if (fk.basic.n_proto == htons(ETH_P_IP)) { 914 - spec.rem_host[0] = fk.addrs.v4addrs.src; 915 - spec.loc_host[0] = fk.addrs.v4addrs.dst; 865 + req->spec.rem_host[0] = fk.addrs.v4addrs.src; 866 + req->spec.loc_host[0] = fk.addrs.v4addrs.dst; 916 867 } else { 917 - memcpy(spec.rem_host, &fk.addrs.v6addrs.src, sizeof(struct in6_addr)); 918 - memcpy(spec.loc_host, &fk.addrs.v6addrs.dst, sizeof(struct in6_addr)); 868 + memcpy(req->spec.rem_host, &fk.addrs.v6addrs.src, 869 + sizeof(struct in6_addr)); 870 + memcpy(req->spec.loc_host, &fk.addrs.v6addrs.dst, 871 + sizeof(struct in6_addr)); 919 872 } 920 873 921 - spec.rem_port = fk.ports.src; 922 - spec.loc_port = fk.ports.dst; 874 + req->spec.rem_port = fk.ports.src; 875 + req->spec.loc_port = fk.ports.dst; 923 876 924 - rc = efx->type->filter_rfs_insert(efx, &spec); 925 - if (rc < 0) 926 - return rc; 927 - 928 - /* Remember this so we can check whether to expire the filter later */ 929 - channel = efx_get_channel(efx, rxq_index); 930 - channel->rps_flow_id[rc] = flow_id; 931 - ++channel->rfs_filters_added; 932 - 933 - if (spec.ether_type == htons(ETH_P_IP)) 934 - netif_info(efx, rx_status, efx->net_dev, 935 - "steering %s %pI4:%u:%pI4:%u to queue %u [flow %u filter %d]\n", 936 - (spec.ip_proto == IPPROTO_TCP) ? "TCP" : "UDP", 937 - spec.rem_host, ntohs(spec.rem_port), spec.loc_host, 938 - ntohs(spec.loc_port), rxq_index, flow_id, rc); 939 - else 940 - netif_info(efx, rx_status, efx->net_dev, 941 - "steering %s [%pI6]:%u:[%pI6]:%u to queue %u [flow %u filter %d]\n", 942 - (spec.ip_proto == IPPROTO_TCP) ? "TCP" : "UDP", 943 - spec.rem_host, ntohs(spec.rem_port), spec.loc_host, 944 - ntohs(spec.loc_port), rxq_index, flow_id, rc); 945 - 946 - return rc; 877 + dev_hold(req->net_dev = net_dev); 878 + INIT_WORK(&req->work, efx_filter_rfs_work); 879 + req->rxq_index = rxq_index; 880 + req->flow_id = flow_id; 881 + schedule_work(&req->work); 882 + return 0; 947 883 } 948 884 949 885 bool __efx_filter_rfs_expire(struct efx_nic *efx, unsigned int quota) ··· 941 899 unsigned int channel_idx, index, size; 942 900 u32 flow_id; 943 901 944 - if (!spin_trylock_bh(&efx->filter_lock)) 902 + if (!mutex_trylock(&efx->rps_mutex)) 945 903 return false; 946 - 947 904 expire_one = efx->type->filter_rfs_expire_one; 948 905 channel_idx = efx->rps_expire_channel; 949 906 index = efx->rps_expire_index; ··· 967 926 efx->rps_expire_channel = channel_idx; 968 927 efx->rps_expire_index = index; 969 928 970 - spin_unlock_bh(&efx->filter_lock); 929 + mutex_unlock(&efx->rps_mutex); 971 930 return true; 972 931 } 973 932
-1
drivers/net/ethernet/sfc/siena.c
··· 1035 1035 .filter_get_rx_id_limit = efx_farch_filter_get_rx_id_limit, 1036 1036 .filter_get_rx_ids = efx_farch_filter_get_rx_ids, 1037 1037 #ifdef CONFIG_RFS_ACCEL 1038 - .filter_rfs_insert = efx_farch_filter_rfs_insert, 1039 1038 .filter_rfs_expire_one = efx_farch_filter_rfs_expire_one, 1040 1039 #endif 1041 1040 #ifdef CONFIG_SFC_MTD