From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1763624AbZBYP0e (ORCPT ); Wed, 25 Feb 2009 10:26:34 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1756274AbZBYPKB (ORCPT ); Wed, 25 Feb 2009 10:10:01 -0500 Received: from mtagate6.de.ibm.com ([195.212.29.155]:47006 "EHLO mtagate6.de.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1760449AbZBYPJp (ORCPT ); Wed, 25 Feb 2009 10:09:45 -0500 Message-Id: <20090225150835.567940767@de.ibm.com> References: <20090225150622.529143164@de.ibm.com> User-Agent: quilt/0.46-1 Date: Wed, 25 Feb 2009 16:06:52 +0100 From: Martin Schwidefsky To: linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Heiko Carstens , Sebastian Ott , Martin Schwidefsky Subject: [patch/s390 30/46] cio: device scan oom fallback. Content-Disposition: inline; filename=129-cio-scan-oom.diff Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Sebastian Ott Since some callers rely on for_each_subchannel_staged to not fail, fall back to brute force scanning using get_subchannel_by_schid in case of a oom situation. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/css.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) Index: quilt-2.6/drivers/s390/cio/css.c =================================================================== --- quilt-2.6.orig/drivers/s390/cio/css.c +++ quilt-2.6/drivers/s390/cio/css.c @@ -83,6 +83,25 @@ static int call_fn_unknown_sch(struct su return rc; } +static int call_fn_all_sch(struct subchannel_id schid, void *data) +{ + struct cb_data *cb = data; + struct subchannel *sch; + int rc = 0; + + sch = get_subchannel_by_schid(schid); + if (sch) { + if (cb->fn_known_sch) + rc = cb->fn_known_sch(sch, cb->data); + put_device(&sch->dev); + } else { + if (cb->fn_unknown_sch) + rc = cb->fn_unknown_sch(schid, cb->data); + } + + return rc; +} + int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *), int (*fn_unknown)(struct subchannel_id, void *), void *data) @@ -90,13 +109,17 @@ int for_each_subchannel_staged(int (*fn_ struct cb_data cb; int rc; - cb.set = idset_sch_new(); - if (!cb.set) - return -ENOMEM; - idset_fill(cb.set); cb.data = data; cb.fn_known_sch = fn_known; cb.fn_unknown_sch = fn_unknown; + + cb.set = idset_sch_new(); + if (!cb.set) + /* fall back to brute force scanning in case of oom */ + return for_each_subchannel(call_fn_all_sch, &cb); + + idset_fill(cb.set); + /* Process registered subchannels. */ rc = bus_for_each_dev(&css_bus_type, NULL, &cb, call_fn_known_sch); if (rc) -- blue skies, Martin. "Reality continues to ruin my life." - Calvin.