Repository: koordinator-sh/koordinator

Issue:
[proposal] Coscheduling move some BeforePreFilter quick check into PreEnqueueExtension
<!-- Please only use this template for submitting proposal -->

**What is your proposal**:
Coscheduling currently checks whether the member Pods of the Gang have reached the Minmember number and whether the Gang has been initialized. K8s 1.28 brings the prequeue extension interface, which can determine whether the conditions for joining the queue are met before the Pod joins ActiveQ. So we can consider putting some Gang checks in PreEnqueue.

**Why is this needed**:

reduce wasty scheduling cycle.

**Is there a suggested solution, if so, please add it**:


Discussion:
@ZiMengSheng: /assign AdrianMachao@koordinator-bot: @ZiMengSheng: GitHub didn't allow me to assign the following users: AdrianMachao.

Note that only [koordinator-sh members](https://github.com/orgs/koordinator-sh/people), repo collaborators and people who have commented on this issue/PR can be assigned. Additionally, issues/PRs can only have 10 assignees at the same time.
For more information please see [the contributor guide](https://git.k8s.io/community/contributors/guide/first-contribution.md#issue-assignment-in-github)

<details>

In response to [this](https://github.com/koordinator-sh/koordinator/issues/2140#issuecomment-2247732241):

>/assign AdrianMachao


Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository.
</details>@AdrianMachao: /assign@hormes: Can you update this picture?

https://github.com/koordinator-sh/koordinator/blob/main/docs/images/koord-scheduler-framework-ext.png@AdrianMachao: > Can you update this picture?
> 
> https://github.com/koordinator-sh/koordinator/blob/main/docs/images/koord-scheduler-framework-ext.png

Got it

Solution patch:
diff --git a/config/manager/scheduler-config.yaml b/config/manager/scheduler-config.yaml
index bd59c27f..4c0534bb 100644
--- a/config/manager/scheduler-config.yaml
+++ b/config/manager/scheduler-config.yaml
@@ -5,7 +5,7 @@ metadata:
   namespace: system
 data:
   koord-scheduler-config: |
-    apiVersion: kubescheduler.config.k8s.io/v1beta3
+    apiVersion: kubescheduler.config.k8s.io/v1
     kind: KubeSchedulerConfiguration
     leaderElection:
       leaderElect: true
@@ -16,7 +16,7 @@ data:
       - pluginConfig:
         - name: NodeResourcesFit
           args:
-            apiVersion: kubescheduler.config.k8s.io/v1beta3
+            apiVersion: kubescheduler.config.k8s.io/v1
             kind: NodeResourcesFitArgs
             scoringStrategy:
               type: LeastAllocated
@@ -31,7 +31,7 @@ data:
                   weight: 1
         - name: LoadAwareScheduling
           args:
-            apiVersion: kubescheduler.config.k8s.io/v1beta3
+            apiVersion: kubescheduler.config.k8s.io/v1
             kind: LoadAwareSchedulingArgs
             filterExpiredNodeMetrics: false
             nodeMetricExpirationSeconds: 300
@@ -46,10 +46,13 @@ data:
               memory: 70
         - name: ElasticQuota
           args:
-            apiVersion: kubescheduler.config.k8s.io/v1beta3
+            apiVersion: kubescheduler.config.k8s.io/v1
             kind: ElasticQuotaArgs
             quotaGroupNamespace: koordinator-system
         plugins:
+          preEnqueue:
+            enabled:
+              - name: Coscheduling
           queueSort:
             disabled:
               - name: "*"
diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh
index f29a57c6..e3394b22 100755
--- a/hack/update-codegen.sh
+++ b/hack/update-codegen.sh
@@ -56,7 +56,7 @@ ${SCRIPT_ROOT}/hack/generate-internal-groups.sh \
   github.com/koordinator-sh/koordinator/pkg/scheduler/apis/generated \
   github.com/koordinator-sh/koordinator/pkg/scheduler/apis \
   github.com/koordinator-sh/koordinator/pkg/scheduler/apis \
-  "config:v1beta3" \
+  "config:v1beta3 config:v1" \
   --output-base "${TEMP_DIR}" \
   --go-header-file hack/boilerplate/boilerplate.go.txt
 
diff --git a/pkg/scheduler/apis/config/scheme/scheme.go b/pkg/scheduler/apis/config/scheme/scheme.go
index 274e29b3..7ef73760 100644
--- a/pkg/scheduler/apis/config/scheme/scheme.go
+++ b/pkg/scheduler/apis/config/scheme/scheme.go
@@ -23,6 +23,7 @@ import (
 	kubeschedulerscheme "k8s.io/kubernetes/pkg/scheduler/apis/config/scheme"
 
 	"github.com/koordinator-sh/koordinator/pkg/scheduler/apis/config"
+	v1 "github.com/koordinator-sh/koordinator/pkg/scheduler/apis/config/v1"
 	"github.com/koordinator-sh/koordinator/pkg/scheduler/apis/config/v1beta3"
 )
 
@@ -42,4 +43,5 @@ func init() {
 func AddToScheme(scheme *runtime.Scheme) {
 	utilruntime.Must(config.AddToScheme(scheme))
 	utilruntime.Must(v1beta3.AddToScheme(scheme))
+	utilruntime.Must(v1.AddToScheme(scheme))
 }
diff --git a/pkg/scheduler/apis/config/v1/defaults.go b/pkg/scheduler/apis/config/v1/defaults.go
new file mode 100644
index 00000000..ea24e6d7
--- /dev/null
+++ b/pkg/scheduler/apis/config/v1/defaults.go
@@ -0,0 +1,211 @@
+/*
+Copyright 2022 The Koordinator 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 v1
+
+import (
+	"math"
+	"time"
+
+	corev1 "k8s.io/api/core/v1"
+	"k8s.io/apimachinery/pkg/api/resource"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	schedconfigv1 "k8s.io/kube-scheduler/config/v1"
+	"k8s.io/utils/pointer"
+
+	"github.com/koordinator-sh/koordinator/apis/extension"
+)
+
+var (
+	defaultNodeMetricExpirationSeconds int64 = 180
+
+	defaultResourceWeights = map[corev1.ResourceName]int64{
+		corev1.ResourceCPU:    1,
+		corev1.ResourceMemory: 1,
+	}
+
+	defaultUsageThresholds = map[corev1.ResourceName]int64{
+		corev1.ResourceCPU:    65, // 65%
+		corev1.ResourceMemory: 95, // 95%
+	}
+
+	defaultEstimatedScalingFactors = map[corev1.ResourceName]int64{
+		corev1.ResourceCPU:    85, // 85%
+		corev1.ResourceMemory: 70, // 70%
+	}
+
+	defaultPreferredCPUBindPolicy = CPUBindPolicyFullPCPUs
+
+	defaultEnablePreemption = pointer.Bool(false)
+
+	defaultDelayEvictTime       = 120 * time.Second
+	defaultRevokePodInterval    = 1 * time.Second
+	defaultDefaultQuotaGroupMax = corev1.ResourceList{
+		// pkg/scheduler/plugins/elasticquota/controller.go syncHandler patch will overflow when the spec Max/Min is too high.
+		corev1.ResourceCPU:    *resource.NewQuantity(math.MaxInt64/5, resource.DecimalSI),
+		corev1.ResourceMemory: *resource.NewQuantity(math.MaxInt64/5, resource.DecimalSI),
+	}
+	defaultSystemQuotaGroupMax = corev1.ResourceList{
+		corev1.ResourceCPU:    *resource.NewQuantity(math.MaxInt64/5, resource.DecimalSI),
+		corev1.ResourceMemory: *resource.NewQuantity(math.MaxInt64/5, resource.BinarySI),
+	}
+
+	defaultQuotaGroupNamespace = "koordinator-system"
+
+	defaultMonitorAllQuotas       = pointer.Bool(false)
+	defaultEnableCheckParentQuota = pointer.Bool(false)
+	defaultEnableRuntimeQuota     = pointer.Bool(true)
+
+	defaultTimeout           = 600 * time.Second
+	defaultControllerWorkers = 1
+)
+
+// SetDefaults_LoadAwareSchedulingArgs sets the default parameters for LoadAwareScheduling plugin.
+func SetDefaults_LoadAwareSchedulingArgs(obj *LoadAwareSchedulingArgs) {
+	if obj.FilterExpiredNodeMetrics == nil {
+		obj.FilterExpiredNodeMetrics = pointer.Bool(true)
+	}
+	if obj.EnableScheduleWhenNodeMetricsExpired == nil {
+		obj.EnableScheduleWhenNodeMetricsExpired = pointer.Bool(false)
+	}
+	if obj.NodeMetricExpirationSeconds == nil {
+		obj.NodeMetricExpirationSeconds = pointer.Int64(defaultNodeMetricExpirationSeconds)
+	}
+	if len(obj.ResourceWeights) == 0 {
+		obj.ResourceWeights = defaultResourceWeights
+	}
+	if len(obj.UsageThresholds) == 0 {
+		obj.UsageThresholds = defaultUsageThresholds
+	}
+	if obj.EstimatedScalingFactors == nil {
+		obj.EstimatedScalingFactors = defaultEstimatedScalingFactors
+	} else {
+		for k, v := range defaultEstimatedScalingFactors {
+			if _, ok := obj.EstimatedScalingFactors[k]; !ok {
+				obj.EstimatedScalingFactors[k] = v
+			}
+		}
+	}
+}
+
+// SetDefaults_NodeNUMAResourceArgs sets the default parameters for NodeNUMANodeResource plugin.
+func SetDefaults_NodeNUMAResourceArgs(obj *NodeNUMAResourceArgs) {
+	if obj.DefaultCPUBindPolicy == nil {
+		policy := defaultPreferredCPUBindPolicy
+		obj.DefaultCPUBindPolicy = &policy
+	}
+	if obj.ScoringStrategy == nil {
+		obj.ScoringStrategy = &ScoringStrategy{
+			Type: LeastAllocated,
+			Resources: []schedconfigv1.ResourceSpec{
+				{
+					Name:   string(corev1.ResourceCPU),
+					Weight: 1,
+				},
+				{
+					Name:   string(corev1.ResourceMemory),
+					Weight: 1,
+				},
+			},
+		}
+	}
+	if obj.NUMAScoringStrategy == nil {
+		obj.NUMAScoringStrategy = &ScoringStrategy{
+			Type: LeastAllocated,
+			Resources: []schedconfigv1.ResourceSpec{
+				{
+					Name:   string(corev1.ResourceCPU),
+					Weight: 1,
+				},
+				{
+					Name:   string(corev1.ResourceMemory),
+					Weight: 1,
+				},
+			},
+		}
+	}
+}
+
+func SetDefaults_ReservationArgs(obj *ReservationArgs) {
+	if obj.EnablePreemption == nil {
+		obj.EnablePreemption = defaultEnablePreemption
+	}
+}
+
+func SetDefaults_ElasticQuotaArgs(obj *ElasticQuotaArgs) {
+	if obj.DelayEvictTime == nil {
+		obj.DelayEvictTime = &metav1.Duration{
+			Duration: defaultDelayEvictTime,
+		}
+	}
+	if obj.RevokePodInterval == nil {
+		obj.RevokePodInterval = &metav1.Duration{
+			Duration: defaultRevokePodInterval,
+		}
+	}
+	if len(obj.DefaultQuotaGroupMax) == 0 {
+		obj.DefaultQuotaGroupMax = defaultDefaultQuotaGroupMax
+	}
+	if len(obj.SystemQuotaGroupMax) == 0 {
+		obj.SystemQuotaGroupMax = defaultSystemQuotaGroupMax
+	}
+	if len(obj.QuotaGroupNamespace) == 0 {
+		obj.QuotaGroupNamespace = defaultQuotaGroupNamespace
+	}
+	if obj.MonitorAllQuotas == nil {
+		obj.MonitorAllQuotas = defaultMonitorAllQuotas
+	}
+	if obj.EnableCheckParentQuota == nil {
+		obj.EnableCheckParentQuota = defaultEnableCheckParentQuota
+	}
+	if obj.EnableRuntimeQuota == nil {
+		obj.EnableRuntimeQuota = defaultEnableRuntimeQuota
+	}
+}
+
+func SetDefaults_CoschedulingArgs(obj *CoschedulingArgs) {
+	if obj.DefaultTimeout == nil {
+		obj.DefaultTimeout = &metav1.Duration{
+			Duration: defaultTimeout,
+		}
+	}
+	if obj.ControllerWorkers == nil {
+		obj.ControllerWorkers = pointer.Int64(int64(defaultControllerWorkers))
+	}
+}
+
+func SetDefaults_DeviceShareArgs(obj *DeviceShareArgs) {
+	if obj.ScoringStrategy == nil {
+		obj.ScoringStrategy = &ScoringStrategy{
+			// By default, LeastAllocate is used to ensure high availability of applications
+			Type: LeastAllocated,
+			Resources: []schedconfigv1.ResourceSpec{
+				{
+					Name:   string(extension.ResourceGPUMemoryRatio),
+					Weight: 1,
+				},
+				{
+					Name:   string(extension.ResourceRDMA),
+					Weight: 1,
+				},
+				{
+					Name:   string(extension.ResourceFPGA),
+					Weight: 1,
+				},
+			},
+		}
+	}
+}
diff --git a/pkg/scheduler/apis/config/v1/doc.go b/pkg/scheduler/apis/config/v1/doc.go
new file mode 100644
index 00000000..214c8135
--- /dev/null
+++ b/pkg/scheduler/apis/config/v1/doc.go
@@ -0,0 +1,24 @@
+/*
+Copyright 2022 The Koordinator 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.
+*/
+
+// +k8s:deepcopy-gen=package
+// +k8s:conversion-gen=github.com/koordinator-sh/koordinator/pkg/scheduler/apis/config
+// +k8s:defaulter-gen=TypeMeta
+// +k8s:defaulter-gen-input=.
+// +groupName=kubescheduler.config.k8s.io
+
+// Package v1
+package v1
diff --git a/pkg/scheduler/apis/config/v1/register.go b/pkg/scheduler/apis/config/v1/register.go
new file mode 100644
index 00000000..7d9083b9
--- /dev/null
+++ b/pkg/scheduler/apis/config/v1/register.go
@@ -0,0 +1,53 @@
+/*
+Copyright 2022 The Koordinator 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 v1
+
+import (
+	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/apimachinery/pkg/runtime/schema"
+	schedschemev1 "k8s.io/kube-scheduler/config/v1"
+)
+
+// SchemeGroupVersion is group version used to register these objects
+var SchemeGroupVersion = schema.GroupVersion{Group: schedschemev1.GroupName, Version: "v1"}
+
+var (
+	localSchemeBuilder = &schedschemev1.SchemeBuilder
+	// AddToScheme is a global function that registers this API group & version to a scheme
+	AddToScheme = localSchemeBuilder.AddToScheme
+)
+
+// addKnownTypes registers known types to the given scheme
+func addKnownTypes(scheme *runtime.Scheme) error {
+	scheme.AddKnownTypes(SchemeGroupVersion,
+		&LoadAwareSchedulingArgs{},
+		&NodeNUMAResourceArgs{},
+		&ReservationArgs{},
+		&ElasticQuotaArgs{},
+		&CoschedulingArgs{},
+		&DeviceShareArgs{},
+	)
+	return nil
+}
+
+func init() {
+	// We only register manually written functions here. The registration of the
+	// generated functions takes place in the generated files. The separation
+	// makes the code compile even when the generated files are missing.
+	localSchemeBuilder.Register(addKnownTypes)
+	localSchemeBuilder.Register(RegisterDefaults)
+}
diff --git a/pkg/scheduler/apis/config/v1/types.go b/pkg/scheduler/apis/config/v1/types.go
new file mode 100644
index 00000000..296aca42
--- /dev/null
+++ b/pkg/scheduler/apis/config/v1/types.go
@@ -0,0 +1,221 @@
+/*
+Copyright 2022 The Koordinator 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 v1
+
+import (
+	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	schedconfigv1 "k8s.io/kube-scheduler/config/v1"
+
+	"github.com/koordinator-sh/koordinator/apis/extension"
+)
+
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+
+// LoadAwareSchedulingArgs holds arguments used to configure the LoadAwareScheduling plugin.
+type LoadAwareSchedulingArgs struct {
+	metav1.TypeMeta `json:",inline"`
+
+	// FilterExpiredNodeMetrics indicates whether to filter nodes where koordlet fails to update NodeMetric.
+	FilterExpiredNodeMetrics *bool `json:"filterExpiredNodeMetrics,omitempty"`
+	// NodeMetricExpirationSeconds indicates the NodeMetric expiration in seconds.
+	// When NodeMetrics expired, the node is considered abnormal.
+	// Default is 180 seconds.
+	NodeMetricExpirationSeconds *int64 `json:"nodeMetricExpirationSeconds,omitempty"`
+	// EnableScheduleWhenNodeMetricsExpired Indicates whether nodes with expired nodeMetrics are allowed to schedule pods.
+	EnableScheduleWhenNodeMetricsExpired *bool `json:"enableScheduleWhenNodeMetricsExpired,omitempty"`
+	// ResourceWeights indicates the weights of resources.
+	// The weights of CPU and Memory are both 1 by default.
+	ResourceWeights map[corev1.ResourceName]int64 `json:"resourceWeights,omitempty"`
+	// UsageThresholds indicates the resource utilization threshold of the whole machine.
+	// The default for CPU is 65%, and the default for memory is 95%.
+	UsageThresholds map[corev1.ResourceName]int64 `json:"usageThresholds,omitempty"`
+	// ProdUsageThresholds indicates the resource utilization threshold of Prod Pods compared to the whole machine.
+	// Not enabled by default
+	ProdUsageThresholds map[corev1.ResourceName]int64 `json:"prodUsageThresholds,omitempty"`
+	// ScoreAccordingProdUsage controls whether to score according to the utilization of Prod Pod
+	ScoreAccordingProdUsage *bool `json:"scoreAccordingProdUsage,omitempty"`
+	// Estimator indicates the expected Estimator to use
+	Estimator string `json:"estimator,omitempty"`
+	// EstimatedScalingFactors indicates the factor when estimating resource usage.
+	// The default value of CPU is 85%, and the default value of Memory is 70%.
+	EstimatedScalingFactors map[corev1.ResourceName]int64 `json:"estimatedScalingFactors,omitempty"`
+	// Aggregated supports resource utilization filtering and scoring based on percentile statistics
+	Aggregated *LoadAwareSchedulingAggregatedArgs `json:"aggregated,omitempty"`
+}
+
+type LoadAwareSchedulingAggregatedArgs struct {
+	// UsageThresholds indicates the resource utilization threshold of the machine based on percentile statistics
+	UsageThresholds map[corev1.ResourceName]int64 `json:"usageThresholds,omitempty"`
+	// UsageAggregationType indicates the percentile type of the machine's utilization when filtering
+	UsageAggregationType extension.AggregationType `json:"usageAggregationType,omitempty"`
+	// UsageAggregatedDuration indicates the statistical period of the percentile of the machine's utilization when filtering
+	UsageAggregatedDuration *metav1.Duration `json:"usageAggregatedDuration,omitempty"`
+
+	// ScoreAggregationType indicates the percentile type of the machine's utilization when scoring
+	ScoreAggregationType extension.AggregationType `json:"scoreAggregationType,omitempty"`
+	// ScoreAggregatedDuration indicates the statistical period of the percentile of Prod Pod's utilization when scoring
+	ScoreAggregatedDuration *metav1.Duration `json:"scoreAggregatedDuration,omitempty"`
+}
+
+// ScoringStrategyType is a "string" type.
+type ScoringStrategyType string
+
+const (
+	// MostAllocated strategy favors node with the least amount of available resource
+	MostAllocated ScoringStrategyType = "MostAllocated"
+	// BalancedAllocation strategy favors nodes with balanced resource usage rate
+	BalancedAllocation ScoringStrategyType = "BalancedAllocation"
+	// LeastAllocated strategy favors node with the most amount of available resource
+	LeastAllocated ScoringStrategyType = "LeastAllocated"
+)
+
+// ScoringStrategy define ScoringStrategyType for the plugin
+type ScoringStrategy struct {
+	// Type selects which strategy to run.
+	Type ScoringStrategyType `json:"type,omitempty"`
+
+	// Resources a list of pairs <resource, weight> to be considered while scoring
+	// allowed weights start from 1.
+	Resources []schedconfigv1.ResourceSpec `json:"resources,omitempty"`
+}
+
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+
+// NodeNUMAResourceArgs holds arguments used to configure the NodeNUMAResource plugin.
+type NodeNUMAResourceArgs struct {
+	metav1.TypeMeta
+
+	// DefaultCPUBindPolicy represents the default CPU bind policy.
+	// If it is empty and the Pod does not declare a binding policy,
+	// the core will not be bound to the LSE/LSR type Pod.
+	DefaultCPUBindPolicy *CPUBindPolicy `json:"defaultCPUBindPolicy,omitempty"`
+	// ScoringStrategy is used to configure the scoring strategy of the node-level.
+	ScoringStrategy *ScoringStrategy `json:"scoringStrategy,omitempty"`
+	// NUMAScoringStrategy is used to configure the scoring strategy of the NUMANode-level
+	NUMAScoringStrategy *ScoringStrategy `json:"numaScoringStrategy,omitempty"`
+}
+
+// CPUBindPolicy defines the CPU binding policy
+type CPUBindPolicy = string
+
+const (
+	// CPUBindPolicyDefault performs the default bind policy that specified in koord-scheduler configuration
+	CPUBindPolicyDefault = CPUBindPolicy(extension.CPUBindPolicyDefault)
+	// CPUBindPolicyFullPCPUs favor cpuset allocation that pack in few physical cores
+	CPUBindPolicyFullPCPUs = CPUBindPolicy(extension.CPUBindPolicyFullPCPUs)
+	// CPUBindPolicySpreadByPCPUs favor cpuset allocation that evenly allocate logical cpus across physical cores
+	CPUBindPolicySpreadByPCPUs = CPUBindPolicy(extension.CPUBindPolicySpreadByPCPUs)
+	// CPUBindPolicyConstrainedBurst constrains the CPU Shared Pool range of the Burstable Pod
+	CPUBindPolicyConstrainedBurst = CPUBindPolicy(extension.CPUBindPolicyConstrainedBurst)
+)
+
+type CPUExclusivePolicy = extension.CPUExclusivePolicy
+
+const (
+	// CPUExclusivePolicyNone does not perform any exclusive policy
+	CPUExclusivePolicyNone CPUExclusivePolicy = extension.CPUExclusivePolicyNone
+	// CPUExclusivePolicyPCPULevel represents mutual exclusion in the physical core dimension
+	CPUExclusivePolicyPCPULevel CPUExclusivePolicy = extension.CPUExclusivePolicyPCPULevel
+	// CPUExclusivePolicyNUMANodeLevel indicates mutual exclusion in the NUMA topology dimension
+	CPUExclusivePolicyNUMANodeLevel CPUExclusivePolicy = extension.CPUExclusivePolicyNUMANodeLevel
+)
+
+// NUMAAllocateStrategy indicates how to choose satisfied NUMA Nodes during binding CPUs
+type NUMAAllocateStrategy = extension.NUMAAllocateStrategy
+
+const (
+	// NUMAMostAllocated indicates that allocates from the NUMA Node with the least amount of available resource.
+	NUMAMostAllocated NUMAAllocateStrategy = extension.NUMAMostAllocated
+	// NUMALeastAllocated indicates that allocates from the NUMA Node with the most amount of available resource.
+	NUMALeastAllocated NUMAAllocateStrategy = extension.NUMALeastAllocated
+	// NUMADistributeEvenly indicates that evenly distribute CPUs across NUMA Nodes.
+	NUMADistributeEvenly NUMAAllocateStrategy = extension.NUMADistributeEvenly
+)
+
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+
+// ReservationArgs holds arguments used to configure the Reservation plugin.
+type ReservationArgs struct {
+	metav1.TypeMeta
+
+	// EnablePreemption indicates whether to enable preemption for reservations.
+	EnablePreemption *bool `json:"enablePreemption,omitempty"`
+}
+
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+
+// ElasticQuotaArgs holds arguments used to configure the ElasticQuota plugin.
+type ElasticQuotaArgs struct {
+	metav1.TypeMeta
+
+	// DelayEvictTime is the duration to handle the jitter of used and runtime
+	DelayEvictTime *metav1.Duration `json:"delayEvictTime,omitempty"`
+
+	// RevokePodInterval is the interval to check quotaGroup's used and runtime
+	RevokePodInterval *metav1.Duration `json:"revokePodInterval,omitempty"`
+
+	// DefaultQuotaGroupMax limit the maxQuota of DefaultQuotaGroup
+	DefaultQuotaGroupMax corev1.ResourceList `json:"defaultQuotaGroupMax,omitempty"`
+
+	// SystemQuotaGroupMax limit the maxQuota of SystemQuotaGroup
+	SystemQuotaGroupMax corev1.ResourceList `json:"systemQuotaGroupMax,omitempty"`
+
+	// QuotaGroupNamespace is the namespace of the DefaultQuotaGroup
+	QuotaGroupNamespace string `json:"quotaGroupNamespace,omitempty"`
+
+	// MonitorAllQuotas monitor the quotaGroups' used and runtime Quota to revoke pods
+	MonitorAllQuotas *bool `json:"monitorAllQuotas,omitempty"`
+
+	// EnableCheckParentQuota check parentQuotaGroups' used and runtime Quota in PreFilter
+	EnableCheckParentQuota *bool `json:"enableCheckParentQuota,omitempty"`
+
+	// EnableRuntimeQuota if false, use max instead of runtime for all checks.
+	EnableRuntimeQuota *bool `json:"enableRuntimeQuota,omitempty"`
+}
+
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+
+// CoschedulingArgs defines the parameters for Gang Scheduling plugin.
+type CoschedulingArgs struct {
+	metav1.TypeMeta
+
+	// DefaultTimeout is the default gang's waiting time in Permit stage
+	// default is 600 seconds
+	DefaultTimeout *metav1.Duration `json:"defaultTimeout,omitempty"`
+	// Workers number of controller
+	// default is 1
+	ControllerWorkers *int64 `json:"controllerWorkers,omitempty"`
+	// Skip check schedule cycle
+	// default is false
+	SkipCheckScheduleCycle *bool `json:"skipCheckScheduleCycle,omitempty"`
+}
+
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+
+// DeviceShareArgs defines the parameters for DeviceShare plugin.
+type DeviceShareArgs struct {
+	metav1.TypeMeta
+
+	// Allocator indicates the expected allocator to use
+	// Deprecated: Adapting to different allocators is no longer supported.
+	Allocator string `json:"allocator,omitempty"`
+	// ScoringStrategy selects the device resource scoring strategy.
+	ScoringStrategy *ScoringStrategy `json:"scoringStrategy,omitempty"`
+	// DisableDeviceNUMATopologyAlignment indicates device don't need to align with other resources' numa topology
+	DisableDeviceNUMATopologyAlignment bool `json:"disableDeviceNUMATopologyAlignment,omitempty"`
+}
diff --git a/pkg/scheduler/apis/config/v1/zz_generated.conversion.go b/pkg/scheduler/apis/config/v1/zz_generated.conversion.go
new file mode 100644
index 00000000..19cdd546
--- /dev/null
+++ b/pkg/scheduler/apis/config/v1/zz_generated.conversion.go
@@ -0,0 +1,407 @@
+//go:build !ignore_autogenerated
+// +build !ignore_autogenerated
+
+/*
+Copyright 2022 The Koordinator 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.
+*/
+
+// Code generated by conversion-gen. DO NOT EDIT.
+
+package v1
+
+import (
+	unsafe "unsafe"
+
+	extension "github.com/koordinator-sh/koordinator/apis/extension"
+	config "github.com/koordinator-sh/koordinator/pkg/scheduler/apis/config"
+	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	conversion "k8s.io/apimachinery/pkg/conversion"
+	runtime "k8s.io/apimachinery/pkg/runtime"
+	configv1 "k8s.io/kube-scheduler/config/v1"
+	apisconfig "k8s.io/kubernetes/pkg/scheduler/apis/config"
+)
+
+func init() {
+	localSchemeBuilder.Register(RegisterConversions)
+}
+
+// RegisterConversions adds conversion functions to the given scheme.
+// Public to allow building arbitrary schemes.
+func RegisterConversions(s *runtime.Scheme) error {
+	if err := s.AddGeneratedConversionFunc((*CoschedulingArgs)(nil), (*config.CoschedulingArgs)(nil), func(a, b interface{}, scope conversion.Scope) error {
+		return Convert_v1_CoschedulingArgs_To_config_CoschedulingArgs(a.(*CoschedulingArgs), b.(*config.CoschedulingArgs), scope)
+	}); err != nil {
+		return err
+	}
+	if err := s.AddGeneratedConversionFunc((*config.CoschedulingArgs)(nil), (*CoschedulingArgs)(nil), func(a, b interface{}, scope conversion.Scope) error {
+		return Convert_config_CoschedulingArgs_To_v1_CoschedulingArgs(a.(*config.CoschedulingArgs), b.(*CoschedulingArgs), scope)
+	}); err != nil {
+		return err
+	}
+	if err := s.AddGeneratedConversionFunc((*DeviceShareArgs)(nil), (*config.DeviceShareArgs)(nil), func(a, b interface{}, scope conversion.Scope) error {
+		return Convert_v1_DeviceShareArgs_To_config_DeviceShareArgs(a.(*DeviceShareArgs), b.(*config.DeviceShareArgs), scope)
+	}); err != nil {
+		return err
+	}
+	if err := s.AddGeneratedConversionFunc((*config.DeviceShareArgs)(nil), (*DeviceShareArgs)(nil), func(a, b interface{}, scope conversion.Scope) error {
+		return Convert_config_DeviceShareArgs_To_v1_DeviceShareArgs(a.(*config.DeviceShareArgs), b.(*DeviceShareArgs), scope)
+	}); err != nil {
+		return err
+	}
+	if err := s.AddGeneratedConversionFunc((*ElasticQuotaArgs)(nil), (*config.ElasticQuotaArgs)(nil), func(a, b interface{}, scope conversion.Scope) error {
+		return Convert_v1_ElasticQuotaArgs_To_config_ElasticQuotaArgs(a.(*ElasticQuotaArgs), b.(*config.ElasticQuotaArgs), scope)
+	}); err != nil {
+		return err
+	}
+	if err := s.AddGeneratedConversionFunc((*config.ElasticQuotaArgs)(nil), (*ElasticQuotaArgs)(nil), func(a, b interface{}, scope conversion.Scope) error {
+		return Convert_config_ElasticQuotaArgs_To_v1_ElasticQuotaArgs(a.(*config.ElasticQuotaArgs), b.(*ElasticQuotaArgs), scope)
+	}); err != nil {
+		return err
+	}
+	if err := s.AddGeneratedConversionFunc((*LoadAwareSchedulingAggregatedArgs)(nil), (*config.LoadAwareSchedulingAggregatedArgs)(nil), func(a, b interface{}, scope conversion.Scope) error {
+		return Convert_v1_LoadAwareSchedulingAggregatedArgs_To_config_LoadAwareSchedulingAggregatedArgs(a.(*LoadAwareSchedulingAggregatedArgs), b.(*config.LoadAwareSchedulingAggregatedArgs), scope)
+	}); err != nil {
+		return err
+	}
+	if err := s.AddGeneratedConversionFunc((*config.LoadAwareSchedulingAggregatedArgs)(nil), (*LoadAwareSchedulingAggregatedArgs)(nil), func(a, b interface{}, scope conversion.Scope) error {
+		return Convert_config_LoadAwareSchedulingAggregatedArgs_To_v1_LoadAwareSchedulingAggregatedArgs(a.(*config.LoadAwareSchedulingAggregatedArgs), b.(*LoadAwareSchedulingAggregatedArgs), scope)
+	}); err != nil {
+		return err
+	}
+	if err := s.AddGeneratedConversionFunc((*LoadAwareSchedulingArgs)(nil), (*config.LoadAwareSchedulingArgs)(nil), func(a, b interface{}, scope conversion.Scope) error {
+		return Convert_v1_LoadAwareSchedulingArgs_To_config_LoadAwareSchedulingArgs(a.(*LoadAwareSchedulingArgs), b.(*config.LoadAwareSchedulingArgs), scope)
+	}); err != nil {
+		return err
+	}
+	if err := s.AddGeneratedConversionFunc((*config.LoadAwareSchedulingArgs)(nil), (*LoadAwareSchedulingArgs)(nil), func(a, b interface{}, scope conversion.Scope) error {
+		return Convert_config_LoadAwareSchedulingArgs_To_v1_LoadAwareSchedulingArgs(a.(*config.LoadAwareSchedulingArgs), b.(*LoadAwareSchedulingArgs), scope)
+	}); err != nil {
+		return err
+	}
+	if err := s.AddGeneratedConversionFunc((*NodeNUMAResourceArgs)(nil), (*config.NodeNUMAResourceArgs)(nil), func(a, b interface{}, scope conversion.Scope) error {
+		return Convert_v1_NodeNUMAResourceArgs_To_config_NodeNUMAResourceArgs(a.(*NodeNUMAResourceArgs), b.(*config.NodeNUMAResourceArgs), scope)
+	}); err != nil {
+		return err
+	}
+	if err := s.AddGeneratedConversionFunc((*config.NodeNUMAResourceArgs)(nil), (*NodeNUMAResourceArgs)(nil), func(a, b interface{}, scope conversion.Scope) error {
+		return Convert_config_NodeNUMAResourceArgs_To_v1_NodeNUMAResourceArgs(a.(*config.NodeNUMAResourceArgs), b.(*NodeNUMAResourceArgs), scope)
+	}); err != nil {
+		return err
+	}
+	if err := s.AddGeneratedConversionFunc((*ReservationArgs)(nil), (*config.ReservationArgs)(nil), func(a, b interface{}, scope conversion.Scope) error {
+		return Convert_v1_ReservationArgs_To_config_ReservationArgs(a.(*ReservationArgs), b.(*config.ReservationArgs), scope)
+	}); err != nil {
+		return err
+	}
+	if err := s.AddGeneratedConversionFunc((*config.ReservationArgs)(nil), (*ReservationArgs)(nil), func(a, b interface{}, scope conversion.Scope) error {
+		return Convert_config_ReservationArgs_To_v1_ReservationArgs(a.(*config.ReservationArgs), b.(*ReservationArgs), scope)
+	}); err != nil {
+		return err
+	}
+	if err := s.AddGeneratedConversionFunc((*ScoringStrategy)(nil), (*config.ScoringStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error {
+		return Convert_v1_ScoringStrategy_To_config_ScoringStrategy(a.(*ScoringStrategy), b.(*config.ScoringStrategy), scope)
+	}); err != nil {
+		return err
+	}
+	if err := s.AddGeneratedConversionFunc((*config.ScoringStrategy)(nil), (*ScoringStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error {
+		return Convert_config_ScoringStrategy_To_v1_ScoringStrategy(a.(*config.ScoringStrategy), b.(*ScoringStrategy), scope)
+	}); err != nil {
+		return err
+	}
+	return nil
+}
+
+func autoConvert_v1_CoschedulingArgs_To_config_CoschedulingArgs(in *CoschedulingArgs, out *config.CoschedulingArgs, s conversion.Scope) error {
+	if err := metav1.Convert_Pointer_v1_Duration_To_v1_Duration(&in.DefaultTimeout, &out.DefaultTimeout, s); err != nil {
+		return err
+	}
+	if err := metav1.Convert_Pointer_int64_To_int64(&in.ControllerWorkers, &out.ControllerWorkers, s); err != nil {
+		return err
+	}
+	if err := metav1.Convert_Pointer_bool_To_bool(&in.SkipCheckScheduleCycle, &out.SkipCheckScheduleCycle, s); err != nil {
+		return err
+	}
+	return nil
+}
+
+// Convert_v1_CoschedulingArgs_To_config_CoschedulingArgs is an autogenerated conversion function.
+func Convert_v1_CoschedulingArgs_To_config_CoschedulingArgs(in *CoschedulingArgs, out *config.CoschedulingArgs, s conversion.Scope) error {
+	return autoConvert_v1_CoschedulingArgs_To_config_CoschedulingArgs(in, out, s)
+}
+
+func autoConvert_config_CoschedulingArgs_To_v1_CoschedulingArgs(in *config.CoschedulingArgs, out *CoschedulingArgs, s conversion.Scope) error {
+	if err := metav1.Convert_v1_Duration_To_Pointer_v1_Duration(&in.DefaultTimeout, &out.DefaultTimeout, s); err != nil {
+		return err
+	}
+	if err := metav1.Convert_int64_To_Pointer_int64(&in.ControllerWorkers, &out.ControllerWorkers, s); err != nil {
+		return err
+	}
+	if err := metav1.Convert_bool_To_Pointer_bool(&in.SkipCheckScheduleCycle, &out.SkipCheckScheduleCycle, s); err != nil {
+		return err
+	}
+	return nil
+}
+
+// Convert_config_CoschedulingArgs_To_v1_CoschedulingArgs is an autogenerated conversion function.
+func Convert_config_CoschedulingArgs_To_v1_CoschedulingArgs(in *config.CoschedulingArgs, out *CoschedulingArgs, s conversion.Scope) error {
+	return autoConvert_config_CoschedulingArgs_To_v1_CoschedulingArgs(in, out, s)
+}
+
+func autoConvert_v1_DeviceShareArgs_To_config_DeviceShareArgs(in *DeviceShareArgs, out *config.DeviceShareArgs, s conversion.Scope) error {
+	out.Allocator = in.Allocator
+	out.ScoringStrategy = (*config.ScoringStrategy)(unsafe.Pointer(in.ScoringStrategy))
+	out.DisableDeviceNUMATopologyAlignment = in.DisableDeviceNUMATopologyAlignment
+	return nil
+}
+
+// Convert_v1_DeviceShareArgs_To_config_DeviceShareArgs is an autogenerated conversion function.
+func Convert_v1_DeviceShareArgs_To_config_DeviceShareArgs(in *DeviceShareArgs, out *config.DeviceShareArgs, s conversion.Scope) error {
+	return autoConvert_v1_DeviceShareArgs_To_config_DeviceShareArgs(in, out, s)
+}
+
+func autoConvert_config_DeviceShareArgs_To_v1_DeviceShareArgs(in *config.DeviceShareArgs, out *DeviceShareArgs, s conversion.Scope) error {
+	out.Allocator = in.Allocator
+	out.ScoringStrategy = (*ScoringStrategy)(unsafe.Pointer(in.ScoringStrategy))
+	out.DisableDeviceNUMATopologyAlignment = in.DisableDeviceNUMATopologyAlignment
+	return nil
+}
+
+// Convert_config_DeviceShareArgs_To_v1_DeviceShareArgs is an autogenerated conversion function.
+func Convert_config_DeviceShareArgs_To_v1_DeviceShareArgs(in *config.DeviceShareArgs, out *DeviceShareArgs, s conversion.Scope) error {
+	return autoConvert_config_DeviceShareArgs_To_v1_DeviceShareArgs(in, out, s)
+}
+
+func autoConvert_v1_ElasticQuotaArgs_To_config_ElasticQuotaArgs(in *ElasticQuotaArgs, out *config.ElasticQuotaArgs, s conversion.Scope) error {
+	if err := metav1.Convert_Pointer_v1_Duration_To_v1_Duration(&in.DelayEvictTime, &out.DelayEvictTime, s); err != nil {
+		return err
+	}
+	if err := metav1.Convert_Pointer_v1_Duration_To_v1_Duration(&in.RevokePodInterval, &out.RevokePodInterval, s); err != nil {
+		return err
+	}
+	out.DefaultQuotaGroupMax = *(*corev1.ResourceList)(unsafe.Pointer(&in.DefaultQuotaGroupMax))
+	out.SystemQuotaGroupMax = *(*corev1.ResourceList)(unsafe.Pointer(&in.SystemQuotaGroupMax))
+	out.QuotaGroupNamespace = in.QuotaGroupNamespace
+	if err := metav1.Convert_Pointer_bool_To_bool(&in.MonitorAllQuotas, &out.MonitorAllQuotas, s); err != nil {
+		return err
+	}
+	if err := metav1.Convert_Pointer_bool_To_bool(&in.EnableCheckParentQuota, &out.EnableCheckParentQuota, s); err != nil {
+		return err
+	}
+	if err := metav1.Convert_Pointer_bool_To_bool(&in.EnableRuntimeQuota, &out.EnableRuntimeQuota, s); err != nil {
+		return err
+	}
+	return nil
+}
+
+// Convert_v1_ElasticQuotaArgs_To_config_ElasticQuotaArgs is an autogenerated conversion function.
+func Convert_v1_ElasticQuotaArgs_To_config_ElasticQuotaArgs(in *ElasticQuotaArgs, out *config.ElasticQuotaArgs, s conversion.Scope) error {
+	return autoConvert_v1_ElasticQuotaArgs_To_config_ElasticQuotaArgs(in, out, s)
+}
+
+func autoConvert_config_ElasticQuotaArgs_To_v1_ElasticQuotaArgs(in *config.ElasticQuotaArgs, out *ElasticQuotaArgs, s conversion.Scope) error {
+	if err := metav1.Convert_v1_Duration_To_Pointer_v1_Duration(&in.DelayEvictTime, &out.DelayEvictTime, s); err != nil {
+		return err
+	}
+	if err := metav1.Convert_v1_Duration_To_Pointer_v1_Duration(&in.RevokePodInterval, &out.RevokePodInterval, s); err != nil {
+		return err
+	}
+	out.DefaultQuotaGroupMax = *(*corev1.ResourceList)(unsafe.Pointer(&in.DefaultQuotaGroupMax))
+	out.SystemQuotaGroupMax = *(*corev1.ResourceList)(unsafe.Pointer(&in.SystemQuotaGroupMax))
+	out.QuotaGroupNamespace = in.QuotaGroupNamespace
+	if err := metav1.Convert_bool_To_Pointer_bool(&in.MonitorAllQuotas, &out.MonitorAllQuotas, s); err != nil {
+		return err
+	}
+	if err := metav1.Convert_bool_To_Pointer_bool(&in.EnableCheckParentQuota, &out.EnableCheckParentQuota, s); err != nil {
+		return err
+	}
+	if err := metav1.Convert_bool_To_Pointer_bool(&in.EnableRuntimeQuota, &out.EnableRuntimeQuota, s); err != nil {
+		return err
+	}
+	return nil
+}
+
+// Convert_config_ElasticQuotaArgs_To_v1_ElasticQuotaArgs is an autogenerated conversion function.
+func Convert_config_ElasticQuotaArgs_To_v1_ElasticQuotaArgs(in *config.ElasticQuotaArgs, out *ElasticQuotaArgs, s conversion.Scope) error {
+	return autoConvert_config_ElasticQuotaArgs_To_v1_ElasticQuotaArgs(in, out, s)
+}
+
+func autoConvert_v1_LoadAwareSchedulingAggregatedArgs_To_config_LoadAwareSchedulingAggregatedArgs(in *LoadAwareSchedulingAggregatedArgs, out *config.LoadAwareSchedulingAggregatedArgs, s conversion.Scope) error {
+	out.UsageThresholds = *(*map[corev1.ResourceName]int64)(unsafe.Pointer(&in.UsageThresholds))
+	out.UsageAggregationType = extension.AggregationType(in.UsageAggregationType)
+	if err := metav1.Convert_Pointer_v1_Duration_To_v1_Duration(&in.UsageAggregatedDuration, &out.UsageAggregatedDuration, s); err != nil {
+		return err
+	}
+	out.ScoreAggregationType = extension.AggregationType(in.ScoreAggregationType)
+	if err := metav1.Convert_Pointer_v1_Duration_To_v1_Duration(&in.ScoreAggregatedDuration, &out.ScoreAggregatedDuration, s); err != nil {
+		return err
+	}
+	return nil
+}
+
+// Convert_v1_LoadAwareSchedulingAggregatedArgs_To_config_LoadAwareSchedulingAggregatedArgs is an autogenerated conversion function.
+func Convert_v1_LoadAwareSchedulingAggregatedArgs_To_config_LoadAwareSchedulingAggregatedArgs(in *LoadAwareSchedulingAggregatedArgs, out *config.LoadAwareSchedulingAggregatedArgs, s conversion.Scope) error {
+	return autoConvert_v1_LoadAwareSchedulingAggregatedArgs_To_config_LoadAwareSchedulingAggregatedArgs(in, out, s)
+}
+
+func autoConvert_config_LoadAwareSchedulingAggregatedArgs_To_v1_LoadAwareSchedulingAggregatedArgs(in *config.LoadAwareSchedulingAggregatedArgs, out *LoadAwareSchedulingAggregatedArgs, s conversion.Scope) error {
+	out.UsageThresholds = *(*map[corev1.ResourceName]int64)(unsafe.Pointer(&in.UsageThresholds))
+	out.UsageAggregationType = extension.AggregationType(in.UsageAggregationType)
+	if err := metav1.Convert_v1_Duration_To_Pointer_v1_Duration(&in.UsageAggregatedDuration, &out.UsageAggregatedDuration, s); err != nil {
+		return err
+	}
+	out.ScoreAggregationType = extension.AggregationType(in.ScoreAggregationType)
+	if err := metav1.Convert_v1_Duration_To_Pointer_v1_Duration(&in.ScoreAggregatedDuration, &out.ScoreAggregatedDuration, s); err != nil {
+		return err
+	}
+	return nil
+}
+
+// Convert_config_LoadAwareSchedulingAggregatedArgs_To_v1_LoadAwareSchedulingAggregatedArgs is an autogenerated conversion function.
+func Convert_config_LoadAwareSchedulingAggregatedArgs_To_v1_LoadAwareSchedulingAggregatedArgs(in *config.LoadAwareSchedulingAggregatedArgs, out *LoadAwareSchedulingAggregatedArgs, s conversion.Scope) error {
+	return autoConvert_config_LoadAwareSchedulingAggregatedArgs_To_v1_LoadAwareSchedulingAggregatedArgs(in, out, s)
+}
+
+func autoConvert_v1_LoadAwareSchedulingArgs_To_config_LoadAwareSchedulingArgs(in *LoadAwareSchedulingArgs, out *config.LoadAwareSchedulingArgs, s conversion.Scope) error {
+	out.FilterExpiredNodeMetrics = (*bool)(unsafe.Pointer(in.FilterExpiredNodeMetrics))
+	out.NodeMetricExpirationSeconds = (*int64)(unsafe.Pointer(in.NodeMetricExpirationSeconds))
+	out.EnableScheduleWhenNodeMetricsExpired = (*bool)(unsafe.Pointer(in.EnableScheduleWhenNodeMetricsExpired))
+	out.ResourceWeights = *(*map[corev1.ResourceName]int64)(unsafe.Pointer(&in.ResourceWeights))
+	out.UsageThresholds = *(*map[corev1.ResourceName]int64)(unsafe.Pointer(&in.UsageThresholds))
+	out.ProdUsageThresholds = *(*map[corev1.ResourceName]int64)(unsafe.Pointer(&in.ProdUsageThresholds))
+	if err := metav1.Convert_Pointer_bool_To_bool(&in.ScoreAccordingProdUsage, &out.ScoreAccordingProdUsage, s); err != nil {
+		return err
+	}
+	out.Estimator = in.Estimator
+	out.EstimatedScalingFactors = *(*map[corev1.ResourceName]int64)(unsafe.Pointer(&in.EstimatedScalingFactors))
+	if in.Aggregated != nil {
+		in, out := &in.Aggregated, &out.Aggregated
+		*out = new(config.LoadAwareSchedulingAggregatedArgs)
+		if err := Convert_v1_LoadAwareSchedulingAggregatedArgs_To_config_LoadAwareSchedulingAggregatedArgs(*in, *out, s); err != nil {
+			return err
+		}
+	} else {
+		out.Aggregated = nil
+	}
+	return nil
+}
+
+// Convert_v1_LoadAwareSchedulingArgs_To_config_LoadAwareSchedulingArgs is an autogenerated conversion function.
+func Convert_v1_LoadAwareSchedulingArgs_To_config_LoadAwareSchedulingArgs(in *LoadAwareSchedulingArgs, out *config.LoadAwareSchedulingArgs, s conversion.Scope) error {
+	return autoConvert_v1_LoadAwareSchedulingArgs_To_config_LoadAwareSchedulingArgs(in, out, s)
+}
+
+func autoConvert_config_LoadAwareSchedulingArgs_To_v1_LoadAwareSchedulingArgs(in *config.LoadAwareSchedulingArgs, out *LoadAwareSchedulingArgs, s conversion.Scope) error {
+	out.FilterExpiredNodeMetrics = (*bool)(unsafe.Pointer(in.FilterExpiredNodeMetrics))
+	out.NodeMetricExpirationSeconds = (*int64)(unsafe.Pointer(in.NodeMetricExpirationSeconds))
+	out.EnableScheduleWhenNodeMetricsExpired = (*bool)(unsafe.Pointer(in.EnableScheduleWhenNodeMetricsExpired))
+	out.ResourceWeights = *(*map[corev1.ResourceName]int64)(unsafe.Pointer(&in.ResourceWeights))
+	out.UsageThresholds = *(*map[corev1.ResourceName]int64)(unsafe.Pointer(&in.UsageThresholds))
+	out.ProdUsageThresholds = *(*map[corev1.ResourceName]int64)(unsafe.Pointer(&in.ProdUsageThresholds))
+	if err := metav1.Convert_bool_To_Pointer_bool(&in.ScoreAccordingProdUsage, &out.ScoreAccordingProdUsage, s); err != nil {
+		return err
+	}
+	out.Estimator = in.Estimator
+	out.EstimatedScalingFactors = *(*map[corev1.ResourceName]int64)(unsafe.Pointer(&in.EstimatedScalingFactors))
+	if in.Aggregated != nil {
+		in, out := &in.Aggregated, &out.Aggregated
+		*out = new(LoadAwareSchedulingAggregatedArgs)
+		if err := Convert_config_LoadAwareSchedulingAggregatedArgs_To_v1_LoadAwareSchedulingAggregatedArgs(*in, *out, s); err != nil {
+			return err
+		}
+	} else {
+		out.Aggregated = nil
+	}
+	return nil
+}
+
+// Convert_config_LoadAwareSchedulingArgs_To_v1_LoadAwareSchedulingArgs is an autogenerated conversion function.
+func Convert_config_LoadAwareSchedulingArgs_To_v1_LoadAwareSchedulingArgs(in *config.LoadAwareSchedulingArgs, out *LoadAwareSchedulingArgs, s conversion.Scope) error {
+	return autoConvert_config_LoadAwareSchedulingArgs_To_v1_LoadAwareSchedulingArgs(in, out, s)
+}
+
+func autoConvert_v1_NodeNUMAResourceArgs_To_config_NodeNUMAResourceArgs(in *NodeNUMAResourceArgs, out *config.NodeNUMAResourceArgs, s conversion.Scope) error {
+	if err := metav1.Convert_Pointer_string_To_string(&in.DefaultCPUBindPolicy, &out.DefaultCPUBindPolicy, s); err != nil {
+		return err
+	}
+	out.ScoringStrategy = (*config.ScoringStrategy)(unsafe.Pointer(in.ScoringStrategy))
+	out.NUMAScoringStrategy = (*config.ScoringStrategy)(unsafe.Pointer(in.NUMAScoringStrategy))
+	return nil
+}
+
+// Convert_v1_NodeNUMAResourceArgs_To_config_NodeNUMAResourceArgs is an autogenerated conversion function.
+func Convert_v1_NodeNUMAResourceArgs_To_config_NodeNUMAResourceArgs(in *NodeNUMAResourceArgs, out *config.NodeNUMAResourceArgs, s conversion.Scope) error {
+	return autoConvert_v1_NodeNUMAResourceArgs_To_config_NodeNUMAResourceArgs(in, out, s)
+}
+
+func autoConvert_config_NodeNUMAResourceArgs_To_v1_NodeNUMAResourceArgs(in *config.NodeNUMAResourceArgs, out *NodeNUMAResourceArgs, s conversion.Scope) error {
+	if err := metav1.Convert_string_To_Pointer_string(&in.DefaultCPUBindPolicy, &out.DefaultCPUBindPolicy, s); err != nil {
+		return err
+	}
+	out.ScoringStrategy = (*ScoringStrategy)(unsafe.Pointer(in.ScoringStrategy))
+	out.NUMAScoringStrategy = (*ScoringStrategy)(unsafe.Pointer(in.NUMAScoringStrategy))
+	return nil
+}
+
+// Convert_config_NodeNUMAResourceArgs_To_v1_NodeNUMAResourceArgs is an autogenerated conversion function.
+func Convert_config_NodeNUMAResourceArgs_To_v1_NodeNUMAResourceArgs(in *config.NodeNUMAResourceArgs, out *NodeNUMAResourceArgs, s conversion.Scope) error {
+	return autoConvert_config_NodeNUMAResourceArgs_To_v1_NodeNUMAResourceArgs(in, out, s)
+}
+
+func autoConvert_v1_ReservationArgs_To_config_ReservationArgs(in *ReservationArgs, out *config.ReservationArgs, s conversion.Scope) error {
+	if err := metav1.Convert_Pointer_bool_To_bool(&in.EnablePreemption, &out.EnablePreemption, s); err != nil {
+		return err
+	}
+	return nil
+}
+
+// Convert_v1_ReservationArgs_To_config_ReservationArgs is an autogenerated conversion function.
+func Convert_v1_ReservationArgs_To_config_ReservationArgs(in *ReservationArgs, out *config.ReservationArgs, s conversion.Scope) error {
+	return autoConvert_v1_ReservationArgs_To_config_ReservationArgs(in, out, s)
+}
+
+func autoConvert_config_ReservationArgs_To_v1_ReservationArgs(in *config.ReservationArgs, out *ReservationArgs, s conversion.Scope) error {
+	if err := metav1.Convert_bool_To_Pointer_bool(&in.EnablePreemption, &out.EnablePreemption, s); err != nil {
+		return err
+	}
+	return nil
+}
+
+// Convert_config_ReservationArgs_To_v1_ReservationArgs is an autogenerated conversion function.
+func Convert_config_ReservationArgs_To_v1_ReservationArgs(in *config.ReservationArgs, out *ReservationArgs, s conversion.Scope) error {
+	return autoConvert_config_ReservationArgs_To_v1_ReservationArgs(in, out, s)
+}
+
+func autoConvert_v1_ScoringStrategy_To_config_ScoringStrategy(in *ScoringStrategy, out *config.ScoringStrategy, s conversion.Scope) error {
+	out.Type = config.ScoringStrategyType(in.Type)
+	out.Resources = *(*[]apisconfig.ResourceSpec)(unsafe.Pointer(&in.Resources))
+	return nil
+}
+
+// Convert_v1_ScoringStrategy_To_config_ScoringStrategy is an autogenerated conversion function.
+func Convert_v1_ScoringStrategy_To_config_ScoringStrategy(in *ScoringStrategy, out *config.ScoringStrategy, s conversion.Scope) error {
+	return autoConvert_v1_ScoringStrategy_To_config_ScoringStrategy(in, out, s)
+}
+
+func autoConvert_config_ScoringStrategy_To_v1_ScoringStrategy(in *config.ScoringStrategy, out *ScoringStrategy, s conversion.Scope) error {
+	out.Type = ScoringStrategyType(in.Type)
+	out.Resources = *(*[]configv1.ResourceSpec)(unsafe.Pointer(&in.Resources))
+	return nil
+}
+
+// Convert_config_ScoringStrategy_To_v1_ScoringStrategy is an autogenerated conversion function.
+func Convert_config_ScoringStrategy_To_v1_ScoringStrategy(in *config.ScoringStrategy, out *ScoringStrategy, s conversion.Scope) error {
+	return autoConvert_config_ScoringStrategy_To_v1_ScoringStrategy(in, out, s)
+}
diff --git a/pkg/scheduler/apis/config/v1/zz_generated.deepcopy.go b/pkg/scheduler/apis/config/v1/zz_generated.deepcopy.go
new file mode 100644
index 00000000..ba394526
--- /dev/null
+++ b/pkg/scheduler/apis/config/v1/zz_generated.deepcopy.go
@@ -0,0 +1,365 @@
+//go:build !ignore_autogenerated
+// +build !ignore_autogenerated
+
+/*
+Copyright 2022 The Koordinator 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.
+*/
+
+// Code generated by deepcopy-gen. DO NOT EDIT.
+
+package v1
+
+import (
+	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	runtime "k8s.io/apimachinery/pkg/runtime"
+	configv1 "k8s.io/kube-scheduler/config/v1"
+)
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *CoschedulingArgs) DeepCopyInto(out *CoschedulingArgs) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	if in.DefaultTimeout != nil {
+		in, out := &in.DefaultTimeout, &out.DefaultTimeout
+		*out = new(metav1.Duration)
+		**out = **in
+	}
+	if in.ControllerWorkers != nil {
+		in, out := &in.ControllerWorkers, &out.ControllerWorkers
+		*out = new(int64)
+		**out = **in
+	}
+	if in.SkipCheckScheduleCycle != nil {
+		in, out := &in.SkipCheckScheduleCycle, &out.SkipCheckScheduleCycle
+		*out = new(bool)
+		**out = **in
+	}
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CoschedulingArgs.
+func (in *CoschedulingArgs) DeepCopy() *CoschedulingArgs {
+	if in == nil {
+		return nil
+	}
+	out := new(CoschedulingArgs)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *CoschedulingArgs) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *DeviceShareArgs) DeepCopyInto(out *DeviceShareArgs) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	if in.ScoringStrategy != nil {
+		in, out := &in.ScoringStrategy, &out.ScoringStrategy
+		*out = new(ScoringStrategy)
+		(*in).DeepCopyInto(*out)
+	}
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeviceShareArgs.
+func (in *DeviceShareArgs) DeepCopy() *DeviceShareArgs {
+	if in == nil {
+		return nil
+	}
+	out := new(DeviceShareArgs)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *DeviceShareArgs) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ElasticQuotaArgs) DeepCopyInto(out *ElasticQuotaArgs) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	if in.DelayEvictTime != nil {
+		in, out := &in.DelayEvictTime, &out.DelayEvictTime
+		*out = new(metav1.Duration)
+		**out = **in
+	}
+	if in.RevokePodInterval != nil {
+		in, out := &in.RevokePodInterval, &out.RevokePodInterval
+		*out = new(metav1.Duration)
+		**out = **in
+	}
+	if in.DefaultQuotaGroupMax != nil {
+		in, out := &in.DefaultQuotaGroupMax, &out.DefaultQuotaGroupMax
+		*out = make(corev1.ResourceList, len(*in))
+		for key, val := range *in {
+			(*out)[key] = val.DeepCopy()
+		}
+	}
+	if in.SystemQuotaGroupMax != nil {
+		in, out := &in.SystemQuotaGroupMax, &out.SystemQuotaGroupMax
+		*out = make(corev1.ResourceList, len(*in))
+		for key, val := range *in {
+			(*out)[key] = val.DeepCopy()
+		}
+	}
+	if in.MonitorAllQuotas != nil {
+		in, out := &in.MonitorAllQuotas, &out.MonitorAllQuotas
+		*out = new(bool)
+		**out = **in
+	}
+	if in.EnableCheckParentQuota != nil {
+		in, out := &in.EnableCheckParentQuota, &out.EnableCheckParentQuota
+		*out = new(bool)
+		**out = **in
+	}
+	if in.EnableRuntimeQuota != nil {
+		in, out := &in.EnableRuntimeQuota, &out.EnableRuntimeQuota
+		*out = new(bool)
+		**out = **in
+	}
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ElasticQuotaArgs.
+func (in *ElasticQuotaArgs) DeepCopy() *ElasticQuotaArgs {
+	if in == nil {
+		return nil
+	}
+	out := new(ElasticQuotaArgs)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *ElasticQuotaArgs) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *LoadAwareSchedulingAggregatedArgs) DeepCopyInto(out *LoadAwareSchedulingAggregatedArgs) {
+	*out = *in
+	if in.UsageThresholds != nil {
+		in, out := &in.UsageThresholds, &out.UsageThresholds
+		*out = make(map[corev1.ResourceName]int64, len(*in))
+		for key, val := range *in {
+			(*out)[key] = val
+		}
+	}
+	if in.UsageAggregatedDuration != nil {
+		in, out := &in.UsageAggregatedDuration, &out.UsageAggregatedDuration
+		*out = new(metav1.Duration)
+		**out = **in
+	}
+	if in.ScoreAggregatedDuration != nil {
+		in, out := &in.ScoreAggregatedDuration, &out.ScoreAggregatedDuration
+		*out = new(metav1.Duration)
+		**out = **in
+	}
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoadAwareSchedulingAggregatedArgs.
+func (in *LoadAwareSchedulingAggregatedArgs) DeepCopy() *LoadAwareSchedulingAggregatedArgs {
+	if in == nil {
+		return nil
+	}
+	out := new(LoadAwareSchedulingAggregatedArgs)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *LoadAwareSchedulingArgs) DeepCopyInto(out *LoadAwareSchedulingArgs) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	if in.FilterExpiredNodeMetrics != nil {
+		in, out := &in.FilterExpiredNodeMetrics, &out.FilterExpiredNodeMetrics
+		*out = new(bool)
+		**out = **in
+	}
+	if in.NodeMetricExpirationSeconds != nil {
+		in, out := &in.NodeMetricExpirationSeconds, &out.NodeMetricExpirationSeconds
+		*out = new(int64)
+		**out = **in
+	}
+	if in.EnableScheduleWhenNodeMetricsExpired != nil {
+		in, out := &in.EnableScheduleWhenNodeMetricsExpired, &out.EnableScheduleWhenNodeMetricsExpired
+		*out = new(bool)
+		**out = **in
+	}
+	if in.ResourceWeights != nil {
+		in, out := &in.ResourceWeights, &out.ResourceWeights
+		*out = make(map[corev1.ResourceName]int64, len(*in))
+		for key, val := range *in {
+			(*out)[key] = val
+		}
+	}
+	if in.UsageThresholds != nil {
+		in, out := &in.UsageThresholds, &out.UsageThresholds
+		*out = make(map[corev1.ResourceName]int64, len(*in))
+		for key, val := range *in {
+			(*out)[key] = val
+		}
+	}
+	if in.ProdUsageThresholds != nil {
+		in, out := &in.ProdUsageThresholds, &out.ProdUsageThresholds
+		*out = make(map[corev1.ResourceName]int64, len(*in))
+		for key, val := range *in {
+			(*out)[key] = val
+		}
+	}
+	if in.ScoreAccordingProdUsage != nil {
+		in, out := &in.ScoreAccordingProdUsage, &out.ScoreAccordingProdUsage
+		*out = new(bool)
+		**out = **in
+	}
+	if in.EstimatedScalingFactors != nil {
+		in, out := &in.EstimatedScalingFactors, &out.EstimatedScalingFactors
+		*out = make(map[corev1.ResourceName]int64, len(*in))
+		for key, val := range *in {
+			(*out)[key] = val
+		}
+	}
+	if in.Aggregated != nil {
+		in, out := &in.Aggregated, &out.Aggregated
+		*out = new(LoadAwareSchedulingAggregatedArgs)
+		(*in).DeepCopyInto(*out)
+	}
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoadAwareSchedulingArgs.
+func (in *LoadAwareSchedulingArgs) DeepCopy() *LoadAwareSchedulingArgs {
+	if in == nil {
+		return nil
+	}
+	out := new(LoadAwareSchedulingArgs)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *LoadAwareSchedulingArgs) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *NodeNUMAResourceArgs) DeepCopyInto(out *NodeNUMAResourceArgs) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	if in.DefaultCPUBindPolicy != nil {
+		in, out := &in.DefaultCPUBindPolicy, &out.DefaultCPUBindPolicy
+		*out = new(string)
+		**out = **in
+	}
+	if in.ScoringStrategy != nil {
+		in, out := &in.ScoringStrategy, &out.ScoringStrategy
+		*out = new(ScoringStrategy)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.NUMAScoringStrategy != nil {
+		in, out := &in.NUMAScoringStrategy, &out.NUMAScoringStrategy
+		*out = new(ScoringStrategy)
+		(*in).DeepCopyInto(*out)
+	}
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeNUMAResourceArgs.
+func (in *NodeNUMAResourceArgs) DeepCopy() *NodeNUMAResourceArgs {
+	if in == nil {
+		return nil
+	}
+	out := new(NodeNUMAResourceArgs)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *NodeNUMAResourceArgs) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ReservationArgs) DeepCopyInto(out *ReservationArgs) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	if in.EnablePreemption != nil {
+		in, out := &in.EnablePreemption, &out.EnablePreemption
+		*out = new(bool)
+		**out = **in
+	}
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReservationArgs.
+func (in *ReservationArgs) DeepCopy() *ReservationArgs {
+	if in == nil {
+		return nil
+	}
+	out := new(ReservationArgs)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *ReservationArgs) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ScoringStrategy) DeepCopyInto(out *ScoringStrategy) {
+	*out = *in
+	if in.Resources != nil {
+		in, out := &in.Resources, &out.Resources
+		*out = make([]configv1.ResourceSpec, len(*in))
+		copy(*out, *in)
+	}
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScoringStrategy.
+func (in *ScoringStrategy) DeepCopy() *ScoringStrategy {
+	if in == nil {
+		return nil
+	}
+	out := new(ScoringStrategy)
+	in.DeepCopyInto(out)
+	return out
+}
diff --git a/pkg/scheduler/apis/config/v1/zz_generated.defaults.go b/pkg/scheduler/apis/config/v1/zz_generated.defaults.go
new file mode 100644
index 00000000..6b419ef3
--- /dev/null
+++ b/pkg/scheduler/apis/config/v1/zz_generated.defaults.go
@@ -0,0 +1,63 @@
+//go:build !ignore_autogenerated
+// +build !ignore_autogenerated
+
+/*
+Copyright 2022 The Koordinator 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.
+*/
+
+// Code generated by defaulter-gen. DO NOT EDIT.
+
+package v1
+
+import (
+	runtime "k8s.io/apimachinery/pkg/runtime"
+)
+
+// RegisterDefaults adds defaulters functions to the given scheme.
+// Public to allow building arbitrary schemes.
+// All generated defaulters are covering - they call all nested defaulters.
+func RegisterDefaults(scheme *runtime.Scheme) error {
+	scheme.AddTypeDefaultingFunc(&CoschedulingArgs{}, func(obj interface{}) { SetObjectDefaults_CoschedulingArgs(obj.(*CoschedulingArgs)) })
+	scheme.AddTypeDefaultingFunc(&DeviceShareArgs{}, func(obj interface{}) { SetObjectDefaults_DeviceShareArgs(obj.(*DeviceShareArgs)) })
+	scheme.AddTypeDefaultingFunc(&ElasticQuotaArgs{}, func(obj interface{}) { SetObjectDefaults_ElasticQuotaArgs(obj.(*ElasticQuotaArgs)) })
+	scheme.AddTypeDefaultingFunc(&LoadAwareSchedulingArgs{}, func(obj interface{}) { SetObjectDefaults_LoadAwareSchedulingArgs(obj.(*LoadAwareSchedulingArgs)) })
+	scheme.AddTypeDefaultingFunc(&NodeNUMAResourceArgs{}, func(obj interface{}) { SetObjectDefaults_NodeNUMAResourceArgs(obj.(*NodeNUMAResourceArgs)) })
+	scheme.AddTypeDefaultingFunc(&ReservationArgs{}, func(obj interface{}) { SetObjectDefaults_ReservationArgs(obj.(*ReservationArgs)) })
+	return nil
+}
+
+func SetObjectDefaults_CoschedulingArgs(in *CoschedulingArgs) {
+	SetDefaults_CoschedulingArgs(in)
+}
+
+func SetObjectDefaults_DeviceShareArgs(in *DeviceShareArgs) {
+	SetDefaults_DeviceShareArgs(in)
+}
+
+func SetObjectDefaults_ElasticQuotaArgs(in *ElasticQuotaArgs) {
+	SetDefaults_ElasticQuotaArgs(in)
+}
+
+func SetObjectDefaults_LoadAwareSchedulingArgs(in *LoadAwareSchedulingArgs) {
+	SetDefaults_LoadAwareSchedulingArgs(in)
+}
+
+func SetObjectDefaults_NodeNUMAResourceArgs(in *NodeNUMAResourceArgs) {
+	SetDefaults_NodeNUMAResourceArgs(in)
+}
+
+func SetObjectDefaults_ReservationArgs(in *ReservationArgs) {
+	SetDefaults_ReservationArgs(in)
+}
diff --git a/pkg/scheduler/plugins/coscheduling/core/core.go b/pkg/scheduler/plugins/coscheduling/core/core.go
index 812b5e54..02889832 100644
--- a/pkg/scheduler/plugins/coscheduling/core/core.go
+++ b/pkg/scheduler/plugins/coscheduling/core/core.go
@@ -61,6 +61,7 @@ const (
 
 // Manager defines the interfaces for PodGroup management.
 type Manager interface {
+	PreEnqueue(context.Context, *corev1.Pod) (err error)
 	PreFilter(context.Context, *framework.CycleState, *corev1.Pod) (err error)
 	Permit(context.Context, *corev1.Pod) (time.Duration, Status)
 	PostBind(context.Context, *corev1.Pod, string)
@@ -224,31 +225,25 @@ func (pgMgr *PodGroupManager) ActivateSiblings(pod *corev1.Pod, state *framework
 	}
 }
 
-// PreFilter
+// PreEnqueue
 // i.Check whether children in Gang has met the requirements of minimum number under each Gang, and reject the pod if negative.
 // ii.Check whether the Gang is inited, and reject the pod if positive.
-// iii.Check whether the Gang is OnceResourceSatisfied
-// iv.Check whether the Gang has met the scheduleCycleValid check, and reject the pod if negative(only Strict mode ).
-// v.Try update scheduleCycle, scheduleCycleValid, childrenScheduleRoundMap as mentioned above.
-func (pgMgr *PodGroupManager) PreFilter(ctx context.Context, state *framework.CycleState, pod *corev1.Pod) (err error) {
+func (pgMgr *PodGroupManager) PreEnqueue(ctx context.Context, pod *corev1.Pod) (err error) {
 	if !util.IsPodNeedGang(pod) {
 		return nil
 	}
-	preFilterState := &stateData{skipReject: false, skipSetCycleInvalid: false}
-	state.Write(stateKey, preFilterState)
+
 	gang := pgMgr.GetGangByPod(pod)
 	if gang == nil {
-		preFilterState.skipSetCycleInvalid = true
 		return fmt.Errorf("can't find gang, gangName: %v, podName: %v", util.GetId(pod.Namespace, util.GetGangNameByPod(pod)),
 			util.GetId(pod.Namespace, pod.Name))
 	}
 
-	// check if gang is initialized
 	if !gang.HasGangInit {
-		preFilterState.skipSetCycleInvalid = true
 		return fmt.Errorf("gang has not init, gangName: %v, podName: %v", gang.Name,
 			util.GetId(pod.Namespace, pod.Name))
 	}
+
 	// resourceSatisfied means pod will directly pass the PreFilter
 	if gang.getGangMatchPolicy() == extension.GangMatchPolicyOnceSatisfied && gang.isGangOnceResourceSatisfied() {
 		return nil
@@ -256,11 +251,30 @@ func (pgMgr *PodGroupManager) PreFilter(ctx context.Context, state *framework.Cy
 
 	// check minNum
 	if gang.getChildrenNum() < gang.getGangMinNum() {
-		preFilterState.skipSetCycleInvalid = true
 		return fmt.Errorf("gang child pod not collect enough, gangName: %v, podName: %v", gang.Name,
 			util.GetId(pod.Namespace, pod.Name))
 	}
 
+	return nil
+}
+
+// PreFilter
+// i.Check whether the Gang has met the scheduleCycleValid check, and reject the pod if negative(only Strict mode ).
+// ii.Check whether the Gang is OnceResourceSatisfied
+// iii.Check whether the Gang has met the scheduleCycleValid check, and reject the pod if negative(only Strict mode ).
+func (pgMgr *PodGroupManager) PreFilter(ctx context.Context, state *framework.CycleState, pod *corev1.Pod) (err error) {
+	if !util.IsPodNeedGang(pod) {
+		return nil
+	}
+	preFilterState := &stateData{skipReject: false, skipSetCycleInvalid: false}
+	state.Write(stateKey, preFilterState)
+	gang := pgMgr.GetGangByPod(pod)
+
+	// resourceSatisfied means pod will directly pass the PreFilter
+	if gang.getGangMatchPolicy() == extension.GangMatchPolicyOnceSatisfied && gang.isGangOnceResourceSatisfied() {
+		return nil
+	}
+
 	if pgMgr.args != nil && pgMgr.args.SkipCheckScheduleCycle {
 		return nil
 	}
@@ -277,17 +291,19 @@ func (pgMgr *PodGroupManager) PreFilter(ctx context.Context, state *framework.Cy
 		if pod.Status.NominatedNodeName != "" {
 			return nil
 		}
-		podScheduleCycle := gang.getChildScheduleCycle(pod)
 		if !gang.isScheduleCycleValid() {
 			preFilterState.skipReject = true
 			return fmt.Errorf("gang scheduleCycle not valid, gangName: %v, podName: %v",
 				gang.Name, util.GetId(pod.Namespace, pod.Name))
 		}
+
+		podScheduleCycle := gang.getChildScheduleCycle(pod)
 		if podScheduleCycle >= gangScheduleCycle {
 			return fmt.Errorf("pod's schedule cycle too large, gangName: %v, podName: %v, podCycle: %v, gangCycle: %v",
 				gang.Name, util.GetId(pod.Namespace, pod.Name), podScheduleCycle, gangScheduleCycle)
 		}
 	}
+
 	return nil
 }
 
diff --git a/pkg/scheduler/plugins/coscheduling/core/ganggroup.go b/pkg/scheduler/plugins/coscheduling/core/ganggroup.go
index 755e3434..5a8b5397 100644
--- a/pkg/scheduler/plugins/coscheduling/core/ganggroup.go
+++ b/pkg/scheduler/plugins/coscheduling/core/ganggroup.go
@@ -83,7 +83,7 @@ func (gg *GangGroupInfo) setScheduleCycleInvalid() {
 
 	if gg.ScheduleCycleValid {
 		gg.ScheduleCycleValid = false
-		klog.Infof("setScheduleCycleInvalid, gangGroupName: %v, valid: %v", gg.GangGroupId)
+		klog.Infof("setScheduleCycleInvalid, gangGroupName: %v, valid: %v", gg.GangGroupId, gg.ScheduleCycleValid)
 	}
 }
 
diff --git a/pkg/scheduler/plugins/coscheduling/coscheduling.go b/pkg/scheduler/plugins/coscheduling/coscheduling.go
index 27fb9138..1f0ddd65 100644
--- a/pkg/scheduler/plugins/coscheduling/coscheduling.go
+++ b/pkg/scheduler/plugins/coscheduling/coscheduling.go
@@ -49,6 +49,7 @@ type Coscheduling struct {
 	pgMgr            core.Manager
 }
 
+var _ framework.PreEnqueuePlugin = &Coscheduling{}
 var _ framework.QueueSortPlugin = &Coscheduling{}
 var _ frameworkext.PreFilterTransformer = &Coscheduling{}
 var _ framework.PreFilterPlugin = &Coscheduling{}
@@ -111,6 +112,17 @@ func (cs *Coscheduling) Name() string {
 	return Name
 }
 
+// PreEnqueue
+// i.Check whether childes in Gang has met the requirements of minimum number under each Gang, and reject the pod if negative.
+// ii.Check whether the Gang has been timeout(check the pod's annotation,later introduced at Permit section) or is inited, and reject the pod if positive.
+func (cs *Coscheduling) PreEnqueue(ctx context.Context, pod *v1.Pod) *framework.Status {
+	if err := cs.pgMgr.PreEnqueue(ctx, pod); err != nil {
+		klog.ErrorS(err, "PreEnqueue failed", "pod", klog.KObj(pod))
+		return framework.NewStatus(framework.UnschedulableAndUnresolvable, err.Error())
+	}
+	return framework.NewStatus(framework.Success, "")
+}
+
 // Less is sorting pods in the scheduling queue in the following order.
 // Firstly, compare the priorities of the two pods, the higher priority (if pod's priority is equal,then compare their KoordinatorPriority at labels )is at the front of the queue,
 // Secondly, compare Gang group ID of the two pods, pods that NOT belong to a Gang will have higher priority than pods that belongs to a Gang,
@@ -162,11 +174,8 @@ func (cs *Coscheduling) Less(podInfo1, podInfo2 *framework.QueuedPodInfo) bool {
 }
 
 // BeforePreFilter
-// if non-strict-mode, we only do step1 and step2:
-// i.Check whether childes in Gang has met the requirements of minimum number under each Gang, and reject the pod if negative.
-// ii.Check whether the Gang has been timeout(check the pod's annotation,later introduced at Permit section) or is inited, and reject the pod if positive.
-// iii.Check whether the Gang has met the scheduleCycleValid check, and reject the pod if negative.
-// iv.Try update scheduleCycle, scheduleCycleValid, childrenScheduleRoundMap as mentioned above.
+// i.Check whether the Gang has met the scheduleCycleValid check, and reject the pod if negative.
+// ii.Try update scheduleCycle, scheduleCycleValid, childrenScheduleRoundMap as mentioned above.
 func (cs *Coscheduling) BeforePreFilter(ctx context.Context, state *framework.CycleState, pod *v1.Pod) (*v1.Pod, bool, *framework.Status) {
 	// If PreFilter fails, return framework.UnschedulableAndUnresolvable to avoid any preemption attempts.
 	if err := cs.pgMgr.PreFilter(ctx, state, pod); err != nil {



Test patch:
diff --git a/pkg/scheduler/plugins/coscheduling/core/core_test.go b/pkg/scheduler/plugins/coscheduling/core/core_test.go
index 90913cd0..463ee998 100644
--- a/pkg/scheduler/plugins/coscheduling/core/core_test.go
+++ b/pkg/scheduler/plugins/coscheduling/core/core_test.go
@@ -139,7 +139,7 @@ func TestPlugin_PreFilter_ResetScheduleTime(t *testing.T) {
 	assert.Equal(t, lastScheduleTime3, gang.GangGroupInfo.ChildrenLastScheduleTime["default/pod2"])
 }
 
-func TestPlugin_PreFilter(t *testing.T) {
+func TestPlugin_PreEnqueue(t *testing.T) {
 	gangACreatedTime := time.Now()
 	mgr := NewManagerForTest().pgMgr
 	tests := []struct {
@@ -223,25 +223,6 @@ func TestPlugin_PreFilter(t *testing.T) {
 			isNonStrictMode:      true,
 			expectStateData:      &stateData{},
 		},
-		{
-			name: "due to reschedule pod6's podScheduleCycle is equal with the gangScheduleCycle",
-			pod:  st.MakePod().Name("pod6").UID("pod6").Namespace("ganga_ns").Label(v1alpha1.PodGroupLabel, "gangc").Obj(),
-			pods: []*corev1.Pod{
-				st.MakePod().Name("pod6-1").UID("pod6-1").Namespace("ganga_ns").Label(v1alpha1.PodGroupLabel, "gangc").Obj(),
-				st.MakePod().Name("pod6-2").UID("pod6-2").Namespace("ganga_ns").Label(v1alpha1.PodGroupLabel, "gangc").Obj(),
-				st.MakePod().Name("pod6-3").UID("pod6-3").Namespace("ganga_ns").Label(v1alpha1.PodGroupLabel, "gangc").Obj(),
-			},
-			pgs:                           makePg("gangc", "ganga_ns", 4, &gangACreatedTime, nil),
-			shouldSetCycleEqualWithGlobal: true,
-			totalNum:                      5,
-			expectedScheduleCycle:         1,
-			expectedChildCycleMap: map[string]int{
-				"ganga_ns/pod6": 1,
-			},
-			expectedErrorMessage:       "pod's schedule cycle too large, gangName: ganga_ns/gangc, podName: ganga_ns/pod6, podCycle: 1, gangCycle: 1",
-			expectedScheduleCycleValid: true,
-			expectStateData:            &stateData{},
-		},
 		{
 			name: "due to reschedule pod6's podScheduleCycle is equal with the gangScheduleCycle, but pod6's nominatedNodeName is not empty",
 			pod: st.MakePod().Name("pod6").UID("pod6").Namespace("ganga_ns").Label(v1alpha1.PodGroupLabel, "gangc").
@@ -265,26 +246,6 @@ func TestPlugin_PreFilter(t *testing.T) {
 			expectedScheduleCycleValid: true,
 			expectStateData:            &stateData{},
 		},
-		{
-			name: "pods count equal with minMember,is StrictMode,but the gang's scheduleCycle is not valid due to pre pod Filter Failed",
-			pod:  st.MakePod().Name("pod7").UID("pod7").Namespace("ganga_ns").Label(v1alpha1.PodGroupLabel, "gangd").Obj(),
-			pods: []*corev1.Pod{
-				st.MakePod().Name("pod7-1").UID("pod7-1").Namespace("ganga_ns").Label(v1alpha1.PodGroupLabel, "gangd").Obj(),
-				st.MakePod().Name("pod7-2").UID("pod7-2").Namespace("ganga_ns").Label(v1alpha1.PodGroupLabel, "gangd").Obj(),
-				st.MakePod().Name("pod7-3").UID("pod7-3").Namespace("ganga_ns").Label(v1alpha1.PodGroupLabel, "gangd").Obj(),
-			},
-			pgs:                   makePg("gangd", "ganga_ns", 4, &gangACreatedTime, nil),
-			expectedScheduleCycle: 1,
-			expectedChildCycleMap: map[string]int{
-				"ganga_ns/pod7": 1,
-			},
-			expectedScheduleCycleValid: false,
-			expectedErrorMessage:       "gang scheduleCycle not valid, gangName: ganga_ns/gangd, podName: ganga_ns/pod7",
-			shouldSetValidToFalse:      true,
-			expectStateData: &stateData{
-				skipReject: true,
-			},
-		},
 		{
 			name: "pods count equal with minMember,is StrictMode, disable check scheduleCycle even if the gang's scheduleCycle is not valid",
 			pod:  st.MakePod().Name("pod7").UID("pod7").Namespace("ganga_ns").Label(v1alpha1.PodGroupLabel, "gangd").Obj(),
@@ -365,6 +326,215 @@ func TestPlugin_PreFilter(t *testing.T) {
 			}
 			ctx := context.TODO()
 
+			// add each neighbor pods and run preFilter
+			for _, pod := range tt.pods {
+				mgr.cache.onPodAdd(pod)
+				mgr.PreEnqueue(ctx, pod)
+
+			}
+			mgr.cache.onPodAdd(tt.pod)
+
+			// set pre cases before test pod run
+			if tt.shouldSetValidToFalse {
+				gang.setScheduleCycleInvalid()
+			}
+			if tt.shouldSetCycleEqualWithGlobal {
+				gang.setChildScheduleCycle(tt.pod, 1)
+			}
+			if tt.resourceSatisfied {
+				gang.setResourceSatisfied()
+			}
+			if tt.shouldSkipCheckScheduleCycle {
+				mgr.args.SkipCheckScheduleCycle = true
+				defer func() {
+					mgr.args.SkipCheckScheduleCycle = false
+				}()
+			}
+			// run the case
+			// cycleState := framework.NewCycleState()
+			// err := mgr.PreFilter(ctx, cycleState, tt.pod)
+			err := mgr.PreEnqueue(ctx, tt.pod)
+			var returnMessage string
+			if err == nil {
+				returnMessage = ""
+			} else {
+				returnMessage = err.Error()
+			}
+
+			assert.Equal(t, tt.expectedErrorMessage, returnMessage)
+		})
+	}
+}
+
+func TestPlugin_PreFilter(t *testing.T) {
+	gangACreatedTime := time.Now()
+	mgr := NewManagerForTest().pgMgr
+	tests := []struct {
+		name string
+		// test pod
+		pod *corev1.Pod
+		// neighbor pods, make the condition ready for the test pod
+		pods []*corev1.Pod
+		pgs  *v1alpha1.PodGroup
+		// assert value
+		// expectedErrorMessage is "" represents that error is nil
+		expectedErrorMessage       string
+		expectedChildCycleMap      map[string]int
+		expectedScheduleCycle      int
+		expectedScheduleCycleValid bool
+		expectStateData            *stateData
+		// case value
+		// next two are set before pg created
+		totalNum          int
+		isNonStrictMode   bool
+		resourceSatisfied bool
+		// next tow are set before test pod run
+		shouldSetValidToFalse         bool
+		shouldSetCycleEqualWithGlobal bool
+		shouldSkipCheckScheduleCycle  bool
+	}{
+		{
+			name:                 "pod does not belong to any gang",
+			pod:                  st.MakePod().Name("pod1").UID("pod1").Namespace("ns1").Obj(),
+			pods:                 []*corev1.Pod{},
+			expectedErrorMessage: "",
+		},
+		{
+			name:                       "gang ResourceSatisfied",
+			pod:                        st.MakePod().Name("podq").UID("podq").Namespace("gangq_ns").Label(v1alpha1.PodGroupLabel, "gangq").Obj(),
+			expectedChildCycleMap:      map[string]int{},
+			pgs:                        makePg("gangq", "gangq_ns", 4, &gangACreatedTime, nil),
+			expectedScheduleCycleValid: true,
+			expectedScheduleCycle:      1,
+			resourceSatisfied:          true,
+			expectStateData:            &stateData{},
+		},
+		{
+			name: "pods count equal with minMember,but is NonStrictMode",
+			pod:  st.MakePod().Name("pod5").UID("pod5").Namespace("gangb_ns").Label(v1alpha1.PodGroupLabel, "gangb").Obj(),
+			pods: []*corev1.Pod{
+				st.MakePod().Name("pod5-1").UID("pod5-1").Namespace("gangb_ns").Label(v1alpha1.PodGroupLabel, "gangb").Obj(),
+				st.MakePod().Name("pod5-2").UID("pod5-2").Namespace("gangb_ns").Label(v1alpha1.PodGroupLabel, "gangb").Obj(),
+				st.MakePod().Name("pod5-3").UID("pod5-3").Namespace("gangb_ns").Label(v1alpha1.PodGroupLabel, "gangb").Obj(),
+			},
+			pgs:                  makePg("gangb", "gangb_ns", 4, &gangACreatedTime, nil),
+			expectedErrorMessage: "",
+			isNonStrictMode:      true,
+			expectStateData:      &stateData{},
+		},
+		{
+			name:                          "due to reschedule pod6's podScheduleCycle is equal with the gangScheduleCycle",
+			pod:                           st.MakePod().Name("pod6").UID("pod6").Namespace("ganga_ns").Label(v1alpha1.PodGroupLabel, "gangc").Obj(),
+			pods:                          []*corev1.Pod{},
+			pgs:                           makePg("gangc", "ganga_ns", 1, &gangACreatedTime, nil),
+			shouldSetCycleEqualWithGlobal: true,
+			totalNum:                      5,
+			expectedScheduleCycle:         1,
+			expectedChildCycleMap: map[string]int{
+				"ganga_ns/pod6": 1,
+			},
+			expectedErrorMessage:       "pod's schedule cycle too large, gangName: ganga_ns/gangc, podName: ganga_ns/pod6, podCycle: 1, gangCycle: 1",
+			expectedScheduleCycleValid: true,
+			expectStateData:            &stateData{},
+		},
+		{
+			name: "due to reschedule pod6's podScheduleCycle is equal with the gangScheduleCycle, but pod6's nominatedNodeName is not empty",
+			pod: st.MakePod().Name("pod6").UID("pod6").Namespace("ganga_ns").Label(v1alpha1.PodGroupLabel, "gangc").
+				NominatedNodeName("N1").Obj(),
+			pods: []*corev1.Pod{
+				st.MakePod().Name("pod6-1").UID("pod6-1").Namespace("ganga_ns").Label(v1alpha1.PodGroupLabel, "gangc").NominatedNodeName("N1").Obj(),
+				st.MakePod().Name("pod6-2").UID("pod6-2").Namespace("ganga_ns").Label(v1alpha1.PodGroupLabel, "gangc").NominatedNodeName("N1").Obj(),
+				st.MakePod().Name("pod6-3").UID("pod6-3").Namespace("ganga_ns").Label(v1alpha1.PodGroupLabel, "gangc").NominatedNodeName("N1").Obj(),
+			},
+			pgs:                           makePg("gangc", "ganga_ns", 4, &gangACreatedTime, nil),
+			shouldSetCycleEqualWithGlobal: true,
+			totalNum:                      5,
+			expectedScheduleCycle:         1,
+			expectedChildCycleMap: map[string]int{
+				"ganga_ns/pod6":   1,
+				"ganga_ns/pod6-1": 1,
+				"ganga_ns/pod6-2": 1,
+				"ganga_ns/pod6-3": 1,
+			},
+			expectedErrorMessage:       "",
+			expectedScheduleCycleValid: true,
+			expectStateData:            &stateData{},
+		},
+		{
+			name:                  "pods count equal with minMember,is StrictMode,but the gang's scheduleCycle is not valid due to pre pod Filter Failed",
+			pod:                   st.MakePod().Name("pod7").UID("pod7").Namespace("ganga_ns").Label(v1alpha1.PodGroupLabel, "gangd").Obj(),
+			pods:                  []*corev1.Pod{},
+			pgs:                   makePg("gangd", "ganga_ns", 1, &gangACreatedTime, nil),
+			expectedScheduleCycle: 1,
+			expectedChildCycleMap: map[string]int{
+				"ganga_ns/pod7": 1,
+			},
+			expectedScheduleCycleValid: false,
+			expectedErrorMessage:       "gang scheduleCycle not valid, gangName: ganga_ns/gangd, podName: ganga_ns/pod7",
+			shouldSetValidToFalse:      true,
+			expectStateData: &stateData{
+				skipReject: true,
+			},
+		},
+		{
+			name:                  "pods count equal with minMember,is StrictMode, disable check scheduleCycle even if the gang's scheduleCycle is not valid",
+			pod:                   st.MakePod().Name("pod7").UID("pod7").Namespace("ganga_ns").Label(v1alpha1.PodGroupLabel, "gangd").Obj(),
+			pods:                  []*corev1.Pod{},
+			pgs:                   makePg("gangd", "ganga_ns", 1, &gangACreatedTime, nil),
+			expectedScheduleCycle: 1,
+			expectedChildCycleMap: map[string]int{
+				"ganga_ns/pod7": 1,
+			},
+			expectedScheduleCycleValid:   false,
+			expectedErrorMessage:         "",
+			shouldSetValidToFalse:        true,
+			shouldSkipCheckScheduleCycle: true,
+			expectStateData:              &stateData{},
+		},
+		{
+			name: "pods count more than minMember,is StrictMode,scheduleCycle valid,and childrenNum reach to total num",
+			pod:  st.MakePod().Name("pod9").UID("pod9").Namespace("ganga_ns").Label(v1alpha1.PodGroupLabel, "ganga").Obj(),
+			pods: []*corev1.Pod{
+				st.MakePod().Name("pod9-1").UID("pod9-1").Namespace("ganga_ns").Label(v1alpha1.PodGroupLabel, "ganga").Obj(),
+				st.MakePod().Name("pod9-2").UID("pod9-2").Namespace("ganga_ns").Label(v1alpha1.PodGroupLabel, "ganga").Obj(),
+				st.MakePod().Name("pod9-3").UID("pod9-3").Namespace("ganga_ns").Label(v1alpha1.PodGroupLabel, "ganga").Obj(),
+				st.MakePod().Name("pod9-4").UID("pod9-4").Namespace("ganga_ns").Label(v1alpha1.PodGroupLabel, "ganga").Obj(),
+			},
+			pgs:                   makePg("ganga", "ganga_ns", 1, &gangACreatedTime, nil),
+			totalNum:              5,
+			expectedScheduleCycle: 1,
+			expectedChildCycleMap: map[string]int{
+				"ganga_ns/pod9":   1,
+				"ganga_ns/pod9-1": 1,
+				"ganga_ns/pod9-2": 1,
+				"ganga_ns/pod9-3": 1,
+				"ganga_ns/pod9-4": 1,
+			},
+			expectedErrorMessage:       "",
+			expectedScheduleCycleValid: true,
+			expectStateData:            &stateData{},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			var gang *Gang
+			// first create the podGroup
+			if tt.pgs != nil {
+				if tt.pgs.Annotations == nil {
+					tt.pgs.Annotations = map[string]string{}
+				}
+				if tt.totalNum != 0 {
+					totalNumStr := strconv.Itoa(tt.totalNum)
+					tt.pgs.Annotations[extension.AnnotationGangTotalNum] = totalNumStr
+				}
+				if tt.isNonStrictMode {
+					tt.pgs.Annotations[extension.AnnotationGangMode] = extension.GangModeNonStrict
+				}
+				mgr.cache.onPodGroupAdd(tt.pgs)
+				gang = mgr.cache.getGangFromCacheByGangId(util.GetId(tt.pgs.Namespace, tt.pgs.Name), false)
+			}
+			ctx := context.TODO()
+
 			// add each neighbor pods and run preFilter
 			for _, pod := range tt.pods {
 				mgr.cache.onPodAdd(pod)
diff --git a/pkg/scheduler/plugins/coscheduling/coscheduling_test.go b/pkg/scheduler/plugins/coscheduling/coscheduling_test.go
index 428b7133..341fd577 100644
--- a/pkg/scheduler/plugins/coscheduling/coscheduling_test.go
+++ b/pkg/scheduler/plugins/coscheduling/coscheduling_test.go
@@ -209,6 +209,7 @@ func newPluginTestSuit(t *testing.T, nodes []*corev1.Node, pgClientSet pgclients
 		schedulertesting.RegisterReservePlugin(Name, proxyNew),
 		schedulertesting.RegisterPermitPlugin(Name, proxyNew),
 		schedulertesting.RegisterPluginAsExtensions(Name, proxyNew, "PostBind"),
+		schedulertesting.RegisterPluginAsExtensions(Name, proxyNew, "PreEnqueue"),
 	}
 	fakeRecorder := record.NewFakeRecorder(1024)
 	eventRecorder := record.NewEventRecorderAdapter(fakeRecorder)
@@ -1217,20 +1218,31 @@ func schedulePod(ctx context.Context, suit *pluginTestSuit, fwk framework.Framew
 		UnschedulablePlugins: sets.Set[string]{},
 	}
 
+	fitError := &framework.FitError{
+		Pod:         pod,
+		NumAllNodes: 1,
+		Diagnosis:   diagnosis,
+	}
+
+	// Run "preEnqueue" plugins
+	s := suit.plugin.(*Coscheduling).PreEnqueue(ctx, pod)
+	if !s.IsSuccess() {
+		info.result = "PreEnqueue"
+		return result, fitError
+	}
+
 	// Run "prefilter" plugins.
-	_, _, s := suit.plugin.(*Coscheduling).BeforePreFilter(ctx, state, pod)
+	_, _, s = suit.plugin.(*Coscheduling).BeforePreFilter(ctx, state, pod)
 	if !s.IsSuccess() {
 		info.result = "PreFiler"
-	} else if injectFilterError {
-		info.result = "Filter"
+		return result, fitError
 	}
-	if info.result != "" {
-		return result, &framework.FitError{
-			Pod:         pod,
-			NumAllNodes: 1,
-			Diagnosis:   diagnosis,
-		}
+
+	if injectFilterError {
+		info.result = "PreFiler"
+		return result, fitError
 	}
+
 	return scheduler.ScheduleResult{
 		SuggestedHost: "fake-host",
 	}, err
@@ -1451,6 +1463,9 @@ func TestNoRejectWhenInvalidCycle(t *testing.T) {
 	_, status := suit.plugin.(*Coscheduling).PostFilter(ctx, framework.NewCycleState(), allPods[0], nil)
 	assert.False(t, status.IsSuccess())
 
+	status = suit.plugin.(*Coscheduling).PreEnqueue(ctx, memberPodsOfGang[util.GetId("default", gangNames[0])][0])
+	assert.True(t, status.IsSuccess())
+
 	_, _, status = suit.plugin.(*Coscheduling).BeforePreFilter(ctx, framework.NewCycleState(), memberPodsOfGang[util.GetId("default", gangNames[0])][0])
 	assert.False(t, status.IsSuccess())