* Re: [PATCH] net: thunderx: prevent concurrent data re-writing by nicvf_set_rx_mode
From: David Miller @ 2018-06-12 22:25 UTC (permalink / raw)
To: dnelson
Cc: Vadim.Lomovtsev, rric, sgoutham, linux-arm-kernel, netdev,
linux-kernel, Vadim.Lomovtsev
In-Reply-To: <036618ae-887f-44b5-2b39-451b81191cc1@redhat.com>
From: Dean Nelson <dnelson@redhat.com>
Date: Mon, 11 Jun 2018 06:22:14 -0500
> On 06/10/2018 02:35 PM, David Miller wrote:
>> From: Vadim Lomovtsev <Vadim.Lomovtsev@caviumnetworks.com>
>> Date: Fri, 8 Jun 2018 02:27:59 -0700
>>
>>> + /* Save message data locally to prevent them from
>>> + * being overwritten by next ndo_set_rx_mode call().
>>> + */
>>> + spin_lock(&nic->rx_mode_wq_lock);
>>> + mode = vf_work->mode;
>>> + mc = vf_work->mc;
>>> + vf_work->mc = NULL;
>
> If I'm reading this code correctly, I believe nic->rx_mode_work.mc
> will
> have been set to NULL before the lock is dropped by
> nicvf_set_rx_mode_task() and acquired by nicvf_set_rx_mode().
>
>
>>> + spin_unlock(&nic->rx_mode_wq_lock);
>> At the moment you drop this lock, the memory behind 'mc' can be
>> freed up by:
>>
>>> + spin_lock(&nic->rx_mode_wq_lock);
>>> + kfree(nic->rx_mode_work.mc);
>
> So the kfree() will be called with a NULL pointer and quickly return.
>
>
>> And you'll crash when you dereference it above via
>> __nicvf_set_rx_mode_task().
>>
>
> I believe the call to kfree() in nicvf_set_rx_mode() is there to free
> up a mc_list that has been allocated by nicvf_set_rx_mode() during a
> previous callback to the function, one that has not yet been processed
> by nicvf_set_rx_mode_task().
>
> In this way only the last 'unprocessed' callback to
> nicvf_set_rx_mode()
> gets processed should there be multiple callbacks occurring between
> the
> times the nicvf_set_rx_mode_task() runs.
>
> In my testing with this patch, this is what I see happening.
You're right, my bad.
Patch applied.
^ permalink raw reply
* Re: [PATCH] net: phy: mdio-gpio: Cut surplus includes
From: David Miller @ 2018-06-12 22:24 UTC (permalink / raw)
To: linus.walleij; +Cc: andrew, f.fainelli, netdev
In-Reply-To: <20180611111903.7221-1-linus.walleij@linaro.org>
From: Linus Walleij <linus.walleij@linaro.org>
Date: Mon, 11 Jun 2018 13:19:03 +0200
> The GPIO MDIO driver now needs only <linux/gpio/consumer.h>
> so cut the legacy <linux/gpio.h> and <linux/of_gpio.h>
> includes that are no longer used.
>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Applied.
^ permalink raw reply
* Re: [PATCH net 0/3] hv_netvsc: notification and namespace fixes
From: David Miller @ 2018-06-12 22:22 UTC (permalink / raw)
To: stephen; +Cc: kys, haiyangz, sthemmin, devel, netdev
In-Reply-To: <20180611194456.8268-1-sthemmin@microsoft.com>
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Mon, 11 Jun 2018 12:44:53 -0700
> This set of patches addresses two set of fixes. First it backs out
> the common callback model which was merged in net-next without
> completing all the review feedback or getting maintainer approval.
>
> Then it fixes the transparent VF management code to handle network
> namespaces.
Series applied.
^ permalink raw reply
* Re: [PATCH net 0/4] nfp: fix a warning, stats, naming and route leak
From: David Miller @ 2018-06-12 22:18 UTC (permalink / raw)
To: jakub.kicinski; +Cc: netdev, oss-drivers
In-Reply-To: <20180612043338.5447-1-jakub.kicinski@netronome.com>
From: Jakub Kicinski <jakub.kicinski@netronome.com>
Date: Mon, 11 Jun 2018 21:33:34 -0700
> Various fixes for the NFP. Patch 1 fixes a harmless GCC 8 warning.
> Patch 2 ensures statistics are correct after users decrease the number
> of channels/rings. Patch 3 restores phy_port_name behaviour for flower,
> ndo_get_phy_port_name used to return -EOPNOTSUPP on one of the netdevs,
> and we need to keep it that way otherwise interface names may change.
> Patch 4 fixes refcnt leak in flower tunnel offload code.
Series applied.
^ permalink raw reply
* Re: [Intel-wired-lan] [jkirsher/next-queue PATCH v2 2/7] net: Add support for subordinate device traffic classes
From: Alexander Duyck @ 2018-06-12 22:18 UTC (permalink / raw)
To: Florian Fainelli; +Cc: Alexander Duyck, intel-wired-lan, Jeff Kirsher, Netdev
In-Reply-To: <f4eaac32-204e-259d-b69b-c2c9885d55fa@gmail.com>
On Tue, Jun 12, 2018 at 10:49 AM, Florian Fainelli <f.fainelli@gmail.com> wrote:
> On 06/12/2018 08:18 AM, Alexander Duyck wrote:
>> This patch is meant to provide the basic tools needed to allow us to create
>> subordinate device traffic classes. The general idea here is to allow
>> subdividing the queues of a device into queue groups accessible through an
>> upper device such as a macvlan.
>>
>> The idea here is to enforce the idea that an upper device has to be a
>> single queue device, ideally with IFF_NO_QUQUE set. With that being the
>> case we can pretty much guarantee that the tc_to_txq mappings and XPS maps
>> for the upper device are unused. As such we could reuse those in order to
>> support subdividing the lower device and distributing those queues between
>> the subordinate devices.
>
> This is not necessarily a valid paradigm to work with. For instance in
> DSA we have IFF_NO_QUEUE devices, but we still expose multiple egress
> queues because that is how an application can choose how it wants to get
> packets transmitted at the switch level. We have a 1:1 representation
> between a queue at the net_device level, and what an egress queue at the
> switch level is, so things like buffer reservation etc. can be configured.
I'm not saying that IFF_NO_QUEUE implies that a device is single
queue, but in this case we enforce that the upper device has to be a
single queue device so that the code in netdev_pick_tx will ignore the
XPS and tc_to_txq mappings for that netdev. I had mentioned
IFF_NO_QUEUE as a suggestion as that allows us to avoid head-of-line
blocking if the lower device starts to apply back-pressure.
> I think you should consider that an upper device might want to have a
> 1:1 mapping to the lower device's queues and make that permissible.
> Thoughts?
I had considered that. However the issue becomes that at that point it
makes the setup much more rigid. With this approach I can enable and
disable the offload without needing to stop the upper device to either
create or remove qdiscs. I would much rather keep the upper device
generic and leave it to the lower device to populate the rings and
such.
^ permalink raw reply
* Re: [PATCH v2] tcp: verify the checksum of the first data segment in a new connection
From: Eric Dumazet @ 2018-06-12 22:03 UTC (permalink / raw)
To: van der Linden, Frank, Eric Dumazet, edumazet@google.com,
netdev@vger.kernel.org
In-Reply-To: <EB56EB1B-8E64-4D2C-9604-5ACFD3857F0D@amazon.com>
On 06/12/2018 02:53 PM, van der Linden, Frank wrote:
> The convention seems to be to call tcp_checksum_complete after tcp_filter has a chance to deal with the packet. I wanted to preserve that.
>
> If that is not a concern, then I agree that this is a far better way to go.
>
> Frank
Given that we can drop the packet earlier from :
if (skb_checksum_init(skb, IPPROTO_TCP, inet_compute_pseudo))
goto csum_error;
I am quite sure we really do not care of tcp_filter() being
hit or not by packets with bad checksum.
Thanks
^ permalink raw reply
* Re: Problems in tc-matchall.8, tc-sample.8
From: Eric S. Raymond @ 2018-06-12 22:00 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <20180612141700.3a679643@xeon-e3>
Stephen Hemminger <stephen@networkplumber.org>:
> Please resubmit as real patch with signed-off-by
I would like to follow your intructions, but that description leaves me
not quite certain what you want. A git format-patch thing? If so, what
git url should I clone from?
--
<a href="http://www.catb.org/~esr/">Eric S. Raymond</a>
My work is funded by the Internet Civil Engineering Institute: https://icei.org
Please visit their site and donate: the civilization you save might be your own.
^ permalink raw reply
* Re: [PATCH v2] tcp: verify the checksum of the first data segment in a new connection
From: van der Linden, Frank @ 2018-06-12 21:53 UTC (permalink / raw)
To: Eric Dumazet, edumazet@google.com, netdev@vger.kernel.org
In-Reply-To: <9541859a-1346-e13a-b97c-a2a63f3b19f4@gmail.com>
The convention seems to be to call tcp_checksum_complete after tcp_filter has a chance to deal with the packet. I wanted to preserve that.
If that is not a concern, then I agree that this is a far better way to go.
Frank
On 6/12/18, 2:50 PM, "Eric Dumazet" <eric.dumazet@gmail.com> wrote:
On 06/12/2018 02:41 PM, Frank van der Linden wrote:
> commit 079096f103fa ("tcp/dccp: install syn_recv requests into ehash
> table") introduced an optimization for the handling of child sockets
> created for a new TCP connection.
>
> But this optimization passes any data associated with the last ACK of the
> connection handshake up the stack without verifying its checksum, because it
> calls tcp_child_process(), which in turn calls tcp_rcv_state_process()
> directly. These lower-level processing functions do not do any checksum
> verification.
>
> Insert a tcp_checksum_complete call in the TCP_NEW_SYN_RECEIVE path to
> fix this.
>
> Signed-off-by: Frank van der Linden <fllinden@amazon.com>
This is way too complicated.
You should call tcp_checksum_complete() earlier and avoid all this mess.
IPV4 part shown here :
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index fed3f1c6616708997f621535efe9412e4afa0a50..7b5f32aa3835b0124b0a9bd342c371df7b46f471 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1730,6 +1730,10 @@ int tcp_v4_rcv(struct sk_buff *skb)
reqsk_put(req);
goto discard_it;
}
+ if (unlikely(tcp_checksum_complete(skb))) {
+ reqsk_put(req);
+ goto csum_error;
+ }
if (unlikely(sk->sk_state != TCP_LISTEN)) {
inet_csk_reqsk_queue_drop_and_put(sk, req);
goto lookup;
^ permalink raw reply
* Re: [PATCH v2] tcp: verify the checksum of the first data segment in a new connection
From: Eric Dumazet @ 2018-06-12 21:50 UTC (permalink / raw)
To: Frank van der Linden, edumazet, netdev
In-Reply-To: <5b203e1b.vy4yU6CwMEwLmNtj%fllinden@amazon.com>
On 06/12/2018 02:41 PM, Frank van der Linden wrote:
> commit 079096f103fa ("tcp/dccp: install syn_recv requests into ehash
> table") introduced an optimization for the handling of child sockets
> created for a new TCP connection.
>
> But this optimization passes any data associated with the last ACK of the
> connection handshake up the stack without verifying its checksum, because it
> calls tcp_child_process(), which in turn calls tcp_rcv_state_process()
> directly. These lower-level processing functions do not do any checksum
> verification.
>
> Insert a tcp_checksum_complete call in the TCP_NEW_SYN_RECEIVE path to
> fix this.
>
> Signed-off-by: Frank van der Linden <fllinden@amazon.com>
This is way too complicated.
You should call tcp_checksum_complete() earlier and avoid all this mess.
IPV4 part shown here :
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index fed3f1c6616708997f621535efe9412e4afa0a50..7b5f32aa3835b0124b0a9bd342c371df7b46f471 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1730,6 +1730,10 @@ int tcp_v4_rcv(struct sk_buff *skb)
reqsk_put(req);
goto discard_it;
}
+ if (unlikely(tcp_checksum_complete(skb))) {
+ reqsk_put(req);
+ goto csum_error;
+ }
if (unlikely(sk->sk_state != TCP_LISTEN)) {
inet_csk_reqsk_queue_drop_and_put(sk, req);
goto lookup;
^ permalink raw reply related
* Re: [PATCH] tcp: verify the checksum of the first data segment in a new connection
From: van der Linden, Frank @ 2018-06-12 21:44 UTC (permalink / raw)
To: Eric Dumazet, edumazet@google.com, netdev@vger.kernel.org
In-Reply-To: <4A996A47-0BA5-4880-BDAD-05037407F1B9@amazon.com>
Resubmitted. The various release/deref requirements in that path make a straight "goto csum_error" impossible without duplicating some lines, but this is 2nd best.
Frank
On 6/11/18, 4:43 PM, "van der Linden, Frank" <fllinden@amazon.com> wrote:
Yeah, true, it's missing INERRS in this case. I'll fix it up a bit.
Frank
On 6/11/18, 4:38 PM, "Eric Dumazet" <eric.dumazet@gmail.com> wrote:
On 06/11/2018 04:25 PM, van der Linden, Frank wrote:
> A few comments on this one:
>
> - obviously this is fairly serious, as it can let corrupted data all the way up to the application
Sure, although anyone relying on CRC checksum for ensuring TCP data integrity
has big troubles ;)
I would rather have a refined version of this patch doing a "goto csum_error"
so that we properly increment TCP_MIB_CSUMERRORS and TCP_MIB_INERRS
Thanks !
^ permalink raw reply
* [PATCH v2] tcp: verify the checksum of the first data segment in a new connection
From: Frank van der Linden @ 2018-06-12 21:41 UTC (permalink / raw)
To: edumazet, netdev
commit 079096f103fa ("tcp/dccp: install syn_recv requests into ehash
table") introduced an optimization for the handling of child sockets
created for a new TCP connection.
But this optimization passes any data associated with the last ACK of the
connection handshake up the stack without verifying its checksum, because it
calls tcp_child_process(), which in turn calls tcp_rcv_state_process()
directly. These lower-level processing functions do not do any checksum
verification.
Insert a tcp_checksum_complete call in the TCP_NEW_SYN_RECEIVE path to
fix this.
Signed-off-by: Frank van der Linden <fllinden@amazon.com>
---
net/ipv4/tcp_ipv4.c | 10 +++++++++-
net/ipv6/tcp_ipv6.c | 10 +++++++++-
2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index f70586b..f361cf9 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1639,6 +1639,7 @@ int tcp_v4_rcv(struct sk_buff *skb)
const struct iphdr *iph;
const struct tcphdr *th;
bool refcounted;
+ bool csumerr = false;
struct sock *sk;
int ret;
@@ -1703,7 +1704,12 @@ int tcp_v4_rcv(struct sk_buff *skb)
th = (const struct tcphdr *)skb->data;
iph = ip_hdr(skb);
tcp_v4_fill_cb(skb, iph, th);
- nsk = tcp_check_req(sk, skb, req, false, &req_stolen);
+
+ csumerr = tcp_checksum_complete(skb);
+ if (!csumerr) {
+ nsk = tcp_check_req(sk, skb, req, false,
+ &req_stolen);
+ }
}
if (!nsk) {
reqsk_put(req);
@@ -1798,6 +1804,8 @@ int tcp_v4_rcv(struct sk_buff *skb)
sk_drops_add(sk, skb);
if (refcounted)
sock_put(sk);
+ if (csumerr)
+ goto csum_error;
goto discard_it;
do_time_wait:
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 6d664d8..17a20fa 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1425,6 +1425,7 @@ static int tcp_v6_rcv(struct sk_buff *skb)
const struct tcphdr *th;
const struct ipv6hdr *hdr;
bool refcounted;
+ bool csumerr = false;
struct sock *sk;
int ret;
struct net *net = dev_net(skb->dev);
@@ -1486,7 +1487,12 @@ static int tcp_v6_rcv(struct sk_buff *skb)
th = (const struct tcphdr *)skb->data;
hdr = ipv6_hdr(skb);
tcp_v6_fill_cb(skb, hdr, th);
- nsk = tcp_check_req(sk, skb, req, false, &req_stolen);
+
+ csumerr = tcp_checksum_complete(skb);
+ if (!csumerr) {
+ nsk = tcp_check_req(sk, skb, req, false,
+ &req_stolen);
+ }
}
if (!nsk) {
reqsk_put(req);
@@ -1577,6 +1583,8 @@ static int tcp_v6_rcv(struct sk_buff *skb)
sk_drops_add(sk, skb);
if (refcounted)
sock_put(sk);
+ if (csumerr)
+ goto csum_error;
goto discard_it;
do_time_wait:
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH] Revert "net: do not allow changing SO_REUSEADDR/SO_REUSEPORT on bound sockets"
From: Maciej Żenczykowski @ 2018-06-12 21:40 UTC (permalink / raw)
To: David Miller; +Cc: bart.vanassche, Linux NetDev, Eric Dumazet
In-Reply-To: <20180612.111031.377845938725821301.davem@davemloft.net>
Any ideas about how to fix the core issue of tb->fast* being
effectively invalid?
ie. currently any reader of tb->fastreuse(port) which isn't simply
testing for it being >= 0 is basically a bug (-1 is the empty tb case,
so that AFAICT keeps on working).
For example sk_reuseport_match(tb, sk) can both fail to match when it
should, and can match when it shouldn't...
(at a quick glance, all the readers, and thus bugs are constrained to
the inet_csk_get_port() function)
Do we just delete that entire 'tb->fast*' optimization? It would
certainly make the code much simpler...
Do we put special case per-family/protocol code (ie. presumably
another indirect call) to fix up tb->fast in the
setsockopt(SOREUSEADDR/PORT) codepath?
Something else?
(btw. I'm not certain if both 0->1 and 1->0 transitions on a bound
socket are equally buggy, I think one is more dangerous then the
other)
^ permalink raw reply
* Re: Problems in tc-matchall.8, tc-sample.8
From: Stephen Hemminger @ 2018-06-12 21:17 UTC (permalink / raw)
To: esr; +Cc: netdev
In-Reply-To: <20180612191614.916303A4F8E@snark.thyrsus.com>
On Tue, 12 Jun 2018 15:16:14 -0400 (EDT)
esr@thyrsus.com wrote:
> This is automatically generated email about markup problems in a man
> page for which you appear to be responsible. If you are not the right
> person or list, please tell me so I can correct my database.
>
> See http://catb.org/~esr/doclifter/bugs.html for details on how and
> why these patches were generated. Feel free to email me with any
> questions. Note: These patches do not change the modification date of
> any manual page. You may wish to do that by hand.
>
> I apologize if this message seems spammy or impersonal. The volume of
> markup bugs I am tracking is over five hundred - there is no real
> alternative to generating bugmail from a database and template.
>
> --
> Eric S. Raymond
Please resubmit as real patch with signed-off-by
^ permalink raw reply
* Re: [RFC PATCH 00/12] Enable PM hibernation on guest VMs
From: Konrad Rzeszutek Wilk @ 2018-06-12 21:09 UTC (permalink / raw)
To: Anchal Agarwal
Cc: tglx, mingo, hpa, x86, boris.ostrovsky, roger.pau, netdev, jgross,
xen-devel, linux-kernel, kamatam, fllinden, vallish, guruanb,
eduval, rjw, pavel, len.brown, linux-pm, cyberax
In-Reply-To: <20180612205619.28156-1-anchalag@amazon.com>
On Tue, Jun 12, 2018 at 08:56:07PM +0000, Anchal Agarwal wrote:
> Hello,
> I am sending out a series of patches that implements guest
> PM hibernation. These guests are running on xen hypervisor.
> The patches had been tested against mainstream kernel and latest
> xen version-4.11. EC2 instance hibernation feature is provided to
> the AWS EC2 customers. PM hibernation uses swap space where
> hibernation image is stored and restored from. I would like
> the community to review and provide some feedback on the patch
> series and if they look good, merge them into 4.17 kernel.
4.17 got released on Jun 3rd. Kind of hard to do a time-machine.
^ permalink raw reply
* [RFC PATCH 09/12] x86/xen: save and restore steal clock
From: Anchal Agarwal @ 2018-06-12 20:56 UTC (permalink / raw)
To: tglx, mingo, hpa, x86
Cc: boris.ostrovsky, konrad.wilk, roger.pau, netdev, jgross,
xen-devel, linux-kernel, kamatam, anchalag, fllinden, vallish,
guruanb, eduval, rjw, pavel, len.brown, linux-pm, cyberax
In-Reply-To: <20180612205619.28156-1-anchalag@amazon.com>
From: Munehisa Kamata <kamatam@amazon.com>
Save steal clock values of all present CPUs in the system core ops
suspend callbacks. Also, restore a boot CPU's steal clock in the system
core resume callback. For non-boot CPUs, restore after they're brought
up, because runstate info for non-boot CPUs are not active until then.
Signed-off-by: Munehisa Kamata <kamatam@amazon.com>
Signed-off-by: Anchal Agarwal <anchalag@amazon.com>
Reviewed-by: Munehisa Kamata <kamatam@amazon.com>
Reviewed-by: Eduardo Valentin <eduval@amazon.com>
---
arch/x86/xen/suspend.c | 13 ++++++++++++-
arch/x86/xen/time.c | 3 +++
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c
index 784c448..dae0f74 100644
--- a/arch/x86/xen/suspend.c
+++ b/arch/x86/xen/suspend.c
@@ -91,12 +91,20 @@ void xen_arch_suspend(void)
static int xen_syscore_suspend(void)
{
struct xen_remove_from_physmap xrfp;
- int ret;
+ int cpu, ret;
/* Xen suspend does similar stuffs in its own logic */
if (xen_suspend_mode_is_xen_suspend())
return 0;
+ for_each_present_cpu(cpu) {
+ /*
+ * Nonboot CPUs are already offline, but the last copy of
+ * runstate info is still accessible.
+ */
+ xen_save_steal_clock(cpu);
+ }
+
xrfp.domid = DOMID_SELF;
xrfp.gpfn = __pa(HYPERVISOR_shared_info) >> PAGE_SHIFT;
@@ -118,6 +126,9 @@ static void xen_syscore_resume(void)
pvclock_resume();
+ /* Nonboot CPUs will be resumed when they're brought up */
+ xen_restore_steal_clock(smp_processor_id());
+
gnttab_resume();
}
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
index e0f1bcf..85f8534 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -523,6 +523,9 @@ static void xen_hvm_setup_cpu_clockevents(void)
{
int cpu = smp_processor_id();
xen_setup_runstate_info(cpu);
+ if (cpu)
+ xen_restore_steal_clock(cpu);
+
/*
* xen_setup_timer(cpu) - snprintf is bad in atomic context. Hence
* doing it xen_hvm_cpu_notify (which gets called by smp_init during
--
2.7.4
^ permalink raw reply related
* [RFC PATCH 12/12] PM / hibernate: update the resume offset on SNAPSHOT_SET_SWAP_AREA
From: Anchal Agarwal @ 2018-06-12 20:56 UTC (permalink / raw)
To: tglx, mingo, hpa, x86
Cc: jgross, len.brown, eduval, vallish, netdev, fllinden, kamatam,
rjw, linux-kernel, anchalag, cyberax, pavel, linux-pm, xen-devel,
boris.ostrovsky, guruanb, roger.pau
In-Reply-To: <20180612205619.28156-1-anchalag@amazon.com>
From: Aleksei Besogonov <cyberax@amazon.com>
The SNAPSHOT_SET_SWAP_AREA is supposed to be used to set the hibernation
offset on a running kernel to enable hibernating to a swap file.
However, it doesn't actually update the swsusp_resume_block variable. As
a result, the hibernation fails at the last step (after all the data is
written out) in the validation of the swap signature in
mark_swapfiles().
Before this patch, the command line processing was the only place where
swsusp_resume_block was set.
Signed-off-by: Aleksei Besogonov <cyberax@amazon.com>
Signed-off-by: Munehisa Kamata <kamatam@amazon.com>
Signed-off-by: Anchal Agarwal <anchalag@amazon.com>
Reviewed-by: Munehisa Kamata <kamatam@amazon.com>
Reviewed-by: Eduardo Valentin <eduval@amazon.com>
---
kernel/power/user.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/kernel/power/user.c b/kernel/power/user.c
index abd2255..b522a42 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -379,8 +379,12 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
if (swdev) {
offset = swap_area.offset;
data->swap = swap_type_of(swdev, offset, NULL);
- if (data->swap < 0)
+ if (data->swap < 0) {
error = -ENODEV;
+ } else {
+ swsusp_resume_device = swdev;
+ swsusp_resume_block = offset;
+ }
} else {
data->swap = -1;
error = -EINVAL;
--
2.7.4
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply related
* [RFC PATCH 11/12] x86/xen: close event channels for PIRQs in system core suspend callback
From: Anchal Agarwal @ 2018-06-12 20:56 UTC (permalink / raw)
To: tglx, mingo, hpa, x86
Cc: boris.ostrovsky, konrad.wilk, roger.pau, netdev, jgross,
xen-devel, linux-kernel, kamatam, anchalag, fllinden, vallish,
guruanb, eduval, rjw, pavel, len.brown, linux-pm, cyberax
In-Reply-To: <20180612205619.28156-1-anchalag@amazon.com>
From: Munehisa Kamata <kamatam@amazon.com>
Close event channels allocated for devices which are backed by PIRQ and
still active when suspending the system core. Normally, the devices are
emulated legacy devices, e.g. PS/2 keyboard, floppy controller and etc.
Without this, in PM hibernation, information about the event channel
remains in hibernation image, but there is no guarantee that the same
event channel numbers are assigned to the devices when restoring the
system. This may cause conflict like the following and prevent some
devices from being restored correctly.
[ 102.330821] ------------[ cut here ]------------
[ 102.333264] WARNING: CPU: 0 PID: 2324 at
drivers/xen/events/events_base.c:878 bind_evtchn_to_irq+0x88/0xf0
...
[ 102.348057] Call Trace:
[ 102.348057] [<ffffffff813001df>] dump_stack+0x63/0x84
[ 102.348057] [<ffffffff81071811>] __warn+0xd1/0xf0
[ 102.348057] [<ffffffff810718fd>] warn_slowpath_null+0x1d/0x20
[ 102.348057] [<ffffffff8139a1f8>] bind_evtchn_to_irq+0x88/0xf0
[ 102.348057] [<ffffffffa00cd420>] ? blkif_copy_from_grant+0xb0/0xb0 [xen_blkfront]
[ 102.348057] [<ffffffff8139a307>] bind_evtchn_to_irqhandler+0x27/0x80
[ 102.348057] [<ffffffffa00cc785>] talk_to_blkback+0x425/0xcd0 [xen_blkfront]
[ 102.348057] [<ffffffff811e0c8a>] ? __kmalloc+0x1ea/0x200
[ 102.348057] [<ffffffffa00ce84d>] blkfront_restore+0x2d/0x60 [xen_blkfront]
[ 102.348057] [<ffffffff813a0078>] xenbus_dev_restore+0x58/0x100
[ 102.348057] [<ffffffff813a1ff0>] ? xenbus_frontend_delayed_resume+0x20/0x20
[ 102.348057] [<ffffffff813a200e>] xenbus_dev_cond_restore+0x1e/0x30
[ 102.348057] [<ffffffff813f797e>] dpm_run_callback+0x4e/0x130
[ 102.348057] [<ffffffff813f7f17>] device_resume+0xe7/0x210
[ 102.348057] [<ffffffff813f7810>] ? pm_dev_dbg+0x80/0x80
[ 102.348057] [<ffffffff813f9374>] dpm_resume+0x114/0x2f0
[ 102.348057] [<ffffffff810c00cf>] hibernation_snapshot+0x15f/0x380
[ 102.348057] [<ffffffff810c0ac3>] hibernate+0x183/0x290
[ 102.348057] [<ffffffff810be1af>] state_store+0xcf/0xe0
[ 102.348057] [<ffffffff813020bf>] kobj_attr_store+0xf/0x20
[ 102.348057] [<ffffffff8127c88a>] sysfs_kf_write+0x3a/0x50
[ 102.348057] [<ffffffff8127c3bb>] kernfs_fop_write+0x10b/0x190
[ 102.348057] [<ffffffff81200008>] __vfs_write+0x28/0x120
[ 102.348057] [<ffffffff81200c19>] ? rw_verify_area+0x49/0xb0
[ 102.348057] [<ffffffff81200e62>] vfs_write+0xb2/0x1b0
[ 102.348057] [<ffffffff81202196>] SyS_write+0x46/0xa0
[ 102.348057] [<ffffffff81520cf7>] entry_SYSCALL_64_fastpath+0x1a/0xa9
[ 102.423005] ---[ end trace b8d6718e22e2b107 ]---
[ 102.425031] genirq: Flags mismatch irq 6. 00000000 (blkif) vs. 00000000 (floppy)
Note that we don't explicitly re-allocate event channels for such
devices in the resume callback. Re-allocation will occur when PM core
re-enable IRQs for the devices at later point.
Signed-off-by: Munehisa Kamata <kamatam@amazon.com>
Signed-off-by: Anchal Agarwal <anchalag@amazon.com>
Reviewed-by: Munehisa Kamata <kamatam@amazon.com>
Reviewed-by: Eduardo Valentin <eduval@amazon.com>
---
arch/x86/xen/suspend.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c
index dae0f74..affa63d 100644
--- a/arch/x86/xen/suspend.c
+++ b/arch/x86/xen/suspend.c
@@ -105,6 +105,8 @@ static int xen_syscore_suspend(void)
xen_save_steal_clock(cpu);
}
+ xen_shutdown_pirqs();
+
xrfp.domid = DOMID_SELF;
xrfp.gpfn = __pa(HYPERVISOR_shared_info) >> PAGE_SHIFT;
--
2.7.4
^ permalink raw reply related
* [RFC PATCH 10/12] xen/events: add xen_shutdown_pirqs helper function
From: Anchal Agarwal @ 2018-06-12 20:56 UTC (permalink / raw)
To: tglx, mingo, hpa, x86
Cc: boris.ostrovsky, konrad.wilk, roger.pau, netdev, jgross,
xen-devel, linux-kernel, kamatam, anchalag, fllinden, vallish,
guruanb, eduval, rjw, pavel, len.brown, linux-pm, cyberax
In-Reply-To: <20180612205619.28156-1-anchalag@amazon.com>
From: Munehisa Kamata <kamatam@amazon.com>
Add a simple helper function to "shutdown" active PIRQs, which actually
closes event channels but keeps related IRQ structures intact. PM
suspend/hibernation code will rely on this.
Signed-off-by: Munehisa Kamata <kamatam@amazon.com>
Signed-off-by: Anchal Agarwal <anchalag@amazon.com>
Reviewed-by: Munehisa Kamata <kamatam@amazon.com>
Reviewed-by: Eduardo Valentin <eduval@amazon.com>
---
drivers/xen/events/events_base.c | 12 ++++++++++++
include/xen/events.h | 1 +
2 files changed, 13 insertions(+)
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index 762378f..88137c8 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -1581,6 +1581,18 @@ void xen_irq_resume(void)
restore_pirqs();
}
+void xen_shutdown_pirqs(void)
+{
+ struct irq_info *info;
+
+ list_for_each_entry(info, &xen_irq_list_head, list) {
+ if (info->type != IRQT_PIRQ || !VALID_EVTCHN(info->evtchn))
+ continue;
+
+ shutdown_pirq(irq_get_irq_data(info->irq));
+ }
+}
+
static struct irq_chip xen_dynamic_chip __read_mostly = {
.name = "xen-dyn",
diff --git a/include/xen/events.h b/include/xen/events.h
index c3e6bc6..e4d5ccb 100644
--- a/include/xen/events.h
+++ b/include/xen/events.h
@@ -70,6 +70,7 @@ static inline void notify_remote_via_evtchn(int port)
void notify_remote_via_irq(int irq);
void xen_irq_resume(void);
+void xen_shutdown_pirqs(void);
/* Clear an irq's pending state, in preparation for polling on it */
void xen_clear_irq_pending(int irq);
--
2.7.4
^ permalink raw reply related
* [RFC PATCH 08/12] xen-time-introduce-xen_-save-restore-_steal_clock
From: Anchal Agarwal @ 2018-06-12 20:56 UTC (permalink / raw)
To: tglx, mingo, hpa, x86
Cc: jgross, len.brown, eduval, vallish, netdev, fllinden, kamatam,
rjw, linux-kernel, anchalag, cyberax, pavel, linux-pm, xen-devel,
boris.ostrovsky, guruanb, roger.pau
In-Reply-To: <20180612205619.28156-1-anchalag@amazon.com>
From: Munehisa Kamata <kamatam@amazon.com>
Currently, steal time accounting code in scheduler expects steal clock
callback to provide monotonically increasing value. If the accounting
code receives a smaller value than previous one, it uses a negative
value to calculate steal time and results in incorrectly updated idle
and steal time accounting. This breaks userspace tools which read
/proc/stat.
top - 08:05:35 up 2:12, 3 users, load average: 0.00, 0.07, 0.23
Tasks: 80 total, 1 running, 79 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.0%us, 0.0%sy, 0.0%ni,30100.0%id, 0.0%wa, 0.0%hi, 0.0%si,-1253874204672.0%st
This can actually happen when a Xen PVHVM guest gets restored from
hibernation, because such a restored guest is just a fresh domain from
Xen perspective and the time information in runstate info starts over
from scratch.
This patch introduces xen_save_steal_clock() which saves current values
in runstate info into per-cpu variables. Its couterpart,
xen_restore_steal_clock(), sets offset if it found the current values in
runstate info are smaller than previous ones. xen_steal_clock() is also
modified to use the offset to ensure that scheduler only sees
monotonically increasing number.
Signed-off-by: Munehisa Kamata <kamatam@amazon.com>
Signed-off-by: Anchal Agarwal <anchalag@amazon.com>
Reviewed-by: Munehisa Kamata <kamatam@amazon.com>
Reviewed-by: Eduardo Valentin <eduval@amazon.com>
---
drivers/xen/time.c | 28 +++++++++++++++++++++++++++-
include/xen/xen-ops.h | 2 ++
2 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/drivers/xen/time.c b/drivers/xen/time.c
index 3e741cd..4756042 100644
--- a/drivers/xen/time.c
+++ b/drivers/xen/time.c
@@ -20,6 +20,8 @@
/* runstate info updated by Xen */
static DEFINE_PER_CPU(struct vcpu_runstate_info, xen_runstate);
+static DEFINE_PER_CPU(u64, xen_prev_steal_clock);
+static DEFINE_PER_CPU(u64, xen_steal_clock_offset);
static DEFINE_PER_CPU(u64[4], old_runstate_time);
@@ -149,7 +151,7 @@ bool xen_vcpu_stolen(int vcpu)
return per_cpu(xen_runstate, vcpu).state == RUNSTATE_runnable;
}
-u64 xen_steal_clock(int cpu)
+static u64 __xen_steal_clock(int cpu)
{
struct vcpu_runstate_info state;
@@ -157,6 +159,30 @@ u64 xen_steal_clock(int cpu)
return state.time[RUNSTATE_runnable] + state.time[RUNSTATE_offline];
}
+u64 xen_steal_clock(int cpu)
+{
+ return __xen_steal_clock(cpu) + per_cpu(xen_steal_clock_offset, cpu);
+}
+
+void xen_save_steal_clock(int cpu)
+{
+ per_cpu(xen_prev_steal_clock, cpu) = xen_steal_clock(cpu);
+}
+
+void xen_restore_steal_clock(int cpu)
+{
+ u64 steal_clock = __xen_steal_clock(cpu);
+
+ if (per_cpu(xen_prev_steal_clock, cpu) > steal_clock) {
+ /* Need to update the offset */
+ per_cpu(xen_steal_clock_offset, cpu) =
+ per_cpu(xen_prev_steal_clock, cpu) - steal_clock;
+ } else {
+ /* Avoid unnecessary steal clock warp */
+ per_cpu(xen_steal_clock_offset, cpu) = 0;
+ }
+}
+
void xen_setup_runstate_info(int cpu)
{
struct vcpu_register_runstate_memory_area area;
diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h
index 65f25bd..10330f8 100644
--- a/include/xen/xen-ops.h
+++ b/include/xen/xen-ops.h
@@ -36,6 +36,8 @@ void xen_time_setup_guest(void);
void xen_manage_runstate_time(int action);
void xen_get_runstate_snapshot(struct vcpu_runstate_info *res);
u64 xen_steal_clock(int cpu);
+void xen_save_steal_clock(int cpu);
+void xen_restore_steal_clock(int cpu);
int xen_setup_shutdown_event(void);
--
2.7.4
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply related
* [RFC PATCH 07/12] xen-netfront: add callbacks for PM suspend and hibernation support
From: Anchal Agarwal @ 2018-06-12 20:56 UTC (permalink / raw)
To: tglx, mingo, hpa, x86
Cc: jgross, len.brown, eduval, vallish, netdev, fllinden, kamatam,
rjw, linux-kernel, anchalag, cyberax, pavel, linux-pm, xen-devel,
boris.ostrovsky, guruanb, roger.pau
In-Reply-To: <20180612205619.28156-1-anchalag@amazon.com>
From: Munehisa Kamata <kamatam@amazon.com>
Add freeze and restore callbacks for PM suspend and hibernation support.
The freeze handler simply disconnects the frotnend from the backend and
frees resources associated with queues after disabling the net_device
from the system. The restore handler just changes the frontend state and
let the xenbus handler to re-allocate the resources and re-connect to the
backend. This can be performed transparently to the rest of the system.
The handlers are used for both PM suspend and hibernation so that we can
keep the existing suspend/resume callbacks for Xen suspend without
modification. Freezing netfront devices is normally expected to finish within a few
hundred milliseconds, but it can rarely take more than 5 seconds and
hit the hard coded timeout, it would depend on backend state which may
be congested and/or have complex configuration. While it's rare case,
longer default timeout seems a bit more reasonable here to avoid hitting
the timeout. Also, make it configurable via module parameter so that we
can cover broader setups than what we know currently.
Signed-off-by: Munehisa Kamata <kamatam@amazon.com>
Signed-off-by: Anchal Agarwal <anchalag@amazon.com>
Reviewed-by: Eduardo Valentin <eduval@amazon.com>
Reviewed-by: Munehisa Kamata <kamatam@amazon.com>
---
drivers/net/xen-netfront.c | 97 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 96 insertions(+), 1 deletion(-)
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 4dd0668..4ea9284 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -43,6 +43,7 @@
#include <linux/moduleparam.h>
#include <linux/mm.h>
#include <linux/slab.h>
+#include <linux/completion.h>
#include <net/ip.h>
#include <xen/xen.h>
@@ -56,6 +57,12 @@
#include <xen/interface/memory.h>
#include <xen/interface/grant_table.h>
+enum netif_freeze_state {
+ NETIF_FREEZE_STATE_UNFROZEN,
+ NETIF_FREEZE_STATE_FREEZING,
+ NETIF_FREEZE_STATE_FROZEN,
+};
+
/* Module parameters */
#define MAX_QUEUES_DEFAULT 8
static unsigned int xennet_max_queues;
@@ -63,6 +70,12 @@ module_param_named(max_queues, xennet_max_queues, uint, 0644);
MODULE_PARM_DESC(max_queues,
"Maximum number of queues per virtual interface");
+static unsigned int netfront_freeze_timeout_secs = 10;
+module_param_named(freeze_timeout_secs,
+ netfront_freeze_timeout_secs, uint, 0644);
+MODULE_PARM_DESC(freeze_timeout_secs,
+ "timeout when freezing netfront device in seconds");
+
static const struct ethtool_ops xennet_ethtool_ops;
struct netfront_cb {
@@ -160,6 +173,10 @@ struct netfront_info {
struct netfront_stats __percpu *tx_stats;
atomic_t rx_gso_checksum_fixup;
+
+ int freeze_state;
+
+ struct completion wait_backend_disconnected;
};
struct netfront_rx_info {
@@ -723,6 +740,21 @@ static int xennet_close(struct net_device *dev)
return 0;
}
+static int xennet_disable_interrupts(struct net_device *dev)
+{
+ struct netfront_info *np = netdev_priv(dev);
+ unsigned int num_queues = dev->real_num_tx_queues;
+ unsigned int i;
+ struct netfront_queue *queue;
+
+ for (i = 0; i < num_queues; ++i) {
+ queue = &np->queues[i];
+ disable_irq(queue->tx_irq);
+ disable_irq(queue->rx_irq);
+ }
+ return 0;
+}
+
static void xennet_move_rx_slot(struct netfront_queue *queue, struct sk_buff *skb,
grant_ref_t ref)
{
@@ -1296,6 +1328,8 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)
np->queues = NULL;
+ init_completion(&np->wait_backend_disconnected);
+
err = -ENOMEM;
np->rx_stats = netdev_alloc_pcpu_stats(struct netfront_stats);
if (np->rx_stats == NULL)
@@ -1782,6 +1816,50 @@ static int xennet_create_queues(struct netfront_info *info,
return 0;
}
+static int netfront_freeze(struct xenbus_device *dev)
+{
+ struct netfront_info *info = dev_get_drvdata(&dev->dev);
+ unsigned long timeout = netfront_freeze_timeout_secs * HZ;
+ int err = 0;
+
+ xennet_disable_interrupts(info->netdev);
+
+ netif_device_detach(info->netdev);
+
+ info->freeze_state = NETIF_FREEZE_STATE_FREEZING;
+
+ /* Kick the backend to disconnect */
+ xenbus_switch_state(dev, XenbusStateClosing);
+
+ /* We don't want to move forward before the frontend is diconnected
+ * from the backend cleanly.
+ */
+ timeout = wait_for_completion_timeout(&info->wait_backend_disconnected,
+ timeout);
+ if (!timeout) {
+ err = -EBUSY;
+ xenbus_dev_error(dev, err, "Freezing timed out;"
+ "the device may become inconsistent state");
+ return err;
+ }
+
+ /* Tear down queues */
+ xennet_disconnect_backend(info);
+ xennet_destroy_queues(info);
+
+ info->freeze_state = NETIF_FREEZE_STATE_FROZEN;
+
+ return err;
+}
+
+static int netfront_restore(struct xenbus_device *dev)
+{
+ /* Kick the backend to re-connect */
+ xenbus_switch_state(dev, XenbusStateInitialising);
+
+ return 0;
+}
+
/* Common code used when first setting up, and when resuming. */
static int talk_to_netback(struct xenbus_device *dev,
struct netfront_info *info)
@@ -1986,6 +2064,8 @@ static int xennet_connect(struct net_device *dev)
spin_unlock_bh(&queue->rx_lock);
}
+ np->freeze_state = NETIF_FREEZE_STATE_UNFROZEN;
+
return 0;
}
@@ -2025,11 +2105,23 @@ static void netback_changed(struct xenbus_device *dev,
case XenbusStateClosed:
wake_up_all(&module_unload_q);
- if (dev->state == XenbusStateClosed)
+ if (dev->state == XenbusStateClosed) {
+ /* dpm context is waiting for the backend */
+ if (np->freeze_state == NETIF_FREEZE_STATE_FREEZING)
+ complete(&np->wait_backend_disconnected);
break;
+ }
/* Missed the backend's CLOSING state -- fallthrough */
case XenbusStateClosing:
wake_up_all(&module_unload_q);
+ /* We may see unexpected Closed or Closing from the backend.
+ * Just ignore it not to prevent the frontend from being
+ * re-connected in the case of PM suspend or hibernation.
+ */
+ if (np->freeze_state == NETIF_FREEZE_STATE_FROZEN &&
+ dev->state == XenbusStateInitialising) {
+ break;
+ }
xenbus_frontend_closed(dev);
break;
}
@@ -2176,6 +2268,9 @@ static struct xenbus_driver netfront_driver = {
.probe = netfront_probe,
.remove = xennet_remove,
.resume = netfront_resume,
+ .freeze = netfront_freeze,
+ .thaw = netfront_restore,
+ .restore = netfront_restore,
.otherend_changed = netback_changed,
};
--
2.7.4
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply related
* [RFC PATCH 06/12] xen-blkfront: add callbacks for PM suspend and hibernation
From: Anchal Agarwal @ 2018-06-12 20:56 UTC (permalink / raw)
To: tglx, mingo, hpa, x86
Cc: jgross, len.brown, eduval, vallish, netdev, fllinden, kamatam,
rjw, linux-kernel, anchalag, cyberax, pavel, linux-pm, xen-devel,
boris.ostrovsky, guruanb, roger.pau
In-Reply-To: <20180612205619.28156-1-anchalag@amazon.com>
From: Munehisa Kamata <kamatam@amazon.com>
Add freeze and restore callbacks for PM suspend and hibernation support.
The freeze handler stops a block-layer queue and disconnect the frontend
from the backend while freeing ring_info and associated resources. The
restore handler re-allocates ring_info and re-connect to the backedend,
so the rest of the kernel can continue to use the block device
transparently.Also, the handlers are used for both PM
suspend and hibernation so that we can keep the existing suspend/resume
callbacks for Xen suspend without modification.
If a backend doesn't have commit 12ea729645ac ("xen/blkback: unmap all
persistent grants when frontend gets disconnected"), the frontend may see
massive amount of grant table warning when freeing resources.
[ 36.852659] deferring g.e. 0xf9 (pfn 0xffffffffffffffff)
[ 36.855089] xen:grant_table: WARNING: g.e. 0x112 still in use!
In this case, persistent grants would need to be disabled.
Ensure no reqs/rsps in rings before disconnecting. When disconnecting
the frontend from the backend in blkfront_freeze(), there still may be
unconsumed requests or responses in the rings, especially when the
backend is backed by network-based device. If the frontend gets
disconnected with such reqs/rsps remaining there, it can cause
grant warnings and/or losing reqs/rsps by freeing pages afterward.
This can lead resumed kernel into unrecoverable state like unexpected
freeing of grant page and/or hung task due to the lost reqs or rsps.
Therefore we have to ensure that there is no unconsumed requests or
responses before disconnecting.
Actually, the frontend just needs to wait for some amount of time so that
the backend can process the requests, put responses and notify the
frontend back. Timeout used here is based on some heuristic. If we somehow
hit the timeout, it would mean something serious happens in the backend,
the frontend will just return an error to PM core and PM
suspend/hibernation will be aborted. This may be something should be
fixed by the backend side, but a frontend side fix is probably
still worth doing to work with broader backends.
Signed-off-by: Anchal Agarwal <anchalag@amazon.com>
Reviewed-by: Munehisa Kamata <kamatam@amazon.com>
Reviewed-by: Eduardo Valentin <eduval@amazon.com>
---
drivers/block/xen-blkfront.c | 158 +++++++++++++++++++++++++++++++++++++++++--
1 file changed, 151 insertions(+), 7 deletions(-)
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index ae00a82f350b..a223864c2220 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -46,6 +46,8 @@
#include <linux/scatterlist.h>
#include <linux/bitmap.h>
#include <linux/list.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
#include <xen/xen.h>
#include <xen/xenbus.h>
@@ -78,6 +80,8 @@ enum blkif_state {
BLKIF_STATE_DISCONNECTED,
BLKIF_STATE_CONNECTED,
BLKIF_STATE_SUSPENDED,
+ BLKIF_STATE_FREEZING,
+ BLKIF_STATE_FROZEN
};
struct grant {
@@ -216,6 +220,7 @@ struct blkfront_info
/* Save uncomplete reqs and bios for migration. */
struct list_head requests;
struct bio_list bio_list;
+ struct completion wait_backend_disconnected;
};
static unsigned int nr_minors;
@@ -262,6 +267,16 @@ static DEFINE_SPINLOCK(minor_lock);
static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo);
static void blkfront_gather_backend_features(struct blkfront_info *info);
static int negotiate_mq(struct blkfront_info *info);
+static void __blkif_free(struct blkfront_info *info);
+
+static inline bool blkfront_ring_is_busy(struct blkif_front_ring *ring)
+{
+ if (RING_SIZE(ring) > RING_FREE_REQUESTS(ring) ||
+ RING_HAS_UNCONSUMED_RESPONSES(ring))
+ return true;
+ else
+ return false;
+}
static int get_id_from_freelist(struct blkfront_ring_info *rinfo)
{
@@ -996,6 +1011,7 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size,
info->sector_size = sector_size;
info->physical_sector_size = physical_sector_size;
blkif_set_queue_limits(info);
+ init_completion(&info->wait_backend_disconnected);
return 0;
}
@@ -1219,6 +1235,8 @@ static void xlvbd_release_gendisk(struct blkfront_info *info)
/* Already hold rinfo->ring_lock. */
static inline void kick_pending_request_queues_locked(struct blkfront_ring_info *rinfo)
{
+ if (unlikely(rinfo->dev_info->connected == BLKIF_STATE_FREEZING))
+ return;
if (!RING_FULL(&rinfo->ring))
blk_mq_start_stopped_hw_queues(rinfo->dev_info->rq, true);
}
@@ -1342,8 +1360,6 @@ static void blkif_free_ring(struct blkfront_ring_info *rinfo)
static void blkif_free(struct blkfront_info *info, int suspend)
{
- unsigned int i;
-
/* Prevent new requests being issued until we fix things up. */
info->connected = suspend ?
BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED;
@@ -1351,6 +1367,13 @@ static void blkif_free(struct blkfront_info *info, int suspend)
if (info->rq)
blk_mq_stop_hw_queues(info->rq);
+ __blkif_free(info);
+}
+
+static void __blkif_free(struct blkfront_info *info)
+{
+ unsigned int i;
+
for (i = 0; i < info->nr_rings; i++)
blkif_free_ring(&info->rinfo[i]);
@@ -1554,8 +1577,10 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
struct blkfront_ring_info *rinfo = (struct blkfront_ring_info *)dev_id;
struct blkfront_info *info = rinfo->dev_info;
- if (unlikely(info->connected != BLKIF_STATE_CONNECTED))
- return IRQ_HANDLED;
+ if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) {
+ if (info->connected != BLKIF_STATE_FREEZING)
+ return IRQ_HANDLED;
+ }
spin_lock_irqsave(&rinfo->ring_lock, flags);
again:
@@ -2005,6 +2030,7 @@ static int blkif_recover(struct blkfront_info *info)
struct bio *bio;
unsigned int segs;
+ bool frozen = info->connected == BLKIF_STATE_FROZEN;
blkfront_gather_backend_features(info);
/* Reset limits changed by blk_mq_update_nr_hw_queues(). */
blkif_set_queue_limits(info);
@@ -2031,6 +2057,9 @@ static int blkif_recover(struct blkfront_info *info)
kick_pending_request_queues(rinfo);
}
+ if (frozen)
+ return 0;
+
list_for_each_entry_safe(req, n, &info->requests, queuelist) {
/* Requeue pending requests (flush or discard) */
list_del_init(&req->queuelist);
@@ -2335,6 +2364,7 @@ static void blkfront_connect(struct blkfront_info *info)
return;
case BLKIF_STATE_SUSPENDED:
+ case BLKIF_STATE_FROZEN:
/*
* If we are recovering from suspension, we need to wait
* for the backend to announce it's features before
@@ -2452,12 +2482,37 @@ static void blkback_changed(struct xenbus_device *dev,
break;
case XenbusStateClosed:
- if (dev->state == XenbusStateClosed)
+ if (dev->state == XenbusStateClosed) {
+ if (info->connected == BLKIF_STATE_FREEZING) {
+ __blkif_free(info);
+ info->connected = BLKIF_STATE_FROZEN;
+ complete(&info->wait_backend_disconnected);
+ break;
+ }
+
+ break;
+ }
+
+ /*
+ * We may somehow receive backend's Closed again while thawing
+ * or restoring and it causes thawing or restoring to fail.
+ * Ignore such unexpected state anyway.
+ */
+ if (info->connected == BLKIF_STATE_FROZEN &&
+ dev->state == XenbusStateInitialised) {
+ dev_dbg(&dev->dev,
+ "ignore the backend's Closed state: %s",
+ dev->nodename);
break;
+ }
/* fall through */
case XenbusStateClosing:
- if (info)
- blkfront_closing(info);
+ if (info) {
+ if (info->connected == BLKIF_STATE_FREEZING)
+ xenbus_frontend_closed(dev);
+ else
+ blkfront_closing(info);
+ }
break;
}
}
@@ -2594,6 +2649,92 @@ static void blkif_release(struct gendisk *disk, fmode_t mode)
mutex_unlock(&blkfront_mutex);
}
+static int blkfront_freeze(struct xenbus_device *dev)
+{
+ unsigned int i;
+ struct blkfront_info *info = dev_get_drvdata(&dev->dev);
+ struct blkfront_ring_info *rinfo;
+ struct blkif_front_ring *ring;
+ /* This would be reasonable timeout as used in xenbus_dev_shutdown() */
+ unsigned int timeout = 5 * HZ;
+ int err = 0;
+
+ info->connected = BLKIF_STATE_FREEZING;
+
+ blk_mq_stop_hw_queues(info->rq);
+
+ for (i = 0; i < info->nr_rings; i++) {
+ rinfo = &info->rinfo[i];
+
+ gnttab_cancel_free_callback(&rinfo->callback);
+ flush_work(&rinfo->work);
+ }
+
+ for (i = 0; i < info->nr_rings; i++) {
+ spinlock_t *lock;
+ bool busy;
+ unsigned long req_timeout_ms = 25;
+ unsigned long ring_timeout;
+
+ rinfo = &info->rinfo[i];
+ ring = &rinfo->ring;
+
+ lock = &rinfo->ring_lock;
+
+ ring_timeout = jiffies +
+ msecs_to_jiffies(req_timeout_ms * RING_SIZE(ring));
+
+ do {
+ spin_lock_irq(lock);
+ busy = blkfront_ring_is_busy(ring);
+ spin_unlock_irq(lock);
+
+ if (busy)
+ msleep(req_timeout_ms);
+ else
+ break;
+ } while (time_is_after_jiffies(ring_timeout));
+
+ /* Timed out */
+ if (busy) {
+ xenbus_dev_error(dev, err, "the ring is still busy");
+ info->connected = BLKIF_STATE_CONNECTED;
+ return -EBUSY;
+ }
+ }
+
+ /* Kick the backend to disconnect */
+ xenbus_switch_state(dev, XenbusStateClosing);
+
+ /*
+ * We don't want to move forward before the frontend is diconnected
+ * from the backend cleanly.
+ */
+ timeout = wait_for_completion_timeout(&info->wait_backend_disconnected,
+ timeout);
+ if (!timeout) {
+ err = -EBUSY;
+ xenbus_dev_error(dev, err, "Freezing timed out;"
+ "the device may become inconsistent state");
+ }
+
+ return err;
+}
+
+static int blkfront_restore(struct xenbus_device *dev)
+{
+ struct blkfront_info *info = dev_get_drvdata(&dev->dev);
+ int err = 0;
+
+ err = talk_to_blkback(dev, info);
+ if (err)
+ goto out;
+ blk_mq_update_nr_hw_queues(&info->tag_set, info->nr_rings);
+
+out:
+ return err;
+}
+
static const struct block_device_operations xlvbd_block_fops =
{
.owner = THIS_MODULE,
@@ -2616,6 +2757,9 @@ static struct xenbus_driver blkfront_driver = {
.resume = blkfront_resume,
.otherend_changed = blkback_changed,
.is_ready = blkfront_is_ready,
+ .freeze = blkfront_freeze,
+ .thaw = blkfront_restore,
+ .restore = blkfront_restore
};
static int __init xlblk_init(void)
--
2.13.6
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply related
* [RFC PATCH 05/12] x86/xen: add system core suspend and resume callbacks
From: Anchal Agarwal @ 2018-06-12 20:56 UTC (permalink / raw)
To: tglx, mingo, hpa, x86
Cc: jgross, len.brown, eduval, vallish, netdev, fllinden, kamatam,
rjw, linux-kernel, anchalag, cyberax, pavel, linux-pm, xen-devel,
boris.ostrovsky, guruanb, roger.pau
In-Reply-To: <20180612205619.28156-1-anchalag@amazon.com>
From: Munehisa Kamata <kamatam@amazon.com>
Add Xen PVHVM specific system core callbacks for PM suspend and
hibernation support. The callbacks suspend and resume Xen primitives,
like shared_info, pvclock and grant table. Note that Xen suspend can
handle them in a different manner, but system core callbacks are called
from the context. So if the callbacks are called from Xen suspend
context, return immediately.
Signed-off-by: Munehisa Kamata <kamatam@amazon.com>
Signed-off-by: Anchal Agarwal <anchalag@amazon.com>
Reviewed-by: Munehisa Kamata <kamatam@amazon.com>
Reviewed-by: Eduardo Valentin <eduval@amazon.com>
---
arch/x86/xen/enlighten_hvm.c | 1 +
arch/x86/xen/suspend.c | 53 ++++++++++++++++++++++++++++++++++++++++++++
include/xen/xen-ops.h | 2 ++
3 files changed, 56 insertions(+)
diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c
index d24ad16..4196a65 100644
--- a/arch/x86/xen/enlighten_hvm.c
+++ b/arch/x86/xen/enlighten_hvm.c
@@ -202,6 +202,7 @@ static void __init xen_hvm_guest_init(void)
if (xen_feature(XENFEAT_hvm_callback_vector))
xen_have_vector_callback = 1;
+ xen_setup_syscore_ops();
xen_hvm_smp_init();
WARN_ON(xen_cpuhp_setup(xen_cpu_up_prepare_hvm, xen_cpu_dead_hvm));
xen_unplug_emulated_devices();
diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c
index 1d83152..784c448 100644
--- a/arch/x86/xen/suspend.c
+++ b/arch/x86/xen/suspend.c
@@ -2,17 +2,22 @@
#include <linux/types.h>
#include <linux/tick.h>
#include <linux/percpu-defs.h>
+#include <linux/syscore_ops.h>
+#include <linux/kernel_stat.h>
#include <xen/xen.h>
#include <xen/interface/xen.h>
+#include <xen/interface/memory.h>
#include <xen/grant_table.h>
#include <xen/events.h>
+#include <xen/xen-ops.h>
#include <asm/cpufeatures.h>
#include <asm/msr-index.h>
#include <asm/xen/hypercall.h>
#include <asm/xen/page.h>
#include <asm/fixmap.h>
+#include <asm/pvclock.h>
#include "xen-ops.h"
#include "mmu.h"
@@ -82,3 +87,51 @@ void xen_arch_suspend(void)
on_each_cpu(xen_vcpu_notify_suspend, NULL, 1);
}
+
+static int xen_syscore_suspend(void)
+{
+ struct xen_remove_from_physmap xrfp;
+ int ret;
+
+ /* Xen suspend does similar stuffs in its own logic */
+ if (xen_suspend_mode_is_xen_suspend())
+ return 0;
+
+ xrfp.domid = DOMID_SELF;
+ xrfp.gpfn = __pa(HYPERVISOR_shared_info) >> PAGE_SHIFT;
+
+ ret = HYPERVISOR_memory_op(XENMEM_remove_from_physmap, &xrfp);
+ if (!ret)
+ HYPERVISOR_shared_info = &xen_dummy_shared_info;
+
+ return ret;
+}
+
+static void xen_syscore_resume(void)
+{
+ /* Xen suspend does similar stuffs in its own logic */
+ if (xen_suspend_mode_is_xen_suspend())
+ return;
+
+ /* No need to setup vcpu_info as it's already moved off */
+ xen_hvm_map_shared_info();
+
+ pvclock_resume();
+
+ gnttab_resume();
+}
+
+/*
+ * These callbacks will be called with interrupts disabled and when having only
+ * one CPU online.
+ */
+static struct syscore_ops xen_hvm_syscore_ops = {
+ .suspend = xen_syscore_suspend,
+ .resume = xen_syscore_resume
+};
+
+void __init xen_setup_syscore_ops(void)
+{
+ if (xen_hvm_domain())
+ register_syscore_ops(&xen_hvm_syscore_ops);
+}
diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h
index be78f6f..65f25bd 100644
--- a/include/xen/xen-ops.h
+++ b/include/xen/xen-ops.h
@@ -43,6 +43,8 @@ bool xen_suspend_mode_is_xen_suspend(void);
bool xen_suspend_mode_is_pm_suspend(void);
bool xen_suspend_mode_is_pm_hibernation(void);
+void xen_setup_syscore_ops(void);
+
extern unsigned long *xen_contiguous_bitmap;
#ifdef CONFIG_XEN_PV
--
2.7.4
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply related
* [RFC PATCH 04/12] x86/xen: Introduce new function to map HYPERVISOR_shared_info on Resume
From: Anchal Agarwal @ 2018-06-12 20:56 UTC (permalink / raw)
To: tglx, mingo, hpa, x86
Cc: jgross, len.brown, eduval, vallish, netdev, fllinden, kamatam,
rjw, linux-kernel, anchalag, cyberax, pavel, linux-pm, xen-devel,
boris.ostrovsky, guruanb, roger.pau
In-Reply-To: <20180612205619.28156-1-anchalag@amazon.com>
Introduce a small function which re-uses shared page's PA allocated
during guest initialization time in reserve_shared_info() and not
allocate new page during resume flow.
It also does the mapping of shared_info_page by calling
xen_hvm_init_shared_info() to use the function.
Signed-off-by: Anchal Agarwal <anchalag@amazon.com>
Reviewed-by: Sebastian Biemueller <sbiemue@amazon.com>
Reviewed-by: Munehisa Kamata <kamatam@amazon.com>
Reviewed-by: Eduardo Valentin <eduval@amazon.com>
CR: https://cr.amazon.com/r/8273203/
---
arch/x86/xen/enlighten_hvm.c | 7 +++++++
arch/x86/xen/xen-ops.h | 1 +
2 files changed, 8 insertions(+)
diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c
index 754d5391d9fa..2c4bcf92a90a 100644
--- a/arch/x86/xen/enlighten_hvm.c
+++ b/arch/x86/xen/enlighten_hvm.c
@@ -24,6 +24,13 @@
static unsigned long shared_info_pfn;
+void xen_hvm_map_shared_info(void)
+{
+ xen_hvm_init_shared_info();
+ if (shared_info_pfn)
+ HYPERVISOR_shared_info = __va(PFN_PHYS(shared_info_pfn));
+}
+
void xen_hvm_init_shared_info(void)
{
struct xen_add_to_physmap xatp;
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
index f377e1820c6c..94c8a009ab35 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -58,6 +58,7 @@ void xen_enable_syscall(void);
void xen_vcpu_restore(void);
void xen_callback_vector(void);
+void xen_hvm_map_shared_info(void);
void xen_hvm_init_shared_info(void);
void xen_unplug_emulated_devices(void);
--
2.14.3
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply related
* [RFC PATCH 03/12] xenbus: add freeze/thaw/restore callbacks support
From: Anchal Agarwal @ 2018-06-12 20:56 UTC (permalink / raw)
To: tglx, mingo, hpa, x86
Cc: jgross, len.brown, eduval, vallish, netdev, fllinden, kamatam,
rjw, linux-kernel, anchalag, cyberax, pavel, linux-pm, xen-devel,
boris.ostrovsky, guruanb, roger.pau
In-Reply-To: <20180612205619.28156-1-anchalag@amazon.com>
From: Munehisa Kamata <kamatam@amazon.com>
Since commit b3e96c0c7562 ("xen: use freeze/restore/thaw PM events for
suspend/resume/chkpt"), xenbus uses PMSG_FREEZE, PMSG_THAW and
PMSG_RESTORE events for Xen suspend. However, they're actually assigned
to xenbus_dev_suspend(), xenbus_dev_cancel() and xenbus_dev_resume()
respectively, and only suspend and resume callbacks are supported at
driver level. To support PM suspend and PM hibernation, modify the bus
level PM callbacks to invoke not only device driver's suspend/resume but
also freeze/thaw/restore.
Note that we'll use freeze/restore callbacks even for PM suspend whereas
suspend/resume callbacks are normally used in the case, becausae the
existing xenbus device drivers already have suspend/resume callbacks
specifically designed for Xen suspend. So we can allow the device
drivers to keep the existing callbacks wihtout modification.
Signed-off-by: Munehisa Kamata <kamatam@amazon.com>
Signed-off-by: Anchal Agarwal <anchalag@amazon.com>
Reviewed-by: Munehisa Kamata <kamatam@amazon.com>
Reviewed-by: Eduardo Valentin <eduval@amazon.com>
---
drivers/xen/xenbus/xenbus_probe.c | 102 ++++++++++++++++++++++++++++++++------
include/xen/xenbus.h | 3 ++
2 files changed, 89 insertions(+), 16 deletions(-)
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index ec9eb4f..95b0a6d 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -49,6 +49,7 @@
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/module.h>
+#include <linux/suspend.h>
#include <asm/page.h>
#include <asm/pgtable.h>
@@ -588,26 +589,47 @@ int xenbus_dev_suspend(struct device *dev)
struct xenbus_driver *drv;
struct xenbus_device *xdev
= container_of(dev, struct xenbus_device, dev);
+ int (*cb)(struct xenbus_device *) = NULL;
+ bool xen_suspend = xen_suspend_mode_is_xen_suspend();
DPRINTK("%s", xdev->nodename);
if (dev->driver == NULL)
return 0;
drv = to_xenbus_driver(dev->driver);
- if (drv->suspend)
- err = drv->suspend(xdev);
- if (err)
- pr_warn("suspend %s failed: %i\n", dev_name(dev), err);
+
+ if (xen_suspend)
+ cb = drv->suspend;
+ else
+ cb = drv->freeze;
+
+ if (cb)
+ err = cb(xdev);
+
+ if (err) {
+ pr_warn("%s %s failed: %i\n", xen_suspend ?
+ "suspend" : "freeze", dev_name(dev), err);
+ return err;
+ }
+
+ if (!xen_suspend) {
+ /* Forget otherend since this can become stale after restore */
+ free_otherend_watch(xdev);
+ free_otherend_details(xdev);
+ }
+
return 0;
}
EXPORT_SYMBOL_GPL(xenbus_dev_suspend);
int xenbus_dev_resume(struct device *dev)
{
- int err;
+ int err = 0;
struct xenbus_driver *drv;
struct xenbus_device *xdev
= container_of(dev, struct xenbus_device, dev);
+ int (*cb)(struct xenbus_device *) = NULL;
+ bool xen_suspend = xen_suspend_mode_is_xen_suspend();
DPRINTK("%s", xdev->nodename);
@@ -616,24 +638,34 @@ int xenbus_dev_resume(struct device *dev)
drv = to_xenbus_driver(dev->driver);
err = talk_to_otherend(xdev);
if (err) {
- pr_warn("resume (talk_to_otherend) %s failed: %i\n",
+ pr_warn("%s (talk_to_otherend) %s failed: %i\n",
+ xen_suspend ? "resume" : "restore",
dev_name(dev), err);
return err;
}
- xdev->state = XenbusStateInitialising;
+ if (xen_suspend)
+ xdev->state = XenbusStateInitialising;
- if (drv->resume) {
- err = drv->resume(xdev);
- if (err) {
- pr_warn("resume %s failed: %i\n", dev_name(dev), err);
- return err;
- }
+ if (xen_suspend)
+ cb = drv->resume;
+ else
+ cb = drv->restore;
+
+ if (cb)
+ err = cb(xdev);
+
+ if (err) {
+ pr_warn("%s %s failed: %i\n",
+ xen_suspend ? "resume" : "restore",
+ dev_name(dev), err);
+ return err;
}
err = watch_otherend(xdev);
if (err) {
- pr_warn("resume (watch_otherend) %s failed: %d.\n",
+ pr_warn("%s (watch_otherend) %s failed: %d.\n",
+ xen_suspend ? "resume" : "restore",
dev_name(dev), err);
return err;
}
@@ -644,8 +676,46 @@ EXPORT_SYMBOL_GPL(xenbus_dev_resume);
int xenbus_dev_cancel(struct device *dev)
{
- /* Do nothing */
- DPRINTK("cancel");
+ int err = 0;
+ struct xenbus_driver *drv;
+ struct xenbus_device *xdev
+ = container_of(dev, struct xenbus_device, dev);
+ bool xen_suspend = xen_suspend_mode_is_xen_suspend();
+
+ if (xen_suspend) {
+ /* Do nothing */
+ DPRINTK("cancel");
+ return 0;
+ }
+
+ DPRINTK("%s", xdev->nodename);
+
+ if (dev->driver == NULL)
+ return 0;
+ drv = to_xenbus_driver(dev->driver);
+
+ err = talk_to_otherend(xdev);
+ if (err) {
+ pr_warn("thaw (talk_to_otherend) %s failed: %d.\n",
+ dev_name(dev), err);
+ return err;
+ }
+
+ if (drv->thaw) {
+ err = drv->thaw(xdev);
+ if (err) {
+ pr_warn("thaw %s failed: %i\n", dev_name(dev), err);
+ return err;
+ }
+ }
+
+ err = watch_otherend(xdev);
+ if (err) {
+ pr_warn("thaw (watch_otherend) %s failed: %d.\n",
+ dev_name(dev), err);
+ return err;
+ }
+
return 0;
}
EXPORT_SYMBOL_GPL(xenbus_dev_cancel);
diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h
index 869c816..20261d5 100644
--- a/include/xen/xenbus.h
+++ b/include/xen/xenbus.h
@@ -100,6 +100,9 @@ struct xenbus_driver {
int (*remove)(struct xenbus_device *dev);
int (*suspend)(struct xenbus_device *dev);
int (*resume)(struct xenbus_device *dev);
+ int (*freeze)(struct xenbus_device *dev);
+ int (*thaw)(struct xenbus_device *dev);
+ int (*restore)(struct xenbus_device *dev);
int (*uevent)(struct xenbus_device *, struct kobj_uevent_env *);
struct device_driver driver;
int (*read_otherend_details)(struct xenbus_device *dev);
--
2.7.4
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply related
* [RFC PATCH 02/12] xen/manage: introduce helper function to know the on-going suspend mode
From: Anchal Agarwal @ 2018-06-12 20:56 UTC (permalink / raw)
To: tglx, mingo, hpa, x86
Cc: jgross, len.brown, eduval, vallish, netdev, fllinden, kamatam,
rjw, linux-kernel, anchalag, cyberax, pavel, linux-pm, xen-devel,
boris.ostrovsky, guruanb, roger.pau
In-Reply-To: <20180612205619.28156-1-anchalag@amazon.com>
From: Munehisa Kamata <kamatam@amazon.com>
Introduce simple functions which help to know the on-going suspend mode
so that other Xen-related code can behave differently according to the
current suspend mode.
Signed-off-by: Munehisa Kamata <kamatam@amazon.com>
Signed-off-by: Anchal Agarwal <anchalag@amazon.com>
Reviewed-by: Alakesh Haloi <alakeshh@amazon.com>
Reviewed-by: Sebastian Biemueller <sbiemue@amazon.com>
Reviewed-by: Munehisa Kamata <kamatam@amazon.com>
Reviewed-by: Eduardo Valentin <eduval@amazon.com>
---
drivers/xen/manage.c | 15 +++++++++++++++
include/xen/xen-ops.h | 4 ++++
2 files changed, 19 insertions(+)
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index 8f9ea87..326631d 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -50,6 +50,21 @@ enum suspend_modes {
/* Protected by pm_mutex */
static enum suspend_modes suspend_mode = NO_SUSPEND;
+bool xen_suspend_mode_is_xen_suspend(void)
+{
+ return suspend_mode == XEN_SUSPEND;
+}
+
+bool xen_suspend_mode_is_pm_suspend(void)
+{
+ return suspend_mode == PM_SUSPEND;
+}
+
+bool xen_suspend_mode_is_pm_hibernation(void)
+{
+ return suspend_mode == PM_HIBERNATION;
+}
+
struct suspend_info {
int cancelled;
};
diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h
index fd23e42..be78f6f 100644
--- a/include/xen/xen-ops.h
+++ b/include/xen/xen-ops.h
@@ -39,6 +39,10 @@ u64 xen_steal_clock(int cpu);
int xen_setup_shutdown_event(void);
+bool xen_suspend_mode_is_xen_suspend(void);
+bool xen_suspend_mode_is_pm_suspend(void);
+bool xen_suspend_mode_is_pm_hibernation(void);
+
extern unsigned long *xen_contiguous_bitmap;
#ifdef CONFIG_XEN_PV
--
2.7.4
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox