diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp
index c977f3784f7d3cdd589af4ce531f3396baec5f83..5a1add258c208ba00c98b990a37cff6c0c27fed6 100644
--- a/indra/newview/llcontrolavatar.cpp
+++ b/indra/newview/llcontrolavatar.cpp
@@ -355,7 +355,7 @@ void LLControlAvatar::updateAnimations()
 {
     if (!mRootVolp)
     {
-        LL_WARNS_ONCE("AnimatedObjects") << "No root vol" << LL_ENDL;
+        LL_WARNS_ONCE("AnimatedObjectsNotify") << "No root vol" << LL_ENDL;
         return;
     }
 
@@ -367,7 +367,7 @@ void LLControlAvatar::updateAnimations()
     for (std::vector<LLVOVolume*>::iterator vol_it = volumes.begin(); vol_it != volumes.end(); ++vol_it)
     {
         LLVOVolume *volp = *vol_it;
-        LL_INFOS("AnimatedObjects") << "updating anim for vol " << volp->getID() << " root " << mRootVolp->getID() << LL_ENDL;
+        //LL_INFOS("AnimatedObjects") << "updating anim for vol " << volp->getID() << " root " << mRootVolp->getID() << LL_ENDL;
         signaled_animation_map_t& signaled_animations = LLObjectSignaledAnimationMap::instance().getMap()[volp->getID()];
         for (std::map<LLUUID,S32>::iterator anim_it = signaled_animations.begin();
              anim_it != signaled_animations.end();
@@ -384,7 +384,7 @@ void LLControlAvatar::updateAnimations()
                 // Animation not already present, use this sequence id.
                 anims[anim_it->first] = anim_it->second;
             }
-            LL_INFOS("AnimatedObjects") << "found anim for vol " << volp->getID() << " anim " << anim_it->first << " root " << mRootVolp->getID() << LL_ENDL;
+            LL_DEBUGS("AnimatedObjectsNotify") << "found anim for vol " << volp->getID() << " anim " << anim_it->first << " root " << mRootVolp->getID() << LL_ENDL;
         }
     }
     if (!mPlaying)
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index e8db01efed48188d53ce1281ccde6dbf0e190580..ba3e9e6993ab12894d817299990f29fa17af9246 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -5085,17 +5085,17 @@ void process_object_animation(LLMessageSystem *mesgsys, void **user_data)
 	
 	mesgsys->getUUIDFast(_PREHASH_Sender, _PREHASH_ID, uuid);
 
-    LL_INFOS("AnimatedObjects") << "Received animation state for object " << uuid << LL_ENDL;
+    LL_DEBUGS("AnimatedObjectsNotify") << "Received animation state for object " << uuid << LL_ENDL;
 
     signaled_animation_map_t signaled_anims;
 	S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_AnimationList);
-	LL_INFOS("AnimatedObjects") << "processing object animation requests, num_blocks " << num_blocks << " uuid " << uuid << LL_ENDL;
+	LL_DEBUGS("AnimatedObjectsNotify") << "processing object animation requests, num_blocks " << num_blocks << " uuid " << uuid << LL_ENDL;
     for( S32 i = 0; i < num_blocks; i++ )
     {
         mesgsys->getUUIDFast(_PREHASH_AnimationList, _PREHASH_AnimID, animation_id, i);
         mesgsys->getS32Fast(_PREHASH_AnimationList, _PREHASH_AnimSequenceID, anim_sequence_id, i);
         signaled_anims[animation_id] = anim_sequence_id;
-        LL_INFOS("AnimatedObjects") << "added signaled_anims animation request for object " 
+        LL_DEBUGS("AnimatedObjectsNotify") << "added signaled_anims animation request for object " 
                                     << uuid << " animation id " << animation_id << LL_ENDL;
     }
     LLObjectSignaledAnimationMap::instance().getMap()[uuid] = signaled_anims;
@@ -5103,20 +5103,20 @@ void process_object_animation(LLMessageSystem *mesgsys, void **user_data)
     LLViewerObject *objp = gObjectList.findObject(uuid);
     if (!objp)
     {
-		LL_WARNS("AnimatedObjects") << "Received animation state for unknown object " << uuid << LL_ENDL;
+		LL_DEBUGS("AnimatedObjectsNotify") << "Received animation state for unknown object " << uuid << LL_ENDL;
         return;
     }
     
 	LLVOVolume *volp = dynamic_cast<LLVOVolume*>(objp);
     if (!volp)
     {
-		LL_WARNS("AnimatedObjects") << "Received animation state for non-volume object " << uuid << LL_ENDL;
+		LL_DEBUGS("AnimatedObjectsNotify") << "Received animation state for non-volume object " << uuid << LL_ENDL;
         return;
     }
 
     if (!volp->isAnimatedObject())
     {
-		LL_WARNS("AnimatedObjects") << "Received animation state for non-animated object " << uuid << LL_ENDL;
+		LL_DEBUGS("AnimatedObjectsNotify") << "Received animation state for non-animated object " << uuid << LL_ENDL;
         return;
     }
 
@@ -5124,7 +5124,7 @@ void process_object_animation(LLMessageSystem *mesgsys, void **user_data)
     LLControlAvatar *avatarp = volp->getControlAvatar();
     if (!avatarp)
     {
-        LL_WARNS("AnimatedObjects") << "Received animation request for object with no control avatar, ignoring " << uuid << LL_ENDL;
+        LL_DEBUGS("AnimatedObjectsNotify") << "Received animation request for object with no control avatar, ignoring " << uuid << LL_ENDL;
         return;
     }
     
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 725f48f0916f10424e1ffa45fce97b3d218bdf43..1f23286dac9aaf300fcf89b0a9cfe131644f65a1 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -2966,20 +2966,38 @@ LLControlAvatar *LLViewerObject::getControlAvatar() const
     return getRootEdit()->mControlAvatar.get();
 }
 
+// Manage the control avatar state of a given object.
+// Any object can be flagged as animated, but for performance reasons
+// we don't want to incur the overhead of managing a control avatar
+// unless this would have some user-visible consequence. That is,
+// there should be at least one rigged mesh in the linkset. Operations
+// that change the state of a linkset, such as linking or unlinking
+// prims, can also mean that a control avatar needs to be added or
+// removed. At the end, if there is a control avatar, we make sure
+// that its animation state is current.
 void LLViewerObject::updateControlAvatar()
 {
     LLViewerObject *root = getRootEdit();
-    bool any_rigged_mesh = root->isRiggedMesh();
-    LLViewerObject::const_child_list_t& child_list = root->getChildren();
-    for (LLViewerObject::const_child_list_t::const_iterator iter = child_list.begin();
-         iter != child_list.end(); ++iter)
+    bool is_animated_object = root->isAnimatedObject();
+    bool has_control_avatar = getControlAvatar();
+    if (!is_animated_object && !has_control_avatar)
     {
-        const LLViewerObject* child = *iter;
-        any_rigged_mesh = any_rigged_mesh || child->isRiggedMesh();
+        return;
     }
 
-    bool has_control_avatar = getControlAvatar();
-    bool should_have_control_avatar = root->isAnimatedObject() && any_rigged_mesh;
+    bool should_have_control_avatar = false;
+    if (is_animated_object)
+    {
+        bool any_rigged_mesh = root->isRiggedMesh();
+        LLViewerObject::const_child_list_t& child_list = root->getChildren();
+        for (LLViewerObject::const_child_list_t::const_iterator iter = child_list.begin();
+             iter != child_list.end(); ++iter)
+        {
+            const LLViewerObject* child = *iter;
+            any_rigged_mesh = any_rigged_mesh || child->isRiggedMesh();
+        }
+        should_have_control_avatar = is_animated_object && any_rigged_mesh;
+    }
 
     if (should_have_control_avatar && !has_control_avatar)
     {
@@ -3018,7 +3036,6 @@ void LLViewerObject::linkControlAvatar()
     if (cav)
     {
         cav->updateAttachmentOverrides();
-        cav->updateAnimations();
         if (!cav->mPlaying)
         {
             cav->mPlaying = true;
@@ -3028,7 +3045,6 @@ void LLViewerObject::linkControlAvatar()
                 cav->mRootVolp->recursiveMarkForUpdate(TRUE);
             }
         }
-        //cav->updateAnimations();
     }
     else
     {