Repository: kubernetes-sigs/descheduler
Pull request #1443 (2024-06-19 19:34:22)

fix: helm leader-election typo to `resourceNamespace`
reported issue: https://kubernetes.slack.com/archives/C09TP78DV/p1718633429179519


Test using `leaderElection.resourceNamescape`
```
helm template deschduler ./descheduler -f ./descheduler/values.yaml --set kind=Deployment --set=leaderElection.enabled=true --set=leaderElection.resourceNamescape=foo

Error: execution error at (descheduler/templates/deployment.yaml:62:16): 'leaderElection.resourceNamescape' is deprecated. instead use 'leaderElection.resourceNamespace'
```

Test using `leaderElection.resourceNamespace`
```
helm template deschduler ./descheduler -f ./descheduler/values.yaml --set kind=Deployment --set=leaderElection.enabled=true --set=leaderElection.resourceNamespace=foo | grep leader-elect-resource-namespace

            - --leader-elect-resource-namespace=foo

k8s-ci-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by:
**Once this PR has been reviewed and has the lgtm label**, please ask for approval from [a7i](https://github.com/a7i). For more information see [the Kubernetes Code Review Process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process).

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fdescheduler).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/kubernetes-sigs/descheduler/blob/master/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["a7i"]} -->

Patch:
diff --git a/README.md b/README.md
index ae99c3845..19baadcf5 100644
--- a/README.md
+++ b/README.md
@@ -128,7 +128,6 @@ These are top level keys in the Descheduler Policy that you can use to configure
 | `nodeSelector` |`string`| `nil` | limiting the nodes which are processed. Only used when `nodeFit`=`true` and only by the PreEvictionFilter Extension Point |
 | `maxNoOfPodsToEvictPerNode` |`int`| `nil` | maximum number of pods evicted from each node (summed through all strategies) |
 | `maxNoOfPodsToEvictPerNamespace` |`int`| `nil` | maximum number of pods evicted from each namespace (summed through all strategies) |
-| `maxNoOfPodsToEvictTotal` |`int`| `nil` | maximum number of pods evicted per rescheduling cycle (summed through all strategies) |
 
 ### Evictor Plugin configuration (Default Evictor)
 
@@ -160,7 +159,6 @@ kind: "DeschedulerPolicy"
 nodeSelector: "node=node1" # you don't need to set this, if not set all will be processed
 maxNoOfPodsToEvictPerNode: 5000 # you don't need to set this, unlimited if not set
 maxNoOfPodsToEvictPerNamespace: 5000 # you don't need to set this, unlimited if not set
-maxNoOfPodsToEvictTotal: 5000 # you don't need to set this, unlimited if not set
 profiles:
   - name: ProfileName
     pluginConfig:
diff --git a/charts/descheduler/Chart.yaml b/charts/descheduler/Chart.yaml
index d7b8fef01..0770f7cb8 100644
--- a/charts/descheduler/Chart.yaml
+++ b/charts/descheduler/Chart.yaml
@@ -1,7 +1,7 @@
 apiVersion: v1
 name: descheduler
-version: 0.30.1
-appVersion: 0.30.1
+version: 0.30.0
+appVersion: 0.30.0
 description: Descheduler for Kubernetes is used to rebalance clusters by evicting pods that can potentially be scheduled on better nodes. In the current implementation, descheduler does not schedule replacement of evicted pods but relies on the default scheduler for that.
 keywords:
 - kubernetes
diff --git a/charts/descheduler/README.md b/charts/descheduler/README.md
index 678cc7df8..05862be91 100644
--- a/charts/descheduler/README.md
+++ b/charts/descheduler/README.md
@@ -52,7 +52,6 @@ The following table lists the configurable parameters of the _descheduler_ chart
 | `imagePullSecrets`                  | Docker repository secrets                                                                                             | `[]`                                      |
 | `nameOverride`                      | String to partially override `descheduler.fullname` template (will prepend the release name)                          | `""`                                      |
 | `fullnameOverride`                  | String to fully override `descheduler.fullname` template                                                              | `""`                                      |
-| `namespaceOverride`                 | Override the deployment namespace; defaults to .Release.Namespace                                                     | `""`                                      |
 | `cronJobApiVersion`                 | CronJob API Group Version                                                                                             | `"batch/v1"`                              |
 | `schedule`                          | The cron schedule to run the _descheduler_ job on                                                                     | `"*/2 * * * *"`                           |
 | `startingDeadlineSeconds`           | If set, configure `startingDeadlineSeconds` for the _descheduler_ job                                                 | `nil`                                     |
diff --git a/charts/descheduler/templates/_helpers.tpl b/charts/descheduler/templates/_helpers.tpl
index 3cfa655ac..5e0baab85 100644
--- a/charts/descheduler/templates/_helpers.tpl
+++ b/charts/descheduler/templates/_helpers.tpl
@@ -24,14 +24,6 @@ If release name contains chart name it will be used as a full name.
 {{- end -}}
 {{- end -}}
 
-{{/*
-Expand the namespace of the release.
-Allows overriding it for multi-namespace deployments in combined charts.
-*/}}
-{{- define "descheduler.namespace" -}}
-{{- default .Release.Namespace .Values.namespaceOverride | trunc 63 | trimSuffix "-" -}}
-{{- end -}}
-
 {{/*
 Create chart name and version as used by the chart label.
 */}}
@@ -95,8 +87,10 @@ Leader Election
 {{- if .Values.leaderElection.resourceName }}
 - --leader-elect-resource-name={{ .Values.leaderElection.resourceName }}
 {{- end }}
-{{- if .Values.leaderElection.resourceNamescape }}
-- --leader-elect-resource-namespace={{ .Values.leaderElection.resourceNamescape }}
+{{/* resource namespace value starts with a typo so keeping resourceNamescape for backwards compatibility */}}
+{{- $resourceNamespace := default .Values.leaderElection.resourceNamespace .Values.leaderElection.resourceNamescape -}}
+{{- if $resourceNamespace -}}
+- --leader-elect-resource-namespace={{ $resourceNamespace }}
 {{- end -}}
 {{- end }}
 {{- end }}
diff --git a/charts/descheduler/templates/clusterrolebinding.yaml b/charts/descheduler/templates/clusterrolebinding.yaml
index b6ccfade3..6cbc62004 100644
--- a/charts/descheduler/templates/clusterrolebinding.yaml
+++ b/charts/descheduler/templates/clusterrolebinding.yaml
@@ -12,5 +12,5 @@ roleRef:
 subjects:
   - kind: ServiceAccount
     name: {{ template "descheduler.serviceAccountName" . }}
-    namespace: {{ include "descheduler.namespace" . }}
+    namespace: {{ .Release.Namespace }}
 {{- end -}}
diff --git a/charts/descheduler/templates/configmap.yaml b/charts/descheduler/templates/configmap.yaml
index a74aef610..ecd69cb3c 100644
--- a/charts/descheduler/templates/configmap.yaml
+++ b/charts/descheduler/templates/configmap.yaml
@@ -3,7 +3,7 @@ apiVersion: v1
 kind: ConfigMap
 metadata:
   name: {{ template "descheduler.fullname" . }}
-  namespace: {{ include "descheduler.namespace" . }}
+  namespace: {{ .Release.Namespace }}
   labels:
     {{- include "descheduler.labels" . | nindent 4 }}
 data:
diff --git a/charts/descheduler/templates/cronjob.yaml b/charts/descheduler/templates/cronjob.yaml
index cbfeca75b..9d18adf09 100644
--- a/charts/descheduler/templates/cronjob.yaml
+++ b/charts/descheduler/templates/cronjob.yaml
@@ -3,7 +3,7 @@ apiVersion: {{ .Values.cronJobApiVersion | default "batch/v1" }}
 kind: CronJob
 metadata:
   name: {{ template "descheduler.fullname" . }}
-  namespace: {{ include "descheduler.namespace" . }}
+  namespace: {{ .Release.Namespace }}
   labels:
     {{- include "descheduler.labels" . | nindent 4 }}
 spec:
diff --git a/charts/descheduler/templates/deployment.yaml b/charts/descheduler/templates/deployment.yaml
index 7820a2733..53d18cb66 100644
--- a/charts/descheduler/templates/deployment.yaml
+++ b/charts/descheduler/templates/deployment.yaml
@@ -3,7 +3,7 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   name: {{ template "descheduler.fullname" . }}
-  namespace: {{ include "descheduler.namespace" . }}
+  namespace: {{ .Release.Namespace }}
   labels:
     {{- include "descheduler.labels" . | nindent 4 }}
 spec:
diff --git a/charts/descheduler/templates/service.yaml b/charts/descheduler/templates/service.yaml
index 7c9a765f3..3faa5ce29 100644
--- a/charts/descheduler/templates/service.yaml
+++ b/charts/descheduler/templates/service.yaml
@@ -6,7 +6,7 @@ metadata:
   labels:
     {{- include "descheduler.labels" . | nindent 4 }}
   name: {{ template "descheduler.fullname" . }}
-  namespace: {{ include "descheduler.namespace" . }}
+  namespace: {{ .Release.Namespace }}
 spec:
   clusterIP: None
   {{- if .Values.service.ipFamilyPolicy }}
diff --git a/charts/descheduler/templates/serviceaccount.yaml b/charts/descheduler/templates/serviceaccount.yaml
index 7c56471d9..325fb8104 100644
--- a/charts/descheduler/templates/serviceaccount.yaml
+++ b/charts/descheduler/templates/serviceaccount.yaml
@@ -3,7 +3,7 @@ apiVersion: v1
 kind: ServiceAccount
 metadata:
   name: {{ template "descheduler.serviceAccountName" . }}
-  namespace: {{ include "descheduler.namespace" . }}
+  namespace: {{ .Release.Namespace }}
   labels:
     {{- include "descheduler.labels" . | nindent 4 }}
 {{- if .Values.serviceAccount.annotations }}
diff --git a/charts/descheduler/templates/servicemonitor.yaml b/charts/descheduler/templates/servicemonitor.yaml
index 4824069a8..25d980468 100644
--- a/charts/descheduler/templates/servicemonitor.yaml
+++ b/charts/descheduler/templates/servicemonitor.yaml
@@ -14,7 +14,7 @@ spec:
   jobLabel: jobLabel
   namespaceSelector:
     matchNames:
-    - {{ include "descheduler.namespace" . }}
+    - {{ .Release.Namespace }}
   selector:
     matchLabels:
       {{- include "descheduler.selectorLabels" . | nindent 6 }}
diff --git a/charts/descheduler/values.yaml b/charts/descheduler/values.yaml
index b6b529614..5d86f066f 100644
--- a/charts/descheduler/values.yaml
+++ b/charts/descheduler/values.yaml
@@ -39,9 +39,6 @@ podSecurityContext: {}
 nameOverride: ""
 fullnameOverride: ""
 
-# -- Override the deployment namespace; defaults to .Release.Namespace
-namespaceOverride: ""
-
 # labels that'll be applied to all resources
 commonLabels: {}
 
@@ -73,7 +70,7 @@ leaderElection: {}
 #  retryPeriod: 2s
 #  resourceLock: "leases"
 #  resourceName: "descheduler"
-#  resourceNamescape: "kube-system"
+#  resourceNamespace: "kube-system"
 
 command:
 - "/bin/descheduler"
diff --git a/docs/deprecated/v1alpha1.md b/docs/deprecated/v1alpha1.md
index c68c50639..3e2956525 100644
--- a/docs/deprecated/v1alpha1.md
+++ b/docs/deprecated/v1alpha1.md
@@ -109,17 +109,17 @@ See the [resources | Kustomize](https://kubectl.docs.kubernetes.io/references/ku
 
 Run As A Job
 ```
-kustomize build 'github.com/kubernetes-sigs/descheduler/kubernetes/job?ref=v0.30.1' | kubectl apply -f -
+kustomize build 'github.com/kubernetes-sigs/descheduler/kubernetes/job?ref=v0.30.0' | kubectl apply -f -
 ```
 
 Run As A CronJob
 ```
-kustomize build 'github.com/kubernetes-sigs/descheduler/kubernetes/cronjob?ref=v0.30.1' | kubectl apply -f -
+kustomize build 'github.com/kubernetes-sigs/descheduler/kubernetes/cronjob?ref=v0.30.0' | kubectl apply -f -
 ```
 
 Run As A Deployment
 ```
-kustomize build 'github.com/kubernetes-sigs/descheduler/kubernetes/deployment?ref=v0.30.1' | kubectl apply -f -
+kustomize build 'github.com/kubernetes-sigs/descheduler/kubernetes/deployment?ref=v0.30.0' | kubectl apply -f -
 ```
 
 ## User Guide
diff --git a/docs/user-guide.md b/docs/user-guide.md
index 2930e7f45..da9e0a784 100644
--- a/docs/user-guide.md
+++ b/docs/user-guide.md
@@ -4,7 +4,6 @@ Starting with descheduler release v0.10.0 container images are available in the
 
 Descheduler Version | Container Image                                 | Architectures           |
 ------------------- |-------------------------------------------------|-------------------------|
-v0.30.1             | registry.k8s.io/descheduler/descheduler:v0.30.1 | AMD64<br>ARM64<br>ARMv7 |
 v0.30.0             | registry.k8s.io/descheduler/descheduler:v0.30.0 | AMD64<br>ARM64<br>ARMv7 |
 v0.29.0             | registry.k8s.io/descheduler/descheduler:v0.29.0 | AMD64<br>ARM64<br>ARMv7 |
 v0.28.1             | registry.k8s.io/descheduler/descheduler:v0.28.1 | AMD64<br>ARM64<br>ARMv7 |
diff --git a/go.mod b/go.mod
index e5e36abc1..cfb08d6c3 100644
--- a/go.mod
+++ b/go.mod
@@ -21,7 +21,7 @@ require (
 	k8s.io/component-base v0.30.0
 	k8s.io/component-helpers v0.30.0
 	k8s.io/klog/v2 v2.120.1
-	k8s.io/utils v0.0.0-20240711033017-18e509b52bc8
+	k8s.io/utils v0.0.0-20240310230437-4693a0247e57
 	sigs.k8s.io/mdtoc v1.1.0
 )
 
diff --git a/go.sum b/go.sum
index 9ebc7c5d4..36472a674 100644
--- a/go.sum
+++ b/go.sum
@@ -334,8 +334,8 @@ k8s.io/kms v0.30.0 h1:ZlnD/ei5lpvUlPw6eLfVvH7d8i9qZ6HwUQgydNVks8g=
 k8s.io/kms v0.30.0/go.mod h1:GrMurD0qk3G4yNgGcsCEmepqf9KyyIrTXYR2lyUOJC4=
 k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag=
 k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98=
-k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A=
-k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
+k8s.io/utils v0.0.0-20240310230437-4693a0247e57 h1:gbqbevonBh57eILzModw6mrkbwM0gQBEuevE/AaBsHY=
+k8s.io/utils v0.0.0-20240310230437-4693a0247e57/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
 sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.29.0 h1:/U5vjBbQn3RChhv7P11uhYvCSm5G2GaIi5AIGBS6r4c=
 sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.29.0/go.mod h1:z7+wmGM2dfIiLRfrC6jb5kV2Mq/sK1ZP303cxzkV5Y4=
 sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
diff --git a/kubernetes/cronjob/cronjob.yaml b/kubernetes/cronjob/cronjob.yaml
index fb08a4043..689590db0 100644
--- a/kubernetes/cronjob/cronjob.yaml
+++ b/kubernetes/cronjob/cronjob.yaml
@@ -16,7 +16,7 @@ spec:
           priorityClassName: system-cluster-critical
           containers:
           - name: descheduler
-            image: registry.k8s.io/descheduler/descheduler:v0.30.1
+            image: registry.k8s.io/descheduler/descheduler:v0.30.0
             volumeMounts:
             - mountPath: /policy-dir
               name: policy-volume
diff --git a/kubernetes/deployment/deployment.yaml b/kubernetes/deployment/deployment.yaml
index c7da89bd8..718b44d1e 100644
--- a/kubernetes/deployment/deployment.yaml
+++ b/kubernetes/deployment/deployment.yaml
@@ -19,7 +19,7 @@ spec:
       serviceAccountName: descheduler-sa
       containers:
         - name: descheduler
-          image: registry.k8s.io/descheduler/descheduler:v0.30.1
+          image: registry.k8s.io/descheduler/descheduler:v0.30.0
           imagePullPolicy: IfNotPresent
           command:
             - "/bin/descheduler"
diff --git a/kubernetes/job/job.yaml b/kubernetes/job/job.yaml
index 119f03c5c..ae62c4cb5 100644
--- a/kubernetes/job/job.yaml
+++ b/kubernetes/job/job.yaml
@@ -14,7 +14,7 @@ spec:
       priorityClassName: system-cluster-critical
       containers:
         - name: descheduler
-          image: registry.k8s.io/descheduler/descheduler:v0.30.1
+          image: registry.k8s.io/descheduler/descheduler:v0.30.0
           volumeMounts:
           - mountPath: /policy-dir
             name: policy-volume
diff --git a/pkg/api/types.go b/pkg/api/types.go
index c729b5e2a..f874c3dd8 100644
--- a/pkg/api/types.go
+++ b/pkg/api/types.go
@@ -38,9 +38,6 @@ type DeschedulerPolicy struct {
 
 	// MaxNoOfPodsToEvictPerNamespace restricts maximum of pods to be evicted per namespace.
 	MaxNoOfPodsToEvictPerNamespace *uint
-
-	// MaxNoOfPodsToTotal restricts maximum of pods to be evicted total.
-	MaxNoOfPodsToEvictTotal *uint
 }
 
 // Namespaces carries a list of included/excluded namespaces
diff --git a/pkg/api/v1alpha1/conversion.go b/pkg/api/v1alpha1/conversion.go
index b8cf87e8f..bb15cf978 100644
--- a/pkg/api/v1alpha1/conversion.go
+++ b/pkg/api/v1alpha1/conversion.go
@@ -64,10 +64,14 @@ func (ei *evictorImpl) PreEvictionFilter(pod *v1.Pod) bool {
 }
 
 // Evict evicts a pod (no pre-check performed)
-func (ei *evictorImpl) Evict(ctx context.Context, pod *v1.Pod, opts evictions.EvictOptions) error {
+func (ei *evictorImpl) Evict(ctx context.Context, pod *v1.Pod, opts evictions.EvictOptions) bool {
 	return ei.podEvictor.EvictPod(ctx, pod, opts)
 }
 
+func (ei *evictorImpl) NodeLimitExceeded(node *v1.Node) bool {
+	return ei.podEvictor.NodeLimitExceeded(node)
+}
+
 // handleImpl implements the framework handle which gets passed to plugins
 type handleImpl struct {
 	clientSet                 clientset.Interface
diff --git a/pkg/api/v1alpha1/strategymigration.go b/pkg/api/v1alpha1/strategymigration.go
index e43243bb6..5dbe0a324 100644
--- a/pkg/api/v1alpha1/strategymigration.go
+++ b/pkg/api/v1alpha1/strategymigration.go
@@ -21,7 +21,7 @@ import (
 
 	v1 "k8s.io/api/core/v1"
 	"k8s.io/klog/v2"
-	utilptr "k8s.io/utils/ptr"
+	utilpointer "k8s.io/utils/pointer"
 	"sigs.k8s.io/descheduler/pkg/api"
 	"sigs.k8s.io/descheduler/pkg/framework/plugins/nodeutilization"
 	"sigs.k8s.io/descheduler/pkg/framework/plugins/podlifetime"
@@ -180,7 +180,7 @@ var StrategyParamsToPluginArgs = map[string]func(params *StrategyParameters) (*a
 			Namespaces:             v1alpha1NamespacesToInternal(params.Namespaces),
 			LabelSelector:          params.LabelSelector,
 			Constraints:            constraints,
-			TopologyBalanceNodeFit: utilptr.To(true),
+			TopologyBalanceNodeFit: utilpointer.Bool(true),
 		}
 		if err := removepodsviolatingtopologyspreadconstraint.ValidateRemovePodsViolatingTopologySpreadConstraintArgs(args); err != nil {
 			klog.ErrorS(err, "unable to validate plugin arguments", "pluginName", removepodsviolatingtopologyspreadconstraint.PluginName)
diff --git a/pkg/api/v1alpha1/types.go b/pkg/api/v1alpha1/types.go
index 11011e968..fb0ccc28a 100644
--- a/pkg/api/v1alpha1/types.go
+++ b/pkg/api/v1alpha1/types.go
@@ -52,9 +52,6 @@ type DeschedulerPolicy struct {
 
 	// MaxNoOfPodsToEvictPerNamespace restricts maximum of pods to be evicted per namespace.
 	MaxNoOfPodsToEvictPerNamespace *uint `json:"maxNoOfPodsToEvictPerNamespace,omitempty"`
-
-	// MaxNoOfPodsToTotal restricts maximum of pods to be evicted total.
-	MaxNoOfPodsToEvictTotal *uint `json:"maxNoOfPodsToEvictTotal,omitempty"`
 }
 
 type (
diff --git a/pkg/api/v1alpha1/zz_generated.deepcopy.go b/pkg/api/v1alpha1/zz_generated.deepcopy.go
index 33d1e39f6..fb57c89f7 100644
--- a/pkg/api/v1alpha1/zz_generated.deepcopy.go
+++ b/pkg/api/v1alpha1/zz_generated.deepcopy.go
@@ -77,11 +77,6 @@ func (in *DeschedulerPolicy) DeepCopyInto(out *DeschedulerPolicy) {
 		*out = new(uint)
 		**out = **in
 	}
-	if in.MaxNoOfPodsToEvictTotal != nil {
-		in, out := &in.MaxNoOfPodsToEvictTotal, &out.MaxNoOfPodsToEvictTotal
-		*out = new(uint)
-		**out = **in
-	}
 	return
 }
 
diff --git a/pkg/api/v1alpha2/types.go b/pkg/api/v1alpha2/types.go
index d663efb86..72c7949d2 100644
--- a/pkg/api/v1alpha2/types.go
+++ b/pkg/api/v1alpha2/types.go
@@ -37,9 +37,6 @@ type DeschedulerPolicy struct {
 
 	// MaxNoOfPodsToEvictPerNamespace restricts maximum of pods to be evicted per namespace.
 	MaxNoOfPodsToEvictPerNamespace *uint `json:"maxNoOfPodsToEvictPerNamespace,omitempty"`
-
-	// MaxNoOfPodsToTotal restricts maximum of pods to be evicted total.
-	MaxNoOfPodsToEvictTotal *uint `json:"maxNoOfPodsToEvictTotal,omitempty"`
 }
 
 type DeschedulerProfile struct {
diff --git a/pkg/api/v1alpha2/zz_generated.conversion.go b/pkg/api/v1alpha2/zz_generated.conversion.go
index a13151ed2..c40500043 100644
--- a/pkg/api/v1alpha2/zz_generated.conversion.go
+++ b/pkg/api/v1alpha2/zz_generated.conversion.go
@@ -104,7 +104,6 @@ func autoConvert_v1alpha2_DeschedulerPolicy_To_api_DeschedulerPolicy(in *Desched
 	out.NodeSelector = (*string)(unsafe.Pointer(in.NodeSelector))
 	out.MaxNoOfPodsToEvictPerNode = (*uint)(unsafe.Pointer(in.MaxNoOfPodsToEvictPerNode))
 	out.MaxNoOfPodsToEvictPerNamespace = (*uint)(unsafe.Pointer(in.MaxNoOfPodsToEvictPerNamespace))
-	out.MaxNoOfPodsToEvictTotal = (*uint)(unsafe.Pointer(in.MaxNoOfPodsToEvictTotal))
 	return nil
 }
 
@@ -123,7 +122,6 @@ func autoConvert_api_DeschedulerPolicy_To_v1alpha2_DeschedulerPolicy(in *api.Des
 	out.NodeSelector = (*string)(unsafe.Pointer(in.NodeSelector))
 	out.MaxNoOfPodsToEvictPerNode = (*uint)(unsafe.Pointer(in.MaxNoOfPodsToEvictPerNode))
 	out.MaxNoOfPodsToEvictPerNamespace = (*uint)(unsafe.Pointer(in.MaxNoOfPodsToEvictPerNamespace))
-	out.MaxNoOfPodsToEvictTotal = (*uint)(unsafe.Pointer(in.MaxNoOfPodsToEvictTotal))
 	return nil
 }
 
diff --git a/pkg/api/v1alpha2/zz_generated.deepcopy.go b/pkg/api/v1alpha2/zz_generated.deepcopy.go
index a0129fd8e..af73d5023 100644
--- a/pkg/api/v1alpha2/zz_generated.deepcopy.go
+++ b/pkg/api/v1alpha2/zz_generated.deepcopy.go
@@ -51,11 +51,6 @@ func (in *DeschedulerPolicy) DeepCopyInto(out *DeschedulerPolicy) {
 		*out = new(uint)
 		**out = **in
 	}
-	if in.MaxNoOfPodsToEvictTotal != nil {
-		in, out := &in.MaxNoOfPodsToEvictTotal, &out.MaxNoOfPodsToEvictTotal
-		*out = new(uint)
-		**out = **in
-	}
 	return
 }
 
diff --git a/pkg/api/zz_generated.deepcopy.go b/pkg/api/zz_generated.deepcopy.go
index 2f84cf1ed..c4abcbf94 100644
--- a/pkg/api/zz_generated.deepcopy.go
+++ b/pkg/api/zz_generated.deepcopy.go
@@ -51,11 +51,6 @@ func (in *DeschedulerPolicy) DeepCopyInto(out *DeschedulerPolicy) {
 		*out = new(uint)
 		**out = **in
 	}
-	if in.MaxNoOfPodsToEvictTotal != nil {
-		in, out := &in.MaxNoOfPodsToEvictTotal, &out.MaxNoOfPodsToEvictTotal
-		*out = new(uint)
-		**out = **in
-	}
 	return
 }
 
diff --git a/pkg/descheduler/client/client.go b/pkg/descheduler/client/client.go
index 964ed3b9b..2a8529d91 100644
--- a/pkg/descheduler/client/client.go
+++ b/pkg/descheduler/client/client.go
@@ -67,11 +67,11 @@ func GetMasterFromKubeconfig(filename string) (string, error) {
 
 	context, ok := config.Contexts[config.CurrentContext]
 	if !ok {
-		return "", fmt.Errorf("failed to get master address from kubeconfig: current context not found")
+		return "", fmt.Errorf("failed to get master address from kubeconfig")
 	}
 
 	if val, ok := config.Clusters[context.Cluster]; ok {
 		return val.Server, nil
 	}
-	return "", fmt.Errorf("failed to get master address from kubeconfig: cluster information not found")
+	return "", fmt.Errorf("failed to get master address from kubeconfig")
 }
diff --git a/pkg/descheduler/descheduler.go b/pkg/descheduler/descheduler.go
index 9b685d140..17b0b16e4 100644
--- a/pkg/descheduler/descheduler.go
+++ b/pkg/descheduler/descheduler.go
@@ -70,20 +70,19 @@ type profileRunner struct {
 }
 
 type descheduler struct {
-	rs                     *options.DeschedulerServer
-	podLister              listersv1.PodLister
-	nodeLister             listersv1.NodeLister
-	namespaceLister        listersv1.NamespaceLister
-	priorityClassLister    schedulingv1.PriorityClassLister
-	getPodsAssignedToNode  podutil.GetPodsAssignedToNodeFunc
-	sharedInformerFactory  informers.SharedInformerFactory
-	deschedulerPolicy      *api.DeschedulerPolicy
-	eventRecorder          events.EventRecorder
-	podEvictor             *evictions.PodEvictor
-	podEvictionReactionFnc func(*fakeclientset.Clientset) func(action core.Action) (bool, runtime.Object, error)
+	rs                         *options.DeschedulerServer
+	podLister                  listersv1.PodLister
+	nodeLister                 listersv1.NodeLister
+	namespaceLister            listersv1.NamespaceLister
+	priorityClassLister        schedulingv1.PriorityClassLister
+	getPodsAssignedToNode      podutil.GetPodsAssignedToNodeFunc
+	sharedInformerFactory      informers.SharedInformerFactory
+	evictionPolicyGroupVersion string
+	deschedulerPolicy          *api.DeschedulerPolicy
+	eventRecorder              events.EventRecorder
 }
 
-func newDescheduler(rs *options.DeschedulerServer, deschedulerPolicy *api.DeschedulerPolicy, evictionPolicyGroupVersion string, eventRecorder events.EventRecorder, sharedInformerFactory informers.SharedInformerFactory) (*descheduler, error) {
+func newDescheduler(ctx context.Context, rs *options.DeschedulerServer, deschedulerPolicy *api.DeschedulerPolicy, evictionPolicyGroupVersion string, eventRecorder events.EventRecorder, sharedInformerFactory informers.SharedInformerFactory) (*descheduler, error) {
 	podInformer := sharedInformerFactory.Core().V1().Pods().Informer()
 	podLister := sharedInformerFactory.Core().V1().Pods().Lister()
 	nodeLister := sharedInformerFactory.Core().V1().Nodes().Lister()
@@ -95,30 +94,17 @@ func newDescheduler(rs *options.DeschedulerServer, deschedulerPolicy *api.Desche
 		return nil, fmt.Errorf("build get pods assigned to node function error: %v", err)
 	}
 
-	podEvictor := evictions.NewPodEvictor(
-		nil,
-		eventRecorder,
-		evictions.NewOptions().
-			WithPolicyGroupVersion(evictionPolicyGroupVersion).
-			WithMaxPodsToEvictPerNode(deschedulerPolicy.MaxNoOfPodsToEvictPerNode).
-			WithMaxPodsToEvictPerNamespace(deschedulerPolicy.MaxNoOfPodsToEvictPerNamespace).
-			WithMaxPodsToEvictTotal(deschedulerPolicy.MaxNoOfPodsToEvictTotal).
-			WithDryRun(rs.DryRun).
-			WithMetricsEnabled(!rs.DisableMetrics),
-	)
-
 	return &descheduler{
-		rs:                     rs,
-		podLister:              podLister,
-		nodeLister:             nodeLister,
-		namespaceLister:        namespaceLister,
-		priorityClassLister:    priorityClassLister,
-		getPodsAssignedToNode:  getPodsAssignedToNode,
-		sharedInformerFactory:  sharedInformerFactory,
-		deschedulerPolicy:      deschedulerPolicy,
-		eventRecorder:          eventRecorder,
-		podEvictor:             podEvictor,
-		podEvictionReactionFnc: podEvictionReactionFnc,
+		rs:                         rs,
+		podLister:                  podLister,
+		nodeLister:                 nodeLister,
+		namespaceLister:            namespaceLister,
+		priorityClassLister:        priorityClassLister,
+		getPodsAssignedToNode:      getPodsAssignedToNode,
+		sharedInformerFactory:      sharedInformerFactory,
+		evictionPolicyGroupVersion: evictionPolicyGroupVersion,
+		deschedulerPolicy:          deschedulerPolicy,
+		eventRecorder:              eventRecorder,
 	}, nil
 }
 
@@ -143,10 +129,7 @@ func (d *descheduler) runDeschedulerLoop(ctx context.Context, nodes []*v1.Node)
 	if d.rs.DryRun {
 		klog.V(3).Infof("Building a cached client from the cluster for the dry run")
 		// Create a new cache so we start from scratch without any leftovers
-		fakeClient := fakeclientset.NewSimpleClientset()
-		// simulate a pod eviction by deleting a pod
-		fakeClient.PrependReactor("create", "pods", d.podEvictionReactionFnc(fakeClient))
-		err := cachedClient(d.rs.Client, fakeClient, d.podLister, d.nodeLister, d.namespaceLister, d.priorityClassLister)
+		fakeClient, err := cachedClient(d.rs.Client, d.podLister, d.nodeLister, d.namespaceLister, d.priorityClassLister)
 		if err != nil {
 			return err
 		}
@@ -170,13 +153,21 @@ func (d *descheduler) runDeschedulerLoop(ctx context.Context, nodes []*v1.Node)
 		client = d.rs.Client
 	}
 
-	klog.V(3).Infof("Setting up the pod evictor")
-	d.podEvictor.SetClient(client)
-	d.podEvictor.ResetCounters()
+	klog.V(3).Infof("Building a pod evictor")
+	podEvictor := evictions.NewPodEvictor(
+		client,
+		d.evictionPolicyGroupVersion,
+		d.rs.DryRun,
+		d.deschedulerPolicy.MaxNoOfPodsToEvictPerNode,
+		d.deschedulerPolicy.MaxNoOfPodsToEvictPerNamespace,
+		nodes,
+		!d.rs.DisableMetrics,
+		d.eventRecorder,
+	)
 
-	d.runProfiles(ctx, client, nodes)
+	d.runProfiles(ctx, client, nodes, podEvictor)
 
-	klog.V(1).InfoS("Number of evicted pods", "totalEvicted", d.podEvictor.TotalEvicted())
+	klog.V(1).InfoS("Number of evicted pods", "totalEvicted", podEvictor.TotalEvicted())
 
 	return nil
 }
@@ -184,7 +175,7 @@ func (d *descheduler) runDeschedulerLoop(ctx context.Context, nodes []*v1.Node)
 // runProfiles runs all the deschedule plugins of all profiles and
 // later runs through all balance plugins of all profiles. (All Balance plugins should come after all Deschedule plugins)
 // see https://github.com/kubernetes-sigs/descheduler/issues/979
-func (d *descheduler) runProfiles(ctx context.Context, client clientset.Interface, nodes []*v1.Node) {
+func (d *descheduler) runProfiles(ctx context.Context, client clientset.Interface, nodes []*v1.Node, podEvictor *evictions.PodEvictor) {
 	var span trace.Span
 	ctx, span = tracing.Tracer().Start(ctx, "runProfiles")
 	defer span.End()
@@ -195,7 +186,7 @@ func (d *descheduler) runProfiles(ctx context.Context, client clientset.Interfac
 			pluginregistry.PluginRegistry,
 			frameworkprofile.WithClientSet(client),
 			frameworkprofile.WithSharedInformerFactory(d.sharedInformerFactory),
-			frameworkprofile.WithPodEvictor(d.podEvictor),
+			frameworkprofile.WithPodEvictor(podEvictor),
 			frameworkprofile.WithGetPodsAssignedToNodeFnc(d.getPodsAssignedToNode),
 		)
 		if err != nil {
@@ -315,8 +306,16 @@ func validateVersionCompatibility(discovery discovery.DiscoveryInterface, versio
 	return nil
 }
 
-func podEvictionReactionFnc(fakeClient *fakeclientset.Clientset) func(action core.Action) (bool, runtime.Object, error) {
-	return func(action core.Action) (bool, runtime.Object, error) {
+func cachedClient(
+	realClient clientset.Interface,
+	podLister listersv1.PodLister,
+	nodeLister listersv1.NodeLister,
+	namespaceLister listersv1.NamespaceLister,
+	priorityClassLister schedulingv1.PriorityClassLister,
+) (clientset.Interface, error) {
+	fakeClient := fakeclientset.NewSimpleClientset()
+	// simulate a pod eviction by deleting a pod
+	fakeClient.PrependReactor("create", "pods", func(action core.Action) (bool, runtime.Object, error) {
 		if action.GetSubresource() == "eviction" {
 			createAct, matched := action.(core.CreateActionImpl)
 			if !matched {
@@ -333,63 +332,54 @@ func podEvictionReactionFnc(fakeClient *fakeclientset.Clientset) func(action cor
 		}
 		// fallback to the default reactor
 		return false, nil, nil
-	}
-}
+	})
 
-func cachedClient(
-	realClient clientset.Interface,
-	fakeClient *fakeclientset.Clientset,
-	podLister listersv1.PodLister,
-	nodeLister listersv1.NodeLister,
-	namespaceLister listersv1.NamespaceLister,
-	priorityClassLister schedulingv1.PriorityClassLister,
-) error {
 	klog.V(3).Infof("Pulling resources for the cached client from the cluster")
 	pods, err := podLister.List(labels.Everything())
 	if err != nil {
-		return fmt.Errorf("unable to list pods: %v", err)
+		return nil, fmt.Errorf("unable to list pods: %v", err)
 	}
 
 	for _, item := range pods {
 		if _, err := fakeClient.CoreV1().Pods(item.Namespace).Create(context.TODO(), item, metav1.CreateOptions{}); err != nil {
-			return fmt.Errorf("unable to copy pod: %v", err)
+			return nil, fmt.Errorf("unable to copy pod: %v", err)
 		}
 	}
 
 	nodes, err := nodeLister.List(labels.Everything())
 	if err != nil {
-		return fmt.Errorf("unable to list nodes: %v", err)
+		return nil, fmt.Errorf("unable to list nodes: %v", err)
 	}
 
 	for _, item := range nodes {
 		if _, err := fakeClient.CoreV1().Nodes().Create(context.TODO(), item, metav1.CreateOptions{}); err != nil {
-			return fmt.Errorf("unable to copy node: %v", err)
+			return nil, fmt.Errorf("unable to copy node: %v", err)
 		}
 	}
 
 	namespaces, err := namespaceLister.List(labels.Everything())
 	if err != nil {
-		return fmt.Errorf("unable to list namespaces: %v", err)
+		return nil, fmt.Errorf("unable to list namespaces: %v", err)
 	}
 
 	for _, item := range namespaces {
 		if _, err := fakeClient.CoreV1().Namespaces().Create(context.TODO(), item, metav1.CreateOptions{}); err != nil {
-			return fmt.Errorf("unable to copy namespace: %v", err)
+			return nil, fmt.Errorf("unable to copy namespace: %v", err)
 		}
 	}
 
 	priorityClasses, err := priorityClassLister.List(labels.Everything())
 	if err != nil {
-		return fmt.Errorf("unable to list priorityclasses: %v", err)
+		return nil, fmt.Errorf("unable to list priorityclasses: %v", err)
 	}
 
 	for _, item := range priorityClasses {
 		if _, err := fakeClient.SchedulingV1().PriorityClasses().Create(context.TODO(), item, metav1.CreateOptions{}); err != nil {
-			return fmt.Errorf("unable to copy priorityclass: %v", err)
+			return nil, fmt.Errorf("unable to copy priorityclass: %v", err)
 		}
 	}
 
-	return nil
+	return fakeClient, nil
 }
 
 func RunDeschedulerStrategies(ctx context.Context, rs *options.DeschedulerServer, deschedulerPolicy *api.DeschedulerPolicy, evictionPolicyGroupVersion string) error {
@@ -398,6 +388,7 @@ func RunDeschedulerStrategies(ctx context.Context, rs *options.DeschedulerServer
 	defer span.End()
 
 	sharedInformerFactory := informers.NewSharedInformerFactoryWithOptions(rs.Client, 0, informers.WithTransform(trimManagedFields))
+	nodeLister := sharedInformerFactory.Core().V1().Nodes().Lister()
 
 	var nodeSelector string
 	if deschedulerPolicy.NodeSelector != nil {
@@ -413,7 +404,7 @@ func RunDeschedulerStrategies(ctx context.Context, rs *options.DeschedulerServer
 	eventBroadcaster, eventRecorder := utils.GetRecorderAndBroadcaster(ctx, eventClient)
 	defer eventBroadcaster.Shutdown()
 
-	descheduler, err := newDescheduler(rs, deschedulerPolicy, evictionPolicyGroupVersion, eventRecorder, sharedInformerFactory)
+	descheduler, err := newDescheduler(ctx, rs, deschedulerPolicy, evictionPolicyGroupVersion, eventRecorder, sharedInformerFactory)
 	if err != nil {
 		span.AddEvent("Failed to create new descheduler", trace.WithAttributes(attribute.String("err", err.Error())))
 		return err
@@ -428,7 +419,7 @@ func RunDeschedulerStrategies(ctx context.Context, rs *options.DeschedulerServer
 		// A next context is created here intentionally to avoid nesting the spans via context.
 		sCtx, sSpan := tracing.Tracer().Start(ctx, "NonSlidingUntil")
 		defer sSpan.End()
-		nodes, err := nodeutil.ReadyNodes(sCtx, rs.Client, descheduler.nodeLister, nodeSelector)
+		nodes, err := nodeutil.ReadyNodes(sCtx, rs.Client, nodeLister, nodeSelector)
 		if err != nil {
 			sSpan.AddEvent("Failed to detect ready nodes", trace.WithAttributes(attribute.String("err", err.Error())))
 			klog.Error(err)
diff --git a/pkg/descheduler/evictions/errors.go b/pkg/descheduler/evictions/errors.go
deleted file mode 100644
index 0bba293c9..000000000
--- a/pkg/descheduler/evictions/errors.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package evictions
-
-type EvictionNodeLimitError struct {
-	node string
-}
-
-func (e EvictionNodeLimitError) Error() string {
-	return "maximum number of evicted pods per node reached"
-}
-
-func NewEvictionNodeLimitError(node string) *EvictionNodeLimitError {
-	return &EvictionNodeLimitError{
-		node: node,
-	}
-}
-
-var _ error = &EvictionNodeLimitError{}
-
-type EvictionNamespaceLimitError struct {
-	namespace string
-}
-
-func (e EvictionNamespaceLimitError) Error() string {
-	return "maximum number of evicted pods per namespace reached"
-}
-
-func NewEvictionNamespaceLimitError(namespace string) *EvictionNamespaceLimitError {
-	return &EvictionNamespaceLimitError{
-		namespace: namespace,
-	}
-}
-
-var _ error = &EvictionNamespaceLimitError{}
-
-type EvictionTotalLimitError struct{}
-
-func (e EvictionTotalLimitError) Error() string {
-	return "maximum number of evicted pods per a descheduling cycle reached"
-}
-
-func NewEvictionTotalLimitError() *EvictionTotalLimitError {
-	return &EvictionTotalLimitError{}
-}
-
-var _ error = &EvictionTotalLimitError{}
diff --git a/pkg/descheduler/evictions/evictions.go b/pkg/descheduler/evictions/evictions.go
index 04b242702..ffbf287df 100644
--- a/pkg/descheduler/evictions/evictions.go
+++ b/pkg/descheduler/evictions/evictions.go
@@ -19,7 +19,6 @@ package evictions
 import (
 	"context"
 	"fmt"
-	"sync"
 
 	"go.opentelemetry.io/otel/attribute"
 	"go.opentelemetry.io/otel/trace"
@@ -43,69 +42,69 @@ type (
 )
 
 type PodEvictor struct {
-	mu                         sync.Mutex
 	client                     clientset.Interface
+	nodes                      []*v1.Node
 	policyGroupVersion         string
 	dryRun                     bool
 	maxPodsToEvictPerNode      *uint
 	maxPodsToEvictPerNamespace *uint
-	maxPodsToEvictTotal        *uint
-	nodePodCount               nodePodEvictedCount
+	nodepodCount               nodePodEvictedCount
 	namespacePodCount          namespacePodEvictCount
-	totalPodCount              uint
 	metricsEnabled             bool
 	eventRecorder              events.EventRecorder
 }
 
 func NewPodEvictor(
 	client clientset.Interface,
+	policyGroupVersion string,
+	dryRun bool,
+	maxPodsToEvictPerNode *uint,
+	maxPodsToEvictPerNamespace *uint,
+	nodes []*v1.Node,
+	metricsEnabled bool,
 	eventRecorder events.EventRecorder,
-	options *Options,
 ) *PodEvictor {
-	if options == nil {
-		options = NewOptions()
+	nodePodCount := make(nodePodEvictedCount)
+	namespacePodCount := make(namespacePodEvictCount)
+	for _, node := range nodes {
+		// Initialize podsEvicted till now with 0.
+		nodePodCount[node.Name] = 0
 	}
 
 	return &PodEvictor{
 		client:                     client,
+		nodes:                      nodes,
+		policyGroupVersion:         policyGroupVersion,
+		dryRun:                     dryRun,
+		maxPodsToEvictPerNode:      maxPodsToEvictPerNode,
+		maxPodsToEvictPerNamespace: maxPodsToEvictPerNamespace,
+		nodepodCount:               nodePodCount,
+		namespacePodCount:          namespacePodCount,
+		metricsEnabled:             metricsEnabled,
 		eventRecorder:              eventRecorder,
-		policyGroupVersion:         options.policyGroupVersion,
-		dryRun:                     options.dryRun,
-		maxPodsToEvictPerNode:      options.maxPodsToEvictPerNode,
-		maxPodsToEvictPerNamespace: options.maxPodsToEvictPerNamespace,
-		maxPodsToEvictTotal:        options.maxPodsToEvictTotal,
-		metricsEnabled:             options.metricsEnabled,
-		nodePodCount:               make(nodePodEvictedCount),
-		namespacePodCount:          make(namespacePodEvictCount),
 	}
 }
 
 // NodeEvicted gives a number of pods evicted for node
 func (pe *PodEvictor) NodeEvicted(node *v1.Node) uint {
-	pe.mu.Lock()
-	defer pe.mu.Unlock()
-	return pe.nodePodCount[node.Name]
+	return pe.nodepodCount[node.Name]
 }
 
 // TotalEvicted gives a number of pods evicted through all nodes
 func (pe *PodEvictor) TotalEvicted() uint {
-	pe.mu.Lock()
-	defer pe.mu.Unlock()
-	return pe.totalPodCount
-}
-
-func (pe *PodEvictor) ResetCounters() {
-	pe.mu.Lock()
-	defer pe.mu.Unlock()
-	pe.nodePodCount = make(nodePodEvictedCount)
-	pe.namespacePodCount = make(namespacePodEvictCount)
-	pe.totalPodCount = 0
+	var total uint
+	for _, count := range pe.nodepodCount {
+		total += count
+	}
+	return total
 }
 
-func (pe *PodEvictor) SetClient(client clientset.Interface) {
-	pe.mu.Lock()
-	defer pe.mu.Unlock()
-	pe.client = client
+// NodeLimitExceeded checks if the number of evictions for a node was exceeded
+func (pe *PodEvictor) NodeLimitExceeded(node *v1.Node) bool {
+	if pe.maxPodsToEvictPerNode != nil {
+		return pe.nodepodCount[node.Name] == *pe.maxPodsToEvictPerNode
+	}
+	return false
 }
 
 // EvictOptions provides a handle for passing additional info to EvictPod
@@ -120,43 +119,29 @@ type EvictOptions struct {
 
 // EvictPod evicts a pod while exercising eviction limits.
 // Returns true when the pod is evicted on the server side.
-func (pe *PodEvictor) EvictPod(ctx context.Context, pod *v1.Pod, opts EvictOptions) error {
-	pe.mu.Lock()
-	defer pe.mu.Unlock()
+func (pe *PodEvictor) EvictPod(ctx context.Context, pod *v1.Pod, opts EvictOptions) bool {
 	var span trace.Span
 	ctx, span = tracing.Tracer().Start(ctx, "EvictPod", trace.WithAttributes(attribute.String("podName", pod.Name), attribute.String("podNamespace", pod.Namespace), attribute.String("reason", opts.Reason), attribute.String("operation", tracing.EvictOperation)))
 	defer span.End()
 
-	if pe.maxPodsToEvictTotal != nil && pe.totalPodCount+1 > *pe.maxPodsToEvictTotal {
-		err := NewEvictionTotalLimitError()
-		if pe.metricsEnabled {
-			metrics.PodsEvicted.With(map[string]string{"result": err.Error(), "strategy": opts.StrategyName, "namespace": pod.Namespace, "node": pod.Spec.NodeName, "profile": opts.ProfileName}).Inc()
-		}
-		span.AddEvent("Eviction Failed", trace.WithAttributes(attribute.String("node", pod.Spec.NodeName), attribute.String("err", err.Error())))
-		klog.ErrorS(err, "Error evicting pod", "limit", *pe.maxPodsToEvictTotal)
-		return err
-	}
-
 	if pod.Spec.NodeName != "" {
-		if pe.maxPodsToEvictPerNode != nil && pe.nodePodCount[pod.Spec.NodeName]+1 > *pe.maxPodsToEvictPerNode {
-			err := NewEvictionNodeLimitError(pod.Spec.NodeName)
+		if pe.maxPodsToEvictPerNode != nil && pe.nodepodCount[pod.Spec.NodeName]+1 > *pe.maxPodsToEvictPerNode {
 			if pe.metricsEnabled {
-				metrics.PodsEvicted.With(map[string]string{"result": err.Error(), "strategy": opts.StrategyName, "namespace": pod.Namespace, "node": pod.Spec.NodeName, "profile": opts.ProfileName}).Inc()
+				metrics.PodsEvicted.With(map[string]string{"result": "maximum number of pods per node reached", "strategy": opts.StrategyName, "namespace": pod.Namespace, "node": pod.Spec.NodeName, "profile": opts.ProfileName}).Inc()
 			}
-			span.AddEvent("Eviction Failed", trace.WithAttributes(attribute.String("node", pod.Spec.NodeName), attribute.String("err", err.Error())))
-			klog.ErrorS(err, "Error evicting pod", "limit", *pe.maxPodsToEvictPerNode, "node", pod.Spec.NodeName)
-			return err
+			span.AddEvent("Eviction Failed", trace.WithAttributes(attribute.String("node", pod.Spec.NodeName), attribute.String("err", "Maximum number of evicted pods per node reached")))
+			klog.ErrorS(fmt.Errorf("maximum number of evicted pods per node reached"), "Error evicting pod", "limit", *pe.maxPodsToEvictPerNode, "node", pod.Spec.NodeName)
+			return false
 		}
 	}
 
 	if pe.maxPodsToEvictPerNamespace != nil && pe.namespacePodCount[pod.Namespace]+1 > *pe.maxPodsToEvictPerNamespace {
-		err := NewEvictionNamespaceLimitError(pod.Namespace)
 		if pe.metricsEnabled {
-			metrics.PodsEvicted.With(map[string]string{"result": err.Error(), "strategy": opts.StrategyName, "namespace": pod.Namespace, "node": pod.Spec.NodeName, "profile": opts.ProfileName}).Inc()
+			metrics.PodsEvicted.With(map[string]string{"result": "maximum number of pods per namespace reached", "strategy": opts.StrategyName, "namespace": pod.Namespace, "node": pod.Spec.NodeName, "profile": opts.ProfileName}).Inc()
 		}
-		span.AddEvent("Eviction Failed", trace.WithAttributes(attribute.String("node", pod.Spec.NodeName), attribute.String("err", err.Error())))
-		klog.ErrorS(err, "Error evicting pod", "limit", *pe.maxPodsToEvictPerNamespace, "namespace", pod.Namespace)
-		return err
+		span.AddEvent("Eviction Failed", trace.WithAttributes(attribute.String("node", pod.Spec.NodeName), attribute.String("err", "Maximum number of evicted pods per namespace reached")))
+		klog.ErrorS(fmt.Errorf("maximum number of evicted pods per namespace reached"), "Error evicting pod", "limit", *pe.maxPodsToEvictPerNamespace, "namespace", pod.Namespace)
+		return false
 	}
 
 	err := evictPod(ctx, pe.client, pod, pe.policyGroupVersion)
@@ -167,14 +152,13 @@ func (pe *PodEvictor) EvictPod(ctx context.Context, pod *v1.Pod, opts EvictOptio
 		if pe.metricsEnabled {
 			metrics.PodsEvicted.With(map[string]string{"result": "error", "strategy": opts.StrategyName, "namespace": pod.Namespace, "node": pod.Spec.NodeName, "profile": opts.ProfileName}).Inc()
 		}
-		return err
+		return false
 	}
 
 	if pod.Spec.NodeName != "" {
-		pe.nodePodCount[pod.Spec.NodeName]++
+		pe.nodepodCount[pod.Spec.NodeName]++
 	}
 	pe.namespacePodCount[pod.Namespace]++
-	pe.totalPodCount++
 
 	if pe.metricsEnabled {
 		metrics.PodsEvicted.With(map[string]string{"result": "success", "strategy": opts.StrategyName, "namespace": pod.Namespace, "node": pod.Spec.NodeName, "profile": opts.ProfileName}).Inc()
@@ -193,7 +177,7 @@ func (pe *PodEvictor) EvictPod(ctx context.Context, pod *v1.Pod, opts EvictOptio
 		}
 		pe.eventRecorder.Eventf(pod, nil, v1.EventTypeNormal, reason, "Descheduled", "pod evicted from %v node by sigs.k8s.io/descheduler", pod.Spec.NodeName)
 	}
-	return nil
+	return true
 }
 
 func evictPod(ctx context.Context, client clientset.Interface, pod *v1.Pod, policyGroupVersion string) error {
diff --git a/pkg/descheduler/evictions/options.go b/pkg/descheduler/evictions/options.go
deleted file mode 100644
index 267854ee4..000000000
--- a/pkg/descheduler/evictions/options.go
+++ /dev/null
@@ -1,51 +0,0 @@
-package evictions
-
-import (
-	policy "k8s.io/api/policy/v1"
-)
-
-type Options struct {
-	policyGroupVersion         string
-	dryRun                     bool
-	maxPodsToEvictPerNode      *uint
-	maxPodsToEvictPerNamespace *uint
-	maxPodsToEvictTotal        *uint
-	metricsEnabled             bool
-}
-
-// NewOptions returns an Options with default values.
-func NewOptions() *Options {
-	return &Options{
-		policyGroupVersion: policy.SchemeGroupVersion.String(),
-	}
-}
-
-func (o *Options) WithPolicyGroupVersion(policyGroupVersion string) *Options {
-	o.policyGroupVersion = policyGroupVersion
-	return o
-}
-
-func (o *Options) WithDryRun(dryRun bool) *Options {
-	o.dryRun = dryRun
-	return o
-}
-
-func (o *Options) WithMaxPodsToEvictPerNode(maxPodsToEvictPerNode *uint) *Options {
-	o.maxPodsToEvictPerNode = maxPodsToEvictPerNode
-	return o
-}
-
-func (o *Options) WithMaxPodsToEvictPerNamespace(maxPodsToEvictPerNamespace *uint) *Options {
-	o.maxPodsToEvictPerNamespace = maxPodsToEvictPerNamespace
-	return o
-}
-
-func (o *Options) WithMaxPodsToEvictTotal(maxPodsToEvictTotal *uint) *Options {
-	o.maxPodsToEvictTotal = maxPodsToEvictTotal
-	return o
-}
-
-func (o *Options) WithMetricsEnabled(metricsEnabled bool) *Options {
-	o.metricsEnabled = metricsEnabled
-	return o
-}
diff --git a/pkg/descheduler/node/node.go b/pkg/descheduler/node/node.go
index 2f0e58e89..d28328065 100644
--- a/pkg/descheduler/node/node.go
+++ b/pkg/descheduler/node/node.go
@@ -18,24 +18,20 @@ package node
 
 import (
 	"context"
-	"errors"
 	"fmt"
-	"sync/atomic"
 
 	v1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/labels"
+	utilerrors "k8s.io/apimachinery/pkg/util/errors"
 	clientset "k8s.io/client-go/kubernetes"
 	listersv1 "k8s.io/client-go/listers/core/v1"
-	"k8s.io/client-go/util/workqueue"
 	"k8s.io/klog/v2"
 	podutil "sigs.k8s.io/descheduler/pkg/descheduler/pod"
 	"sigs.k8s.io/descheduler/pkg/utils"
 )
 
-const workersCount = 100
-
 // ReadyNodes returns ready nodes irrespective of whether they are
 // schedulable or not.
 func ReadyNodes(ctx context.Context, client clientset.Interface, nodeLister listersv1.NodeLister, nodeSelector string) ([]*v1.Node, error) {
@@ -108,96 +104,90 @@ func IsReady(node *v1.Node) bool {
 // This function is used when the NodeFit pod filtering feature of the Descheduler is enabled.
 // This function currently considers a subset of the Kubernetes Scheduler's predicates when
 // deciding if a pod would fit on a node, but more predicates may be added in the future.
-// There should be no methods to modify nodes or pods in this method.
-func NodeFit(nodeIndexer podutil.GetPodsAssignedToNodeFunc, pod *v1.Pod, node *v1.Node) error {
+func NodeFit(nodeIndexer podutil.GetPodsAssignedToNodeFunc, pod *v1.Pod, node *v1.Node) []error {
 	// Check node selector and required affinity
+	var errors []error
 	if ok, err := utils.PodMatchNodeSelector(pod, node); err != nil {
-		return err
+		errors = append(errors, err)
 	} else if !ok {
-		return errors.New("pod node selector does not match the node label")
+		errors = append(errors, fmt.Errorf("pod node selector does not match the node label"))
 	}
-
 	// Check taints (we only care about NoSchedule and NoExecute taints)
 	ok := utils.TolerationsTolerateTaintsWithFilter(pod.Spec.Tolerations, node.Spec.Taints, func(taint *v1.Taint) bool {
 		return taint.Effect == v1.TaintEffectNoSchedule || taint.Effect == v1.TaintEffectNoExecute
 	})
 	if !ok {
-		return errors.New("pod does not tolerate taints on the node")
+		errors = append(errors, fmt.Errorf("pod does not tolerate taints on the node"))
 	}
-
 	// Check if the pod can fit on a node based off it's requests
 	if pod.Spec.NodeName == "" || pod.Spec.NodeName != node.Name {
-		if ok, reqError := fitsRequest(nodeIndexer, pod, node); !ok {
-			return reqError
+		if ok, reqErrors := fitsRequest(nodeIndexer, pod, node); !ok {
+			errors = append(errors, reqErrors...)
 		}
 	}
-
 	// Check if node is schedulable
 	if IsNodeUnschedulable(node) {
-		return errors.New("node is not schedulable")
+		errors = append(errors, fmt.Errorf("node is not schedulable"))
 	}
 
 	// Check if pod matches inter-pod anti-affinity rule of pod on node
 	if match, err := podMatchesInterPodAntiAffinity(nodeIndexer, pod, node); err != nil {
-		return err
+		errors = append(errors, err)
 	} else if match {
-		return errors.New("pod matches inter-pod anti-affinity rule of other pod on node")
+		errors = append(errors, fmt.Errorf("pod matches inter-pod anti-affinity rule of other pod on node"))
 	}
 
-	return nil
+	return errors
 }
 
-func podFitsNodes(nodeIndexer podutil.GetPodsAssignedToNodeFunc, pod *v1.Pod, nodes []*v1.Node, excludeFilter func(pod *v1.Pod, node *v1.Node) bool) bool {
-	ctx, cancel := context.WithCancel(context.Background())
-	defer cancel()
-
-	var filteredLen int32
-	checkNode := func(i int) {
-		node := nodes[i]
-		if excludeFilter != nil && excludeFilter(pod, node) {
-			return
+// PodFitsAnyOtherNode checks if the given pod will fit any of the given nodes, besides the node
+// the pod is already running on. The predicates used to determine if the pod will fit can be found in the NodeFit function.
+func PodFitsAnyOtherNode(nodeIndexer podutil.GetPodsAssignedToNodeFunc, pod *v1.Pod, nodes []*v1.Node) bool {
+	for _, node := range nodes {
+		// Skip node pod is already on
+		if node.Name == pod.Spec.NodeName {
+			continue
 		}
-		err := NodeFit(nodeIndexer, pod, node)
-		if err == nil {
+
+		errors := NodeFit(nodeIndexer, pod, node)
+		if len(errors) == 0 {
 			klog.V(4).InfoS("Pod fits on node", "pod", klog.KObj(pod), "node", klog.KObj(node))
-			atomic.AddInt32(&filteredLen, 1)
-			cancel()
-		} else {
-			klog.V(4).InfoS("Pod does not fit on node", "pod", klog.KObj(pod), "node", klog.KObj(node), "err", err.Error())
+			return true
 		}
+		klog.V(4).InfoS("Pod does not fit on any other node",
+			"pod:", klog.KObj(pod), "node:", klog.KObj(node), "error:", utilerrors.NewAggregate(errors).Error())
 	}
 
-	// Stops searching for more nodes once a node are found.
-	workqueue.ParallelizeUntil(ctx, workersCount, len(nodes), checkNode)
-
-	return filteredLen > 0
-}
-
-// PodFitsAnyOtherNode checks if the given pod will fit any of the given nodes, besides the node
-// the pod is already running on. The predicates used to determine if the pod will fit can be found in the NodeFit function.
-func PodFitsAnyOtherNode(nodeIndexer podutil.GetPodsAssignedToNodeFunc, pod *v1.Pod, nodes []*v1.Node) bool {
-	return podFitsNodes(nodeIndexer, pod, nodes, func(pod *v1.Pod, node *v1.Node) bool {
-		return pod.Spec.NodeName == node.Name
-	})
+	return false
 }
 
 // PodFitsAnyNode checks if the given pod will fit any of the given nodes. The predicates used
 // to determine if the pod will fit can be found in the NodeFit function.
 func PodFitsAnyNode(nodeIndexer podutil.GetPodsAssignedToNodeFunc, pod *v1.Pod, nodes []*v1.Node) bool {
-	return podFitsNodes(nodeIndexer, pod, nodes, nil)
+	for _, node := range nodes {
+		errors := NodeFit(nodeIndexer, pod, node)
+		if len(errors) == 0 {
+			klog.V(4).InfoS("Pod fits on node", "pod", klog.KObj(pod), "node", klog.KObj(node))
+			return true
+		}
+		klog.V(4).InfoS("Pod does not fit on any node",
+			"pod:", klog.KObj(pod), "node:", klog.KObj(node), "error:", utilerrors.NewAggregate(errors).Error())
+	}
+
+	return false
 }
 
 // PodFitsCurrentNode checks if the given pod will fit onto the given node. The predicates used
 // to determine if the pod will fit can be found in the NodeFit function.
 func PodFitsCurrentNode(nodeIndexer podutil.GetPodsAssignedToNodeFunc, pod *v1.Pod, node *v1.Node) bool {
-	err := NodeFit(nodeIndexer, pod, node)
-	if err == nil {
+	errors := NodeFit(nodeIndexer, pod, node)
+	if len(errors) == 0 {
 		klog.V(4).InfoS("Pod fits on node", "pod", klog.KObj(pod), "node", klog.KObj(node))
 		return true
 	}
 
 	klog.V(4).InfoS("Pod does not fit on current node",
-		"pod", klog.KObj(pod), "node", klog.KObj(node), "error", err)
+		"pod:", klog.KObj(pod), "node:", klog.KObj(node), "error:", utilerrors.NewAggregate(errors).Error())
 
 	return false
 }
@@ -210,7 +200,9 @@ func IsNodeUnschedulable(node *v1.Node) bool {
 
 // fitsRequest determines if a pod can fit on a node based on its resource requests. It returns true if
 // the pod will fit.
-func fitsRequest(nodeIndexer podutil.GetPodsAssignedToNodeFunc, pod *v1.Pod, node *v1.Node) (bool, error) {
+func fitsRequest(nodeIndexer podutil.GetPodsAssignedToNodeFunc, pod *v1.Pod, node *v1.Node) (bool, []error) {
+	var insufficientResources []error
+
 	// Get pod requests
 	podRequests, _ := utils.PodRequestsAndLimits(pod)
 	resourceNames := make([]v1.ResourceName, 0, len(podRequests))
@@ -220,22 +212,25 @@ func fitsRequest(nodeIndexer podutil.GetPodsAssignedToNodeFunc, pod *v1.Pod, nod
 
 	availableResources, err := nodeAvailableResources(nodeIndexer, node, resourceNames)
 	if err != nil {
-		return false, err
+		return false, []error{err}
 	}
 
+	podFitsOnNode := true
 	for _, resource := range resourceNames {
 		podResourceRequest := podRequests[resource]
 		availableResource, ok := availableResources[resource]
 		if !ok || podResourceRequest.MilliValue() > availableResource.MilliValue() {
-			return false, fmt.Errorf("insufficient %v", resource)
+			insufficientResources = append(insufficientResources, fmt.Errorf("insufficient %v", resource))
+			podFitsOnNode = false
 		}
 	}
 	// check pod num, at least one pod number is avaibalbe
 	if availableResources[v1.ResourcePods].MilliValue() <= 0 {
-		return false, fmt.Errorf("insufficient %v", v1.ResourcePods)
+		insufficientResources = append(insufficientResources, fmt.Errorf("insufficient %v", v1.ResourcePods))
+		podFitsOnNode = false
 	}
 
-	return true, nil
+	return podFitsOnNode, insufficientResources
 }
 
 // nodeAvailableResources returns resources mapped to the quanitity available on the node.
diff --git a/pkg/descheduler/pod/pods.go b/pkg/descheduler/pod/pods.go
index 1e7ef289b..e1aa8656b 100644
--- a/pkg/descheduler/pod/pods.go
+++ b/pkg/descheduler/pod/pods.go
@@ -99,6 +99,9 @@ func (o *Options) BuildFilterFunc() (FilterFunc, error) {
 		}
 	}
 	return func(pod *v1.Pod) bool {
+		if o.filter != nil && !o.filter(pod) {
+			return false
+		}
 		if len(o.includedNamespaces) > 0 && !o.includedNamespaces.Has(pod.Namespace) {
 			return false
 		}
@@ -108,9 +111,6 @@ func (o *Options) BuildFilterFunc() (FilterFunc, error) {
 		if s != nil && !s.Matches(labels.Set(pod.GetLabels())) {
 			return false
 		}
-		if o.filter != nil && !o.filter(pod) {
-			return false
-		}
 		return true
 	}, nil
 }
diff --git a/pkg/framework/fake/fake.go b/pkg/framework/fake/fake.go
index a16132d40..53a7c80b8 100644
--- a/pkg/framework/fake/fake.go
+++ b/pkg/framework/fake/fake.go
@@ -46,6 +46,10 @@ func (hi *HandleImpl) PreEvictionFilter(pod *v1.Pod) bool {
 	return hi.EvictorFilterImpl.PreEvictionFilter(pod)
 }
 
-func (hi *HandleImpl) Evict(ctx context.Context, pod *v1.Pod, opts evictions.EvictOptions) error {
+func (hi *HandleImpl) Evict(ctx context.Context, pod *v1.Pod, opts evictions.EvictOptions) bool {
 	return hi.PodEvictorImpl.EvictPod(ctx, pod, opts)
 }
+
+func (hi *HandleImpl) NodeLimitExceeded(node *v1.Node) bool {
+	return hi.PodEvictorImpl.NodeLimitExceeded(node)
+}
diff --git a/pkg/framework/plugins/defaultevictor/defaultevictor.go b/pkg/framework/plugins/defaultevictor/defaultevictor.go
index ff25ff5c0..f7e635562 100644
--- a/pkg/framework/plugins/defaultevictor/defaultevictor.go
+++ b/pkg/framework/plugins/defaultevictor/defaultevictor.go
@@ -244,15 +244,6 @@ func (d *DefaultEvictor) Filter(pod *v1.Pod) bool {
 
 func getPodIndexerByOwnerRefs(indexName string, handle frameworktypes.Handle) (cache.Indexer, error) {
 	podInformer := handle.SharedInformerFactory().Core().V1().Pods().Informer()
-	indexer := podInformer.GetIndexer()
-
-	// do not reinitialize the indexer, if it's been defined already
-	for name := range indexer.GetIndexers() {
-		if name == indexName {
-			return indexer, nil
-		}
-	}
-
 	if err := podInformer.AddIndexers(cache.Indexers{
 		indexName: func(obj interface{}) ([]string, error) {
 			pod, ok := obj.(*v1.Pod)
@@ -266,5 +257,6 @@ func getPodIndexerByOwnerRefs(indexName string, handle frameworktypes.Handle) (c
 		return nil, err
 	}
 
+	indexer := podInformer.GetIndexer()
 	return indexer, nil
 }
diff --git a/pkg/framework/plugins/nodeutilization/nodeutilization.go b/pkg/framework/plugins/nodeutilization/nodeutilization.go
index b3a352aad..b19e55cad 100644
--- a/pkg/framework/plugins/nodeutilization/nodeutilization.go
+++ b/pkg/framework/plugins/nodeutilization/nodeutilization.go
@@ -274,14 +274,8 @@ func evictPodsFromSourceNodes(
 		klog.V(1).InfoS("Evicting pods based on priority, if they have same priority, they'll be evicted based on QoS tiers")
 		// sort the evictable Pods based on priority. This also sorts them based on QoS. If there are multiple pods with same priority, they are sorted based on QoS tiers.
 		podutil.SortPodsBasedOnPriorityLowToHigh(removablePods)
-		err := evictPods(ctx, evictableNamespaces, removablePods, node, totalAvailableUsage, taintsOfDestinationNodes, podEvictor, evictOptions, continueEviction)
-		if err != nil {
-			switch err.(type) {
-			case *evictions.EvictionTotalLimitError:
-				return
-			default:
-			}
-		}
+		evictPods(ctx, evictableNamespaces, removablePods, node, totalAvailableUsage, taintsOfDestinationNodes, podEvictor, evictOptions, continueEviction)
+
 	}
 }
 
@@ -295,7 +289,7 @@ func evictPods(
 	podEvictor frameworktypes.Evictor,
 	evictOptions evictions.EvictOptions,
 	continueEviction continueEvictionCond,
-) error {
+) {
 	var excludedNamespaces sets.Set[string]
 	if evictableNamespaces != nil {
 		excludedNamespaces = sets.New(evictableNamespaces.Exclude...)
@@ -317,52 +311,45 @@ func evictPods(
 				continue
 			}
 
-			if !preEvictionFilterWithOptions(pod) {
-				continue
-			}
-			err = podEvictor.Evict(ctx, pod, evictOptions)
-			if err == nil {
-				klog.V(3).InfoS("Evicted pods", "pod", klog.KObj(pod))
-
-				for name := range totalAvailableUsage {
-					if name == v1.ResourcePods {
-						nodeInfo.usage[name].Sub(*resource.NewQuantity(1, resource.DecimalSI))
-						totalAvailableUsage[name].Sub(*resource.NewQuantity(1, resource.DecimalSI))
-					} else {
-						quantity := utils.GetResourceRequestQuantity(pod, name)
-						nodeInfo.usage[name].Sub(quantity)
-						totalAvailableUsage[name].Sub(quantity)
+			if preEvictionFilterWithOptions(pod) {
+				if podEvictor.Evict(ctx, pod, evictOptions) {
+					klog.V(3).InfoS("Evicted pods", "pod", klog.KObj(pod))
+
+					for name := range totalAvailableUsage {
+						if name == v1.ResourcePods {
+							nodeInfo.usage[name].Sub(*resource.NewQuantity(1, resource.DecimalSI))
+							totalAvailableUsage[name].Sub(*resource.NewQuantity(1, resource.DecimalSI))
+						} else {
+							quantity := utils.GetResourceRequestQuantity(pod, name)
+							nodeInfo.usage[name].Sub(quantity)
+							totalAvailableUsage[name].Sub(quantity)
+						}
 					}
-				}
 
-				keysAndValues := []interface{}{
-					"node", nodeInfo.node.Name,
-					"CPU", nodeInfo.usage[v1.ResourceCPU].MilliValue(),
-					"Mem", nodeInfo.usage[v1.ResourceMemory].Value(),
-					"Pods", nodeInfo.usage[v1.ResourcePods].Value(),
-				}
-				for name := range totalAvailableUsage {
-					if !nodeutil.IsBasicResource(name) {
-						keysAndValues = append(keysAndValues, string(name), totalAvailableUsage[name].Value())
+					keysAndValues := []interface{}{
+						"node", nodeInfo.node.Name,
+						"CPU", nodeInfo.usage[v1.ResourceCPU].MilliValue(),
+						"Mem", nodeInfo.usage[v1.ResourceMemory].Value(),
+						"Pods", nodeInfo.usage[v1.ResourcePods].Value(),
+					}
+					for name := range totalAvailableUsage {
+						if !nodeutil.IsBasicResource(name) {
+							keysAndValues = append(keysAndValues, string(name), totalAvailableUsage[name].Value())
+						}
 					}
-				}
 
-				klog.V(3).InfoS("Updated node usage", keysAndValues...)
-				// check if pods can be still evicted
-				if !continueEviction(nodeInfo, totalAvailableUsage) {
-					break
+					klog.V(3).InfoS("Updated node usage", keysAndValues...)
+					// check if pods can be still evicted
+					if !continueEviction(nodeInfo, totalAvailableUsage) {
+						break
+					}
 				}
-				continue
 			}
-			switch err.(type) {
-			case *evictions.EvictionNodeLimitError, *evictions.EvictionTotalLimitError:
-				return err
-			default:
-				klog.Errorf("eviction failed: %v", err)
+			if podEvictor.NodeLimitExceeded(nodeInfo.node) {
+				return
 			}
 		}
 	}
-	return nil
 }
 
 // sortNodesByUsage sorts nodes based on usage according to the given plugin.
diff --git a/pkg/framework/plugins/podlifetime/pod_lifetime.go b/pkg/framework/plugins/podlifetime/pod_lifetime.go
index 79f711f31..ecc8a118d 100644
--- a/pkg/framework/plugins/podlifetime/pod_lifetime.go
+++ b/pkg/framework/plugins/podlifetime/pod_lifetime.go
@@ -131,19 +131,9 @@ func (d *PodLifeTime) Deschedule(ctx context.Context, nodes []*v1.Node) *framewo
 	// in the event that PDB or settings such maxNoOfPodsToEvictPer* prevent too much eviction
 	podutil.SortPodsBasedOnAge(podsToEvict)
 
-loop:
 	for _, pod := range podsToEvict {
-		err := d.handle.Evictor().Evict(ctx, pod, evictions.EvictOptions{StrategyName: PluginName})
-		if err == nil {
-			continue
-		}
-		switch err.(type) {
-		case *evictions.EvictionNodeLimitError:
-			continue loop
-		case *evictions.EvictionTotalLimitError:
-			return nil
-		default:
-			klog.Errorf("eviction failed: %v", err)
+		if !d.handle.Evictor().NodeLimitExceeded(nodeMap[pod.Spec.NodeName]) {
+			d.handle.Evictor().Evict(ctx, pod, evictions.EvictOptions{StrategyName: PluginName})
 		}
 	}
 
diff --git a/pkg/framework/plugins/removeduplicates/removeduplicates.go b/pkg/framework/plugins/removeduplicates/removeduplicates.go
index 3d92ba8b0..1ad0ed2f5 100644
--- a/pkg/framework/plugins/removeduplicates/removeduplicates.go
+++ b/pkg/framework/plugins/removeduplicates/removeduplicates.go
@@ -210,17 +210,9 @@ func (r *RemoveDuplicates) Balance(ctx context.Context, nodes []*v1.Node) *frame
 				// It's assumed all duplicated pods are in the same priority class
 				// TODO(jchaloup): check if the pod has a different node to lend to
 				for _, pod := range pods[upperAvg-1:] {
-					err := r.handle.Evictor().Evict(ctx, pod, evictions.EvictOptions{StrategyName: PluginName})
-					if err == nil {
-						continue
-					}
-					switch err.(type) {
-					case *evictions.EvictionNodeLimitError:
+					r.handle.Evictor().Evict(ctx, pod, evictions.EvictOptions{StrategyName: PluginName})
+					if r.handle.Evictor().NodeLimitExceeded(nodeMap[nodeName]) {
 						continue loop
-					case *evictions.EvictionTotalLimitError:
-						return nil
-					default:
-						klog.Errorf("eviction failed: %v", err)
 					}
 				}
 			}
diff --git a/pkg/framework/plugins/removefailedpods/defaults.go b/pkg/framework/plugins/removefailedpods/defaults.go
index cd2e62d87..3fa38d165 100644
--- a/pkg/framework/plugins/removefailedpods/defaults.go
+++ b/pkg/framework/plugins/removefailedpods/defaults.go
@@ -15,7 +15,7 @@ package removefailedpods
 
 import (
 	"k8s.io/apimachinery/pkg/runtime"
-	utilptr "k8s.io/utils/ptr"
+	utilpointer "k8s.io/utils/pointer"
 )
 
 func addDefaultingFuncs(scheme *runtime.Scheme) error {
@@ -36,7 +36,7 @@ func SetDefaults_RemoveFailedPodsArgs(obj runtime.Object) {
 		args.ExcludeOwnerKinds = nil
 	}
 	if args.MinPodLifetimeSeconds == nil {
-		args.MinPodLifetimeSeconds = utilptr.To[uint](3600)
+		args.MinPodLifetimeSeconds = utilpointer.Uint(3600)
 	}
 	if args.Reasons == nil {
 		args.Reasons = nil
diff --git a/pkg/framework/plugins/removefailedpods/failedpods.go b/pkg/framework/plugins/removefailedpods/failedpods.go
index 8b1badc26..9eca25db4 100644
--- a/pkg/framework/plugins/removefailedpods/failedpods.go
+++ b/pkg/framework/plugins/removefailedpods/failedpods.go
@@ -102,19 +102,10 @@ func (d *RemoveFailedPods) Deschedule(ctx context.Context, nodes []*v1.Node) *fr
 			}
 		}
 		totalPods := len(pods)
-	loop:
 		for i := 0; i < totalPods; i++ {
-			err := d.handle.Evictor().Evict(ctx, pods[i], evictions.EvictOptions{StrategyName: PluginName})
-			if err == nil {
-				continue
-			}
-			switch err.(type) {
-			case *evictions.EvictionNodeLimitError:
-				break loop
-			case *evictions.EvictionTotalLimitError:
-				return nil
-			default:
-				klog.Errorf("eviction failed: %v", err)
+			d.handle.Evictor().Evict(ctx, pods[i], evictions.EvictOptions{StrategyName: PluginName})
+			if d.handle.Evictor().NodeLimitExceeded(node) {
+				break
 			}
 		}
 	}
diff --git a/pkg/framework/plugins/removepodshavingtoomanyrestarts/toomanyrestarts.go b/pkg/framework/plugins/removepodshavingtoomanyrestarts/toomanyrestarts.go
index fb9656971..6c8181834 100644
--- a/pkg/framework/plugins/removepodshavingtoomanyrestarts/toomanyrestarts.go
+++ b/pkg/framework/plugins/removepodshavingtoomanyrestarts/toomanyrestarts.go
@@ -122,19 +122,10 @@ func (d *RemovePodsHavingTooManyRestarts) Deschedule(ctx context.Context, nodes
 			}
 		}
 		totalPods := len(pods)
-	loop:
 		for i := 0; i < totalPods; i++ {
-			err := d.handle.Evictor().Evict(ctx, pods[i], evictions.EvictOptions{StrategyName: PluginName})
-			if err == nil {
-				continue
-			}
-			switch err.(type) {
-			case *evictions.EvictionNodeLimitError:
-				break loop
-			case *evictions.EvictionTotalLimitError:
-				return nil
-			default:
-				klog.Errorf("eviction failed: %v", err)
+			d.handle.Evictor().Evict(ctx, pods[i], evictions.EvictOptions{StrategyName: PluginName})
+			if d.handle.Evictor().NodeLimitExceeded(node) {
+				break
 			}
 		}
 	}
diff --git a/pkg/framework/plugins/removepodsviolatinginterpodantiaffinity/pod_antiaffinity.go b/pkg/framework/plugins/removepodsviolatinginterpodantiaffinity/pod_antiaffinity.go
index 476566a18..69e9c8eba 100644
--- a/pkg/framework/plugins/removepodsviolatinginterpodantiaffinity/pod_antiaffinity.go
+++ b/pkg/framework/plugins/removepodsviolatinginterpodantiaffinity/pod_antiaffinity.go
@@ -98,8 +98,7 @@ loop:
 		for i := 0; i < totalPods; i++ {
 			if utils.CheckPodsWithAntiAffinityExist(pods[i], podsInANamespace, nodeMap) {
 				if d.handle.Evictor().Filter(pods[i]) && d.handle.Evictor().PreEvictionFilter(pods[i]) {
-					err := d.handle.Evictor().Evict(ctx, pods[i], evictions.EvictOptions{StrategyName: PluginName})
-					if err == nil {
+					if d.handle.Evictor().Evict(ctx, pods[i], evictions.EvictOptions{StrategyName: PluginName}) {
 						// Since the current pod is evicted all other pods which have anti-affinity with this
 						// pod need not be evicted.
 						// Update allPods.
@@ -107,18 +106,12 @@ loop:
 						pods = append(pods[:i], pods[i+1:]...)
 						i--
 						totalPods--
-						continue
-					}
-					switch err.(type) {
-					case *evictions.EvictionNodeLimitError:
-						continue loop
-					case *evictions.EvictionTotalLimitError:
-						return nil
-					default:
-						klog.Errorf("eviction failed: %v", err)
 					}
 				}
 			}
+			if d.handle.Evictor().NodeLimitExceeded(node) {
+				continue loop
+			}
 		}
 	}
 	return nil
diff --git a/pkg/framework/plugins/removepodsviolatingnodeaffinity/node_affinity.go b/pkg/framework/plugins/removepodsviolatingnodeaffinity/node_affinity.go
index 586ce2218..96d1be1f0 100644
--- a/pkg/framework/plugins/removepodsviolatingnodeaffinity/node_affinity.go
+++ b/pkg/framework/plugins/removepodsviolatingnodeaffinity/node_affinity.go
@@ -134,20 +134,11 @@ func (d *RemovePodsViolatingNodeAffinity) processNodes(ctx context.Context, node
 			}
 		}
 
-	loop:
 		for _, pod := range pods {
 			klog.V(1).InfoS("Evicting pod", "pod", klog.KObj(pod))
-			err := d.handle.Evictor().Evict(ctx, pod, evictions.EvictOptions{StrategyName: PluginName})
-			if err == nil {
-				continue
-			}
-			switch err.(type) {
-			case *evictions.EvictionNodeLimitError:
-				break loop
-			case *evictions.EvictionTotalLimitError:
-				return nil
-			default:
-				klog.Errorf("eviction failed: %v", err)
+			d.handle.Evictor().Evict(ctx, pod, evictions.EvictOptions{StrategyName: PluginName})
+			if d.handle.Evictor().NodeLimitExceeded(node) {
+				break
 			}
 		}
 	}
diff --git a/pkg/framework/plugins/removepodsviolatingnodetaints/node_taint.go b/pkg/framework/plugins/removepodsviolatingnodetaints/node_taint.go
index e447a4662..ce8fabf07 100644
--- a/pkg/framework/plugins/removepodsviolatingnodetaints/node_taint.go
+++ b/pkg/framework/plugins/removepodsviolatingnodetaints/node_taint.go
@@ -114,7 +114,6 @@ func (d *RemovePodsViolatingNodeTaints) Deschedule(ctx context.Context, nodes []
 			}
 		}
 		totalPods := len(pods)
-	loop:
 		for i := 0; i < totalPods; i++ {
 			if !utils.TolerationsTolerateTaintsWithFilter(
 				pods[i].Spec.Tolerations,
@@ -122,17 +121,9 @@ func (d *RemovePodsViolatingNodeTaints) Deschedule(ctx context.Context, nodes []
 				d.taintFilterFnc,
 			) {
 				klog.V(2).InfoS("Not all taints with NoSchedule effect are tolerated after update for pod on node", "pod", klog.KObj(pods[i]), "node", klog.KObj(node))
-				err := d.handle.Evictor().Evict(ctx, pods[i], evictions.EvictOptions{StrategyName: PluginName})
-				if err == nil {
-					continue
-				}
-				switch err.(type) {
-				case *evictions.EvictionNodeLimitError:
-					break loop
-				case *evictions.EvictionTotalLimitError:
-					return nil
-				default:
-					klog.Errorf("eviction failed: %v", err)
+				d.handle.Evictor().Evict(ctx, pods[i], evictions.EvictOptions{StrategyName: PluginName})
+				if d.handle.Evictor().NodeLimitExceeded(node) {
+					break
 				}
 			}
 		}
diff --git a/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/defaults.go b/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/defaults.go
index 55b4092f8..205f39f11 100644
--- a/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/defaults.go
+++ b/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/defaults.go
@@ -16,7 +16,7 @@ package removepodsviolatingtopologyspreadconstraint
 import (
 	v1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/runtime"
-	utilptr "k8s.io/utils/ptr"
+	utilpointer "k8s.io/utils/pointer"
 )
 
 func addDefaultingFuncs(scheme *runtime.Scheme) error {
@@ -34,7 +34,7 @@ func SetDefaults_RemovePodsViolatingTopologySpreadConstraintArgs(obj runtime.Obj
 		args.LabelSelector = nil
 	}
 	if args.TopologyBalanceNodeFit == nil {
-		args.TopologyBalanceNodeFit = utilptr.To(true)
+		args.TopologyBalanceNodeFit = utilpointer.Bool(true)
 	}
 	if len(args.Constraints) == 0 {
 		args.Constraints = append(args.Constraints, v1.DoNotSchedule)
diff --git a/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/topologyspreadconstraint.go b/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/topologyspreadconstraint.go
index c66b71556..2f03c35a0 100644
--- a/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/topologyspreadconstraint.go
+++ b/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/topologyspreadconstraint.go
@@ -26,7 +26,7 @@ import (
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/util/sets"
 	"k8s.io/klog/v2"
-	utilptr "k8s.io/utils/ptr"
+	utilpointer "k8s.io/utils/pointer"
 
 	v1helper "k8s.io/component-helpers/scheduling/corev1"
 	"k8s.io/component-helpers/scheduling/corev1/nodeaffinity"
@@ -235,18 +235,10 @@ func (d *RemovePodsViolatingTopologySpreadConstraint) Balance(ctx context.Contex
 		}
 
 		if d.handle.Evictor().PreEvictionFilter(pod) {
-			err := d.handle.Evictor().Evict(ctx, pod, evictions.EvictOptions{StrategyName: PluginName})
-			if err == nil {
-				continue
-			}
-			switch err.(type) {
-			case *evictions.EvictionNodeLimitError:
-				nodeLimitExceeded[pod.Spec.NodeName] = true
-			case *evictions.EvictionTotalLimitError:
-				return nil
-			default:
-				klog.Errorf("eviction failed: %v", err)
-			}
+			d.handle.Evictor().Evict(ctx, pod, evictions.EvictOptions{StrategyName: PluginName})
+		}
+		if d.handle.Evictor().NodeLimitExceeded(nodeMap[pod.Spec.NodeName]) {
+			nodeLimitExceeded[pod.Spec.NodeName] = true
 		}
 	}
 
@@ -313,7 +305,7 @@ func (d *RemovePodsViolatingTopologySpreadConstraint) balanceDomains(
 	isEvictable := d.handle.Evictor().Filter
 	sortedDomains := sortDomains(constraintTopologies, isEvictable)
 	getPodsAssignedToNode := d.handle.GetPodsAssignedToNodeFunc()
-	topologyBalanceNodeFit := utilptr.Deref(d.args.TopologyBalanceNodeFit, true)
+	topologyBalanceNodeFit := utilpointer.BoolDeref(d.args.TopologyBalanceNodeFit, true)
 
 	eligibleNodes := filterEligibleNodes(nodes, tsc)
 	nodesBelowIdealAvg := filterNodesBelowIdealAvg(eligibleNodes, sortedDomains, tsc.TopologyKey, idealAvg)
diff --git a/pkg/framework/profile/profile.go b/pkg/framework/profile/profile.go
index 5cac3ea27..330c64662 100644
--- a/pkg/framework/profile/profile.go
+++ b/pkg/framework/profile/profile.go
@@ -59,11 +59,15 @@ func (ei *evictorImpl) PreEvictionFilter(pod *v1.Pod) bool {
 }
 
 // Evict evicts a pod (no pre-check performed)
-func (ei *evictorImpl) Evict(ctx context.Context, pod *v1.Pod, opts evictions.EvictOptions) error {
+func (ei *evictorImpl) Evict(ctx context.Context, pod *v1.Pod, opts evictions.EvictOptions) bool {
 	opts.ProfileName = ei.profileName
 	return ei.podEvictor.EvictPod(ctx, pod, opts)
 }
 
+func (ei *evictorImpl) NodeLimitExceeded(node *v1.Node) bool {
+	return ei.podEvictor.NodeLimitExceeded(node)
+}
+
 // handleImpl implements the framework handle which gets passed to plugins
 type handleImpl struct {
 	clientSet                 clientset.Interface
diff --git a/pkg/framework/types/types.go b/pkg/framework/types/types.go
index 1d5e1d95c..c49530363 100644
--- a/pkg/framework/types/types.go
+++ b/pkg/framework/types/types.go
@@ -46,7 +46,9 @@ type Evictor interface {
 	// PreEvictionFilter checks if pod can be evicted right before eviction
 	PreEvictionFilter(*v1.Pod) bool
 	// Evict evicts a pod (no pre-check performed)
-	Evict(context.Context, *v1.Pod, evictions.EvictOptions) error
+	Evict(context.Context, *v1.Pod, evictions.EvictOptions) bool
+	// NodeLimitExceeded checks if the number of evictions for a node was exceeded
+	NodeLimitExceeded(node *v1.Node) bool
 }
 
 // Status describes result of an extension point invocation
diff --git a/pkg/utils/predicates.go b/pkg/utils/predicates.go
index e59711731..7153f1792 100644
--- a/pkg/utils/predicates.go
+++ b/pkg/utils/predicates.go
@@ -66,7 +66,10 @@ func PodMatchNodeSelector(pod *v1.Pod, node *v1.Node) (bool, error) {
 	if node == nil {
 		return false, fmt.Errorf("node not found")
 	}
-	return podMatchesNodeLabels(pod, node), nil
+	if podMatchesNodeLabels(pod, node) {
+		return true, nil
+	}
+	return false, nil
 }
 
 // The pod can only schedule onto nodes that satisfy requirements in both NodeAffinity and nodeSelector.
diff --git a/vendor/k8s.io/utils/net/multi_listen.go b/vendor/k8s.io/utils/net/multi_listen.go
deleted file mode 100644
index 7cb7795be..000000000
--- a/vendor/k8s.io/utils/net/multi_listen.go
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
-Copyright 2024 The Kubernetes Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package net
-
-import (
-	"context"
-	"fmt"
-	"net"
-	"sync"
-)
-
-// connErrPair pairs conn and error which is returned by accept on sub-listeners.
-type connErrPair struct {
-	conn net.Conn
-	err  error
-}
-
-// multiListener implements net.Listener
-type multiListener struct {
-	listeners []net.Listener
-	wg        sync.WaitGroup
-
-	// connCh passes accepted connections, from child listeners to parent.
-	connCh chan connErrPair
-	// stopCh communicates from parent to child listeners.
-	stopCh chan struct{}
-}
-
-// compile time check to ensure *multiListener implements net.Listener
-var _ net.Listener = &multiListener{}
-
-// MultiListen returns net.Listener which can listen on and accept connections for
-// the given network on multiple addresses. Internally it uses stdlib to create
-// sub-listener and multiplexes connection requests using go-routines.
-// The network must be "tcp", "tcp4" or "tcp6".
-// It follows the semantics of net.Listen that primarily means:
-//  1. If the host is an unspecified/zero IP address with "tcp" network, MultiListen
-//     listens on all available unicast and anycast IP addresses of the local system.
-//  2. Use "tcp4" or "tcp6" to exclusively listen on IPv4 or IPv6 family, respectively.
-//  3. The host can accept names (e.g, localhost) and it will create a listener for at
-//     most one of the host's IP.
-func MultiListen(ctx context.Context, network string, addrs ...string) (net.Listener, error) {
-	var lc net.ListenConfig
-	return multiListen(
-		ctx,
-		network,
-		addrs,
-		func(ctx context.Context, network, address string) (net.Listener, error) {
-			return lc.Listen(ctx, network, address)
-		})
-}
-
-// multiListen implements MultiListen by consuming stdlib functions as dependency allowing
-// mocking for unit-testing.
-func multiListen(
-	ctx context.Context,
-	network string,
-	addrs []string,
-	listenFunc func(ctx context.Context, network, address string) (net.Listener, error),
-) (net.Listener, error) {
-	if !(network == "tcp" || network == "tcp4" || network == "tcp6") {
-		return nil, fmt.Errorf("network %q not supported", network)
-	}
-	if len(addrs) == 0 {
-		return nil, fmt.Errorf("no address provided to listen on")
-	}
-
-	ml := &multiListener{
-		connCh: make(chan connErrPair),
-		stopCh: make(chan struct{}),
-	}
-	for _, addr := range addrs {
-		l, err := listenFunc(ctx, network, addr)
-		if err != nil {
-			// close all the sub-listeners and exit
-			_ = ml.Close()
-			return nil, err
-		}
-		ml.listeners = append(ml.listeners, l)
-	}
-
-	for _, l := range ml.listeners {
-		ml.wg.Add(1)
-		go func(l net.Listener) {
-			defer ml.wg.Done()
-			for {
-				// Accept() is blocking, unless ml.Close() is called, in which
-				// case it will return immediately with an error.
-				conn, err := l.Accept()
-				// This assumes that ANY error from Accept() will terminate the
-				// sub-listener. We could maybe be more precise, but it
-				// doesn't seem necessary.
-				terminate := err != nil
-
-				select {
-				case ml.connCh <- connErrPair{conn: conn, err: err}:
-				case <-ml.stopCh:
-					// In case we accepted a connection AND were stopped, and
-					// this select-case was chosen, just throw away the
-					// connection.  This avoids potentially blocking on connCh
-					// or leaking a connection.
-					if conn != nil {
-						_ = conn.Close()
-					}
-					terminate = true
-				}
-				// Make sure we don't loop on Accept() returning an error and
-				// the select choosing the channel case.
-				if terminate {
-					return
-				}
-			}
-		}(l)
-	}
-	return ml, nil
-}
-
-// Accept implements net.Listener. It waits for and returns a connection from
-// any of the sub-listener.
-func (ml *multiListener) Accept() (net.Conn, error) {
-	// wait for any sub-listener to enqueue an accepted connection
-	connErr, ok := <-ml.connCh
-	if !ok {
-		// The channel will be closed only when Close() is called on the
-		// multiListener. Closing of this channel implies that all
-		// sub-listeners are also closed, which causes a "use of closed
-		// network connection" error on their Accept() calls. We return the
-		// same error for multiListener.Accept() if multiListener.Close()
-		// has already been called.
-		return nil, fmt.Errorf("use of closed network connection")
-	}
-	return connErr.conn, connErr.err
-}
-
-// Close implements net.Listener. It will close all sub-listeners and wait for
-// the go-routines to exit.
-func (ml *multiListener) Close() error {
-	// Make sure this can be called repeatedly without explosions.
-	select {
-	case <-ml.stopCh:
-		return fmt.Errorf("use of closed network connection")
-	default:
-	}
-
-	// Tell all sub-listeners to stop.
-	close(ml.stopCh)
-
-	// Closing the listeners causes Accept() to immediately return an error in
-	// the sub-listener go-routines.
-	for _, l := range ml.listeners {
-		_ = l.Close()
-	}
-
-	// Wait for all the sub-listener go-routines to exit.
-	ml.wg.Wait()
-	close(ml.connCh)
-
-	// Drain any already-queued connections.
-	for connErr := range ml.connCh {
-		if connErr.conn != nil {
-			_ = connErr.conn.Close()
-		}
-	}
-	return nil
-}
-
-// Addr is an implementation of the net.Listener interface.  It always returns
-// the address of the first listener.  Callers should  use conn.LocalAddr() to
-// obtain the actual local address of the sub-listener.
-func (ml *multiListener) Addr() net.Addr {
-	return ml.listeners[0].Addr()
-}
-
-// Addrs is like Addr, but returns the address for all registered listeners.
-func (ml *multiListener) Addrs() []net.Addr {
-	var ret []net.Addr
-	for _, l := range ml.listeners {
-		ret = append(ret, l.Addr())
-	}
-	return ret
-}
diff --git a/vendor/k8s.io/utils/trace/trace.go b/vendor/k8s.io/utils/trace/trace.go
index 559aebb59..187eb5d8c 100644
--- a/vendor/k8s.io/utils/trace/trace.go
+++ b/vendor/k8s.io/utils/trace/trace.go
@@ -192,7 +192,7 @@ func (t *Trace) Log() {
 	t.endTime = &endTime
 	t.lock.Unlock()
 	// an explicit logging request should dump all the steps out at the higher level
-	if t.parentTrace == nil && klogV(2) { // We don't start logging until Log or LogIfLong is called on the root trace
+	if t.parentTrace == nil { // We don't start logging until Log or LogIfLong is called on the root trace
 		t.logTrace()
 	}
 }
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 4eba6da54..c13c1fa03 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -1232,7 +1232,7 @@ k8s.io/kube-openapi/pkg/validation/errors
 k8s.io/kube-openapi/pkg/validation/spec
 k8s.io/kube-openapi/pkg/validation/strfmt
 k8s.io/kube-openapi/pkg/validation/strfmt/bson
-# k8s.io/utils v0.0.0-20240711033017-18e509b52bc8
+# k8s.io/utils v0.0.0-20240310230437-4693a0247e57
 ## explicit; go 1.18
 k8s.io/utils/buffer
 k8s.io/utils/clock


Test patch:
diff --git a/pkg/api/v1alpha1/strategymigration_test.go b/pkg/api/v1alpha1/strategymigration_test.go
index 862239e57..78639d322 100644
--- a/pkg/api/v1alpha1/strategymigration_test.go
+++ b/pkg/api/v1alpha1/strategymigration_test.go
@@ -22,7 +22,7 @@ import (
 
 	"github.com/google/go-cmp/cmp"
 	v1 "k8s.io/api/core/v1"
-	utilptr "k8s.io/utils/ptr"
+	utilpointer "k8s.io/utils/pointer"
 	"sigs.k8s.io/descheduler/pkg/api"
 	"sigs.k8s.io/descheduler/pkg/framework/plugins/nodeutilization"
 	"sigs.k8s.io/descheduler/pkg/framework/plugins/podlifetime"
@@ -51,7 +51,7 @@ func TestStrategyParamsToPluginArgsRemovePodsViolatingNodeTaints(t *testing.T) {
 					"dedicated=special-user",
 					"reserved",
 				},
-				ThresholdPriority: utilptr.To[int32](100),
+				ThresholdPriority: utilpointer.Int32(100),
 				Namespaces: &Namespaces{
 					Exclude: []string{"test1"},
 				},
@@ -116,12 +116,12 @@ func TestStrategyParamsToPluginArgsRemoveFailedPods(t *testing.T) {
 			description: "wire in all valid parameters",
 			params: &StrategyParameters{
 				FailedPods: &FailedPods{
-					MinPodLifetimeSeconds:   utilptr.To[uint](3600),
+					MinPodLifetimeSeconds:   utilpointer.Uint(3600),
 					ExcludeOwnerKinds:       []string{"Job"},
 					Reasons:                 []string{"NodeAffinity"},
 					IncludingInitContainers: true,
 				},
-				ThresholdPriority: utilptr.To[int32](100),
+				ThresholdPriority: utilpointer.Int32(100),
 				Namespaces: &Namespaces{
 					Exclude: []string{"test1"},
 				},
@@ -131,7 +131,7 @@ func TestStrategyParamsToPluginArgsRemoveFailedPods(t *testing.T) {
 				Name: removefailedpods.PluginName,
 				Args: &removefailedpods.RemoveFailedPodsArgs{
 					ExcludeOwnerKinds:       []string{"Job"},
-					MinPodLifetimeSeconds:   utilptr.To[uint](3600),
+					MinPodLifetimeSeconds:   utilpointer.Uint(3600),
 					Reasons:                 []string{"NodeAffinity"},
 					IncludingInitContainers: true,
 					Namespaces: &api.Namespaces{
@@ -189,7 +189,7 @@ func TestStrategyParamsToPluginArgsRemovePodsViolatingNodeAffinity(t *testing.T)
 			description: "wire in all valid parameters",
 			params: &StrategyParameters{
 				NodeAffinityType:  []string{"requiredDuringSchedulingIgnoredDuringExecution"},
-				ThresholdPriority: utilptr.To[int32](100),
+				ThresholdPriority: utilpointer.Int32(100),
 				Namespaces: &Namespaces{
 					Exclude: []string{"test1"},
 				},
@@ -260,7 +260,7 @@ func TestStrategyParamsToPluginArgsRemovePodsViolatingInterPodAntiAffinity(t *te
 		{
 			description: "wire in all valid parameters",
 			params: &StrategyParameters{
-				ThresholdPriority: utilptr.To[int32](100),
+				ThresholdPriority: utilpointer.Int32(100),
 				Namespaces: &Namespaces{
 					Exclude: []string{"test1"},
 				},
@@ -327,7 +327,7 @@ func TestStrategyParamsToPluginArgsRemovePodsHavingTooManyRestarts(t *testing.T)
 					PodRestartThreshold:     100,
 					IncludingInitContainers: true,
 				},
-				ThresholdPriority: utilptr.To[int32](100),
+				ThresholdPriority: utilpointer.Int32(100),
 				Namespaces: &Namespaces{
 					Exclude: []string{"test1"},
 				},
@@ -403,13 +403,13 @@ func TestStrategyParamsToPluginArgsPodLifeTime(t *testing.T) {
 			description: "wire in all valid parameters",
 			params: &StrategyParameters{
 				PodLifeTime: &PodLifeTime{
-					MaxPodLifeTimeSeconds: utilptr.To[uint](86400),
+					MaxPodLifeTimeSeconds: utilpointer.Uint(86400),
 					States: []string{
 						"Pending",
 						"PodInitializing",
 					},
 				},
-				ThresholdPriority: utilptr.To[int32](100),
+				ThresholdPriority: utilpointer.Int32(100),
 				Namespaces: &Namespaces{
 					Exclude: []string{"test1"},
 				},
@@ -418,7 +418,7 @@ func TestStrategyParamsToPluginArgsPodLifeTime(t *testing.T) {
 			result: &api.PluginConfig{
 				Name: podlifetime.PluginName,
 				Args: &podlifetime.PodLifeTimeArgs{
-					MaxPodLifeTimeSeconds: utilptr.To[uint](86400),
+					MaxPodLifeTimeSeconds: utilpointer.Uint(86400),
 					States: []string{
 						"Pending",
 						"PodInitializing",
@@ -433,7 +433,7 @@ func TestStrategyParamsToPluginArgsPodLifeTime(t *testing.T) {
 			description: "invalid params namespaces",
 			params: &StrategyParameters{
 				PodLifeTime: &PodLifeTime{
-					MaxPodLifeTimeSeconds: utilptr.To[uint](86400),
+					MaxPodLifeTimeSeconds: utilpointer.Uint(86400),
 				},
 				Namespaces: &Namespaces{
 					Exclude: []string{"test1"},
@@ -491,7 +491,7 @@ func TestStrategyParamsToPluginArgsRemoveDuplicates(t *testing.T) {
 				RemoveDuplicates: &RemoveDuplicates{
 					ExcludeOwnerKinds: []string{"ReplicaSet"},
 				},
-				ThresholdPriority: utilptr.To[int32](100),
+				ThresholdPriority: utilpointer.Int32(100),
 				Namespaces: &Namespaces{
 					Exclude: []string{"test1"},
 				},
@@ -511,7 +511,7 @@ func TestStrategyParamsToPluginArgsRemoveDuplicates(t *testing.T) {
 			description: "invalid params namespaces",
 			params: &StrategyParameters{
 				PodLifeTime: &PodLifeTime{
-					MaxPodLifeTimeSeconds: utilptr.To[uint](86400),
+					MaxPodLifeTimeSeconds: utilpointer.Uint(86400),
 				},
 				Namespaces: &Namespaces{
 					Exclude: []string{"test1"},
@@ -559,7 +559,7 @@ func TestStrategyParamsToPluginArgsRemovePodsViolatingTopologySpreadConstraint(t
 			description: "wire in all valid parameters",
 			params: &StrategyParameters{
 				IncludeSoftConstraints: true,
-				ThresholdPriority:      utilptr.To[int32](100),
+				ThresholdPriority:      utilpointer.Int32(100),
 				Namespaces: &Namespaces{
 					Exclude: []string{"test1"},
 				},
@@ -569,7 +569,7 @@ func TestStrategyParamsToPluginArgsRemovePodsViolatingTopologySpreadConstraint(t
 				Name: removepodsviolatingtopologyspreadconstraint.PluginName,
 				Args: &removepodsviolatingtopologyspreadconstraint.RemovePodsViolatingTopologySpreadConstraintArgs{
 					Constraints:            []v1.UnsatisfiableConstraintAction{v1.DoNotSchedule, v1.ScheduleAnyway},
-					TopologyBalanceNodeFit: utilptr.To(true),
+					TopologyBalanceNodeFit: utilpointer.Bool(true),
 					Namespaces: &api.Namespaces{
 						Exclude: []string{"test1"},
 					},
@@ -586,7 +586,7 @@ func TestStrategyParamsToPluginArgsRemovePodsViolatingTopologySpreadConstraint(t
 				Name: removepodsviolatingtopologyspreadconstraint.PluginName,
 				Args: &removepodsviolatingtopologyspreadconstraint.RemovePodsViolatingTopologySpreadConstraintArgs{
 					Constraints:            []v1.UnsatisfiableConstraintAction{v1.DoNotSchedule},
-					TopologyBalanceNodeFit: utilptr.To(true),
+					TopologyBalanceNodeFit: utilpointer.Bool(true),
 				},
 			},
 		},
@@ -646,7 +646,7 @@ func TestStrategyParamsToPluginArgsHighNodeUtilization(t *testing.T) {
 						"pods":   Percentage(20),
 					},
 				},
-				ThresholdPriority: utilptr.To[int32](100),
+				ThresholdPriority: utilpointer.Int32(100),
 				Namespaces: &Namespaces{
 					Exclude: []string{"test1"},
 				},
@@ -759,7 +759,7 @@ func TestStrategyParamsToPluginArgsLowNodeUtilization(t *testing.T) {
 					},
 					UseDeviationThresholds: true,
 				},
-				ThresholdPriority: utilptr.To[int32](100),
+				ThresholdPriority: utilpointer.Int32(100),
 				Namespaces: &Namespaces{
 					Exclude: []string{"test1"},
 				},
diff --git a/pkg/descheduler/descheduler_test.go b/pkg/descheduler/descheduler_test.go
index f12a3570a..596def186 100644
--- a/pkg/descheduler/descheduler_test.go
+++ b/pkg/descheduler/descheduler_test.go
@@ -9,133 +9,62 @@ import (
 	v1 "k8s.io/api/core/v1"
 	policy "k8s.io/api/policy/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/conversion"
 	"k8s.io/apimachinery/pkg/runtime"
 	apiversion "k8s.io/apimachinery/pkg/version"
 	fakediscovery "k8s.io/client-go/discovery/fake"
-	"k8s.io/client-go/informers"
 	fakeclientset "k8s.io/client-go/kubernetes/fake"
 	core "k8s.io/client-go/testing"
 	"sigs.k8s.io/descheduler/cmd/descheduler/app/options"
 	"sigs.k8s.io/descheduler/pkg/api"
-	nodeutil "sigs.k8s.io/descheduler/pkg/descheduler/node"
+	"sigs.k8s.io/descheduler/pkg/api/v1alpha1"
 	"sigs.k8s.io/descheduler/pkg/framework/pluginregistry"
 	"sigs.k8s.io/descheduler/pkg/framework/plugins/defaultevictor"
 	"sigs.k8s.io/descheduler/pkg/framework/plugins/removeduplicates"
 	"sigs.k8s.io/descheduler/pkg/framework/plugins/removepodsviolatingnodetaints"
-	"sigs.k8s.io/descheduler/pkg/utils"
 	deschedulerversion "sigs.k8s.io/descheduler/pkg/version"
 	"sigs.k8s.io/descheduler/test"
 )
 
-func initPluginRegistry() {
-	pluginregistry.PluginRegistry = pluginregistry.NewRegistry()
-	pluginregistry.Register(removeduplicates.PluginName, removeduplicates.New, &removeduplicates.RemoveDuplicates{}, &removeduplicates.RemoveDuplicatesArgs{}, removeduplicates.ValidateRemoveDuplicatesArgs, removeduplicates.SetDefaults_RemoveDuplicatesArgs, pluginregistry.PluginRegistry)
-	pluginregistry.Register(defaultevictor.PluginName, defaultevictor.New, &defaultevictor.DefaultEvictor{}, &defaultevictor.DefaultEvictorArgs{}, defaultevictor.ValidateDefaultEvictorArgs, defaultevictor.SetDefaults_DefaultEvictorArgs, pluginregistry.PluginRegistry)
-	pluginregistry.Register(removepodsviolatingnodetaints.PluginName, removepodsviolatingnodetaints.New, &removepodsviolatingnodetaints.RemovePodsViolatingNodeTaints{}, &removepodsviolatingnodetaints.RemovePodsViolatingNodeTaintsArgs{}, removepodsviolatingnodetaints.ValidateRemovePodsViolatingNodeTaintsArgs, removepodsviolatingnodetaints.SetDefaults_RemovePodsViolatingNodeTaintsArgs, pluginregistry.PluginRegistry)
+// scope contains information about an ongoing conversion.
+type scope struct {
+	converter *conversion.Converter
+	meta      *conversion.Meta
 }
 
-func removePodsViolatingNodeTaintsPolicy() *api.DeschedulerPolicy {
-	return &api.DeschedulerPolicy{
-		Profiles: []api.DeschedulerProfile{
-			{
-				Name: "Profile",
-				PluginConfigs: []api.PluginConfig{
-					{
-						Name: "RemovePodsViolatingNodeTaints",
-						Args: &removepodsviolatingnodetaints.RemovePodsViolatingNodeTaintsArgs{},
-					},
-					{
-						Name: "DefaultEvictor",
-						Args: &defaultevictor.DefaultEvictorArgs{},
-					},
-				},
-				Plugins: api.Plugins{
-					Filter: api.PluginSet{
-						Enabled: []string{
-							"DefaultEvictor",
-						},
-					},
-					Deschedule: api.PluginSet{
-						Enabled: []string{
-							"RemovePodsViolatingNodeTaints",
-						},
-					},
-				},
-			},
-		},
-	}
+// Convert continues a conversion.
+func (s scope) Convert(src, dest interface{}) error {
+	return s.converter.Convert(src, dest, s.meta)
 }
 
-func removeDuplicatesPolicy() *api.DeschedulerPolicy {
-	return &api.DeschedulerPolicy{
-		Profiles: []api.DeschedulerProfile{
-			{
-				Name: "Profile",
-				PluginConfigs: []api.PluginConfig{
-					{
-						Name: "RemoveDuplicates",
-						Args: &removeduplicates.RemoveDuplicatesArgs{},
-					},
-					{
-						Name: "DefaultEvictor",
-						Args: &defaultevictor.DefaultEvictorArgs{},
-					},
-				},
-				Plugins: api.Plugins{
-					Filter: api.PluginSet{
-						Enabled: []string{
-							"DefaultEvictor",
-						},
-					},
-					Balance: api.PluginSet{
-						Enabled: []string{
-							"RemoveDuplicates",
-						},
-					},
-				},
-			},
-		},
-	}
-}
-
-func initDescheduler(t *testing.T, ctx context.Context, internalDeschedulerPolicy *api.DeschedulerPolicy, objects ...runtime.Object) (*options.DeschedulerServer, *descheduler, *fakeclientset.Clientset) {
-	client := fakeclientset.NewSimpleClientset(objects...)
-	eventClient := fakeclientset.NewSimpleClientset(objects...)
-
-	rs, err := options.NewDeschedulerServer()
-	if err != nil {
-		t.Fatalf("Unable to initialize server: %v", err)
-	}
-	rs.Client = client
-	rs.EventClient = eventClient
-
-	sharedInformerFactory := informers.NewSharedInformerFactoryWithOptions(rs.Client, 0, informers.WithTransform(trimManagedFields))
-	eventBroadcaster, eventRecorder := utils.GetRecorderAndBroadcaster(ctx, client)
-
-	descheduler, err := newDescheduler(rs, internalDeschedulerPolicy, "v1", eventRecorder, sharedInformerFactory)
-	if err != nil {
-		eventBroadcaster.Shutdown()
-		t.Fatalf("Unable to create a descheduler instance: %v", err)
-	}
-
-	sharedInformerFactory.Start(ctx.Done())
-	sharedInformerFactory.WaitForCacheSync(ctx.Done())
-
-	return rs, descheduler, client
+// Meta returns the meta object that was originally passed to Convert.
+func (s scope) Meta() *conversion.Meta {
+	return s.meta
 }
 
 func TestTaintsUpdated(t *testing.T) {
-	initPluginRegistry()
+	pluginregistry.PluginRegistry = pluginregistry.NewRegistry()
+	pluginregistry.Register(removepodsviolatingnodetaints.PluginName, removepodsviolatingnodetaints.New, &removepodsviolatingnodetaints.RemovePodsViolatingNodeTaints{}, &removepodsviolatingnodetaints.RemovePodsViolatingNodeTaintsArgs{}, removepodsviolatingnodetaints.ValidateRemovePodsViolatingNodeTaintsArgs, removepodsviolatingnodetaints.SetDefaults_RemovePodsViolatingNodeTaintsArgs, pluginregistry.PluginRegistry)
+	pluginregistry.Register(defaultevictor.PluginName, defaultevictor.New, &defaultevictor.DefaultEvictor{}, &defaultevictor.DefaultEvictorArgs{}, defaultevictor.ValidateDefaultEvictorArgs, defaultevictor.SetDefaults_DefaultEvictorArgs, pluginregistry.PluginRegistry)
 
 	ctx := context.Background()
 	n1 := test.BuildTestNode("n1", 2000, 3000, 10, nil)
 	n2 := test.BuildTestNode("n2", 2000, 3000, 10, nil)
 
 	p1 := test.BuildTestPod(fmt.Sprintf("pod_1_%s", n1.Name), 200, 0, n1.Name, nil)
-	p1.ObjectMeta.OwnerReferences = test.GetReplicaSetOwnerRefList()
+	p1.ObjectMeta.OwnerReferences = []metav1.OwnerReference{
+		{},
+	}
 
 	client := fakeclientset.NewSimpleClientset(n1, n2, p1)
 	eventClient := fakeclientset.NewSimpleClientset(n1, n2, p1)
+	dp := &v1alpha1.DeschedulerPolicy{
+		Strategies: v1alpha1.StrategyList{
+			"RemovePodsViolatingNodeTaints": v1alpha1.DeschedulerStrategy{
+				Enabled: true,
+			},
+		},
+	}
 
 	rs, err := options.NewDeschedulerServer()
 	if err != nil {
@@ -166,9 +95,16 @@ func TestTaintsUpdated(t *testing.T) {
 	}
 
 	var evictedPods []string
-	client.PrependReactor("create", "pods", podEvictionReactionTestingFnc(&evictedPods))
+	client.PrependReactor("create", "pods", podEvictionReactionFuc(&evictedPods))
 
-	if err := RunDeschedulerStrategies(ctx, rs, removePodsViolatingNodeTaintsPolicy(), "v1"); err != nil {
+	internalDeschedulerPolicy := &api.DeschedulerPolicy{}
+	scope := scope{}
+	err = v1alpha1.V1alpha1ToInternal(dp, pluginregistry.PluginRegistry, internalDeschedulerPolicy, scope)
+	if err != nil {
+		t.Fatalf("Unable to convert v1alpha1 to v1alpha2: %v", err)
+	}
+
+	if err := RunDeschedulerStrategies(ctx, rs, internalDeschedulerPolicy, "v1"); err != nil {
 		t.Fatalf("Unable to run descheduler strategies: %v", err)
 	}
 
@@ -178,7 +114,9 @@ func TestTaintsUpdated(t *testing.T) {
 }
 
 func TestDuplicate(t *testing.T) {
-	initPluginRegistry()
+	pluginregistry.PluginRegistry = pluginregistry.NewRegistry()
+	pluginregistry.Register(removeduplicates.PluginName, removeduplicates.New, &removeduplicates.RemoveDuplicates{}, &removeduplicates.RemoveDuplicatesArgs{}, removeduplicates.ValidateRemoveDuplicatesArgs, removeduplicates.SetDefaults_RemoveDuplicatesArgs, pluginregistry.PluginRegistry)
+	pluginregistry.Register(defaultevictor.PluginName, defaultevictor.New, &defaultevictor.DefaultEvictor{}, &defaultevictor.DefaultEvictorArgs{}, defaultevictor.ValidateDefaultEvictorArgs, defaultevictor.SetDefaults_DefaultEvictorArgs, pluginregistry.PluginRegistry)
 
 	ctx := context.Background()
 	node1 := test.BuildTestNode("n1", 2000, 3000, 10, nil)
@@ -198,6 +136,13 @@ func TestDuplicate(t *testing.T) {
 
 	client := fakeclientset.NewSimpleClientset(node1, node2, p1, p2, p3)
 	eventClient := fakeclientset.NewSimpleClientset(node1, node2, p1, p2, p3)
+	dp := &v1alpha1.DeschedulerPolicy{
+		Strategies: v1alpha1.StrategyList{
+			"RemoveDuplicates": v1alpha1.DeschedulerStrategy{
+				Enabled: true,
+			},
+		},
+	}
 
 	rs, err := options.NewDeschedulerServer()
 	if err != nil {
@@ -216,14 +161,20 @@ func TestDuplicate(t *testing.T) {
 	}
 
 	var evictedPods []string
-	client.PrependReactor("create", "pods", podEvictionReactionTestingFnc(&evictedPods))
+	client.PrependReactor("create", "pods", podEvictionReactionFuc(&evictedPods))
 
-	if err := RunDeschedulerStrategies(ctx, rs, removeDuplicatesPolicy(), "v1"); err != nil {
+	internalDeschedulerPolicy := &api.DeschedulerPolicy{}
+	scope := scope{}
+	err = v1alpha1.V1alpha1ToInternal(dp, pluginregistry.PluginRegistry, internalDeschedulerPolicy, scope)
+	if err != nil {
+		t.Fatalf("Unable to convert v1alpha1 to v1alpha2: %v", err)
+	}
+	if err := RunDeschedulerStrategies(ctx, rs, internalDeschedulerPolicy, "v1"); err != nil {
 		t.Fatalf("Unable to run descheduler strategies: %v", err)
 	}
 
 	if len(evictedPods) == 0 {
-		t.Fatalf("Unable to evict pods\n")
+		t.Fatalf("Unable to evict pod, node taint did not get propagated to descheduler strategies %v\n", err)
 	}
 }
 
@@ -358,7 +309,7 @@ func TestValidateVersionCompatibility(t *testing.T) {
 	}
 }
 
-func podEvictionReactionTestingFnc(evictedPods *[]string) func(action core.Action) (bool, runtime.Object, error) {
+func podEvictionReactionFuc(evictedPods *[]string) func(action core.Action) (bool, runtime.Object, error) {
 	return func(action core.Action) (bool, runtime.Object, error) {
 		if action.GetSubresource() == "eviction" {
 			createAct, matched := action.(core.CreateActionImpl)
@@ -372,81 +323,3 @@ func podEvictionReactionTestingFnc(evictedPods *[]string) func(action core.Actio
 		return false, nil, nil // fallback to the default reactor
 	}
 }
-
-func TestPodEvictorReset(t *testing.T) {
-	initPluginRegistry()
-
-	ctx := context.Background()
-	node1 := test.BuildTestNode("n1", 2000, 3000, 10, nil)
-	node2 := test.BuildTestNode("n2", 2000, 3000, 10, nil)
-
-	p1 := test.BuildTestPod("p1", 100, 0, node1.Name, nil)
-	p1.Namespace = "dev"
-	p2 := test.BuildTestPod("p2", 100, 0, node1.Name, nil)
-	p2.Namespace = "dev"
-	p3 := test.BuildTestPod("p3", 100, 0, node1.Name, nil)
-	p3.Namespace = "dev"
-	p4 := test.BuildTestPod("p4", 100, 0, node1.Name, nil)
-	p4.Namespace = "dev"
-
-	ownerRef1 := test.GetReplicaSetOwnerRefList()
-	p1.ObjectMeta.OwnerReferences = ownerRef1
-	p2.ObjectMeta.OwnerReferences = ownerRef1
-	p3.ObjectMeta.OwnerReferences = ownerRef1
-	p4.ObjectMeta.OwnerReferences = ownerRef1
-
-	ctxCancel, cancel := context.WithCancel(ctx)
-	rs, descheduler, client := initDescheduler(t, ctxCancel, removeDuplicatesPolicy(), node1, node2, p1, p2, p3, p4)
-	defer cancel()
-
-	var evictedPods []string
-	client.PrependReactor("create", "pods", podEvictionReactionTestingFnc(&evictedPods))
-
-	var fakeEvictedPods []string
-	descheduler.podEvictionReactionFnc = func(*fakeclientset.Clientset) func(action core.Action) (bool, runtime.Object, error) {
-		return podEvictionReactionTestingFnc(&fakeEvictedPods)
-	}
-
-	nodes, err := nodeutil.ReadyNodes(ctx, rs.Client, descheduler.nodeLister, "")
-	if err != nil {
-		t.Fatalf("Unable to get ready nodes: %v", err)
-	}
-
-	// a single pod eviction expected
-	err = descheduler.runDeschedulerLoop(ctx, nodes)
-	if err != nil {
-		t.Fatalf("Unable to run a descheduling loop: %v", err)
-	}
-	if descheduler.podEvictor.TotalEvicted() != 2 || len(evictedPods) != 2 || len(fakeEvictedPods) != 0 {
-		t.Fatalf("Expected (2,2,0) pods evicted, got (%v, %v, %v) instead", descheduler.podEvictor.TotalEvicted(), len(evictedPods), len(fakeEvictedPods))
-	}
-
-	// a single pod eviction expected
-	err = descheduler.runDeschedulerLoop(ctx, nodes)
-	if err != nil {
-		t.Fatalf("Unable to run a descheduling loop: %v", err)
-	}
-	if descheduler.podEvictor.TotalEvicted() != 2 || len(evictedPods) != 4 || len(fakeEvictedPods) != 0 {
-		t.Fatalf("Expected (2,4,0) pods evicted, got (%v, %v, %v) instead", descheduler.podEvictor.TotalEvicted(), len(evictedPods), len(fakeEvictedPods))
-	}
-
-	// check the fake client syncing and the right pods evicted
-	rs.DryRun = true
-	evictedPods = []string{}
-	// a single pod eviction expected
-	err = descheduler.runDeschedulerLoop(ctx, nodes)
-	if err != nil {
-		t.Fatalf("Unable to run a descheduling loop: %v", err)
-	}
-	if descheduler.podEvictor.TotalEvicted() != 2 || len(evictedPods) != 0 || len(fakeEvictedPods) != 2 {
-		t.Fatalf("Expected (2,0,2) pods evicted, got (%v, %v, %v) instead", descheduler.podEvictor.TotalEvicted(), len(evictedPods), len(fakeEvictedPods))
-	}
-	// a single pod eviction expected
-	err = descheduler.runDeschedulerLoop(ctx, nodes)
-	if err != nil {
-		t.Fatalf("Unable to run a descheduling loop: %v", err)
-	}
-	if descheduler.podEvictor.TotalEvicted() != 2 || len(evictedPods) != 0 || len(fakeEvictedPods) != 4 {
-		t.Fatalf("Expected (2,0,4) pods evicted, got (%v, %v, %v) instead", descheduler.podEvictor.TotalEvicted(), len(evictedPods), len(fakeEvictedPods))
-	}
-}
diff --git a/pkg/descheduler/evictions/evictions_test.go b/pkg/descheduler/evictions/evictions_test.go
index 475b0bc9d..9a931c781 100644
--- a/pkg/descheduler/evictions/evictions_test.go
+++ b/pkg/descheduler/evictions/evictions_test.go
@@ -22,12 +22,9 @@ import (
 
 	v1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/client-go/kubernetes/fake"
 	core "k8s.io/client-go/testing"
-	"k8s.io/client-go/tools/events"
-	utilptr "k8s.io/utils/ptr"
 	podutil "sigs.k8s.io/descheduler/pkg/descheduler/pod"
 	"sigs.k8s.io/descheduler/pkg/utils"
 	"sigs.k8s.io/descheduler/test"
@@ -116,52 +113,3 @@ func TestPodTypes(t *testing.T) {
 		t.Errorf("Expected p1 to be a normal pod.")
 	}
 }
-
-func TestNewPodEvictor(t *testing.T) {
-	pod1 := test.BuildTestPod("pod", 400, 0, "node", nil)
-
-	fakeClient := fake.NewSimpleClientset(pod1)
-
-	eventRecorder := &events.FakeRecorder{}
-
-	podEvictor := NewPodEvictor(
-		fakeClient,
-		eventRecorder,
-		NewOptions().WithMaxPodsToEvictPerNode(utilptr.To[uint](1)),
-	)
-
-	stubNode := &v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "node"}}
-
-	// 0 evictions expected
-	if evictions := podEvictor.NodeEvicted(stubNode); evictions != 0 {
-		t.Errorf("Expected 0 node evictions, got %q instead", evictions)
-	}
-	// 0 evictions expected
-	if evictions := podEvictor.TotalEvicted(); evictions != 0 {
-		t.Errorf("Expected 0 total evictions, got %q instead", evictions)
-	}
-
-	if err := podEvictor.EvictPod(context.TODO(), pod1, EvictOptions{}); err != nil {
-		t.Errorf("Expected a pod eviction, got an eviction error instead: %v", err)
-	}
-
-	// 1 node eviction expected
-	if evictions := podEvictor.NodeEvicted(stubNode); evictions != 1 {
-		t.Errorf("Expected 1 node eviction, got %q instead", evictions)
-	}
-	// 1 total eviction expected
-	if evictions := podEvictor.TotalEvicted(); evictions != 1 {
-		t.Errorf("Expected 1 total evictions, got %q instead", evictions)
-	}
-
-	err := podEvictor.EvictPod(context.TODO(), pod1, EvictOptions{})
-	if err == nil {
-		t.Errorf("Expected a pod eviction error, got nil instead")
-	}
-	switch err.(type) {
-	case *EvictionNodeLimitError:
-		// all good
-	default:
-		t.Errorf("Expected a pod eviction EvictionNodeLimitError error, got a different error instead: %v", err)
-	}
-}
diff --git a/pkg/descheduler/node/node_test.go b/pkg/descheduler/node/node_test.go
index 006156383..383e18bc5 100644
--- a/pkg/descheduler/node/node_test.go
+++ b/pkg/descheduler/node/node_test.go
@@ -19,7 +19,6 @@ package node
 import (
 	"context"
 	"errors"
-	"sync"
 	"testing"
 
 	v1 "k8s.io/api/core/v1"
@@ -231,7 +230,7 @@ func TestPodFitsAnyOtherNode(t *testing.T) {
 	nodeTaintValue := "gpu"
 
 	// Staging node has no scheduling restrictions, but the pod always starts here and PodFitsAnyOtherNode() doesn't take into account the node the pod is running on.
-	nodeNames := []string{"node1", "node2", "stagingNode", "node4"}
+	nodeNames := []string{"node1", "node2", "stagingNode"}
 
 	tests := []struct {
 		description string
@@ -717,151 +716,6 @@ func TestPodFitsAnyOtherNode(t *testing.T) {
 			},
 			success: false,
 		},
-		{
-			description: "There are four nodes. One node has a taint, and the other three nodes do not meet the resource requirements, should fail",
-			pod: test.BuildTestPod("p1", 1000, 2*1000*1000*1000, nodeNames[2], func(pod *v1.Pod) {
-				pod.Spec.NodeSelector = map[string]string{
-					nodeLabelKey: nodeLabelValue,
-				}
-				pod.Spec.Containers[0].Resources.Requests[v1.ResourceEphemeralStorage] = *resource.NewQuantity(10*1000*1000*1000, resource.DecimalSI)
-			}),
-			nodes: []*v1.Node{
-				test.BuildTestNode(nodeNames[0], 64000, 128*1000*1000*1000, 200, func(node *v1.Node) {
-					node.ObjectMeta.Labels = map[string]string{
-						nodeLabelKey: nodeLabelValue,
-					}
-
-					node.Status.Allocatable[v1.ResourceEphemeralStorage] = *resource.NewQuantity(1000*1000*1000*1000, resource.DecimalSI)
-					node.Spec.Taints = []v1.Taint{
-						{
-							Key:    nodeTaintKey,
-							Value:  nodeTaintValue,
-							Effect: v1.TaintEffectNoSchedule,
-						},
-					}
-				}),
-				test.BuildTestNode(nodeNames[1], 3000, 8*1000*1000*1000, 12, func(node *v1.Node) {
-					node.ObjectMeta.Labels = map[string]string{
-						nodeLabelKey: nodeLabelValue,
-					}
-
-					node.Status.Allocatable[v1.ResourceEphemeralStorage] = *resource.NewQuantity(200*1000*1000*1000, resource.DecimalSI)
-				}),
-				test.BuildTestNode(nodeNames[2], 3000, 8*1000*1000*1000, 12, nil),
-				test.BuildTestNode(nodeNames[3], 0, 0, 0, nil),
-			},
-			podsOnNodes: []*v1.Pod{
-				test.BuildTestPod("3-core-pod", 2000, 4*1000*1000*1000, nodeNames[1], func(pod *v1.Pod) {
-					pod.ObjectMeta = metav1.ObjectMeta{
-						Namespace: "test",
-						Labels: map[string]string{
-							"test": "true",
-						},
-					}
-					pod.Spec.Containers[0].Resources.Requests[v1.ResourceEphemeralStorage] = *resource.NewQuantity(10*1000*1000*1000, resource.DecimalSI)
-					pod.Spec.Overhead = createResourceList(1000, 1000*1000*1000, 1000*1000*1000)
-				}),
-			},
-			success: false,
-		},
-		{
-			description: "There are four nodes. First node has a taint, second node has no label, third node do not meet the resource requirements, just fourth node meets the requirements, should success",
-			pod: test.BuildTestPod("p1", 1000, 2*1000*1000*1000, nodeNames[2], func(pod *v1.Pod) {
-				pod.Spec.NodeSelector = map[string]string{
-					nodeLabelKey: nodeLabelValue,
-				}
-				pod.Spec.Containers[0].Resources.Requests[v1.ResourceEphemeralStorage] = *resource.NewQuantity(10*1000*1000*1000, resource.DecimalSI)
-			}),
-			nodes: []*v1.Node{
-				test.BuildTestNode(nodeNames[0], 64000, 128*1000*1000*1000, 200, func(node *v1.Node) {
-					node.ObjectMeta.Labels = map[string]string{
-						nodeLabelKey: nodeLabelValue,
-					}
-
-					node.Status.Allocatable[v1.ResourceEphemeralStorage] = *resource.NewQuantity(1000*1000*1000*1000, resource.DecimalSI)
-					node.Spec.Taints = []v1.Taint{
-						{
-							Key:    nodeTaintKey,
-							Value:  nodeTaintValue,
-							Effect: v1.TaintEffectNoSchedule,
-						},
-					}
-				}),
-				test.BuildTestNode(nodeNames[1], 8000, 8*1000*1000*1000, 12, func(node *v1.Node) {
-					node.Status.Allocatable[v1.ResourceEphemeralStorage] = *resource.NewQuantity(200*1000*1000*1000, resource.DecimalSI)
-				}),
-				test.BuildTestNode(nodeNames[2], 1000, 8*1000*1000*1000, 12, nil),
-				test.BuildTestNode(nodeNames[3], 8000, 8*1000*1000*1000, 12, func(node *v1.Node) {
-					node.ObjectMeta.Labels = map[string]string{
-						nodeLabelKey: nodeLabelValue,
-					}
-
-					node.Status.Allocatable[v1.ResourceEphemeralStorage] = *resource.NewQuantity(1000*1000*1000*1000, resource.DecimalSI)
-				}),
-			},
-			podsOnNodes: []*v1.Pod{
-				test.BuildTestPod("3-core-pod", 2000, 4*1000*1000*1000, nodeNames[1], func(pod *v1.Pod) {
-					pod.ObjectMeta = metav1.ObjectMeta{
-						Namespace: "test",
-						Labels: map[string]string{
-							"test": "true",
-						},
-					}
-					pod.Spec.Containers[0].Resources.Requests[v1.ResourceEphemeralStorage] = *resource.NewQuantity(10*1000*1000*1000, resource.DecimalSI)
-					pod.Spec.Overhead = createResourceList(1000, 1000*1000*1000, 1000*1000*1000)
-				}),
-			},
-			success: true,
-		},
-		{
-			description: "There are four nodes. First node has a taint, second node has no label, third node do not meet the resource requirements, fourth node is the one where the pod is located, should fail",
-			pod: test.BuildTestPod("p1", 1000, 2*1000*1000*1000, nodeNames[3], func(pod *v1.Pod) {
-				pod.Spec.NodeSelector = map[string]string{
-					nodeLabelKey: nodeLabelValue,
-				}
-				pod.Spec.Containers[0].Resources.Requests[v1.ResourceEphemeralStorage] = *resource.NewQuantity(10*1000*1000*1000, resource.DecimalSI)
-			}),
-			nodes: []*v1.Node{
-				test.BuildTestNode(nodeNames[0], 64000, 128*1000*1000*1000, 200, func(node *v1.Node) {
-					node.ObjectMeta.Labels = map[string]string{
-						nodeLabelKey: nodeLabelValue,
-					}
-
-					node.Status.Allocatable[v1.ResourceEphemeralStorage] = *resource.NewQuantity(1000*1000*1000*1000, resource.DecimalSI)
-					node.Spec.Taints = []v1.Taint{
-						{
-							Key:    nodeTaintKey,
-							Value:  nodeTaintValue,
-							Effect: v1.TaintEffectNoSchedule,
-						},
-					}
-				}),
-				test.BuildTestNode(nodeNames[1], 8000, 8*1000*1000*1000, 12, func(node *v1.Node) {
-					node.Status.Allocatable[v1.ResourceEphemeralStorage] = *resource.NewQuantity(200*1000*1000*1000, resource.DecimalSI)
-				}),
-				test.BuildTestNode(nodeNames[2], 1000, 8*1000*1000*1000, 12, nil),
-				test.BuildTestNode(nodeNames[3], 8000, 8*1000*1000*1000, 12, func(node *v1.Node) {
-					node.ObjectMeta.Labels = map[string]string{
-						nodeLabelKey: nodeLabelValue,
-					}
-
-					node.Status.Allocatable[v1.ResourceEphemeralStorage] = *resource.NewQuantity(1000*1000*1000*1000, resource.DecimalSI)
-				}),
-			},
-			podsOnNodes: []*v1.Pod{
-				test.BuildTestPod("3-core-pod", 2000, 4*1000*1000*1000, nodeNames[1], func(pod *v1.Pod) {
-					pod.ObjectMeta = metav1.ObjectMeta{
-						Namespace: "test",
-						Labels: map[string]string{
-							"test": "true",
-						},
-					}
-					pod.Spec.Containers[0].Resources.Requests[v1.ResourceEphemeralStorage] = *resource.NewQuantity(10*1000*1000*1000, resource.DecimalSI)
-					pod.Spec.Overhead = createResourceList(1000, 1000*1000*1000, 1000*1000*1000)
-				}),
-			},
-			success: false,
-		},
 	}
 
 	for _, tc := range tests {
@@ -899,51 +753,6 @@ func TestPodFitsAnyOtherNode(t *testing.T) {
 	}
 }
 
-func TestPodFitsNodes(t *testing.T) {
-	nodeNames := []string{"node1", "node2", "node3", "node4"}
-	pod := test.BuildTestPod("p1", 950, 2*1000*1000*1000, nodeNames[0], nil)
-	nodes := []*v1.Node{
-		test.BuildTestNode(nodeNames[0], 1000, 8*1000*1000*1000, 12, nil),
-		test.BuildTestNode(nodeNames[1], 200, 8*1000*1000*1000, 12, nil),
-		test.BuildTestNode(nodeNames[2], 300, 8*1000*1000*1000, 12, nil),
-		test.BuildTestNode(nodeNames[3], 400, 8*1000*1000*1000, 12, nil),
-	}
-
-	ctx, cancel := context.WithCancel(context.Background())
-	defer cancel()
-
-	var objs []runtime.Object
-	for _, node := range nodes {
-		objs = append(objs, node)
-	}
-	objs = append(objs, pod)
-
-	fakeClient := fake.NewSimpleClientset(objs...)
-
-	sharedInformerFactory := informers.NewSharedInformerFactory(fakeClient, 0)
-	podInformer := sharedInformerFactory.Core().V1().Pods().Informer()
-
-	getPodsAssignedToNode, err := podutil.BuildGetPodsAssignedToNodeFunc(podInformer)
-	if err != nil {
-		t.Errorf("Build get pods assigned to node function error: %v", err)
-	}
-
-	sharedInformerFactory.Start(ctx.Done())
-	sharedInformerFactory.WaitForCacheSync(ctx.Done())
-
-	var nodesTraversed sync.Map
-	podFitsNodes(getPodsAssignedToNode, pod, nodes, func(pod *v1.Pod, node *v1.Node) bool {
-		nodesTraversed.Store(node.Name, node)
-		return true
-	})
-
-	for _, node := range nodes {
-		if _, exists := nodesTraversed.Load(node.Name); !exists {
-			t.Errorf("Node %v was not proccesed", node.Name)
-		}
-	}
-}
-
 func TestNodeFit(t *testing.T) {
 	node := test.BuildTestNode("node", 64000, 128*1000*1000*1000, 2, func(node *v1.Node) {
 		node.ObjectMeta.Labels = map[string]string{
@@ -1043,9 +852,9 @@ func TestNodeFit(t *testing.T) {
 
 			sharedInformerFactory.Start(ctx.Done())
 			sharedInformerFactory.WaitForCacheSync(ctx.Done())
-			err = NodeFit(getPodsAssignedToNode, tc.pod, tc.node)
-			if (err == nil && tc.err != nil) || (err != nil && err.Error() != tc.err.Error()) {
-				t.Errorf("Test %#v failed, got %v, expect %v", tc.description, err, tc.err)
+			errs := NodeFit(getPodsAssignedToNode, tc.pod, tc.node)
+			if (len(errs) == 0 && tc.err != nil) || (len(errs) > 0 && errs[0].Error() != tc.err.Error()) {
+				t.Errorf("Test %#v failed, got %v, expect %v", tc.description, errs, tc.err)
 			}
 		})
 	}
diff --git a/pkg/descheduler/policyconfig_test.go b/pkg/descheduler/policyconfig_test.go
index f6151b94f..7f415150b 100644
--- a/pkg/descheduler/policyconfig_test.go
+++ b/pkg/descheduler/policyconfig_test.go
@@ -22,9 +22,8 @@ import (
 
 	"github.com/google/go-cmp/cmp"
 	v1 "k8s.io/api/core/v1"
-	"k8s.io/apimachinery/pkg/conversion"
 	fakeclientset "k8s.io/client-go/kubernetes/fake"
-	utilptr "k8s.io/utils/ptr"
+	utilpointer "k8s.io/utils/pointer"
 	"sigs.k8s.io/descheduler/pkg/api"
 	"sigs.k8s.io/descheduler/pkg/api/v1alpha1"
 	"sigs.k8s.io/descheduler/pkg/framework/pluginregistry"
@@ -41,22 +40,6 @@ import (
 	"sigs.k8s.io/descheduler/pkg/utils"
 )
 
-// scope contains information about an ongoing conversion.
-type scope struct {
-	converter *conversion.Converter
-	meta      *conversion.Meta
-}
-
-// Convert continues a conversion.
-func (s scope) Convert(src, dest interface{}) error {
-	return s.converter.Convert(src, dest, s.meta)
-}
-
-// Meta returns the meta object that was originally passed to Convert.
-func (s scope) Meta() *conversion.Meta {
-	return s.meta
-}
-
 func TestV1alpha1ToV1alpha2(t *testing.T) {
 	SetupPlugins()
 	defaultEvictorPluginConfig := api.PluginConfig{
@@ -154,11 +137,11 @@ func TestV1alpha1ToV1alpha2(t *testing.T) {
 		{
 			description: "convert global policy fields to defaultevictor",
 			policy: &v1alpha1.DeschedulerPolicy{
-				EvictFailedBarePods:     utilptr.To(true),
-				EvictLocalStoragePods:   utilptr.To(true),
-				EvictSystemCriticalPods: utilptr.To(true),
-				EvictDaemonSetPods:      utilptr.To(true),
-				IgnorePVCPods:           utilptr.To(true),
+				EvictFailedBarePods:     utilpointer.Bool(true),
+				EvictLocalStoragePods:   utilpointer.Bool(true),
+				EvictSystemCriticalPods: utilpointer.Bool(true),
+				EvictDaemonSetPods:      utilpointer.Bool(true),
+				IgnorePVCPods:           utilpointer.Bool(true),
 				Strategies: v1alpha1.StrategyList{
 					removeduplicates.PluginName: v1alpha1.DeschedulerStrategy{
 						Enabled: true,
@@ -484,7 +467,7 @@ func TestV1alpha1ToV1alpha2(t *testing.T) {
 								Name: removepodsviolatingtopologyspreadconstraint.PluginName,
 								Args: &removepodsviolatingtopologyspreadconstraint.RemovePodsViolatingTopologySpreadConstraintArgs{
 									Constraints:            []v1.UnsatisfiableConstraintAction{v1.DoNotSchedule},
-									TopologyBalanceNodeFit: utilptr.To(true),
+									TopologyBalanceNodeFit: utilpointer.Bool(true),
 								},
 							},
 						},
@@ -550,7 +533,7 @@ func TestV1alpha1ToV1alpha2(t *testing.T) {
 						Enabled: true,
 						Params: &v1alpha1.StrategyParameters{
 							FailedPods: &v1alpha1.FailedPods{
-								MinPodLifetimeSeconds:   utilptr.To[uint](3600),
+								MinPodLifetimeSeconds:   utilpointer.Uint(3600),
 								ExcludeOwnerKinds:       []string{"Job"},
 								Reasons:                 []string{"NodeAffinity"},
 								IncludingInitContainers: true,
@@ -684,7 +667,7 @@ func TestV1alpha1ToV1alpha2(t *testing.T) {
 								Name: removefailedpods.PluginName,
 								Args: &removefailedpods.RemoveFailedPodsArgs{
 									ExcludeOwnerKinds:       []string{"Job"},
-									MinPodLifetimeSeconds:   utilptr.To[uint](3600),
+									MinPodLifetimeSeconds:   utilpointer.Uint(3600),
 									Reasons:                 []string{"NodeAffinity"},
 									IncludingInitContainers: true,
 								},
@@ -801,7 +784,7 @@ func TestV1alpha1ToV1alpha2(t *testing.T) {
 								Name: removepodsviolatingtopologyspreadconstraint.PluginName,
 								Args: &removepodsviolatingtopologyspreadconstraint.RemovePodsViolatingTopologySpreadConstraintArgs{
 									Constraints:            []v1.UnsatisfiableConstraintAction{v1.DoNotSchedule, v1.ScheduleAnyway},
-									TopologyBalanceNodeFit: utilptr.To(true),
+									TopologyBalanceNodeFit: utilpointer.Bool(true),
 								},
 							},
 						},
@@ -837,7 +820,7 @@ func TestV1alpha1ToV1alpha2(t *testing.T) {
 				nodeutilization.LowNodeUtilizationPluginName: v1alpha1.DeschedulerStrategy{
 					Enabled: true,
 					Params: &v1alpha1.StrategyParameters{
-						ThresholdPriority:          utilptr.To[int32](100),
+						ThresholdPriority:          utilpointer.Int32(100),
 						ThresholdPriorityClassName: "name",
 						NodeResourceUtilizationThresholds: &v1alpha1.NodeResourceUtilizationThresholds{
 							Thresholds: v1alpha1.ResourceThresholds{
@@ -888,7 +871,7 @@ func TestDecodeVersionedPolicy(t *testing.T) {
 		Name: defaultevictor.PluginName,
 		Args: &defaultevictor.DefaultEvictorArgs{
 			PriorityThreshold: &api.PriorityThreshold{
-				Value: utilptr.To[int32](utils.SystemCriticalPriority),
+				Value: utilpointer.Int32(utils.SystemCriticalPriority),
 			},
 		},
 	}
@@ -925,7 +908,7 @@ strategies:
 									Namespaces: &api.Namespaces{
 										Include: []string{"testleaderelection-a"},
 									},
-									MaxPodLifeTimeSeconds: utilptr.To[uint](5),
+									MaxPodLifeTimeSeconds: utilpointer.Uint(5),
 								},
 							},
 						},
@@ -969,7 +952,7 @@ strategies:
 								Name: "DefaultEvictor",
 								Args: &defaultevictor.DefaultEvictorArgs{
 									PriorityThreshold: &api.PriorityThreshold{
-										Value: utilptr.To[int32](0),
+										Value: utilpointer.Int32(0),
 									},
 								},
 							},
@@ -979,7 +962,7 @@ strategies:
 									Namespaces: &api.Namespaces{
 										Include: []string{"testleaderelection-a"},
 									},
-									MaxPodLifeTimeSeconds: utilptr.To[uint](5),
+									MaxPodLifeTimeSeconds: utilpointer.Uint(5),
 								},
 							},
 						},
@@ -1052,7 +1035,7 @@ profiles:
 									EvictFailedBarePods:     true,
 									EvictLocalStoragePods:   true,
 									EvictDaemonSetPods:      true,
-									PriorityThreshold:       &api.PriorityThreshold{Value: utilptr.To[int32](2000000000)},
+									PriorityThreshold:       &api.PriorityThreshold{Value: utilpointer.Int32(2000000000)},
 									NodeFit:                 true,
 								},
 							},
@@ -1209,14 +1192,14 @@ profiles:
 									EvictFailedBarePods:     true,
 									EvictLocalStoragePods:   true,
 									EvictDaemonSetPods:      true,
-									PriorityThreshold:       &api.PriorityThreshold{Value: utilptr.To[int32](2000000000)},
+									PriorityThreshold:       &api.PriorityThreshold{Value: utilpointer.Int32(2000000000)},
 									NodeFit:                 true,
 								},
 							},
 							{
 								Name: removefailedpods.PluginName,
 								Args: &removefailedpods.RemoveFailedPodsArgs{
-									MinPodLifetimeSeconds: utilptr.To[uint](3600),
+									MinPodLifetimeSeconds: utilpointer.Uint(3600),
 								},
 							},
 						},
@@ -1267,14 +1250,14 @@ profiles:
 									EvictFailedBarePods:     true,
 									EvictLocalStoragePods:   true,
 									EvictDaemonSetPods:      true,
-									PriorityThreshold:       &api.PriorityThreshold{Value: utilptr.To[int32](2000000000)},
+									PriorityThreshold:       &api.PriorityThreshold{Value: utilpointer.Int32(2000000000)},
 									NodeFit:                 true,
 								},
 							},
 							{
 								Name: removefailedpods.PluginName,
 								Args: &removefailedpods.RemoveFailedPodsArgs{
-									MinPodLifetimeSeconds: utilptr.To[uint](3600),
+									MinPodLifetimeSeconds: utilpointer.Uint(3600),
 								},
 							},
 						},
diff --git a/pkg/framework/plugins/defaultevictor/defaultevictor_test.go b/pkg/framework/plugins/defaultevictor/defaultevictor_test.go
index 16dcad49d..0cd3d804d 100644
--- a/pkg/framework/plugins/defaultevictor/defaultevictor_test.go
+++ b/pkg/framework/plugins/defaultevictor/defaultevictor_test.go
@@ -15,7 +15,6 @@ package defaultevictor
 
 import (
 	"context"
-	"fmt"
 	"testing"
 
 	v1 "k8s.io/api/core/v1"
@@ -32,19 +31,6 @@ import (
 	"sigs.k8s.io/descheduler/test"
 )
 
-type testCase struct {
-	description             string
-	pods                    []*v1.Pod
-	nodes                   []*v1.Node
-	evictFailedBarePods     bool
-	evictLocalStoragePods   bool
-	evictSystemCriticalPods bool
-	priorityThreshold       *int32
-	nodeFit                 bool
-	minReplicas             uint
-	result                  bool
-}
-
 func TestDefaultEvictorPreEvictionFilter(t *testing.T) {
 	n1 := test.BuildTestNode("node1", 1000, 2000, 13, nil)
 
@@ -53,6 +39,17 @@ func TestDefaultEvictorPreEvictionFilter(t *testing.T) {
 
 	nodeLabelKey := "datacenter"
 	nodeLabelValue := "east"
+	type testCase struct {
+		description             string
+		pods                    []*v1.Pod
+		nodes                   []*v1.Node
+		evictFailedBarePods     bool
+		evictLocalStoragePods   bool
+		evictSystemCriticalPods bool
+		priorityThreshold       *int32
+		nodeFit                 bool
+		result                  bool
+	}
 
 	testCases := []testCase{
 		{
@@ -308,7 +305,45 @@ func TestDefaultEvictorPreEvictionFilter(t *testing.T) {
 			ctx, cancel := context.WithCancel(context.Background())
 			defer cancel()
 
-			evictorPlugin, err := initializePlugin(ctx, test)
+			var objs []runtime.Object
+			for _, node := range test.nodes {
+				objs = append(objs, node)
+			}
+			for _, pod := range test.pods {
+				objs = append(objs, pod)
+			}
+
+			fakeClient := fake.NewSimpleClientset(objs...)
+
+			sharedInformerFactory := informers.NewSharedInformerFactory(fakeClient, 0)
+			podInformer := sharedInformerFactory.Core().V1().Pods().Informer()
+
+			getPodsAssignedToNode, err := podutil.BuildGetPodsAssignedToNodeFunc(podInformer)
+			if err != nil {
+				t.Errorf("Build get pods assigned to node function error: %v", err)
+			}
+
+			sharedInformerFactory.Start(ctx.Done())
+			sharedInformerFactory.WaitForCacheSync(ctx.Done())
+
+			defaultEvictorArgs := &DefaultEvictorArgs{
+				EvictLocalStoragePods:   test.evictLocalStoragePods,
+				EvictSystemCriticalPods: test.evictSystemCriticalPods,
+				IgnorePvcPods:           false,
+				EvictFailedBarePods:     test.evictFailedBarePods,
+				PriorityThreshold: &api.PriorityThreshold{
+					Value: test.priorityThreshold,
+				},
+				NodeFit: test.nodeFit,
+			}
+
+			evictorPlugin, err := New(
+				defaultEvictorArgs,
+				&frameworkfake.HandleImpl{
+					ClientsetImpl:                 fakeClient,
+					GetPodsAssignedToNodeFuncImpl: getPodsAssignedToNode,
+					SharedInformerFactoryImpl:     sharedInformerFactory,
+				})
 			if err != nil {
 				t.Fatalf("Unable to initialize the plugin: %v", err)
 			}
@@ -331,6 +366,19 @@ func TestDefaultEvictorFilter(t *testing.T) {
 
 	ownerRefUUID := uuid.NewUUID()
 
+	type testCase struct {
+		description             string
+		pods                    []*v1.Pod
+		nodes                   []*v1.Node
+		evictFailedBarePods     bool
+		evictLocalStoragePods   bool
+		evictSystemCriticalPods bool
+		priorityThreshold       *int32
+		nodeFit                 bool
+		minReplicas             uint
+		result                  bool
+	}
+
 	testCases := []testCase{
 		{
 			description: "Failed pod eviction with no ownerRefs",
@@ -709,106 +757,54 @@ func TestDefaultEvictorFilter(t *testing.T) {
 			ctx, cancel := context.WithCancel(context.Background())
 			defer cancel()
 
-			evictorPlugin, err := initializePlugin(ctx, test)
-			if err != nil {
-				t.Fatalf("Unable to initialize the plugin: %v", err)
+			var objs []runtime.Object
+			for _, node := range test.nodes {
+				objs = append(objs, node)
 			}
-
-			result := evictorPlugin.(frameworktypes.EvictorPlugin).Filter(test.pods[0])
-			if (result) != test.result {
-				t.Errorf("Filter should return for pod %s %t, but it returns %t", test.pods[0].Name, test.result, result)
+			for _, pod := range test.pods {
+				objs = append(objs, pod)
 			}
-		})
-	}
-}
 
-func TestReinitialization(t *testing.T) {
-	n1 := test.BuildTestNode("node1", 1000, 2000, 13, nil)
-	ownerRefUUID := uuid.NewUUID()
-
-	testCases := []testCase{
-		{
-			description: "minReplicas of 2, multiple owners, eviction",
-			pods: []*v1.Pod{
-				test.BuildTestPod("p1", 1, 1, n1.Name, func(pod *v1.Pod) {
-					pod.ObjectMeta.OwnerReferences = append(test.GetNormalPodOwnerRefList(), test.GetNormalPodOwnerRefList()...)
-					pod.ObjectMeta.OwnerReferences[0].UID = ownerRefUUID
-				}),
-				test.BuildTestPod("p2", 1, 1, n1.Name, func(pod *v1.Pod) {
-					pod.ObjectMeta.OwnerReferences = test.GetNormalPodOwnerRefList()
-				}),
-			},
-			minReplicas: 2,
-			result:      true,
-		},
-	}
+			fakeClient := fake.NewSimpleClientset(objs...)
 
-	for _, test := range testCases {
-		t.Run(test.description, func(t *testing.T) {
-			ctx, cancel := context.WithCancel(context.Background())
-			defer cancel()
+			sharedInformerFactory := informers.NewSharedInformerFactory(fakeClient, 0)
+			podInformer := sharedInformerFactory.Core().V1().Pods().Informer()
 
-			evictorPlugin, err := initializePlugin(ctx, test)
+			getPodsAssignedToNode, err := podutil.BuildGetPodsAssignedToNodeFunc(podInformer)
 			if err != nil {
-				t.Fatalf("Unable to initialize the plugin: %v", err)
+				t.Errorf("Build get pods assigned to node function error: %v", err)
 			}
 
-			defaultEvictor, ok := evictorPlugin.(*DefaultEvictor)
-			if !ok {
-				t.Fatalf("Unable to initialize as a DefaultEvictor plugin")
+			sharedInformerFactory.Start(ctx.Done())
+			sharedInformerFactory.WaitForCacheSync(ctx.Done())
+
+			defaultEvictorArgs := &DefaultEvictorArgs{
+				EvictLocalStoragePods:   test.evictLocalStoragePods,
+				EvictSystemCriticalPods: test.evictSystemCriticalPods,
+				IgnorePvcPods:           false,
+				EvictFailedBarePods:     test.evictFailedBarePods,
+				PriorityThreshold: &api.PriorityThreshold{
+					Value: test.priorityThreshold,
+				},
+				NodeFit:     test.nodeFit,
+				MinReplicas: test.minReplicas,
 			}
-			_, err = New(defaultEvictor.args, defaultEvictor.handle)
+
+			evictorPlugin, err := New(
+				defaultEvictorArgs,
+				&frameworkfake.HandleImpl{
+					ClientsetImpl:                 fakeClient,
+					GetPodsAssignedToNodeFuncImpl: getPodsAssignedToNode,
+					SharedInformerFactoryImpl:     sharedInformerFactory,
+				})
 			if err != nil {
-				t.Fatalf("Unable to reinitialize the plugin: %v", err)
+				t.Fatalf("Unable to initialize the plugin: %v", err)
 			}
-		})
-	}
-}
-
-func initializePlugin(ctx context.Context, test testCase) (frameworktypes.Plugin, error) {
-	var objs []runtime.Object
-	for _, node := range test.nodes {
-		objs = append(objs, node)
-	}
-	for _, pod := range test.pods {
-		objs = append(objs, pod)
-	}
-
-	fakeClient := fake.NewSimpleClientset(objs...)
-
-	sharedInformerFactory := informers.NewSharedInformerFactory(fakeClient, 0)
-	podInformer := sharedInformerFactory.Core().V1().Pods().Informer()
-
-	getPodsAssignedToNode, err := podutil.BuildGetPodsAssignedToNodeFunc(podInformer)
-	if err != nil {
-		return nil, fmt.Errorf("build get pods assigned to node function error: %v", err)
-	}
-
-	sharedInformerFactory.Start(ctx.Done())
-	sharedInformerFactory.WaitForCacheSync(ctx.Done())
 
-	defaultEvictorArgs := &DefaultEvictorArgs{
-		EvictLocalStoragePods:   test.evictLocalStoragePods,
-		EvictSystemCriticalPods: test.evictSystemCriticalPods,
-		IgnorePvcPods:           false,
-		EvictFailedBarePods:     test.evictFailedBarePods,
-		PriorityThreshold: &api.PriorityThreshold{
-			Value: test.priorityThreshold,
-		},
-		NodeFit:     test.nodeFit,
-		MinReplicas: test.minReplicas,
-	}
-
-	evictorPlugin, err := New(
-		defaultEvictorArgs,
-		&frameworkfake.HandleImpl{
-			ClientsetImpl:                 fakeClient,
-			GetPodsAssignedToNodeFuncImpl: getPodsAssignedToNode,
-			SharedInformerFactoryImpl:     sharedInformerFactory,
+			result := evictorPlugin.(frameworktypes.EvictorPlugin).Filter(test.pods[0])
+			if (result) != test.result {
+				t.Errorf("Filter should return for pod %s %t, but it returns %t", test.pods[0].Name, test.result, result)
+			}
 		})
-	if err != nil {
-		return nil, fmt.Errorf("unable to initialize the plugin: %v", err)
 	}
-
-	return evictorPlugin, nil
 }
diff --git a/pkg/framework/plugins/defaultevictor/defaults_test.go b/pkg/framework/plugins/defaultevictor/defaults_test.go
index 026af73be..165935687 100644
--- a/pkg/framework/plugins/defaultevictor/defaults_test.go
+++ b/pkg/framework/plugins/defaultevictor/defaults_test.go
@@ -19,7 +19,7 @@ import (
 	"github.com/google/go-cmp/cmp"
 	"k8s.io/apimachinery/pkg/runtime"
 	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
-	utilptr "k8s.io/utils/ptr"
+	"k8s.io/utils/pointer"
 	"sigs.k8s.io/descheduler/pkg/api"
 )
 
@@ -55,7 +55,7 @@ func TestSetDefaults_DefaultEvictorArgs(t *testing.T) {
 				EvictFailedBarePods:     true,
 				LabelSelector:           nil,
 				PriorityThreshold: &api.PriorityThreshold{
-					Value: utilptr.To[int32](800),
+					Value: pointer.Int32(800),
 				},
 				NodeFit: true,
 			},
@@ -68,7 +68,7 @@ func TestSetDefaults_DefaultEvictorArgs(t *testing.T) {
 				EvictFailedBarePods:     true,
 				LabelSelector:           nil,
 				PriorityThreshold: &api.PriorityThreshold{
-					Value: utilptr.To[int32](800),
+					Value: pointer.Int32(800),
 				},
 				NodeFit: true,
 			},
diff --git a/pkg/framework/plugins/nodeutilization/highnodeutilization_test.go b/pkg/framework/plugins/nodeutilization/highnodeutilization_test.go
index 1f4fd5cd5..bfe55594e 100644
--- a/pkg/framework/plugins/nodeutilization/highnodeutilization_test.go
+++ b/pkg/framework/plugins/nodeutilization/highnodeutilization_test.go
@@ -115,7 +115,6 @@ func TestHighNodeUtilization(t *testing.T) {
 				}),
 				test.BuildTestPod("p2", 400, 0, n1NodeName, func(pod *v1.Pod) {
 					// A Critical Pod.
-					test.SetNormalOwnerRef(pod)
 					pod.Namespace = "kube-system"
 					priority := utils.SystemCriticalPriority
 					pod.Spec.Priority = &priority
@@ -168,7 +167,6 @@ func TestHighNodeUtilization(t *testing.T) {
 				// These won't be evicted.
 				test.BuildTestPod("p2", 400, 0, n1NodeName, func(pod *v1.Pod) {
 					// A Critical Pod.
-					test.SetNormalOwnerRef(pod)
 					pod.Namespace = "kube-system"
 					priority := utils.SystemCriticalPriority
 					pod.Spec.Priority = &priority
@@ -486,7 +484,16 @@ func TestHighNodeUtilization(t *testing.T) {
 
 			eventRecorder := &events.FakeRecorder{}
 
-			podEvictor := evictions.NewPodEvictor(fakeClient, eventRecorder, nil)
+			podEvictor := evictions.NewPodEvictor(
+				fakeClient,
+				"v1",
+				false,
+				nil,
+				nil,
+				testCase.nodes,
+				false,
+				eventRecorder,
+			)
 
 			defaultevictorArgs := &defaultevictor.DefaultEvictorArgs{
 				EvictLocalStoragePods:   false,
@@ -631,8 +638,13 @@ func TestHighNodeUtilizationWithTaints(t *testing.T) {
 
 			podEvictor := evictions.NewPodEvictor(
 				fakeClient,
+				"policy/v1",
+				false,
+				&item.evictionsExpected,
+				nil,
+				item.nodes,
+				false,
 				eventRecorder,
-				evictions.NewOptions().WithMaxPodsToEvictPerNode(&item.evictionsExpected),
 			)
 
 			defaultevictorArgs := &defaultevictor.DefaultEvictorArgs{
diff --git a/pkg/framework/plugins/nodeutilization/lownodeutilization_test.go b/pkg/framework/plugins/nodeutilization/lownodeutilization_test.go
index ab167b667..63ade79f0 100644
--- a/pkg/framework/plugins/nodeutilization/lownodeutilization_test.go
+++ b/pkg/framework/plugins/nodeutilization/lownodeutilization_test.go
@@ -175,23 +175,18 @@ func TestLowNodeUtilization(t *testing.T) {
 			},
 			pods: []*v1.Pod{
 				test.BuildTestPod("p1", 400, 0, n1NodeName, func(pod *v1.Pod) {
-					test.SetNormalOwnerRef(pod)
 					pod.Namespace = "namespace1"
 				}),
 				test.BuildTestPod("p2", 400, 0, n1NodeName, func(pod *v1.Pod) {
-					test.SetNormalOwnerRef(pod)
 					pod.Namespace = "namespace1"
 				}),
 				test.BuildTestPod("p3", 400, 0, n1NodeName, func(pod *v1.Pod) {
-					test.SetNormalOwnerRef(pod)
 					pod.Namespace = "namespace1"
 				}),
 				test.BuildTestPod("p4", 400, 0, n1NodeName, func(pod *v1.Pod) {
-					test.SetNormalOwnerRef(pod)
 					pod.Namespace = "namespace1"
 				}),
 				test.BuildTestPod("p5", 400, 0, n1NodeName, func(pod *v1.Pod) {
-					test.SetNormalOwnerRef(pod)
 					pod.Namespace = "namespace1"
 				}),
 				// These won't be evicted.
@@ -247,15 +242,12 @@ func TestLowNodeUtilization(t *testing.T) {
 				test.BuildTestPod("p1", 400, 0, n1NodeName, test.SetRSOwnerRef),
 				test.BuildTestPod("p2", 400, 0, n1NodeName, test.SetRSOwnerRef),
 				test.BuildTestPod("p3", 400, 0, n1NodeName, func(pod *v1.Pod) {
-					// TODO(zhifei92): add ownerRef for pod
 					pod.Namespace = "namespace3"
 				}),
 				test.BuildTestPod("p4", 400, 0, n1NodeName, func(pod *v1.Pod) {
-					// TODO(zhifei92): add ownerRef for pod
 					pod.Namespace = "namespace4"
 				}),
 				test.BuildTestPod("p5", 400, 0, n1NodeName, func(pod *v1.Pod) {
-					// TODO(zhifei92): add ownerRef for pod
 					pod.Namespace = "namespace5"
 				}),
 				// These won't be evicted.
@@ -279,7 +271,6 @@ func TestLowNodeUtilization(t *testing.T) {
 				}),
 				test.BuildTestPod("p8", 400, 0, n1NodeName, func(pod *v1.Pod) {
 					// A Critical Pod.
-					test.SetNormalOwnerRef(pod)
 					pod.Namespace = "kube-system"
 					priority := utils.SystemCriticalPriority
 					pod.Spec.Priority = &priority
@@ -335,7 +326,6 @@ func TestLowNodeUtilization(t *testing.T) {
 				}),
 				test.BuildTestPod("p8", 400, 300, n1NodeName, func(pod *v1.Pod) {
 					// A Critical Pod.
-					test.SetNormalOwnerRef(pod)
 					pod.Namespace = "kube-system"
 					priority := utils.SystemCriticalPriority
 					pod.Spec.Priority = &priority
@@ -406,7 +396,6 @@ func TestLowNodeUtilization(t *testing.T) {
 				}),
 				test.BuildTestPod("p8", 400, 0, n1NodeName, func(pod *v1.Pod) {
 					// A Critical Pod.
-					test.SetNormalOwnerRef(pod)
 					pod.Namespace = "kube-system"
 					priority := utils.SystemCriticalPriority
 					pod.Spec.Priority = &priority
@@ -430,7 +419,7 @@ func TestLowNodeUtilization(t *testing.T) {
 				test.BuildTestNode(n2NodeName, 4000, 3000, 10, nil),
 				test.BuildTestNode(n3NodeName, 4000, 3000, 10, test.SetNodeUnschedulable),
 			},
-			// All pods are assumed to be burstable (tc.BuildTestNode always sets both cpu/memory resource requests to some value)
+			// All pods are assumed to be burstable (test.BuildTestNode always sets both cpu/memory resource requests to some value)
 			pods: []*v1.Pod{
 				test.BuildTestPod("p1", 400, 0, n1NodeName, func(pod *v1.Pod) {
 					test.SetRSOwnerRef(pod)
@@ -474,7 +463,6 @@ func TestLowNodeUtilization(t *testing.T) {
 				}),
 				test.BuildTestPod("p8", 400, 0, n1NodeName, func(pod *v1.Pod) {
 					// A Critical Pod.
-					test.SetNormalOwnerRef(pod)
 					pod.Namespace = "kube-system"
 					priority := utils.SystemCriticalPriority
 					pod.Spec.Priority = &priority
@@ -550,7 +538,6 @@ func TestLowNodeUtilization(t *testing.T) {
 				}),
 				test.BuildTestPod("p8", 0, 0, n1NodeName, func(pod *v1.Pod) {
 					// A Critical Pod.
-					test.SetNormalOwnerRef(pod)
 					test.SetPodExtendedResourceRequest(pod, extendedResource, 1)
 					pod.Namespace = "kube-system"
 					priority := utils.SystemCriticalPriority
@@ -633,7 +620,6 @@ func TestLowNodeUtilization(t *testing.T) {
 				}),
 				test.BuildTestPod("p8", 400, 0, n1NodeName, func(pod *v1.Pod) {
 					// A Critical Pod.
-					test.SetNormalOwnerRef(pod)
 					pod.Namespace = "kube-system"
 					priority := utils.SystemCriticalPriority
 					pod.Spec.Priority = &priority
@@ -698,7 +684,6 @@ func TestLowNodeUtilization(t *testing.T) {
 				}),
 				test.BuildTestPod("p8", 400, 0, n1NodeName, func(pod *v1.Pod) {
 					// A Critical Pod.
-					test.SetNormalOwnerRef(pod)
 					pod.Namespace = "kube-system"
 					priority := utils.SystemCriticalPriority
 					pod.Spec.Priority = &priority
@@ -791,7 +776,6 @@ func TestLowNodeUtilization(t *testing.T) {
 				}),
 				test.BuildTestPod("p8", 400, 0, n1NodeName, func(pod *v1.Pod) {
 					// A Critical Pod.
-					test.SetNormalOwnerRef(pod)
 					pod.Namespace = "kube-system"
 					priority := utils.SystemCriticalPriority
 					pod.Spec.Priority = &priority
@@ -843,7 +827,6 @@ func TestLowNodeUtilization(t *testing.T) {
 				}),
 				test.BuildTestPod("p8", 400, 0, n1NodeName, func(pod *v1.Pod) {
 					// A Critical Pod.
-					test.SetNormalOwnerRef(pod)
 					pod.Namespace = "kube-system"
 					priority := utils.SystemCriticalPriority
 					pod.Spec.Priority = &priority
@@ -855,16 +838,16 @@ func TestLowNodeUtilization(t *testing.T) {
 		},
 	}
 
-	for _, tc := range testCases {
-		t.Run(tc.name, func(t *testing.T) {
+	for _, test := range testCases {
+		t.Run(test.name, func(t *testing.T) {
 			ctx, cancel := context.WithCancel(context.Background())
 			defer cancel()
 
 			var objs []runtime.Object
-			for _, node := range tc.nodes {
+			for _, node := range test.nodes {
 				objs = append(objs, node)
 			}
-			for _, pod := range tc.pods {
+			for _, pod := range test.pods {
 				objs = append(objs, pod)
 			}
 			fakeClient := fake.NewSimpleClientset(objs...)
@@ -878,12 +861,12 @@ func TestLowNodeUtilization(t *testing.T) {
 			}
 
 			podsForEviction := make(map[string]struct{})
-			for _, pod := range tc.evictedPods {
+			for _, pod := range test.evictedPods {
 				podsForEviction[pod] = struct{}{}
 			}
 
 			evictionFailed := false
-			if len(tc.evictedPods) > 0 {
+			if len(test.evictedPods) > 0 {
 				fakeClient.Fake.AddReactor("create", "pods", func(action core.Action) (bool, runtime.Object, error) {
 					getAction := action.(core.CreateAction)
 					obj := getAction.GetObject()
@@ -903,7 +886,16 @@ func TestLowNodeUtilization(t *testing.T) {
 
 			eventRecorder := &events.FakeRecorder{}
 
-			podEvictor := evictions.NewPodEvictor(fakeClient, eventRecorder, nil)
+			podEvictor := evictions.NewPodEvictor(
+				fakeClient,
+				policy.SchemeGroupVersion.String(),
+				false,
+				nil,
+				nil,
+				test.nodes,
+				false,
+				eventRecorder,
+			)
 
 			defaultEvictorFilterArgs := &defaultevictor.DefaultEvictorArgs{
 				EvictLocalStoragePods:   false,
@@ -934,20 +926,20 @@ func TestLowNodeUtilization(t *testing.T) {
 			}
 
 			plugin, err := NewLowNodeUtilization(&LowNodeUtilizationArgs{
-				Thresholds:             tc.thresholds,
-				TargetThresholds:       tc.targetThresholds,
-				UseDeviationThresholds: tc.useDeviationThresholds,
-				EvictableNamespaces:    tc.evictableNamespaces,
+				Thresholds:             test.thresholds,
+				TargetThresholds:       test.targetThresholds,
+				UseDeviationThresholds: test.useDeviationThresholds,
+				EvictableNamespaces:    test.evictableNamespaces,
 			},
 				handle)
 			if err != nil {
 				t.Fatalf("Unable to initialize the plugin: %v", err)
 			}
-			plugin.(frameworktypes.BalancePlugin).Balance(ctx, tc.nodes)
+			plugin.(frameworktypes.BalancePlugin).Balance(ctx, test.nodes)
 
 			podsEvicted := podEvictor.TotalEvicted()
-			if tc.expectedPodsEvicted != podsEvicted {
-				t.Errorf("Expected %v pods to be evicted but %v got evicted", tc.expectedPodsEvicted, podsEvicted)
+			if test.expectedPodsEvicted != podsEvicted {
+				t.Errorf("Expected %v pods to be evicted but %v got evicted", test.expectedPodsEvicted, podsEvicted)
 			}
 			if evictionFailed {
 				t.Errorf("Pod evictions failed unexpectedly")
@@ -979,14 +971,11 @@ func TestLowNodeUtilizationWithTaints(t *testing.T) {
 		},
 	}
 
-	var uint0, uint1 uint = 0, 1
 	tests := []struct {
-		name                  string
-		nodes                 []*v1.Node
-		pods                  []*v1.Pod
-		maxPodsToEvictPerNode *uint
-		maxPodsToEvictTotal   *uint
-		evictionsExpected     uint
+		name              string
+		nodes             []*v1.Node
+		pods              []*v1.Pod
+		evictionsExpected uint
 	}{
 		{
 			name:  "No taints",
@@ -1042,26 +1031,6 @@ func TestLowNodeUtilizationWithTaints(t *testing.T) {
 			},
 			evictionsExpected: 1,
 		},
-		{
-			name:  "Pod which tolerates node taint, set maxPodsToEvictTotal(0), should not be expelled",
-			nodes: []*v1.Node{n1, n3withTaints},
-			pods: []*v1.Pod{
-				// Node 1 pods
-				test.BuildTestPod(fmt.Sprintf("pod_1_%s", n1.Name), 200, 0, n1.Name, test.SetRSOwnerRef),
-				test.BuildTestPod(fmt.Sprintf("pod_2_%s", n1.Name), 200, 0, n1.Name, test.SetRSOwnerRef),
-				test.BuildTestPod(fmt.Sprintf("pod_3_%s", n1.Name), 200, 0, n1.Name, test.SetRSOwnerRef),
-				test.BuildTestPod(fmt.Sprintf("pod_4_%s", n1.Name), 200, 0, n1.Name, test.SetRSOwnerRef),
-				test.BuildTestPod(fmt.Sprintf("pod_5_%s", n1.Name), 200, 0, n1.Name, test.SetRSOwnerRef),
-				test.BuildTestPod(fmt.Sprintf("pod_6_%s", n1.Name), 200, 0, n1.Name, test.SetRSOwnerRef),
-				test.BuildTestPod(fmt.Sprintf("pod_7_%s", n1.Name), 200, 0, n1.Name, test.SetRSOwnerRef),
-				podThatToleratesTaint,
-				// Node 3 pods
-				test.BuildTestPod(fmt.Sprintf("pod_9_%s", n3withTaints.Name), 200, 0, n3withTaints.Name, test.SetRSOwnerRef),
-			},
-			maxPodsToEvictPerNode: &uint1,
-			maxPodsToEvictTotal:   &uint0,
-			evictionsExpected:     0,
-		},
 	}
 
 	for _, item := range tests {
@@ -1091,8 +1060,13 @@ func TestLowNodeUtilizationWithTaints(t *testing.T) {
 
 			podEvictor := evictions.NewPodEvictor(
 				fakeClient,
+				policy.SchemeGroupVersion.String(),
+				false,
+				&item.evictionsExpected,
+				nil,
+				item.nodes,
+				false,
 				eventRecorder,
-				evictions.NewOptions().WithMaxPodsToEvictPerNode(&item.evictionsExpected),
 			)
 
 			defaultEvictorFilterArgs := &defaultevictor.DefaultEvictorArgs{
diff --git a/pkg/framework/plugins/podlifetime/defaults_test.go b/pkg/framework/plugins/podlifetime/defaults_test.go
index 7a6a64e3c..70d4b1766 100644
--- a/pkg/framework/plugins/podlifetime/defaults_test.go
+++ b/pkg/framework/plugins/podlifetime/defaults_test.go
@@ -20,7 +20,7 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
-	utilptr "k8s.io/utils/ptr"
+	"k8s.io/utils/pointer"
 	"sigs.k8s.io/descheduler/pkg/api"
 )
 
@@ -47,7 +47,7 @@ func TestSetDefaults_PodLifeTimeArgs(t *testing.T) {
 				LabelSelector: &metav1.LabelSelector{
 					MatchLabels: map[string]string{"foo": "bar"},
 				},
-				MaxPodLifeTimeSeconds: utilptr.To[uint](600),
+				MaxPodLifeTimeSeconds: pointer.Uint(600),
 				States:                []string{"Pending"},
 			},
 			want: &PodLifeTimeArgs{
@@ -55,7 +55,7 @@ func TestSetDefaults_PodLifeTimeArgs(t *testing.T) {
 				LabelSelector: &metav1.LabelSelector{
 					MatchLabels: map[string]string{"foo": "bar"},
 				},
-				MaxPodLifeTimeSeconds: utilptr.To[uint](600),
+				MaxPodLifeTimeSeconds: pointer.Uint(600),
 				States:                []string{"Pending"},
 			},
 		},
diff --git a/pkg/framework/plugins/podlifetime/pod_lifetime_test.go b/pkg/framework/plugins/podlifetime/pod_lifetime_test.go
index e0ca64843..16536cbc3 100644
--- a/pkg/framework/plugins/podlifetime/pod_lifetime_test.go
+++ b/pkg/framework/plugins/podlifetime/pod_lifetime_test.go
@@ -22,6 +22,7 @@ import (
 	"time"
 
 	v1 "k8s.io/api/core/v1"
+	policyv1 "k8s.io/api/policy/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/client-go/informers"
@@ -156,7 +157,6 @@ func TestPodLifeTime(t *testing.T) {
 		ignorePvcPods              bool
 		maxPodsToEvictPerNode      *uint
 		maxPodsToEvictPerNamespace *uint
-		maxPodsToEvictTotal        *uint
 		applyPodsFunc              func(pods []*v1.Pod)
 	}{
 		{
@@ -315,17 +315,6 @@ func TestPodLifeTime(t *testing.T) {
 			maxPodsToEvictPerNamespace: utilptr.To[uint](1),
 			expectedEvictedPodCount:    1,
 		},
-		{
-			description: "1 Oldest pod should be evicted when maxPodsToEvictTotal is set to 1",
-			args: &PodLifeTimeArgs{
-				MaxPodLifeTimeSeconds: &maxLifeTime,
-			},
-			pods:                       []*v1.Pod{p1, p2, p9},
-			nodes:                      []*v1.Node{node1},
-			maxPodsToEvictPerNamespace: utilptr.To[uint](2),
-			maxPodsToEvictTotal:        utilptr.To[uint](1),
-			expectedEvictedPodCount:    1,
-		},
 		{
 			description: "1 Oldest pod should be evicted when maxPodsToEvictPerNode is set to 1",
 			args: &PodLifeTimeArgs{
@@ -569,11 +558,13 @@ func TestPodLifeTime(t *testing.T) {
 
 			podEvictor := evictions.NewPodEvictor(
 				fakeClient,
+				policyv1.SchemeGroupVersion.String(),
+				false,
+				tc.maxPodsToEvictPerNode,
+				tc.maxPodsToEvictPerNamespace,
+				tc.nodes,
+				false,
 				eventRecorder,
-				evictions.NewOptions().
-					WithMaxPodsToEvictPerNode(tc.maxPodsToEvictPerNode).
-					WithMaxPodsToEvictPerNamespace(tc.maxPodsToEvictPerNamespace).
-					WithMaxPodsToEvictTotal(tc.maxPodsToEvictTotal),
 			)
 
 			defaultEvictorFilterArgs := &defaultevictor.DefaultEvictorArgs{
diff --git a/pkg/framework/plugins/removeduplicates/removeduplicates_test.go b/pkg/framework/plugins/removeduplicates/removeduplicates_test.go
index 26d90e36a..6a14ba878 100644
--- a/pkg/framework/plugins/removeduplicates/removeduplicates_test.go
+++ b/pkg/framework/plugins/removeduplicates/removeduplicates_test.go
@@ -26,6 +26,7 @@ import (
 	frameworktypes "sigs.k8s.io/descheduler/pkg/framework/types"
 
 	v1 "k8s.io/api/core/v1"
+	policyv1 "k8s.io/api/policy/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
@@ -312,7 +313,16 @@ func TestFindDuplicatePods(t *testing.T) {
 
 			eventRecorder := &events.FakeRecorder{}
 
-			podEvictor := evictions.NewPodEvictor(fakeClient, eventRecorder, nil)
+			podEvictor := evictions.NewPodEvictor(
+				fakeClient,
+				"v1",
+				false,
+				nil,
+				nil,
+				testCase.nodes,
+				false,
+				eventRecorder,
+			)
 
 			nodeFit := testCase.nodefit
 
@@ -752,7 +762,16 @@ func TestRemoveDuplicatesUniformly(t *testing.T) {
 
 			eventRecorder := &events.FakeRecorder{}
 
-			podEvictor := evictions.NewPodEvictor(fakeClient, eventRecorder, nil)
+			podEvictor := evictions.NewPodEvictor(
+				fakeClient,
+				policyv1.SchemeGroupVersion.String(),
+				false,
+				nil,
+				nil,
+				testCase.nodes,
+				false,
+				eventRecorder,
+			)
 
 			defaultEvictorFilterArgs := &defaultevictor.DefaultEvictorArgs{
 				EvictLocalStoragePods:   false,
diff --git a/pkg/framework/plugins/removefailedpods/defaults_test.go b/pkg/framework/plugins/removefailedpods/defaults_test.go
index 406b9002a..fa7bb210e 100644
--- a/pkg/framework/plugins/removefailedpods/defaults_test.go
+++ b/pkg/framework/plugins/removefailedpods/defaults_test.go
@@ -20,7 +20,7 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
-	utilptr "k8s.io/utils/ptr"
+	"k8s.io/utils/pointer"
 	"sigs.k8s.io/descheduler/pkg/api"
 )
 
@@ -48,7 +48,7 @@ func TestSetDefaults_RemoveFailedPodsArgs(t *testing.T) {
 				Namespaces:              &api.Namespaces{},
 				LabelSelector:           &metav1.LabelSelector{},
 				ExcludeOwnerKinds:       []string{"ReplicaSet"},
-				MinPodLifetimeSeconds:   utilptr.To[uint](0),
+				MinPodLifetimeSeconds:   pointer.Uint(0),
 				Reasons:                 []string{"reason"},
 				IncludingInitContainers: true,
 			},
@@ -56,7 +56,7 @@ func TestSetDefaults_RemoveFailedPodsArgs(t *testing.T) {
 				Namespaces:              &api.Namespaces{},
 				LabelSelector:           &metav1.LabelSelector{},
 				ExcludeOwnerKinds:       []string{"ReplicaSet"},
-				MinPodLifetimeSeconds:   utilptr.To[uint](0),
+				MinPodLifetimeSeconds:   pointer.Uint(0),
 				Reasons:                 []string{"reason"},
 				IncludingInitContainers: true,
 			},
diff --git a/pkg/framework/plugins/removefailedpods/failedpods_test.go b/pkg/framework/plugins/removefailedpods/failedpods_test.go
index c148d796e..d052fc670 100644
--- a/pkg/framework/plugins/removefailedpods/failedpods_test.go
+++ b/pkg/framework/plugins/removefailedpods/failedpods_test.go
@@ -21,6 +21,7 @@ import (
 	"testing"
 
 	v1 "k8s.io/api/core/v1"
+	policyv1 "k8s.io/api/policy/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/client-go/informers"
@@ -374,7 +375,16 @@ func TestRemoveFailedPods(t *testing.T) {
 
 			eventRecorder := &events.FakeRecorder{}
 
-			podEvictor := evictions.NewPodEvictor(fakeClient, eventRecorder, nil)
+			podEvictor := evictions.NewPodEvictor(
+				fakeClient,
+				policyv1.SchemeGroupVersion.String(),
+				false,
+				nil,
+				nil,
+				tc.nodes,
+				false,
+				eventRecorder,
+			)
 
 			defaultevictorArgs := &defaultevictor.DefaultEvictorArgs{
 				EvictLocalStoragePods:   false,
diff --git a/pkg/framework/plugins/removepodshavingtoomanyrestarts/toomanyrestarts_test.go b/pkg/framework/plugins/removepodshavingtoomanyrestarts/toomanyrestarts_test.go
index 188e971a3..bf50e89ae 100644
--- a/pkg/framework/plugins/removepodshavingtoomanyrestarts/toomanyrestarts_test.go
+++ b/pkg/framework/plugins/removepodshavingtoomanyrestarts/toomanyrestarts_test.go
@@ -22,6 +22,7 @@ import (
 	"testing"
 
 	v1 "k8s.io/api/core/v1"
+	policyv1 "k8s.io/api/policy/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/client-go/informers"
@@ -311,8 +312,8 @@ func TestRemovePodsHavingTooManyRestarts(t *testing.T) {
 		t.Run(tc.description, func(t *testing.T) {
 			pods := append(
 				initPods(node1),
-				test.BuildTestPod("CPU-consumer-1", 150, 100, node4.Name, test.SetNormalOwnerRef),
-				test.BuildTestPod("CPU-consumer-2", 150, 100, node5.Name, test.SetNormalOwnerRef),
+				test.BuildTestPod("CPU-consumer-1", 150, 100, node4.Name, nil),
+				test.BuildTestPod("CPU-consumer-2", 150, 100, node5.Name, nil),
 			)
 			if tc.applyFunc != nil {
 				tc.applyFunc(pods)
@@ -345,10 +346,13 @@ func TestRemovePodsHavingTooManyRestarts(t *testing.T) {
 
 			podEvictor := evictions.NewPodEvictor(
 				fakeClient,
+				policyv1.SchemeGroupVersion.String(),
+				false,
+				tc.maxPodsToEvictPerNode,
+				tc.maxNoOfPodsToEvictPerNamespace,
+				tc.nodes,
+				false,
 				eventRecorder,
-				evictions.NewOptions().
-					WithMaxPodsToEvictPerNode(tc.maxPodsToEvictPerNode).
-					WithMaxPodsToEvictPerNamespace(tc.maxNoOfPodsToEvictPerNamespace),
 			)
 
 			defaultevictorArgs := &defaultevictor.DefaultEvictorArgs{
diff --git a/pkg/framework/plugins/removepodsviolatinginterpodantiaffinity/pod_antiaffinity_test.go b/pkg/framework/plugins/removepodsviolatinginterpodantiaffinity/pod_antiaffinity_test.go
index c6d434d04..648298844 100644
--- a/pkg/framework/plugins/removepodsviolatinginterpodantiaffinity/pod_antiaffinity_test.go
+++ b/pkg/framework/plugins/removepodsviolatinginterpodantiaffinity/pod_antiaffinity_test.go
@@ -21,6 +21,7 @@ import (
 	"testing"
 
 	v1 "k8s.io/api/core/v1"
+	policyv1 "k8s.io/api/policy/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/client-go/informers"
@@ -121,7 +122,6 @@ func TestPodAntiAffinity(t *testing.T) {
 		description                    string
 		maxPodsToEvictPerNode          *uint
 		maxNoOfPodsToEvictPerNamespace *uint
-		maxNoOfPodsToEvictTotal        *uint
 		pods                           []*v1.Pod
 		expectedEvictedPodCount        uint
 		nodeFit                        bool
@@ -147,14 +147,6 @@ func TestPodAntiAffinity(t *testing.T) {
 			nodes:                          []*v1.Node{node1},
 			expectedEvictedPodCount:        3,
 		},
-		{
-			description:                    "Maximum pods to evict (maxNoOfPodsToEvictTotal)",
-			maxNoOfPodsToEvictPerNamespace: &uint3,
-			maxNoOfPodsToEvictTotal:        &uint1,
-			pods:                           []*v1.Pod{p1, p2, p3, p4},
-			nodes:                          []*v1.Node{node1},
-			expectedEvictedPodCount:        1,
-		},
 		{
 			description:             "Evict only 1 pod after sorting",
 			pods:                    []*v1.Pod{p5, p6, p7},
@@ -243,11 +235,13 @@ func TestPodAntiAffinity(t *testing.T) {
 
 			podEvictor := evictions.NewPodEvictor(
 				fakeClient,
+				policyv1.SchemeGroupVersion.String(),
+				false,
+				test.maxPodsToEvictPerNode,
+				test.maxNoOfPodsToEvictPerNamespace,
+				test.nodes,
+				false,
 				eventRecorder,
-				evictions.NewOptions().
-					WithMaxPodsToEvictPerNode(test.maxPodsToEvictPerNode).
-					WithMaxPodsToEvictPerNamespace(test.maxNoOfPodsToEvictPerNamespace).
-					WithMaxPodsToEvictTotal(test.maxNoOfPodsToEvictTotal),
 			)
 
 			defaultevictorArgs := &defaultevictor.DefaultEvictorArgs{
diff --git a/pkg/framework/plugins/removepodsviolatingnodeaffinity/node_affinity_test.go b/pkg/framework/plugins/removepodsviolatingnodeaffinity/node_affinity_test.go
index 200193a10..9cf0cdd2a 100644
--- a/pkg/framework/plugins/removepodsviolatingnodeaffinity/node_affinity_test.go
+++ b/pkg/framework/plugins/removepodsviolatingnodeaffinity/node_affinity_test.go
@@ -21,6 +21,7 @@ import (
 	"testing"
 
 	v1 "k8s.io/api/core/v1"
+	policyv1 "k8s.io/api/policy/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/client-go/informers"
@@ -119,7 +120,6 @@ func TestRemovePodsViolatingNodeAffinity(t *testing.T) {
 		expectedEvictedPodCount        uint
 		maxPodsToEvictPerNode          *uint
 		maxNoOfPodsToEvictPerNamespace *uint
-		maxNoOfPodsToEvictTotal        *uint
 		args                           RemovePodsViolatingNodeAffinityArgs
 		nodefit                        bool
 	}{
@@ -238,17 +238,6 @@ func TestRemovePodsViolatingNodeAffinity(t *testing.T) {
 			nodes:                          []*v1.Node{nodeWithoutLabels, nodeWithLabels},
 			maxNoOfPodsToEvictPerNamespace: &uint1,
 		},
-		{
-			description:             "Pod is scheduled on node without matching labels, another schedulable node available, maxNoOfPodsToEvictTotal set to 0, should not be evicted [required affinity]",
-			expectedEvictedPodCount: 0,
-			args: RemovePodsViolatingNodeAffinityArgs{
-				NodeAffinityType: []string{"requiredDuringSchedulingIgnoredDuringExecution"},
-			},
-			pods:                           addPodsToNode(nodeWithoutLabels, nil, "requiredDuringSchedulingIgnoredDuringExecution"),
-			nodes:                          []*v1.Node{nodeWithoutLabels, nodeWithLabels},
-			maxNoOfPodsToEvictPerNamespace: &uint1,
-			maxNoOfPodsToEvictTotal:        &uint0,
-		},
 		{
 			description:             "Pod is scheduled on node without matching labels, another schedulable node available, maxNoOfPodsToEvictPerNamespace set to 1, should be evicted [preferred affinity]",
 			expectedEvictedPodCount: 1,
@@ -372,11 +361,13 @@ func TestRemovePodsViolatingNodeAffinity(t *testing.T) {
 
 			podEvictor := evictions.NewPodEvictor(
 				fakeClient,
+				policyv1.SchemeGroupVersion.String(),
+				false,
+				tc.maxPodsToEvictPerNode,
+				tc.maxNoOfPodsToEvictPerNamespace,
+				tc.nodes,
+				false,
 				eventRecorder,
-				evictions.NewOptions().
-					WithMaxPodsToEvictPerNode(tc.maxPodsToEvictPerNode).
-					WithMaxPodsToEvictPerNamespace(tc.maxNoOfPodsToEvictPerNamespace).
-					WithMaxPodsToEvictTotal(tc.maxNoOfPodsToEvictTotal),
 			)
 
 			defaultevictorArgs := &defaultevictor.DefaultEvictorArgs{
diff --git a/pkg/framework/plugins/removepodsviolatingnodetaints/node_taint_test.go b/pkg/framework/plugins/removepodsviolatingnodetaints/node_taint_test.go
index b09177403..1cbfc3e54 100644
--- a/pkg/framework/plugins/removepodsviolatingnodetaints/node_taint_test.go
+++ b/pkg/framework/plugins/removepodsviolatingnodetaints/node_taint_test.go
@@ -22,6 +22,7 @@ import (
 	"testing"
 
 	v1 "k8s.io/api/core/v1"
+	policyv1 "k8s.io/api/policy/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/client-go/informers"
@@ -109,12 +110,6 @@ func TestDeletePodsViolatingNodeTaints(t *testing.T) {
 	p4 := test.BuildTestPod("p4", 100, 0, node1.Name, nil)
 	p5 := test.BuildTestPod("p5", 100, 0, node1.Name, nil)
 	p6 := test.BuildTestPod("p6", 100, 0, node1.Name, nil)
-	p7 := test.BuildTestPod("p7", 100, 0, node2.Name, nil)
-	p8 := test.BuildTestPod("p8", 100, 0, node2.Name, nil)
-	p9 := test.BuildTestPod("p9", 100, 0, node2.Name, nil)
-	p10 := test.BuildTestPod("p10", 100, 0, node2.Name, nil)
-	p11 := test.BuildTestPod("p11", 100, 0, node2.Name, nil)
-	p12 := test.BuildTestPod("p11", 100, 0, node2.Name, nil)
 
 	p1.ObjectMeta.OwnerReferences = test.GetNormalPodOwnerRefList()
 	p2.ObjectMeta.OwnerReferences = test.GetNormalPodOwnerRefList()
@@ -122,11 +117,13 @@ func TestDeletePodsViolatingNodeTaints(t *testing.T) {
 	p4.ObjectMeta.OwnerReferences = test.GetNormalPodOwnerRefList()
 	p5.ObjectMeta.OwnerReferences = test.GetNormalPodOwnerRefList()
 	p6.ObjectMeta.OwnerReferences = test.GetNormalPodOwnerRefList()
-	p7.ObjectMeta.OwnerReferences = test.GetNormalPodOwnerRefList()
-	p8.ObjectMeta.OwnerReferences = test.GetNormalPodOwnerRefList()
-	p9.ObjectMeta.OwnerReferences = test.GetNormalPodOwnerRefList()
-	p10.ObjectMeta.OwnerReferences = test.GetNormalPodOwnerRefList()
+	p7 := test.BuildTestPod("p7", 100, 0, node2.Name, nil)
+	p8 := test.BuildTestPod("p8", 100, 0, node2.Name, nil)
+	p9 := test.BuildTestPod("p9", 100, 0, node2.Name, nil)
+	p10 := test.BuildTestPod("p10", 100, 0, node2.Name, nil)
+	p11 := test.BuildTestPod("p11", 100, 0, node2.Name, nil)
 	p11.ObjectMeta.OwnerReferences = test.GetNormalPodOwnerRefList()
+	p12 := test.BuildTestPod("p11", 100, 0, node2.Name, nil)
 	p12.ObjectMeta.OwnerReferences = test.GetNormalPodOwnerRefList()
 
 	// The following 4 pods won't get evicted.
@@ -177,7 +174,7 @@ func TestDeletePodsViolatingNodeTaints(t *testing.T) {
 	p15 = addTolerationToPod(p15, "testTaint", "test", 1, v1.TaintEffectNoSchedule)
 	p15 = addTolerationToPod(p15, "testingTaint", "testing", 1, v1.TaintEffectNoSchedule)
 
-	var uint1, uint2 uint = 1, 2
+	var uint1 uint = 1
 
 	tests := []struct {
 		description                    string
@@ -187,7 +184,6 @@ func TestDeletePodsViolatingNodeTaints(t *testing.T) {
 		evictSystemCriticalPods        bool
 		maxPodsToEvictPerNode          *uint
 		maxNoOfPodsToEvictPerNamespace *uint
-		maxNoOfPodsToEvictTotal        *uint
 		expectedEvictedPodCount        uint
 		nodeFit                        bool
 		includePreferNoSchedule        bool
@@ -210,16 +206,6 @@ func TestDeletePodsViolatingNodeTaints(t *testing.T) {
 			evictSystemCriticalPods: false,
 			expectedEvictedPodCount: 1, // p4 gets evicted
 		},
-		{
-			description:             "Only <maxNoOfPodsToEvictTotal> number of Pods not tolerating node taint should be evicted",
-			pods:                    []*v1.Pod{p1, p5, p6},
-			nodes:                   []*v1.Node{node1},
-			evictLocalStoragePods:   false,
-			evictSystemCriticalPods: false,
-			maxPodsToEvictPerNode:   &uint2,
-			maxNoOfPodsToEvictTotal: &uint1,
-			expectedEvictedPodCount: 1, // p5 or p6 gets evicted
-		},
 		{
 			description:             "Only <maxPodsToEvictPerNode> number of Pods not tolerating node taint should be evicted",
 			pods:                    []*v1.Pod{p1, p5, p6},
@@ -238,15 +224,6 @@ func TestDeletePodsViolatingNodeTaints(t *testing.T) {
 			maxNoOfPodsToEvictPerNamespace: &uint1,
 			expectedEvictedPodCount:        1, // p5 or p6 gets evicted
 		},
-		{
-			description:                    "Only <maxNoOfPodsToEvictPerNamespace> number of Pods not tolerating node taint should be evicted",
-			pods:                           []*v1.Pod{p1, p5, p6},
-			nodes:                          []*v1.Node{node1},
-			evictLocalStoragePods:          false,
-			evictSystemCriticalPods:        false,
-			maxNoOfPodsToEvictPerNamespace: &uint1,
-			expectedEvictedPodCount:        1, // p5 or p6 gets evicted
-		},
 		{
 			description:             "Critical pods not tolerating node taint should not be evicted",
 			pods:                    []*v1.Pod{p7, p8, p9, p10},
@@ -425,11 +402,13 @@ func TestDeletePodsViolatingNodeTaints(t *testing.T) {
 
 			podEvictor := evictions.NewPodEvictor(
 				fakeClient,
+				policyv1.SchemeGroupVersion.String(),
+				false,
+				tc.maxPodsToEvictPerNode,
+				tc.maxNoOfPodsToEvictPerNamespace,
+				tc.nodes,
+				false,
 				eventRecorder,
-				evictions.NewOptions().
-					WithMaxPodsToEvictPerNode(tc.maxPodsToEvictPerNode).
-					WithMaxPodsToEvictPerNamespace(tc.maxNoOfPodsToEvictPerNamespace).
-					WithMaxPodsToEvictTotal(tc.maxNoOfPodsToEvictTotal),
 			)
 
 			defaultevictorArgs := &defaultevictor.DefaultEvictorArgs{
diff --git a/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/defaults_test.go b/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/defaults_test.go
index 0901e7087..926e08562 100644
--- a/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/defaults_test.go
+++ b/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/defaults_test.go
@@ -21,7 +21,7 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
-	utilptr "k8s.io/utils/ptr"
+	utilpointer "k8s.io/utils/pointer"
 	"sigs.k8s.io/descheduler/pkg/api"
 )
 
@@ -48,7 +48,7 @@ func TestSetDefaults_RemovePodsViolatingTopologySpreadConstraintArgs(t *testing.
 				Namespaces:             nil,
 				LabelSelector:          nil,
 				Constraints:            []v1.UnsatisfiableConstraintAction{v1.DoNotSchedule},
-				TopologyBalanceNodeFit: utilptr.To(true),
+				TopologyBalanceNodeFit: utilpointer.Bool(true),
 			},
 		},
 		{
@@ -62,7 +62,7 @@ func TestSetDefaults_RemovePodsViolatingTopologySpreadConstraintArgs(t *testing.
 				Namespaces:             &api.Namespaces{},
 				LabelSelector:          &metav1.LabelSelector{},
 				Constraints:            []v1.UnsatisfiableConstraintAction{v1.DoNotSchedule, v1.ScheduleAnyway},
-				TopologyBalanceNodeFit: utilptr.To(true),
+				TopologyBalanceNodeFit: utilpointer.Bool(true),
 			},
 		},
 		{
@@ -70,16 +70,16 @@ func TestSetDefaults_RemovePodsViolatingTopologySpreadConstraintArgs(t *testing.
 			in:   &RemovePodsViolatingTopologySpreadConstraintArgs{},
 			want: &RemovePodsViolatingTopologySpreadConstraintArgs{
 				Constraints:            []v1.UnsatisfiableConstraintAction{v1.DoNotSchedule},
-				TopologyBalanceNodeFit: utilptr.To(true),
+				TopologyBalanceNodeFit: utilpointer.Bool(true),
 			},
 		},
 		{
 			name: "RemovePodsViolatingTopologySpreadConstraintArgs with TopologyBalanceNodeFit=false",
 			in: &RemovePodsViolatingTopologySpreadConstraintArgs{
-				TopologyBalanceNodeFit: utilptr.To(false),
+				TopologyBalanceNodeFit: utilpointer.Bool(false),
 			},
 			want: &RemovePodsViolatingTopologySpreadConstraintArgs{
-				TopologyBalanceNodeFit: utilptr.To(false),
+				TopologyBalanceNodeFit: utilpointer.Bool(false),
 				Constraints:            []v1.UnsatisfiableConstraintAction{v1.DoNotSchedule},
 			},
 		},
@@ -90,7 +90,7 @@ func TestSetDefaults_RemovePodsViolatingTopologySpreadConstraintArgs(t *testing.
 			},
 			want: &RemovePodsViolatingTopologySpreadConstraintArgs{
 				Constraints:            []v1.UnsatisfiableConstraintAction{v1.DoNotSchedule},
-				TopologyBalanceNodeFit: utilptr.To(true),
+				TopologyBalanceNodeFit: utilpointer.Bool(true),
 			},
 		},
 	}
diff --git a/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/topologyspreadconstraint_test.go b/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/topologyspreadconstraint_test.go
index c62336d79..d7ab72682 100644
--- a/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/topologyspreadconstraint_test.go
+++ b/pkg/framework/plugins/removepodsviolatingtopologyspreadconstraint/topologyspreadconstraint_test.go
@@ -16,7 +16,7 @@ import (
 	"k8s.io/client-go/kubernetes/fake"
 	core "k8s.io/client-go/testing"
 	"k8s.io/client-go/tools/events"
-	utilptr "k8s.io/utils/ptr"
+	utilpointer "k8s.io/utils/pointer"
 
 	"sigs.k8s.io/descheduler/pkg/api"
 	"sigs.k8s.io/descheduler/pkg/descheduler/evictions"
@@ -1205,7 +1205,7 @@ func TestTopologySpreadConstraint(t *testing.T) {
 			}),
 			expectedEvictedCount: 1,
 			namespaces:           []string{"ns1"},
-			args:                 RemovePodsViolatingTopologySpreadConstraintArgs{TopologyBalanceNodeFit: utilptr.To(false)},
+			args:                 RemovePodsViolatingTopologySpreadConstraintArgs{TopologyBalanceNodeFit: utilpointer.Bool(false)},
 			nodeFit:              true,
 		},
 		{
@@ -1456,7 +1456,16 @@ func TestTopologySpreadConstraint(t *testing.T) {
 
 			eventRecorder := &events.FakeRecorder{}
 
-			podEvictor := evictions.NewPodEvictor(fakeClient, eventRecorder, nil)
+			podEvictor := evictions.NewPodEvictor(
+				fakeClient,
+				"v1",
+				false,
+				nil,
+				nil,
+				tc.nodes,
+				false,
+				eventRecorder,
+			)
 
 			defaultevictorArgs := &defaultevictor.DefaultEvictorArgs{
 				EvictLocalStoragePods:   false,
diff --git a/pkg/framework/profile/profile_test.go b/pkg/framework/profile/profile_test.go
index 481586627..8823c57a6 100644
--- a/pkg/framework/profile/profile_test.go
+++ b/pkg/framework/profile/profile_test.go
@@ -185,11 +185,10 @@ func TestProfileDescheduleBalanceExtensionPointsEviction(t *testing.T) {
 			if test.extensionPoint == frameworktypes.DescheduleExtensionPoint {
 				fakePlugin.AddReactor(string(frameworktypes.DescheduleExtensionPoint), func(action fakeplugin.Action) (handled, filter bool, err error) {
 					if dAction, ok := action.(fakeplugin.DescheduleAction); ok {
-						err := dAction.Handle().Evictor().Evict(ctx, p1, evictions.EvictOptions{StrategyName: fakePlugin.PluginName})
-						if err == nil {
+						if dAction.Handle().Evictor().Evict(ctx, p1, evictions.EvictOptions{StrategyName: fakePlugin.PluginName}) {
 							return true, false, nil
 						}
-						return true, false, fmt.Errorf("pod not evicted: %v", err)
+						return true, false, fmt.Errorf("pod not evicted")
 					}
 					return false, false, nil
 				})
@@ -197,11 +196,10 @@ func TestProfileDescheduleBalanceExtensionPointsEviction(t *testing.T) {
 			if test.extensionPoint == frameworktypes.BalanceExtensionPoint {
 				fakePlugin.AddReactor(string(frameworktypes.BalanceExtensionPoint), func(action fakeplugin.Action) (handled, filter bool, err error) {
 					if dAction, ok := action.(fakeplugin.BalanceAction); ok {
-						err := dAction.Handle().Evictor().Evict(ctx, p1, evictions.EvictOptions{StrategyName: fakePlugin.PluginName})
-						if err == nil {
+						if dAction.Handle().Evictor().Evict(ctx, p1, evictions.EvictOptions{StrategyName: fakePlugin.PluginName}) {
 							return true, false, nil
 						}
-						return true, false, fmt.Errorf("pod not evicted: %v", err)
+						return true, false, fmt.Errorf("pod not evicted")
 					}
 					return false, false, nil
 				})
@@ -246,7 +244,7 @@ func TestProfileDescheduleBalanceExtensionPointsEviction(t *testing.T) {
 			eventBroadcaster, eventRecorder := utils.GetRecorderAndBroadcaster(ctx, eventClient)
 			defer eventBroadcaster.Shutdown()
 
-			podEvictor := evictions.NewPodEvictor(client, eventRecorder, nil)
+			podEvictor := evictions.NewPodEvictor(client, "policy/v1", false, nil, nil, nodes, true, eventRecorder)
 
 			prfl, err := NewProfile(
 				test.config,
@@ -308,6 +306,7 @@ func TestProfileExtensionPoints(t *testing.T) {
 
 	n1 := testutils.BuildTestNode("n1", 2000, 3000, 10, nil)
 	n2 := testutils.BuildTestNode("n2", 2000, 3000, 10, nil)
+	nodes := []*v1.Node{n1, n2}
 
 	p1 := testutils.BuildTestPod(fmt.Sprintf("pod_1_%s", n1.Name), 200, 0, n1.Name, nil)
 	p1.ObjectMeta.OwnerReferences = []metav1.OwnerReference{{}}
@@ -394,7 +393,7 @@ func TestProfileExtensionPoints(t *testing.T) {
 	eventBroadcaster, eventRecorder := utils.GetRecorderAndBroadcaster(ctx, eventClient)
 	defer eventBroadcaster.Shutdown()
 
-	podEvictor := evictions.NewPodEvictor(client, eventRecorder, nil)
+	podEvictor := evictions.NewPodEvictor(client, "policy/v1", false, nil, nil, nodes, true, eventRecorder)
 
 	prfl, err := NewProfile(
 		api.DeschedulerProfile{
@@ -606,7 +605,7 @@ func TestProfileExtensionPointOrdering(t *testing.T) {
 	eventBroadcaster, eventRecorder := utils.GetRecorderAndBroadcaster(ctx, eventClient)
 	defer eventBroadcaster.Shutdown()
 
-	podEvictor := evictions.NewPodEvictor(client, eventRecorder, nil)
+	podEvictor := evictions.NewPodEvictor(client, "policy/v1", false, nil, nil, nodes, true, eventRecorder)
 
 	prfl, err := NewProfile(
 		api.DeschedulerProfile{
diff --git a/test/e2e/e2e_duplicatepods_test.go b/test/e2e/e2e_duplicatepods_test.go
index e0f543bdf..4eb94df90 100644
--- a/test/e2e/e2e_duplicatepods_test.go
+++ b/test/e2e/e2e_duplicatepods_test.go
@@ -32,7 +32,8 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/labels"
 	"k8s.io/client-go/tools/events"
-	utilptr "k8s.io/utils/ptr"
+	"k8s.io/utils/pointer"
+	utilpointer "k8s.io/utils/pointer"
 	"sigs.k8s.io/descheduler/pkg/descheduler/evictions"
 	eutils "sigs.k8s.io/descheduler/pkg/descheduler/evictions/utils"
 )
@@ -40,14 +41,15 @@ import (
 func TestRemoveDuplicates(t *testing.T) {
 	ctx := context.Background()
 
-	clientSet, sharedInformerFactory, _, getPodsAssignedToNode := initializeClient(ctx, t)
+	clientSet, sharedInformerFactory, _, getPodsAssignedToNode, stopCh := initializeClient(t)
+	defer close(stopCh)
 
 	nodeList, err := clientSet.CoreV1().Nodes().List(ctx, metav1.ListOptions{})
 	if err != nil {
 		t.Errorf("Error listing node with %v", err)
 	}
 
-	_, workerNodes := splitNodesAndWorkerNodes(nodeList.Items)
+	nodes, workerNodes := splitNodesAndWorkerNodes(nodeList.Items)
 
 	t.Log("Creating testing namespace")
 	testNamespace := &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "e2e-" + strings.ToLower(t.Name())}}
@@ -74,9 +76,9 @@ func TestRemoveDuplicates(t *testing.T) {
 				},
 				Spec: v1.PodSpec{
 					SecurityContext: &v1.PodSecurityContext{
-						RunAsNonRoot: utilptr.To(true),
-						RunAsUser:    utilptr.To[int64](1000),
-						RunAsGroup:   utilptr.To[int64](1000),
+						RunAsNonRoot: utilpointer.Bool(true),
+						RunAsUser:    utilpointer.Int64(1000),
+						RunAsGroup:   utilpointer.Int64(1000),
 						SeccompProfile: &v1.SeccompProfile{
 							Type: v1.SeccompProfileTypeRuntimeDefault,
 						},
@@ -87,7 +89,7 @@ func TestRemoveDuplicates(t *testing.T) {
 						Image:           "registry.k8s.io/pause",
 						Ports:           []v1.ContainerPort{{ContainerPort: 80}},
 						SecurityContext: &v1.SecurityContext{
-							AllowPrivilegeEscalation: utilptr.To(false),
+							AllowPrivilegeEscalation: utilpointer.Bool(false),
 							Capabilities: &v1.Capabilities{
 								Drop: []v1.Capability{
 									"ALL",
@@ -111,7 +113,7 @@ func TestRemoveDuplicates(t *testing.T) {
 			description: "Evict Pod even Pods schedule to specific node",
 			replicasNum: 4,
 			beforeFunc: func(deployment *appsv1.Deployment) {
-				deployment.Spec.Replicas = utilptr.To[int32](4)
+				deployment.Spec.Replicas = pointer.Int32(4)
 				deployment.Spec.Template.Spec.NodeName = workerNodes[0].Name
 			},
 			expectedEvictedPodCount: 2,
@@ -120,7 +122,7 @@ func TestRemoveDuplicates(t *testing.T) {
 			description: "Evict Pod even Pods with local storage",
 			replicasNum: 5,
 			beforeFunc: func(deployment *appsv1.Deployment) {
-				deployment.Spec.Replicas = utilptr.To[int32](5)
+				deployment.Spec.Replicas = pointer.Int32(5)
 				deployment.Spec.Template.Spec.Volumes = []v1.Volume{
 					{
 						Name: "sample",
@@ -138,7 +140,7 @@ func TestRemoveDuplicates(t *testing.T) {
 			description: "Ignores eviction with minReplicas of 4",
 			replicasNum: 3,
 			beforeFunc: func(deployment *appsv1.Deployment) {
-				deployment.Spec.Replicas = utilptr.To[int32](3)
+				deployment.Spec.Replicas = pointer.Int32(3)
 			},
 			expectedEvictedPodCount: 0,
 			minReplicas:             4,
@@ -170,7 +172,16 @@ func TestRemoveDuplicates(t *testing.T) {
 
 			eventRecorder := &events.FakeRecorder{}
 
-			podEvictor := evictions.NewPodEvictor(clientSet, eventRecorder, nil)
+			podEvictor := evictions.NewPodEvictor(
+				clientSet,
+				evictionPolicyGroupVersion,
+				false,
+				nil,
+				nil,
+				nodes,
+				false,
+				eventRecorder,
+			)
 
 			defaultevictorArgs := &defaultevictor.DefaultEvictorArgs{
 				EvictLocalStoragePods:   true,
diff --git a/test/e2e/e2e_failedpods_test.go b/test/e2e/e2e_failedpods_test.go
index ac4a7cd09..6908d3f36 100644
--- a/test/e2e/e2e_failedpods_test.go
+++ b/test/e2e/e2e_failedpods_test.go
@@ -12,7 +12,7 @@ import (
 	"k8s.io/apimachinery/pkg/labels"
 	"k8s.io/apimachinery/pkg/util/wait"
 	clientset "k8s.io/client-go/kubernetes"
-	utilptr "k8s.io/utils/ptr"
+	"k8s.io/utils/pointer"
 	frameworkfake "sigs.k8s.io/descheduler/pkg/framework/fake"
 	"sigs.k8s.io/descheduler/pkg/framework/plugins/defaultevictor"
 	"sigs.k8s.io/descheduler/pkg/framework/plugins/removefailedpods"
@@ -24,7 +24,8 @@ var oneHourPodLifetimeSeconds uint = 3600
 
 func TestFailedPods(t *testing.T) {
 	ctx := context.Background()
-	clientSet, sharedInformerFactory, _, getPodsAssignedToNode := initializeClient(ctx, t)
+	clientSet, sharedInformerFactory, _, getPodsAssignedToNode, stopCh := initializeClient(t)
+	defer close(stopCh)
 	nodeList, err := clientSet.CoreV1().Nodes().List(ctx, metav1.ListOptions{})
 	if err != nil {
 		t.Errorf("Error listing node with %v", err)
@@ -75,7 +76,7 @@ func TestFailedPods(t *testing.T) {
 			defer jobClient.Delete(ctx, job.Name, metav1.DeleteOptions{PropagationPolicy: &deletePropagationPolicy})
 			waitForJobPodPhase(ctx, t, clientSet, job, v1.PodFailed)
 
-			podEvictor := initPodEvictorOrFail(t, clientSet, getPodsAssignedToNode)
+			podEvictor := initPodEvictorOrFail(t, clientSet, getPodsAssignedToNode, nodes)
 
 			defaultevictorArgs := &defaultevictor.DefaultEvictorArgs{
 				EvictLocalStoragePods:   true,
@@ -146,14 +147,14 @@ func initFailedJob(name, namespace string) *batchv1.Job {
 				Spec:       podSpec,
 				ObjectMeta: metav1.ObjectMeta{Labels: labelsSet},
 			},
-			BackoffLimit: utilptr.To[int32](0),
+			BackoffLimit: pointer.Int32(0),
 		},
 	}
 }
 
 func waitForJobPodPhase(ctx context.Context, t *testing.T, clientSet clientset.Interface, job *batchv1.Job, phase v1.PodPhase) {
 	podClient := clientSet.CoreV1().Pods(job.Namespace)
-	if err := wait.PollUntilContextTimeout(ctx, 5*time.Second, 30*time.Second, true, func(ctx context.Context) (bool, error) {
+	if err := wait.PollImmediate(5*time.Second, 30*time.Second, func() (bool, error) {
 		t.Log(labels.FormatLabels(job.Labels))
 		if podList, err := podClient.List(ctx, metav1.ListOptions{LabelSelector: labels.FormatLabels(job.Labels)}); err != nil {
 			return false, err
diff --git a/test/e2e/e2e_leaderelection_test.go b/test/e2e/e2e_leaderelection_test.go
index 705ef28b1..9b4937b6c 100644
--- a/test/e2e/e2e_leaderelection_test.go
+++ b/test/e2e/e2e_leaderelection_test.go
@@ -30,7 +30,9 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/labels"
 	clientset "k8s.io/client-go/kubernetes"
-	utilptr "k8s.io/utils/ptr"
+	"k8s.io/utils/pointer"
+
+	utilpointer "k8s.io/utils/pointer"
 	"sigs.k8s.io/descheduler/cmd/descheduler/app/options"
 	"sigs.k8s.io/descheduler/pkg/descheduler"
 )
@@ -39,7 +41,8 @@ func TestLeaderElection(t *testing.T) {
 	descheduler.SetupPlugins()
 	ctx := context.Background()
 
-	clientSet, _, _, _ := initializeClient(ctx, t)
+	clientSet, _, _, _, stopCh := initializeClient(t)
+	defer close(stopCh)
 
 	ns1 := "e2e-" + strings.ToLower(t.Name()+"-a")
 	ns2 := "e2e-" + strings.ToLower(t.Name()+"-b")
@@ -153,7 +156,7 @@ func createDeployment(ctx context.Context, clientSet clientset.Interface, namesp
 			Labels:    map[string]string{"test": "leaderelection", "name": "test-leaderelection"},
 		},
 		Spec: appsv1.DeploymentSpec{
-			Replicas: utilptr.To[int32](replicas),
+			Replicas: pointer.Int32(replicas),
 			Selector: &metav1.LabelSelector{
 				MatchLabels: map[string]string{"test": "leaderelection", "name": "test-leaderelection"},
 			},
@@ -163,9 +166,9 @@ func createDeployment(ctx context.Context, clientSet clientset.Interface, namesp
 				},
 				Spec: v1.PodSpec{
 					SecurityContext: &v1.PodSecurityContext{
-						RunAsNonRoot: utilptr.To(true),
-						RunAsUser:    utilptr.To[int64](1000),
-						RunAsGroup:   utilptr.To[int64](1000),
+						RunAsNonRoot: utilpointer.Bool(true),
+						RunAsUser:    utilpointer.Int64(1000),
+						RunAsGroup:   utilpointer.Int64(1000),
 						SeccompProfile: &v1.SeccompProfile{
 							Type: v1.SeccompProfileTypeRuntimeDefault,
 						},
@@ -176,7 +179,7 @@ func createDeployment(ctx context.Context, clientSet clientset.Interface, namesp
 						Image:           "registry.k8s.io/pause",
 						Ports:           []v1.ContainerPort{{ContainerPort: 80}},
 						SecurityContext: &v1.SecurityContext{
-							AllowPrivilegeEscalation: utilptr.To(false),
+							AllowPrivilegeEscalation: utilpointer.Bool(false),
 							Capabilities: &v1.Capabilities{
 								Drop: []v1.Capability{
 									"ALL",
diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go
index e9f9629ac..2ae907480 100644
--- a/test/e2e/e2e_test.go
+++ b/test/e2e/e2e_test.go
@@ -39,7 +39,8 @@ import (
 	listersv1 "k8s.io/client-go/listers/core/v1"
 	"k8s.io/client-go/tools/events"
 	componentbaseconfig "k8s.io/component-base/config"
-	utilptr "k8s.io/utils/ptr"
+	"k8s.io/utils/pointer"
+	utilpointer "k8s.io/utils/pointer"
 	"sigs.k8s.io/descheduler/cmd/descheduler/app/options"
 	"sigs.k8s.io/descheduler/pkg/api"
 	deschedulerapi "sigs.k8s.io/descheduler/pkg/api"
@@ -63,7 +64,7 @@ func RcByNameContainer(name, namespace string, replicas int32, labels map[string
 	// Add "name": name to the labels, overwriting if it exists.
 	labels["name"] = name
 	if gracePeriod == nil {
-		gracePeriod = utilptr.To[int64](0)
+		gracePeriod = pointer.Int64(0)
 	}
 	return &v1.ReplicationController{
 		TypeMeta: metav1.TypeMeta{
@@ -75,7 +76,7 @@ func RcByNameContainer(name, namespace string, replicas int32, labels map[string
 			Namespace: namespace,
 		},
 		Spec: v1.ReplicationControllerSpec{
-			Replicas: utilptr.To[int32](replicas),
+			Replicas: pointer.Int32(replicas),
 			Selector: map[string]string{
 				"name": name,
 			},
@@ -94,7 +95,7 @@ func DsByNameContainer(name, namespace string, labels map[string]string, gracePe
 	// Add "name": name to the labels, overwriting if it exists.
 	labels["name"] = name
 	if gracePeriod == nil {
-		gracePeriod = utilptr.To[int64](0)
+		gracePeriod = pointer.Int64(0)
 	}
 	return &appsv1.DaemonSet{
 		TypeMeta: metav1.TypeMeta{
@@ -121,12 +122,14 @@ func DsByNameContainer(name, namespace string, labels map[string]string, gracePe
 	}
 }
 
-func initializeClient(ctx context.Context, t *testing.T) (clientset.Interface, informers.SharedInformerFactory, listersv1.NodeLister, podutil.GetPodsAssignedToNodeFunc) {
+func initializeClient(t *testing.T) (clientset.Interface, informers.SharedInformerFactory, listersv1.NodeLister, podutil.GetPodsAssignedToNodeFunc, chan struct{}) {
 	clientSet, err := client.CreateClient(componentbaseconfig.ClientConnectionConfiguration{Kubeconfig: os.Getenv("KUBECONFIG")}, "")
 	if err != nil {
 		t.Errorf("Error during client creation with %v", err)
 	}
 
+	stopChannel := make(chan struct{})
+
 	sharedInformerFactory := informers.NewSharedInformerFactory(clientSet, 0)
 	nodeLister := sharedInformerFactory.Core().V1().Nodes().Lister()
 	podInformer := sharedInformerFactory.Core().V1().Pods().Informer()
@@ -136,15 +139,15 @@ func initializeClient(ctx context.Context, t *testing.T) (clientset.Interface, i
 		t.Errorf("build get pods assigned to node function error: %v", err)
 	}
 
-	sharedInformerFactory.Start(ctx.Done())
-	sharedInformerFactory.WaitForCacheSync(ctx.Done())
+	sharedInformerFactory.Start(stopChannel)
+	sharedInformerFactory.WaitForCacheSync(stopChannel)
 
-	waitForNodesReady(ctx, t, clientSet, nodeLister)
-	return clientSet, sharedInformerFactory, nodeLister, getPodsAssignedToNode
+	waitForNodesReady(context.Background(), t, clientSet, nodeLister)
+	return clientSet, sharedInformerFactory, nodeLister, getPodsAssignedToNode, stopChannel
 }
 
 func waitForNodesReady(ctx context.Context, t *testing.T, clientSet clientset.Interface, nodeLister listersv1.NodeLister) {
-	if err := wait.PollUntilContextTimeout(ctx, 5*time.Second, 30*time.Second, true, func(ctx context.Context) (bool, error) {
+	if err := wait.PollImmediate(5*time.Second, 30*time.Second, func() (bool, error) {
 		nodeList, err := clientSet.CoreV1().Nodes().List(ctx, metav1.ListOptions{})
 		if err != nil {
 			return false, err
@@ -191,10 +194,13 @@ func runPodLifetimePlugin(
 
 	podEvictor := evictions.NewPodEvictor(
 		clientset,
+		evictionPolicyGroupVersion,
+		false,
+		nil,
+		maxPodsToEvictPerNamespace,
+		nodes,
+		false,
 		&events.FakeRecorder{},
-		evictions.NewOptions().
-			WithPolicyGroupVersion(evictionPolicyGroupVersion).
-			WithMaxPodsToEvictPerNamespace(maxPodsToEvictPerNamespace),
 	)
 
 	var thresholdPriority int32
@@ -274,14 +280,15 @@ func intersectStrings(lista, listb []string) []string {
 func TestLowNodeUtilization(t *testing.T) {
 	ctx := context.Background()
 
-	clientSet, sharedInformerFactory, _, getPodsAssignedToNode := initializeClient(ctx, t)
+	clientSet, sharedInformerFactory, _, getPodsAssignedToNode, stopCh := initializeClient(t)
+	defer close(stopCh)
 
 	nodeList, err := clientSet.CoreV1().Nodes().List(ctx, metav1.ListOptions{})
 	if err != nil {
 		t.Errorf("Error listing node with %v", err)
 	}
 
-	_, workerNodes := splitNodesAndWorkerNodes(nodeList.Items)
+	nodes, workerNodes := splitNodesAndWorkerNodes(nodeList.Items)
 
 	t.Log("Creating testing namespace")
 	testNamespace := &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "e2e-" + strings.ToLower(t.Name())}}
@@ -311,9 +318,9 @@ func TestLowNodeUtilization(t *testing.T) {
 			},
 			Spec: v1.PodSpec{
 				SecurityContext: &v1.PodSecurityContext{
-					RunAsNonRoot: utilptr.To(true),
-					RunAsUser:    utilptr.To[int64](1000),
-					RunAsGroup:   utilptr.To[int64](1000),
+					RunAsNonRoot: utilpointer.Bool(true),
+					RunAsUser:    utilpointer.Int64(1000),
+					RunAsGroup:   utilpointer.Int64(1000),
 					SeccompProfile: &v1.SeccompProfile{
 						Type: v1.SeccompProfileTypeRuntimeDefault,
 					},
@@ -370,7 +377,7 @@ func TestLowNodeUtilization(t *testing.T) {
 	waitForRCPodsRunning(ctx, t, clientSet, rc)
 
 	// Run LowNodeUtilization plugin
-	podEvictor := initPodEvictorOrFail(t, clientSet, getPodsAssignedToNode)
+	podEvictor := initPodEvictorOrFail(t, clientSet, getPodsAssignedToNode, nodes)
 
 	defaultevictorArgs := &defaultevictor.DefaultEvictorArgs{
 		EvictLocalStoragePods:   true,
@@ -444,7 +451,8 @@ func TestLowNodeUtilization(t *testing.T) {
 func TestNamespaceConstraintsInclude(t *testing.T) {
 	ctx := context.Background()
 
-	clientSet, _, nodeInformer, getPodsAssignedToNode := initializeClient(ctx, t)
+	clientSet, _, nodeInformer, getPodsAssignedToNode, stopCh := initializeClient(t)
+	defer close(stopCh)
 
 	testNamespace := &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "e2e-" + strings.ToLower(t.Name())}}
 	if _, err := clientSet.CoreV1().Namespaces().Create(ctx, testNamespace, metav1.CreateOptions{}); err != nil {
@@ -481,7 +489,7 @@ func TestNamespaceConstraintsInclude(t *testing.T) {
 	}, "", nil, false, false, nil, nil, getPodsAssignedToNode)
 
 	// All pods are supposed to be deleted, wait until all the old pods are deleted
-	if err := wait.PollUntilContextTimeout(ctx, time.Second, 20*time.Second, true, func(ctx context.Context) (bool, error) {
+	if err := wait.PollImmediate(time.Second, 20*time.Second, func() (bool, error) {
 		podList, err := clientSet.CoreV1().Pods(rc.Namespace).List(ctx, metav1.ListOptions{LabelSelector: labels.SelectorFromSet(rc.Spec.Template.Labels).String()})
 		if err != nil {
 			return false, nil
@@ -514,7 +522,8 @@ func TestNamespaceConstraintsInclude(t *testing.T) {
 func TestNamespaceConstraintsExclude(t *testing.T) {
 	ctx := context.Background()
 
-	clientSet, _, nodeInformer, getPodsAssignedToNode := initializeClient(ctx, t)
+	clientSet, _, nodeInformer, getPodsAssignedToNode, stopCh := initializeClient(t)
+	defer close(stopCh)
 
 	testNamespace := &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "e2e-" + strings.ToLower(t.Name())}}
 	if _, err := clientSet.CoreV1().Namespaces().Create(ctx, testNamespace, metav1.CreateOptions{}); err != nil {
@@ -580,7 +589,8 @@ func testEvictSystemCritical(t *testing.T, isPriorityClass bool) {
 	lowPriority := int32(500)
 	ctx := context.Background()
 
-	clientSet, _, nodeInformer, getPodsAssignedToNode := initializeClient(ctx, t)
+	clientSet, _, nodeInformer, getPodsAssignedToNode, stopCh := initializeClient(t)
+	defer close(stopCh)
 
 	testNamespace := &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "e2e-" + strings.ToLower(t.Name())}}
 	if _, err := clientSet.CoreV1().Namespaces().Create(ctx, testNamespace, metav1.CreateOptions{}); err != nil {
@@ -667,7 +677,7 @@ func testEvictSystemCritical(t *testing.T, isPriorityClass bool) {
 
 	// All pods are supposed to be deleted, wait until all pods in the test namespace are terminating
 	t.Logf("All pods in the test namespace, no matter their priority (including system-node-critical and system-cluster-critical), will be deleted")
-	if err := wait.PollUntilContextTimeout(ctx, time.Second, 30*time.Second, true, func(ctx context.Context) (bool, error) {
+	if err := wait.PollImmediate(time.Second, 30*time.Second, func() (bool, error) {
 		podList, err := clientSet.CoreV1().Pods(testNamespace.Name).List(ctx, metav1.ListOptions{})
 		if err != nil {
 			return false, nil
@@ -703,7 +713,8 @@ func TestEvictDaemonSetPod(t *testing.T) {
 func testEvictDaemonSetPod(t *testing.T, isDaemonSet bool) {
 	ctx := context.Background()
 
-	clientSet, _, nodeInformer, getPodsAssignedToNode := initializeClient(ctx, t)
+	clientSet, _, nodeInformer, getPodsAssignedToNode, stopCh := initializeClient(t)
+	defer close(stopCh)
 
 	testNamespace := &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "e2e-" + strings.ToLower(t.Name())}}
 	if _, err := clientSet.CoreV1().Namespaces().Create(ctx, testNamespace, metav1.CreateOptions{}); err != nil {
@@ -734,7 +745,7 @@ func testEvictDaemonSetPod(t *testing.T, isDaemonSet bool) {
 
 	// All pods are supposed to be deleted, wait until all pods in the test namespace are terminating
 	t.Logf("All daemonset pods in the test namespace, will be deleted")
-	if err := wait.PollUntilContextTimeout(ctx, time.Second, 30*time.Second, true, func(ctx context.Context) (bool, error) {
+	if err := wait.PollImmediate(time.Second, 30*time.Second, func() (bool, error) {
 		podList, err := clientSet.CoreV1().Pods(testNamespace.Name).List(ctx, metav1.ListOptions{})
 		if err != nil {
 			return false, nil
@@ -776,7 +787,8 @@ func testPriority(t *testing.T, isPriorityClass bool) {
 	lowPriority := int32(500)
 	ctx := context.Background()
 
-	clientSet, _, nodeInformer, getPodsAssignedToNode := initializeClient(ctx, t)
+	clientSet, _, nodeInformer, getPodsAssignedToNode, stopCh := initializeClient(t)
+	defer close(stopCh)
 
 	testNamespace := &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "e2e-" + strings.ToLower(t.Name())}}
 	if _, err := clientSet.CoreV1().Namespaces().Create(ctx, testNamespace, metav1.CreateOptions{}); err != nil {
@@ -870,7 +882,7 @@ func testPriority(t *testing.T, isPriorityClass bool) {
 	}
 
 	// check if all pods with low priority class are evicted
-	if err := wait.PollUntilContextTimeout(ctx, time.Second, 30*time.Second, true, func(ctx context.Context) (bool, error) {
+	if err := wait.PollImmediate(time.Second, 30*time.Second, func() (bool, error) {
 		podListLowPriority, err := clientSet.CoreV1().Pods(rcLowPriority.Namespace).List(
 			ctx, metav1.ListOptions{LabelSelector: labels.SelectorFromSet(rcLowPriority.Spec.Template.Labels).String()})
 		if err != nil {
@@ -904,7 +916,8 @@ func testPriority(t *testing.T, isPriorityClass bool) {
 func TestPodLabelSelector(t *testing.T) {
 	ctx := context.Background()
 
-	clientSet, _, nodeInformer, getPodsAssignedToNode := initializeClient(ctx, t)
+	clientSet, _, nodeInformer, getPodsAssignedToNode, stopCh := initializeClient(t)
+	defer close(stopCh)
 
 	testNamespace := &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "e2e-" + strings.ToLower(t.Name())}}
 	if _, err := clientSet.CoreV1().Namespaces().Create(ctx, testNamespace, metav1.CreateOptions{}); err != nil {
@@ -972,7 +985,7 @@ func TestPodLabelSelector(t *testing.T) {
 	}
 
 	// check if all selected pods are evicted
-	if err := wait.PollUntilContextTimeout(ctx, time.Second, 30*time.Second, true, func(ctx context.Context) (bool, error) {
+	if err := wait.PollImmediate(time.Second, 30*time.Second, func() (bool, error) {
 		podListEvict, err := clientSet.CoreV1().Pods(rcEvict.Namespace).List(
 			ctx, metav1.ListOptions{LabelSelector: labels.SelectorFromSet(rcEvict.Spec.Template.Labels).String()})
 		if err != nil {
@@ -1006,7 +1019,8 @@ func TestPodLabelSelector(t *testing.T) {
 func TestEvictAnnotation(t *testing.T) {
 	ctx := context.Background()
 
-	clientSet, _, nodeLister, getPodsAssignedToNode := initializeClient(ctx, t)
+	clientSet, _, nodeLister, getPodsAssignedToNode, stopCh := initializeClient(t)
+	defer close(stopCh)
 
 	testNamespace := &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "e2e-" + strings.ToLower(t.Name())}}
 	if _, err := clientSet.CoreV1().Namespaces().Create(ctx, testNamespace, metav1.CreateOptions{}); err != nil {
@@ -1052,7 +1066,7 @@ func TestEvictAnnotation(t *testing.T) {
 	t.Log("Running PodLifetime plugin")
 	runPodLifetimePlugin(ctx, t, clientSet, nodeLister, nil, "", nil, false, false, nil, nil, getPodsAssignedToNode)
 
-	if err := wait.PollUntilContextTimeout(ctx, 5*time.Second, time.Minute, true, func(ctx context.Context) (bool, error) {
+	if err := wait.PollImmediate(5*time.Second, time.Minute, func() (bool, error) {
 		podList, err = clientSet.CoreV1().Pods(rc.Namespace).List(ctx, metav1.ListOptions{LabelSelector: labels.SelectorFromSet(rc.Spec.Template.Labels).String()})
 		if err != nil {
 			return false, fmt.Errorf("unable to list pods after running plugin: %v", err)
@@ -1077,7 +1091,8 @@ func TestEvictAnnotation(t *testing.T) {
 func TestPodLifeTimeOldestEvicted(t *testing.T) {
 	ctx := context.Background()
 
-	clientSet, _, nodeLister, getPodsAssignedToNode := initializeClient(ctx, t)
+	clientSet, _, nodeLister, getPodsAssignedToNode, stopCh := initializeClient(t)
+	defer close(stopCh)
 
 	testNamespace := &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "e2e-" + strings.ToLower(t.Name())}}
 	if _, err := clientSet.CoreV1().Namespaces().Create(ctx, testNamespace, metav1.CreateOptions{}); err != nil {
@@ -1101,7 +1116,7 @@ func TestPodLifeTimeOldestEvicted(t *testing.T) {
 	oldestPod := podList.Items[0]
 
 	t.Log("Scale the rs to 5 replicas with the 4 new pods having a more recent creation timestamp")
-	rc.Spec.Replicas = utilptr.To[int32](5)
+	rc.Spec.Replicas = pointer.Int32(5)
 	rc, err = clientSet.CoreV1().ReplicationControllers(rc.Namespace).Update(ctx, rc, metav1.UpdateOptions{})
 	if err != nil {
 		t.Errorf("Error updating deployment %v", err)
@@ -1170,7 +1185,7 @@ func TestDeschedulingInterval(t *testing.T) {
 }
 
 func waitForRCPodsRunning(ctx context.Context, t *testing.T, clientSet clientset.Interface, rc *v1.ReplicationController) {
-	if err := wait.PollUntilContextTimeout(ctx, 5*time.Second, 30*time.Second, true, func(ctx context.Context) (bool, error) {
+	if err := wait.PollImmediate(5*time.Second, 30*time.Second, func() (bool, error) {
 		podList, err := clientSet.CoreV1().Pods(rc.Namespace).List(ctx, metav1.ListOptions{
 			LabelSelector: labels.SelectorFromSet(labels.Set(rc.Spec.Template.ObjectMeta.Labels)).String(),
 		})
@@ -1194,7 +1209,7 @@ func waitForRCPodsRunning(ctx context.Context, t *testing.T, clientSet clientset
 }
 
 func waitForTerminatingPodsToDisappear(ctx context.Context, t *testing.T, clientSet clientset.Interface, namespace string) {
-	if err := wait.PollUntilContextTimeout(ctx, 5*time.Second, 30*time.Second, true, func(ctx context.Context) (bool, error) {
+	if err := wait.PollImmediate(5*time.Second, 30*time.Second, func() (bool, error) {
 		podList, err := clientSet.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{})
 		if err != nil {
 			return false, err
@@ -1222,7 +1237,7 @@ func deleteDS(ctx context.Context, t *testing.T, clientSet clientset.Interface,
 		t.Fatalf("Error updating daemonset %v", err)
 	}
 
-	if err := wait.PollUntilContextTimeout(ctx, 5*time.Second, time.Minute, true, func(ctx context.Context) (bool, error) {
+	if err := wait.PollImmediate(5*time.Second, time.Minute, func() (bool, error) {
 		podList, _ := clientSet.CoreV1().Pods(ds.Namespace).List(ctx, metav1.ListOptions{LabelSelector: labels.SelectorFromSet(ds.Spec.Template.Labels).String()})
 		t.Logf("Waiting for %v DS pods to disappear, still %v remaining", ds.Name, len(podList.Items))
 		if len(podList.Items) > 0 {
@@ -1237,7 +1252,7 @@ func deleteDS(ctx context.Context, t *testing.T, clientSet clientset.Interface,
 		t.Fatalf("Error deleting ds %v", err)
 	}
 
-	if err := wait.PollUntilContextTimeout(ctx, time.Second, 10*time.Second, true, func(ctx context.Context) (bool, error) {
+	if err := wait.PollImmediate(time.Second, 10*time.Second, func() (bool, error) {
 		_, err := clientSet.AppsV1().DaemonSets(ds.Namespace).Get(ctx, ds.Name, metav1.GetOptions{})
 		if err != nil && strings.Contains(err.Error(), "not found") {
 			return true, nil
@@ -1251,13 +1266,13 @@ func deleteDS(ctx context.Context, t *testing.T, clientSet clientset.Interface,
 func deleteRC(ctx context.Context, t *testing.T, clientSet clientset.Interface, rc *v1.ReplicationController) {
 	// set number of replicas to 0
 	rcdeepcopy := rc.DeepCopy()
-	rcdeepcopy.Spec.Replicas = utilptr.To[int32](0)
+	rcdeepcopy.Spec.Replicas = pointer.Int32(0)
 	if _, err := clientSet.CoreV1().ReplicationControllers(rcdeepcopy.Namespace).Update(ctx, rcdeepcopy, metav1.UpdateOptions{}); err != nil {
 		t.Fatalf("Error updating replica controller %v", err)
 	}
 
 	// wait 30 seconds until all pods are deleted
-	if err := wait.PollUntilContextTimeout(ctx, 5*time.Second, 30*time.Second, true, func(ctx context.Context) (bool, error) {
+	if err := wait.PollImmediate(5*time.Second, 30*time.Second, func() (bool, error) {
 		scale, err := clientSet.CoreV1().ReplicationControllers(rc.Namespace).GetScale(ctx, rc.Name, metav1.GetOptions{})
 		if err != nil {
 			return false, err
@@ -1267,7 +1282,7 @@ func deleteRC(ctx context.Context, t *testing.T, clientSet clientset.Interface,
 		t.Fatalf("Error deleting rc pods %v", err)
 	}
 
-	if err := wait.PollUntilContextTimeout(ctx, 5*time.Second, time.Minute, true, func(ctx context.Context) (bool, error) {
+	if err := wait.PollImmediate(5*time.Second, time.Minute, func() (bool, error) {
 		podList, _ := clientSet.CoreV1().Pods(rc.Namespace).List(ctx, metav1.ListOptions{LabelSelector: labels.SelectorFromSet(rc.Spec.Template.Labels).String()})
 		t.Logf("Waiting for %v RC pods to disappear, still %v remaining", rc.Name, len(podList.Items))
 		if len(podList.Items) > 0 {
@@ -1282,7 +1297,7 @@ func deleteRC(ctx context.Context, t *testing.T, clientSet clientset.Interface,
 		t.Fatalf("Error deleting rc %v", err)
 	}
 
-	if err := wait.PollUntilContextTimeout(ctx, time.Second, 10*time.Second, true, func(ctx context.Context) (bool, error) {
+	if err := wait.PollImmediate(time.Second, 10*time.Second, func() (bool, error) {
 		_, err := clientSet.CoreV1().ReplicationControllers(rc.Namespace).Get(ctx, rc.Name, metav1.GetOptions{})
 		if err != nil && strings.Contains(err.Error(), "not found") {
 			return true, nil
@@ -1331,8 +1346,8 @@ func createBalancedPodForNodes(
 		if err != nil {
 			t.Logf("Failed to delete memory balanced pods: %v.", err)
 		} else {
-			err := wait.PollUntilContextTimeout(ctx, 2*time.Second, time.Minute, true, func(ctx context.Context) (bool, error) {
-				podList, err := cs.CoreV1().Pods(ns).List(ctx, metav1.ListOptions{
+			err := wait.PollImmediate(2*time.Second, time.Minute, func() (bool, error) {
+				podList, err := cs.CoreV1().Pods(ns).List(context.TODO(), metav1.ListOptions{
 					LabelSelector: labels.SelectorFromSet(labels.Set(balancePodLabel)).String(),
 				})
 				if err != nil {
@@ -1400,9 +1415,9 @@ func createBalancedPodForNodes(
 			},
 			Spec: v1.PodSpec{
 				SecurityContext: &v1.PodSecurityContext{
-					RunAsNonRoot: utilptr.To(true),
-					RunAsUser:    utilptr.To[int64](1000),
-					RunAsGroup:   utilptr.To[int64](1000),
+					RunAsNonRoot: utilpointer.Bool(true),
+					RunAsUser:    utilpointer.Int64(1000),
+					RunAsGroup:   utilpointer.Int64(1000),
 					SeccompProfile: &v1.SeccompProfile{
 						Type: v1.SeccompProfileTypeRuntimeDefault,
 					},
@@ -1512,7 +1527,7 @@ func computeCPUMemFraction(t *testing.T, cs clientset.Interface, node *v1.Node,
 }
 
 func waitForPodRunning(ctx context.Context, t *testing.T, clientSet clientset.Interface, pod *v1.Pod) {
-	if err := wait.PollUntilContextTimeout(ctx, 5*time.Second, 30*time.Second, true, func(ctx context.Context) (bool, error) {
+	if err := wait.PollImmediate(5*time.Second, 30*time.Second, func() (bool, error) {
 		podItem, err := clientSet.CoreV1().Pods(pod.Namespace).Get(ctx, pod.Name, metav1.GetOptions{})
 		if err != nil {
 			return false, err
@@ -1530,7 +1545,7 @@ func waitForPodRunning(ctx context.Context, t *testing.T, clientSet clientset.In
 }
 
 func waitForPodsRunning(ctx context.Context, t *testing.T, clientSet clientset.Interface, labelMap map[string]string, desireRunningPodNum int, namespace string) {
-	if err := wait.PollUntilContextTimeout(ctx, 10*time.Second, 60*time.Second, true, func(ctx context.Context) (bool, error) {
+	if err := wait.PollImmediate(10*time.Second, 60*time.Second, func() (bool, error) {
 		podList, err := clientSet.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{
 			LabelSelector: labels.SelectorFromSet(labelMap).String(),
 		})
@@ -1566,7 +1581,7 @@ func splitNodesAndWorkerNodes(nodes []v1.Node) ([]*v1.Node, []*v1.Node) {
 	return allNodes, workerNodes
 }
 
-func initPodEvictorOrFail(t *testing.T, clientSet clientset.Interface, getPodsAssignedToNode podutil.GetPodsAssignedToNodeFunc) *evictions.PodEvictor {
+func initPodEvictorOrFail(t *testing.T, clientSet clientset.Interface, getPodsAssignedToNode podutil.GetPodsAssignedToNodeFunc, nodes []*v1.Node) *evictions.PodEvictor {
 	evictionPolicyGroupVersion, err := eutils.SupportEviction(clientSet)
 	if err != nil || len(evictionPolicyGroupVersion) == 0 {
 		t.Fatalf("Error creating eviction policy group: %v", err)
@@ -1576,7 +1591,12 @@ func initPodEvictorOrFail(t *testing.T, clientSet clientset.Interface, getPodsAs
 
 	return evictions.NewPodEvictor(
 		clientSet,
+		evictionPolicyGroupVersion,
+		false,
+		nil,
+		nil,
+		nodes,
+		false,
 		eventRecorder,
-		evictions.NewOptions().WithPolicyGroupVersion(evictionPolicyGroupVersion),
 	)
 }
diff --git a/test/e2e/e2e_toomanyrestarts_test.go b/test/e2e/e2e_toomanyrestarts_test.go
index 261937e37..e0f0479ce 100644
--- a/test/e2e/e2e_toomanyrestarts_test.go
+++ b/test/e2e/e2e_toomanyrestarts_test.go
@@ -29,7 +29,9 @@ import (
 	"k8s.io/apimachinery/pkg/labels"
 	clientset "k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/tools/events"
-	utilptr "k8s.io/utils/ptr"
+	"k8s.io/utils/pointer"
+
+	utilpointer "k8s.io/utils/pointer"
 	"sigs.k8s.io/descheduler/pkg/descheduler/evictions"
 	eutils "sigs.k8s.io/descheduler/pkg/descheduler/evictions/utils"
 	frameworkfake "sigs.k8s.io/descheduler/pkg/framework/fake"
@@ -41,14 +43,15 @@ import (
 func TestTooManyRestarts(t *testing.T) {
 	ctx := context.Background()
 
-	clientSet, sharedInformerFactory, _, getPodsAssignedToNode := initializeClient(ctx, t)
+	clientSet, sharedInformerFactory, _, getPodsAssignedToNode, stopCh := initializeClient(t)
+	defer close(stopCh)
 
 	nodeList, err := clientSet.CoreV1().Nodes().List(ctx, metav1.ListOptions{})
 	if err != nil {
 		t.Errorf("Error listing node with %v", err)
 	}
 
-	_, workerNodes := splitNodesAndWorkerNodes(nodeList.Items)
+	nodes, workerNodes := splitNodesAndWorkerNodes(nodeList.Items)
 
 	t.Logf("Creating testing namespace %v", t.Name())
 	testNamespace := &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "e2e-" + strings.ToLower(t.Name())}}
@@ -64,7 +67,7 @@ func TestTooManyRestarts(t *testing.T) {
 			Labels:    map[string]string{"test": "restart-pod", "name": "test-toomanyrestarts"},
 		},
 		Spec: appsv1.DeploymentSpec{
-			Replicas: utilptr.To[int32](4),
+			Replicas: pointer.Int32(4),
 			Selector: &metav1.LabelSelector{
 				MatchLabels: map[string]string{"test": "restart-pod", "name": "test-toomanyrestarts"},
 			},
@@ -74,9 +77,9 @@ func TestTooManyRestarts(t *testing.T) {
 				},
 				Spec: v1.PodSpec{
 					SecurityContext: &v1.PodSecurityContext{
-						RunAsNonRoot: utilptr.To(true),
-						RunAsUser:    utilptr.To[int64](1000),
-						RunAsGroup:   utilptr.To[int64](1000),
+						RunAsNonRoot: utilpointer.Bool(true),
+						RunAsUser:    utilpointer.Int64(1000),
+						RunAsGroup:   utilpointer.Int64(1000),
 						SeccompProfile: &v1.SeccompProfile{
 							Type: v1.SeccompProfileTypeRuntimeDefault,
 						},
@@ -89,7 +92,7 @@ func TestTooManyRestarts(t *testing.T) {
 						Args:            []string{"-c", "sleep 1s && exit 1"},
 						Ports:           []v1.ContainerPort{{ContainerPort: 80}},
 						SecurityContext: &v1.SecurityContext{
-							AllowPrivilegeEscalation: utilptr.To(false),
+							AllowPrivilegeEscalation: utilpointer.Bool(false),
 							Capabilities: &v1.Capabilities{
 								Drop: []v1.Capability{
 									"ALL",
@@ -161,8 +164,13 @@ func TestTooManyRestarts(t *testing.T) {
 
 			podEvictor := evictions.NewPodEvictor(
 				clientSet,
+				evictionPolicyGroupVersion,
+				false,
+				nil,
+				nil,
+				nodes,
+				false,
 				eventRecorder,
-				evictions.NewOptions().WithPolicyGroupVersion(evictionPolicyGroupVersion),
 			)
 
 			defaultevictorArgs := &defaultevictor.DefaultEvictorArgs{
diff --git a/test/e2e/e2e_topologyspreadconstraint_test.go b/test/e2e/e2e_topologyspreadconstraint_test.go
index 6ecc347ae..6c925e4e2 100644
--- a/test/e2e/e2e_topologyspreadconstraint_test.go
+++ b/test/e2e/e2e_topologyspreadconstraint_test.go
@@ -21,13 +21,13 @@ const zoneTopologyKey string = "topology.kubernetes.io/zone"
 
 func TestTopologySpreadConstraint(t *testing.T) {
 	ctx := context.Background()
-	clientSet, _, _, getPodsAssignedToNode := initializeClient(ctx, t)
-
+	clientSet, _, _, getPodsAssignedToNode, stopCh := initializeClient(t)
+	defer close(stopCh)
 	nodeList, err := clientSet.CoreV1().Nodes().List(ctx, metav1.ListOptions{})
 	if err != nil {
 		t.Errorf("Error listing node with %v", err)
 	}
-	_, workerNodes := splitNodesAndWorkerNodes(nodeList.Items)
+	nodes, workerNodes := splitNodesAndWorkerNodes(nodeList.Items)
 	t.Log("Creating testing namespace")
 	testNamespace := &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "e2e-" + strings.ToLower(t.Name())}}
 	if _, err := clientSet.CoreV1().Namespaces().Create(ctx, testNamespace, metav1.CreateOptions{}); err != nil {
@@ -138,7 +138,7 @@ func TestTopologySpreadConstraint(t *testing.T) {
 			defer test.DeleteDeployment(ctx, t, clientSet, violatorDeployment)
 			test.WaitForDeploymentPodsRunning(ctx, t, clientSet, violatorDeployment)
 
-			podEvictor := initPodEvictorOrFail(t, clientSet, getPodsAssignedToNode)
+			podEvictor := initPodEvictorOrFail(t, clientSet, getPodsAssignedToNode, nodes)
 
 			// Run TopologySpreadConstraint strategy
 			t.Logf("Running RemovePodsViolatingTopologySpreadConstraint strategy for %s", name)
diff --git a/test/test_utils.go b/test/test_utils.go
index c43a942ff..d1d6008fc 100644
--- a/test/test_utils.go
+++ b/test/test_utils.go
@@ -28,10 +28,9 @@ import (
 	"k8s.io/apimachinery/pkg/api/resource"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/labels"
-	"k8s.io/apimachinery/pkg/util/uuid"
 	"k8s.io/apimachinery/pkg/util/wait"
 	clientset "k8s.io/client-go/kubernetes"
-	utilptr "k8s.io/utils/ptr"
+	utilpointer "k8s.io/utils/pointer"
 )
 
 func BuildTestDeployment(name, namespace string, replicas int32, labels map[string]string, apply func(deployment *appsv1.Deployment)) *appsv1.Deployment {
@@ -48,7 +47,7 @@ func BuildTestDeployment(name, namespace string, replicas int32, labels map[stri
 			Namespace: namespace,
 		},
 		Spec: appsv1.DeploymentSpec{
-			Replicas: utilptr.To[int32](replicas),
+			Replicas: utilpointer.Int32(replicas),
 			Selector: &metav1.LabelSelector{
 				MatchLabels: map[string]string{
 					"name": name,
@@ -58,7 +57,7 @@ func BuildTestDeployment(name, namespace string, replicas int32, labels map[stri
 				ObjectMeta: metav1.ObjectMeta{
 					Labels: labels,
 				},
-				Spec: MakePodSpec("", utilptr.To[int64](0)),
+				Spec: MakePodSpec("", utilpointer.Int64(0)),
 			},
 		},
 	}
@@ -77,7 +76,6 @@ func BuildTestPod(name string, cpu, memory int64, nodeName string, apply func(*v
 			Namespace: "default",
 			Name:      name,
 			SelfLink:  fmt.Sprintf("/api/v1/namespaces/default/pods/%s", name),
-			UID:       uuid.NewUUID(),
 		},
 		Spec: v1.PodSpec{
 			Containers: []v1.Container{
@@ -174,9 +172,9 @@ func BuildTestNode(name string, millicpu, mem, pods int64, apply func(*v1.Node))
 func MakePodSpec(priorityClassName string, gracePeriod *int64) v1.PodSpec {
 	return v1.PodSpec{
 		SecurityContext: &v1.PodSecurityContext{
-			RunAsNonRoot: utilptr.To(true),
-			RunAsUser:    utilptr.To[int64](1000),
-			RunAsGroup:   utilptr.To[int64](1000),
+			RunAsNonRoot: utilpointer.Bool(true),
+			RunAsUser:    utilpointer.Int64(1000),
+			RunAsGroup:   utilpointer.Int64(1000),
 			SeccompProfile: &v1.SeccompProfile{
 				Type: v1.SeccompProfileTypeRuntimeDefault,
 			},
@@ -197,7 +195,7 @@ func MakePodSpec(priorityClassName string, gracePeriod *int64) v1.PodSpec {
 				},
 			},
 			SecurityContext: &v1.SecurityContext{
-				AllowPrivilegeEscalation: utilptr.To(false),
+				AllowPrivilegeEscalation: utilpointer.Bool(false),
 				Capabilities: &v1.Capabilities{
 					Drop: []v1.Capability{
 						"ALL",
@@ -274,7 +272,7 @@ func SetNodeExtendedResource(node *v1.Node, resourceName v1.ResourceName, reques
 func DeleteDeployment(ctx context.Context, t *testing.T, clientSet clientset.Interface, deployment *appsv1.Deployment) {
 	// set number of replicas to 0
 	deploymentCopy := deployment.DeepCopy()
-	deploymentCopy.Spec.Replicas = utilptr.To[int32](0)
+	deploymentCopy.Spec.Replicas = utilpointer.Int32(0)
 	if _, err := clientSet.AppsV1().Deployments(deploymentCopy.Namespace).Update(ctx, deploymentCopy, metav1.UpdateOptions{}); err != nil {
 		t.Fatalf("Error updating replica controller %v", err)
 	}