From nobody Wed Feb 11 18:58:57 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C84B6C678D5 for ; Sat, 11 Mar 2023 03:15:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229761AbjCKDPB (ORCPT ); Fri, 10 Mar 2023 22:15:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56268 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229455AbjCKDO7 (ORCPT ); Fri, 10 Mar 2023 22:14:59 -0500 Received: from todd.t-8ch.de (todd.t-8ch.de [159.69.126.157]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 10798132A94 for ; Fri, 10 Mar 2023 19:14:57 -0800 (PST) From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=weissschuh.net; s=mail; t=1678504495; bh=7UpojwGw4Wjc6iwDTG11oJXV5hBbJObX8sfOzw0j3+8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Zuk3/bEco0V/MQXZlAcAPaRUfq7PBCyCHrQ5lII+Ejk8k5muVy2a8j2D9o65dIe4F SN5qJxczydCRpCvjAZlU61FElYRahnllDt3phpk2ftEsX3DwthmRQCWOpaC0HIJJ0W fojPpoCxInntp/Jpzl3pMUswSsbdVq9HDcIg5YR8= Date: Sat, 11 Mar 2023 03:14:46 +0000 Subject: [PATCH 1/4] kobject: define common logging prefix MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20230311-kobject-warning-v1-1-1ebba4f71fb5@weissschuh.net> References: <20230311-kobject-warning-v1-0-1ebba4f71fb5@weissschuh.net> In-Reply-To: <20230311-kobject-warning-v1-0-1ebba4f71fb5@weissschuh.net> To: Greg Kroah-Hartman , "Rafael J. Wysocki" Cc: linux-kernel@vger.kernel.org, =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Mailer: b4 0.12.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1678504493; l=4592; i=linux@weissschuh.net; s=20221212; h=from:subject:message-id; bh=7UpojwGw4Wjc6iwDTG11oJXV5hBbJObX8sfOzw0j3+8=; b=srn5/5x4qNccxjCHSdFcj5F169tzEJq4pb0s/zWHAQ8IsN85mklJg4gN9ClW7E8LNGFsu+m19 eUbb4wQJLKgA94beuVi7iaIN2+Jx8vzhVXebWmGchzayQCZ7O5c8qIg X-Developer-Key: i=linux@weissschuh.net; a=ed25519; pk=KcycQgFPX2wGR5azS7RhpBqedglOZVgRPfdFSPB1LNw= Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org All log messages start with the prefix "kobject: ". Deduplicate this by using the pr_fmt() facility. This makes the very long log strings shorter. Signed-off-by: Thomas Wei=C3=9Fschuh --- lib/kobject.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/lib/kobject.c b/lib/kobject.c index 6e2f0bee3560..09c81ffb8b33 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -10,6 +10,8 @@ * about using the kobject interface. */ =20 +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -127,7 +129,7 @@ static int fill_kobj_path(const struct kobject *kobj, c= har *path, int length) *(path + --length) =3D '/'; } =20 - pr_debug("kobject: '%s' (%p): %s: path =3D '%s'\n", kobject_name(kobj), + pr_debug("'%s' (%p): %s: path =3D '%s'\n", kobject_name(kobj), kobj, __func__, path); =20 return 0; @@ -223,7 +225,7 @@ static int kobject_add_internal(struct kobject *kobj) kobj->parent =3D parent; } =20 - pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'\n", + pr_debug("'%s' (%p): %s: parent: '%s', set: '%s'\n", kobject_name(kobj), kobj, __func__, parent ? kobject_name(parent) : "", kobj->kset ? kobject_name(&kobj->kset->kobj) : ""); @@ -359,7 +361,7 @@ static __printf(3, 0) int kobject_add_varg(struct kobje= ct *kobj, =20 retval =3D kobject_set_name_vargs(kobj, fmt, vargs); if (retval) { - pr_err("kobject: can not set name properly!\n"); + pr_err("can not set name properly!\n"); return retval; } kobj->parent =3D parent; @@ -588,7 +590,7 @@ static void __kobject_del(struct kobject *kobj) =20 /* send "remove" if the caller did not do it but sent "add" */ if (kobj->state_add_uevent_sent && !kobj->state_remove_uevent_sent) { - pr_debug("kobject: '%s' (%p): auto cleanup 'remove' event\n", + pr_debug("'%s' (%p): auto cleanup 'remove' event\n", kobject_name(kobj), kobj); kobject_uevent(kobj, KOBJ_REMOVE); } @@ -658,16 +660,16 @@ static void kobject_cleanup(struct kobject *kobj) const struct kobj_type *t =3D get_ktype(kobj); const char *name =3D kobj->name; =20 - pr_debug("kobject: '%s' (%p): %s, parent %p\n", + pr_debug("'%s' (%p): %s, parent %p\n", kobject_name(kobj), kobj, __func__, kobj->parent); =20 if (t && !t->release) - pr_debug("kobject: '%s' (%p): does not have a release() function, it is = broken and must be fixed. See Documentation/core-api/kobject.rst.\n", + pr_debug("'%s' (%p): does not have a release() function, it is broken an= d must be fixed. See Documentation/core-api/kobject.rst.\n", kobject_name(kobj), kobj); =20 /* remove from sysfs if the caller did not do it */ if (kobj->state_in_sysfs) { - pr_debug("kobject: '%s' (%p): auto cleanup kobject_del\n", + pr_debug("'%s' (%p): auto cleanup kobject_del\n", kobject_name(kobj), kobj); __kobject_del(kobj); } else { @@ -676,14 +678,14 @@ static void kobject_cleanup(struct kobject *kobj) } =20 if (t && t->release) { - pr_debug("kobject: '%s' (%p): calling ktype release\n", + pr_debug("'%s' (%p): calling ktype release\n", kobject_name(kobj), kobj); t->release(kobj); } =20 /* free name if we allocated it */ if (name) { - pr_debug("kobject: '%s': free name\n", name); + pr_debug("'%s': free name\n", name); kfree_const(name); } =20 @@ -703,8 +705,8 @@ static void kobject_release(struct kref *kref) struct kobject *kobj =3D container_of(kref, struct kobject, kref); #ifdef CONFIG_DEBUG_KOBJECT_RELEASE unsigned long delay =3D HZ + HZ * get_random_u32_below(4); - pr_info("kobject: '%s' (%p): %s, parent %p (delayed %ld)\n", - kobject_name(kobj), kobj, __func__, kobj->parent, delay); + pr_info("'%s' (%p): %s, parent %p (delayed %ld)\n", + kobject_name(kobj), kobj, __func__, kobj->parent, delay); INIT_DELAYED_WORK(&kobj->release, kobject_delayed_cleanup); =20 schedule_delayed_work(&kobj->release, delay); @@ -733,7 +735,7 @@ EXPORT_SYMBOL(kobject_put); =20 static void dynamic_kobj_release(struct kobject *kobj) { - pr_debug("kobject: (%p): %s\n", kobj, __func__); + pr_debug("(%p): %s\n", kobj, __func__); kfree(kobj); } =20 @@ -910,7 +912,7 @@ EXPORT_SYMBOL_GPL(kset_find_obj); static void kset_release(struct kobject *kobj) { struct kset *kset =3D container_of(kobj, struct kset, kobj); - pr_debug("kobject: '%s' (%p): %s\n", + pr_debug("'%s' (%p): %s\n", kobject_name(kobj), kobj, __func__); kfree(kset); } --=20 2.39.2 From nobody Wed Feb 11 18:58:57 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F216FC678D5 for ; Sat, 11 Mar 2023 03:15:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229928AbjCKDPO (ORCPT ); Fri, 10 Mar 2023 22:15:14 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56316 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229455AbjCKDPC (ORCPT ); Fri, 10 Mar 2023 22:15:02 -0500 Received: from todd.t-8ch.de (todd.t-8ch.de [159.69.126.157]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9A33A132A94 for ; Fri, 10 Mar 2023 19:15:00 -0800 (PST) From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=weissschuh.net; s=mail; t=1678504498; bh=pCEog6vxwSuKmvKLhc80450ur1XxkLoLlCfazqFt1F0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=hBhcLJv3vkpuVK0jz9kWGargi8oM/bWAOYD6b4P03pAkENPLv8TeRN2rJbLaUmet5 IveFF1TAXhGbIly7PajneFQT5Jdc+hGo47BFvsWy2bx6AlZfQQR4AMzWdbwgFXJHcf pnJS6C4tsZgfrqkZMEdRpXeacTh+b6IIf7boqCzg= Date: Sat, 11 Mar 2023 03:14:47 +0000 Subject: [PATCH 2/4] kobject: align stacktrace levels to logging message MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20230311-kobject-warning-v1-2-1ebba4f71fb5@weissschuh.net> References: <20230311-kobject-warning-v1-0-1ebba4f71fb5@weissschuh.net> In-Reply-To: <20230311-kobject-warning-v1-0-1ebba4f71fb5@weissschuh.net> To: Greg Kroah-Hartman , "Rafael J. Wysocki" Cc: linux-kernel@vger.kernel.org, =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Mailer: b4 0.12.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1678504493; l=1551; i=linux@weissschuh.net; s=20221212; h=from:subject:message-id; bh=pCEog6vxwSuKmvKLhc80450ur1XxkLoLlCfazqFt1F0=; b=4MfIfOAfHwH+ONwUjubatS0nY+UNzyAioLh2YI5evEhAVmI2SI6nfiNqost8qs2AkmLHZ+MnA Qy30P6yFsQJB/MX3UbN6LRaFSgyzDqODqAOxjyJmumiLFKIOgiyhq3G X-Developer-Key: i=linux@weissschuh.net; a=ed25519; pk=KcycQgFPX2wGR5azS7RhpBqedglOZVgRPfdFSPB1LNw= Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Without an explicit level the stacktraces are printed at a default level. If this level does not match the one from the logging level it may happen that the stacktrace is shown without the message or vice versa. Both these cases are confusing, so make sure the user always sees both, the message and the stacktrace. Signed-off-by: Thomas Wei=C3=9Fschuh --- lib/kobject.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/kobject.c b/lib/kobject.c index 09c81ffb8b33..f79a434e1231 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -340,7 +340,7 @@ void kobject_init(struct kobject *kobj, const struct ko= bj_type *ktype) /* do not error out as sometimes we can recover */ pr_err("kobject (%p): tried to init an initialized object, something is = seriously wrong.\n", kobj); - dump_stack(); + dump_stack_lvl(KERN_ERR); } =20 kobject_init_internal(kobj); @@ -349,7 +349,7 @@ void kobject_init(struct kobject *kobj, const struct ko= bj_type *ktype) =20 error: pr_err("kobject (%p): %s\n", kobj, err_str); - dump_stack(); + dump_stack_lvl(KERN_ERR); } EXPORT_SYMBOL(kobject_init); =20 @@ -413,7 +413,7 @@ int kobject_add(struct kobject *kobj, struct kobject *p= arent, if (!kobj->state_initialized) { pr_err("kobject '%s' (%p): tried to add an uninitialized object, somethi= ng is seriously wrong.\n", kobject_name(kobj), kobj); - dump_stack(); + dump_stack_lvl(KERN_ERR); return -EINVAL; } va_start(args, fmt); --=20 2.39.2 From nobody Wed Feb 11 18:58:57 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2E718C74A4B for ; Sat, 11 Mar 2023 03:15:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229885AbjCKDPK (ORCPT ); Fri, 10 Mar 2023 22:15:10 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56300 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229685AbjCKDPA (ORCPT ); Fri, 10 Mar 2023 22:15:00 -0500 Received: from todd.t-8ch.de (todd.t-8ch.de [159.69.126.157]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7C180133D85 for ; Fri, 10 Mar 2023 19:14:59 -0800 (PST) From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=weissschuh.net; s=mail; t=1678504497; bh=bcH+RH7mDEjMHFrUjTVALbIb4nQlqXgmdbui5y0vy1A=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=kZlB8FGBEQR31hU+wKRBi9KYXlBrcyD6oV6v1XjOWQ9rq66wgHNpRLUYSOmNhz7Br l6Yp+IzrR3+0bACs+iePMSyg0ht3HPlIsconcH/LC/yUOylCtvqQX8jFC0GqBmPhYm sNVQQlQVNd+oYDwJp7sNEmFVCU47JwnhOhAuop3s= Date: Sat, 11 Mar 2023 03:14:48 +0000 Subject: [PATCH 3/4] kobject: validate ktype release function during add MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20230311-kobject-warning-v1-3-1ebba4f71fb5@weissschuh.net> References: <20230311-kobject-warning-v1-0-1ebba4f71fb5@weissschuh.net> In-Reply-To: <20230311-kobject-warning-v1-0-1ebba4f71fb5@weissschuh.net> To: Greg Kroah-Hartman , "Rafael J. Wysocki" Cc: linux-kernel@vger.kernel.org, =?utf-8?q?Thomas_Wei=C3=9Fschuh?= , Mirsad Todorovac X-Mailer: b4 0.12.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1678504493; l=1594; i=linux@weissschuh.net; s=20221212; h=from:subject:message-id; bh=bcH+RH7mDEjMHFrUjTVALbIb4nQlqXgmdbui5y0vy1A=; b=50p1tv7SGpwBneKoN/Ga7uCuCMRtktJIjevrXw7BKAo/GJRDKjp4L4KPNaEMK1kGTq5H/XvCN 2HYvnPom76ECJekV40mWOmNExjS+TiGlSVG6Z6k1CBiIVMWP+H+Xi6G X-Developer-Key: i=linux@weissschuh.net; a=ed25519; pk=KcycQgFPX2wGR5azS7RhpBqedglOZVgRPfdFSPB1LNw= Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Validating the ktype during cleanup is suboptimal. Many kobjects are only destroyed during shutdown which makes it hard to observe the messages. Instead perform the validation when the object is added. Reported-by: Mirsad Todorovac Link: https://lore.kernel.org/lkml/60b2b66c-22c9-1d38-ed1c-7b7d95e32720@alu= .unizg.hr/ Signed-off-by: Thomas Wei=C3=9Fschuh --- lib/kobject.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/kobject.c b/lib/kobject.c index f79a434e1231..68ff8a48b784 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -215,6 +215,10 @@ static int kobject_add_internal(struct kobject *kobj) return -EINVAL; } =20 + if (kobj->ktype && !kobj->ktype->release) + pr_debug("'%s' (%p): does not have a release() function, it is broken an= d must be fixed. See Documentation/core-api/kobject.rst.\n", + kobject_name(kobj), kobj); + parent =3D kobject_get(kobj->parent); =20 /* join kset if set, use it as parent if we do not already have one */ @@ -663,10 +667,6 @@ static void kobject_cleanup(struct kobject *kobj) pr_debug("'%s' (%p): %s, parent %p\n", kobject_name(kobj), kobj, __func__, kobj->parent); =20 - if (t && !t->release) - pr_debug("'%s' (%p): does not have a release() function, it is broken an= d must be fixed. See Documentation/core-api/kobject.rst.\n", - kobject_name(kobj), kobj); - /* remove from sysfs if the caller did not do it */ if (kobj->state_in_sysfs) { pr_debug("'%s' (%p): auto cleanup kobject_del\n", --=20 2.39.2 From nobody Wed Feb 11 18:58:57 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1E4F5C61DA4 for ; Sat, 11 Mar 2023 03:15:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229614AbjCKDPG (ORCPT ); Fri, 10 Mar 2023 22:15:06 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56270 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229577AbjCKDO7 (ORCPT ); Fri, 10 Mar 2023 22:14:59 -0500 Received: from todd.t-8ch.de (todd.t-8ch.de [IPv6:2a01:4f8:c010:41de::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 10EEF133A4C for ; Fri, 10 Mar 2023 19:14:57 -0800 (PST) From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=weissschuh.net; s=mail; t=1678504495; bh=sOiskQrdfCnIJT4uxkWaPY9RlNau8EXPiu1P/We8tr0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=r/d9r6prZI3rN88Jp8LpvVV4Mclk1h/7E1U1QKzH2As+OnhYe1m3BJ3lpvCqdoDRR 73Yyu6R8b0J3Vpa3t6yAjxvuHDG7lGPTT+KqdxAV8ZMFB1WhF6f9jVPMe/4aN48OqQ oXGNywQObYH9ARQEdw7bFa/nYQjggFazBV3pqFBo= Date: Sat, 11 Mar 2023 03:14:49 +0000 Subject: [PATCH 4/4] kobject: upgrade log of missing release func to warn MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20230311-kobject-warning-v1-4-1ebba4f71fb5@weissschuh.net> References: <20230311-kobject-warning-v1-0-1ebba4f71fb5@weissschuh.net> In-Reply-To: <20230311-kobject-warning-v1-0-1ebba4f71fb5@weissschuh.net> To: Greg Kroah-Hartman , "Rafael J. Wysocki" Cc: linux-kernel@vger.kernel.org, =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Mailer: b4 0.12.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1678504493; l=1778; i=linux@weissschuh.net; s=20221212; h=from:subject:message-id; bh=sOiskQrdfCnIJT4uxkWaPY9RlNau8EXPiu1P/We8tr0=; b=1ar91zJaVsxFyRXTGIyF83f5ARIzmhFC06gDZVTbz4t54KvrLwhjwOawF3WfOLvvQEPg1PIEi 02YIqkm5pAjC3TH5+EyWKZjVzcYuLfMLDj8RjMEHNFi76kqhIebznaV X-Developer-Key: i=linux@weissschuh.net; a=ed25519; pk=KcycQgFPX2wGR5azS7RhpBqedglOZVgRPfdFSPB1LNw= Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The documentation is outspoken in its requirement for a release() function. Documentation/core-api/kobject.rst: One important point cannot be overstated: every kobject must have a release() method, and the kobject must persist (in a consistent state) until that method is called. If these constraints are not met, the code is flawed. Note that the kernel will warn you if you forget to provide a release() method. Do not try to get rid of this warning by providing an "empty" release function. So adapt the logging to actually provide the promised warning. At the moment there are still kobjects that do not have a release() function, notably integrity_ktype and acpi_hotplug_profile_ktype. Therefore leave it at pr_warn(). When the remaining cases are fixed the message could be upgraded to pr_err() and/or an -EINVAL could be returned. Signed-off-by: Thomas Wei=C3=9Fschuh --- lib/kobject.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/kobject.c b/lib/kobject.c index 68ff8a48b784..8723f477095e 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -215,9 +215,11 @@ static int kobject_add_internal(struct kobject *kobj) return -EINVAL; } =20 - if (kobj->ktype && !kobj->ktype->release) - pr_debug("'%s' (%p): does not have a release() function, it is broken an= d must be fixed. See Documentation/core-api/kobject.rst.\n", - kobject_name(kobj), kobj); + if (kobj->ktype && !kobj->ktype->release) { + pr_warn("'%s' (%p): does not have a release() function, it is broken and= must be fixed. See Documentation/core-api/kobject.rst.\n", + kobject_name(kobj), kobj); + dump_stack_lvl(KERN_WARNING); + } =20 parent =3D kobject_get(kobj->parent); =20 --=20 2.39.2