From: Suzuki Shota <suzuki_shota_t3@lab.ntt.co.jp>
To: intel-wired-lan@osuosl.org
Subject: [Intel-wired-lan] [PATCH net] igb: Fix oops caused by missing queue pairing
Date: Thu, 23 Jul 2015 14:56:44 +0900 [thread overview]
Message-ID: <55B0821C.4060809@lab.ntt.co.jp> (raw)
In-Reply-To: <1435710352-956-1-git-send-email-suzuki_shota_t3@lab.ntt.co.jp>
Dear Jeffrey,
With regard to the patch I submitted,
would you tell me the review status of it?
(I'm watching Patchwork of intel-wired-lan,
but the state of my patch is still 'New')
Do I have to do other things?
Regards,
Shota Suzuki
On 2015/07/01 9:25, Shota Suzuki wrote:
> When initializing igb driver (e.g. 82576, I350), IGB_FLAG_QUEUE_PAIRS is
> set if adapter->rss_queues exceeds half of max_rss_queues in
> igb_init_queue_configuration().
> On the other hand, IGB_FLAG_QUEUE_PAIRS is not set even if the number of
> queues exceeds half of max_combined in igb_set_channels() when changing
> the number of queues by "ethtool -L".
> In this case, if numvecs is larger than MAX_MSIX_ENTRIES (10), the size
> of adapter->msix_entries[], an overflow can occur in
> igb_set_interrupt_capability(), which in turn leads to an oops.
>
> Fix this problem as follows:
> - When changing the number of queues by "ethtool -L", set
> IGB_FLAG_QUEUE_PAIRS in the same way as initializing igb driver.
> - When increasing the size of q_vector, reallocate it appropriately.
> (With IGB_FLAG_QUEUE_PAIRS set, the size of q_vector gets larger.)
>
> Another possible way to fix this problem is to cap the queues at its
> initial number, which is the number of the initial online cpus. But this
> is not the optimal way because we cannnot increase queues when another
> cpu becomes online.
>
> Note that before commit cd14ef54d25b ("igb: Change to use statically
> allocated array for MSIx entries"), this problem did not cause oops
> but just made the number of queues become 1 because of entering msi_only
> mode in igb_set_interrupt_capability().
>
> Fixes: 907b7835799f ("igb: Add ethtool support to configure number of channels")
> Signed-off-by: Shota Suzuki <suzuki_shota_t3@lab.ntt.co.jp>
> ---
> Although we might be able to additionally unset IGB_FLAG_QUEUE_PAIRS
> when it is not needed, this patch doesn't change existing behaviour
> because such a change is not a bug fix.
>
> drivers/net/ethernet/intel/igb/igb.h | 1 +
> drivers/net/ethernet/intel/igb/igb_ethtool.c | 5 ++++-
> drivers/net/ethernet/intel/igb/igb_main.c | 16 ++++++++++++++--
> 3 files changed, 19 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
> index c2bd4f9..212d668 100644
> --- a/drivers/net/ethernet/intel/igb/igb.h
> +++ b/drivers/net/ethernet/intel/igb/igb.h
> @@ -540,6 +540,7 @@ void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, unsigned char *va,
> struct sk_buff *skb);
> int igb_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr);
> int igb_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr);
> +void igb_set_flag_queue_pairs(struct igb_adapter *, const u32);
> #ifdef CONFIG_IGB_HWMON
> void igb_sysfs_exit(struct igb_adapter *adapter);
> int igb_sysfs_init(struct igb_adapter *adapter);
> diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c
> index d5673eb..0afc091 100644
> --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
> +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
> @@ -2991,6 +2991,7 @@ static int igb_set_channels(struct net_device *netdev,
> {
> struct igb_adapter *adapter = netdev_priv(netdev);
> unsigned int count = ch->combined_count;
> + unsigned int max_combined = 0;
>
> /* Verify they are not requesting separate vectors */
> if (!count || ch->rx_count || ch->tx_count)
> @@ -3001,11 +3002,13 @@ static int igb_set_channels(struct net_device *netdev,
> return -EINVAL;
>
> /* Verify the number of channels doesn't exceed hw limits */
> - if (count > igb_max_channels(adapter))
> + max_combined = igb_max_channels(adapter);
> + if (count > max_combined)
> return -EINVAL;
>
> if (count != adapter->rss_queues) {
> adapter->rss_queues = count;
> + igb_set_flag_queue_pairs(adapter, max_combined);
>
> /* Hardware has to reinitialize queues and interrupts to
> * match the new configuration.
> diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
> index f287186..59dc2b4 100644
> --- a/drivers/net/ethernet/intel/igb/igb_main.c
> +++ b/drivers/net/ethernet/intel/igb/igb_main.c
> @@ -1205,10 +1205,14 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter,
>
> /* allocate q_vector and rings */
> q_vector = adapter->q_vector[v_idx];
> - if (!q_vector)
> + if (!q_vector) {
> q_vector = kzalloc(size, GFP_KERNEL);
> - else
> + } else if (size > ksize(q_vector)) {
> + kfree_rcu(q_vector, rcu);
> + q_vector = kzalloc(size, GFP_KERNEL);
> + } else {
> memset(q_vector, 0, size);
> + }
> if (!q_vector)
> return -ENOMEM;
>
> @@ -2888,6 +2892,14 @@ static void igb_init_queue_configuration(struct igb_adapter *adapter)
>
> adapter->rss_queues = min_t(u32, max_rss_queues, num_online_cpus());
>
> + igb_set_flag_queue_pairs(adapter, max_rss_queues);
> +}
> +
> +void igb_set_flag_queue_pairs(struct igb_adapter *adapter,
> + const u32 max_rss_queues)
> +{
> + struct e1000_hw *hw = &adapter->hw;
> +
> /* Determine if we need to pair queues. */
> switch (hw->mac.type) {
> case e1000_82575:
>
next prev parent reply other threads:[~2015-07-23 5:56 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-01 0:25 [Intel-wired-lan] [PATCH net] igb: Fix oops caused by missing queue pairing Shota Suzuki
2015-07-23 5:56 ` Suzuki Shota [this message]
2015-07-23 14:11 ` Jeff Kirsher
2015-08-15 1:42 ` Brown, Aaron F
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=55B0821C.4060809@lab.ntt.co.jp \
--to=suzuki_shota_t3@lab.ntt.co.jp \
--cc=intel-wired-lan@osuosl.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox