From dc9b309d03074862daad9ef05ef643da870f6722 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Thu, 19 Oct 2017 22:24:31 -0400 Subject: [PATCH] osdc/Objecter: skip sparse-read result decode if bufferlist is empty If the OSD does not execute sub-ops due to errors encountered prior to the sub-op, the sub-op result remains zeroed with empty out data. Attempting to decode the empty bufferlist results in large exception handling CPU overhead. Fixes: http://tracker.ceph.com/issues/21844 Signed-off-by: Jason Dillaman --- src/osdc/Objecter.h | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/osdc/Objecter.h b/src/osdc/Objecter.h index 3358d6bb24e8c..569e328ee6c4e 100644 --- a/src/osdc/Objecter.h +++ b/src/osdc/Objecter.h @@ -335,13 +335,20 @@ struct ObjectOperation { void finish(int r) override { bufferlist::iterator iter = bl.begin(); if (r >= 0) { - try { - ::decode(*extents, iter); - ::decode(*data_bl, iter); - } catch (buffer::error& e) { - if (prval) - *prval = -EIO; - } + // NOTE: it's possible the sub-op has not been executed but the result + // code remains zeroed. Avoid the costly exception handling on a + // potential IO path. + if (bl.length() > 0) { + try { + ::decode(*extents, iter); + ::decode(*data_bl, iter); + } catch (buffer::error& e) { + if (prval) + *prval = -EIO; + } + } else if (prval) { + *prval = -EIO; + } } } }; -- 2.39.5